# API Admin — Guia de Implementacion

> Stack: Laravel + MongoDB + Laravel Sanctum
> Prefijo base: /api/admin/*
> Seguridad: Bearer Token (Sanctum) + rol administrador

---

## 1. Archivos creados / modificados

| Archivo | Descripcion |
|---------|-------------|
| app/Http/Middleware/AdminApiMiddleware.php | Verifica rol=administrador. Retorna JSON 403 (sin redirect). |
| app/Http/Kernel.php | Registra alias admin.api |
| app/Http/Controllers/Api/Admin/UsuarioController.php | CRUD usuarios + activar/desactivar |
| app/Http/Controllers/Api/Admin/VcardController.php | Listar, ver, editar vcards; por usuario |
| app/Http/Controllers/Api/Admin/MembresiaController.php | Ver/activar/desactivar membresia + cambiar plan |
| app/Http/Controllers/Api/Admin/PagoController.php | Historial HealthPagos + transacciones wallet |
| app/Http/Controllers/Api/Admin/LogController.php | Log de movimientos global y por usuario |
| app/Http/Controllers/Api/Admin/MiniWebController.php | Miniwebs con usuario y vcard vinculada |
| routes/api.php | 34 rutas nuevas bajo /api/admin/* |

---

## 2. Implementar en otro proyecto

### 2.1 Requisitos previos
- Laravel >= 10
- mongodb/laravel-mongodb instalado
- laravel/sanctum configurado
- Modelo User con HasApiTokens y relacion rol() -> Rol
- Modelo Rol con campo nombre (valor "administrador")

### 2.2 Copiar estos archivos
```
app/Http/Middleware/AdminApiMiddleware.php
app/Http/Controllers/Api/Admin/UsuarioController.php
app/Http/Controllers/Api/Admin/VcardController.php
app/Http/Controllers/Api/Admin/MembresiaController.php
app/Http/Controllers/Api/Admin/PagoController.php
app/Http/Controllers/Api/Admin/LogController.php
app/Http/Controllers/Api/Admin/MiniWebController.php
```

### 2.3 Registrar middleware en app/Http/Kernel.php
```php
protected $routeMiddleware = [
    // ... existentes ...
    'admin.api' => \App\Http\Middleware\AdminApiMiddleware::class,
];
```

### 2.4 Agregar rutas en routes/api.php
```php
use App\Http\Controllers\Api\Admin\UsuarioController   as AdminUsuario;
use App\Http\Controllers\Api\Admin\VcardController     as AdminVcard;
use App\Http\Controllers\Api\Admin\MembresiaController as AdminMembresia;
use App\Http\Controllers\Api\Admin\PagoController      as AdminPago;
use App\Http\Controllers\Api\Admin\LogController       as AdminLog;
use App\Http\Controllers\Api\Admin\MiniWebController   as AdminMiniWeb;

Route::middleware(['auth:sanctum', 'admin.api'])->prefix('admin')->name('admin.')->group(function () {

    // Usuarios
    Route::get('usuarios',                         [AdminUsuario::class,  'index']);
    Route::get('usuarios/{id}',                    [AdminUsuario::class,  'show']);
    Route::put('usuarios/{id}',                    [AdminUsuario::class,  'update']);
    Route::post('usuarios/{id}/activar',           [AdminUsuario::class,  'activar']);
    Route::post('usuarios/{id}/desactivar',        [AdminUsuario::class,  'desactivar']);

    // VCards
    Route::get('vcards',                           [AdminVcard::class,    'index']);
    Route::get('vcards/{id}',                      [AdminVcard::class,    'show']);
    Route::put('vcards/{id}',                      [AdminVcard::class,    'update']);
    Route::get('usuarios/{userId}/vcards',         [AdminVcard::class,    'byUsuario']);

    // Membresias
    Route::get('planes',                                 [AdminMembresia::class, 'planes']);
    Route::get('usuarios/{id}/membresia',                [AdminMembresia::class, 'show']);
    Route::post('usuarios/{id}/activar-membresia',       [AdminMembresia::class, 'activar']);
    Route::post('usuarios/{id}/desactivar-membresia',    [AdminMembresia::class, 'desactivar']);
    Route::post('usuarios/{id}/cambiar-plan',            [AdminMembresia::class, 'cambiarPlan']);

    // Pagos
    Route::get('pagos',                            [AdminPago::class,     'index']);
    Route::get('transacciones',                    [AdminPago::class,     'transacciones']);
    Route::get('usuarios/{userId}/pagos',          [AdminPago::class,     'byUsuario']);
    Route::get('usuarios/{userId}/transacciones',  [AdminPago::class,     'transaccionesByUsuario']);

    // Logs
    Route::get('logs',                             [AdminLog::class,      'index']);
    Route::get('usuarios/{userId}/logs',           [AdminLog::class,      'byUsuario']);

    // MiniWebs
    Route::get('miniwebs',                         [AdminMiniWeb::class,  'index']);
    Route::get('miniwebs/{id}',                    [AdminMiniWeb::class,  'show']);
    Route::get('usuarios/{userId}/miniwebs',       [AdminMiniWeb::class,  'byUsuario']);
});
```

---

## 3. Flujo de autenticacion

### Login
```http
POST /api/login
Content-Type: application/json

{
  "email": "admin@example.com",
  "password": "secret"
}
```
Respuesta:
```json
{
  "access_token": "1|abc123...",
  "token_type": "Bearer",
  "user": { ... }
}
```

### Usar token en cada peticion
```
Authorization: Bearer 1|abc123...
```

### Logout
```http
POST /api/logout
Authorization: Bearer 1|abc123...
```

---

## 4. Referencia de endpoints

### Usuarios /api/admin/usuarios

| Metodo | Ruta | Descripcion | Query params |
|--------|------|-------------|--------------|
| GET | /api/admin/usuarios | Lista paginada | search, estado, plan_id, per_page |
| GET | /api/admin/usuarios/{id} | Detalle: plan, vcards, wallet, perfil | — |
| PUT | /api/admin/usuarios/{id} | Edita name, email, rol_id, plan_id | — |
| POST | /api/admin/usuarios/{id}/activar | Activa cuenta (estado=true) | — |
| POST | /api/admin/usuarios/{id}/desactivar | Desactiva cuenta (estado=false) | — |

Ejemplo PUT:
```json
{ "name": "Juan Garcia", "email": "juan@empresa.com", "plan_id": "664abc123" }
```

---

### VCards /api/admin/vcards

| Metodo | Ruta | Descripcion | Query params |
|--------|------|-------------|--------------|
| GET | /api/admin/vcards | Lista paginada | search, estado, user_id, per_page |
| GET | /api/admin/vcards/{id} | Detalle con usuario | — |
| PUT | /api/admin/vcards/{id} | Edita datos basicos | — |
| GET | /api/admin/usuarios/{userId}/vcards | Vcards de un usuario | — |

Campos editables: nombre, cargo, descripcion, telefono, whatsapp, email, empresa,
direccion, website, pais, ciudad, estado, privacidad, es_borrador

---

### Membresias

| Metodo | Ruta | Descripcion | Body |
|--------|------|-------------|------|
| GET | /api/admin/planes | Lista planes activos | — |
| GET | /api/admin/usuarios/{id}/membresia | Estado de membresia | — |
| POST | /api/admin/usuarios/{id}/activar-membresia | Activa/renueva | { "anual": true, "dias": 365 } |
| POST | /api/admin/usuarios/{id}/cambiar-plan | Cambia plan | { "plan_id": "abc", "anual": false } |
| POST | /api/admin/usuarios/{id}/desactivar-membresia | Desactiva | — |

Logica activar-membresia:
- Si ya tiene membresia vigente, los dias se SUMAN (no se pisa la fecha).
- anual:true = +365 dias. anual:false = +30 dias (o los dias que se indiquen).

---

### Pagos

| Metodo | Ruta | Descripcion | Query params |
|--------|------|-------------|--------------|
| GET | /api/admin/pagos | Historial global HealthPagos | user_id, estado, moneda, desde, hasta, per_page |
| GET | /api/admin/transacciones | Transacciones wallet global | type, status, per_page |
| GET | /api/admin/usuarios/{id}/pagos | Pagos de un usuario + total pagado | — |
| GET | /api/admin/usuarios/{id}/transacciones | Wallet de un usuario | — |

Valores estado (HealthPago): pendiente, completado, fallido
Valores type (Transaction): deposit, withdraw, transfer_in, transfer_out, purchase, adjustment
Valores status (Transaction): pending, completed, failed

---

### Logs

| Metodo | Ruta | Descripcion | Query params |
|--------|------|-------------|--------------|
| GET | /api/admin/logs | Log global de movimientos | user_id, type, search, desde, hasta, per_page |
| GET | /api/admin/usuarios/{id}/logs | Logs de un usuario | — |

Valores type: create, edit, delete, delete cuenta

---

### MiniWebs

| Metodo | Ruta | Descripcion | Query params |
|--------|------|-------------|--------------|
| GET | /api/admin/miniwebs | Lista paginada | search, user_id, per_page |
| GET | /api/admin/miniwebs/{id} | Detalle con usuario + vcard vinculada | — |
| GET | /api/admin/usuarios/{id}/miniwebs | Miniwebs de un usuario | — |

---

## 5. Respuestas de error

| HTTP | Cuando |
|------|--------|
| 401 | Token ausente o invalido |
| 403 | Autenticado pero sin rol administrador |
| 404 | Recurso no encontrado |
| 422 | Validacion fallida |

Ejemplo 403:
```json
{
  "error": "Acceso denegado. Se requieren privilegios de administrador.",
  "code": 403
}
```

---

## 6. Modelos requeridos

| Modelo | Coleccion MongoDB | Relaciones usadas |
|--------|------------------|-------------------|
| User | users | rol, plan, perfil, wallet, vcards, setup |
| Vcard | vcard | user |
| Planes | planes | tarifas |
| HealthPago | health_pagos | — |
| Transaction | transactions | wallet |
| Wallet | wallets | user |
| Log | log | user |
| MiniWeb | miniwebs | user, vcard |
| Rol | rol | — |

---

## 7. Paginacion

Todos los listados retornan estructura estandar de Laravel:
```json
{
  "current_page": 1,
  "data": [ ... ],
  "per_page": 20,
  "total": 150,
  "last_page": 8,
  "next_page_url": "https://...",
  "prev_page_url": null
}
```
Maximo per_page: 100

---

## 8. Prueba rapida con curl

```bash
# 1. Login y guardar token
TOKEN=$(curl -s -X POST https://tudominio.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@example.com","password":"secret"}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")

# 2. Listar usuarios
curl https://tudominio.com/api/admin/usuarios \
  -H "Authorization: Bearer $TOKEN"

# 3. Vcards de un usuario
curl https://tudominio.com/api/admin/usuarios/USER_ID/vcards \
  -H "Authorization: Bearer $TOKEN"

# 4. Activar membresia anual
curl -X POST https://tudominio.com/api/admin/usuarios/USER_ID/activar-membresia \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"anual": true}'

# 5. Cambiar plan
curl -X POST https://tudominio.com/api/admin/usuarios/USER_ID/cambiar-plan \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"plan_id": "PLAN_ID"}'

# 6. Historial de pagos con filtros
curl "https://tudominio.com/api/admin/pagos?estado=completado&desde=2026-01-01&per_page=50" \
  -H "Authorization: Bearer $TOKEN"

# 7. Logs de un usuario
curl https://tudominio.com/api/admin/usuarios/USER_ID/logs \
  -H "Authorization: Bearer $TOKEN"

# 8. MiniWebs con busqueda
curl "https://tudominio.com/api/admin/miniwebs?search=empresa" \
  -H "Authorization: Bearer $TOKEN"
```
