# API REST · Sistema de Carnetización Municipal Inteligente

API REST en PHP puro (sin framework ni Composer) para la gestión integral de
carnets institucionales de empleados municipales.

- **Base URL local:** `http://localhost/cytid/api`
- **Documentación OpenAPI 3.0:** [`swagger.json`](./swagger.json)
- **Formato:** JSON (UTF-8)
- **Autenticación:** Bearer Token (`Authorization: Bearer <token>`) o header `X-API-TOKEN`.

> Importe el archivo `swagger.json` en [Swagger Editor](https://editor.swagger.io)
> o en Postman / Insomnia para una vista interactiva.

---

## 1. Autenticación

### Iniciar sesión

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

{ "usuario": "admin", "password": "Admin@2026" }
```

Respuesta:

```json
{
  "token": "a1b2c3...d4e5",
  "tipo": "Bearer",
  "expira_en": "2026-06-12 12:00:00",
  "usuario": { "id": 1, "usuario": "admin", "rol_id": 1 }
}
```

Use el `token` en TODAS las llamadas siguientes:

```http
Authorization: Bearer a1b2c3...d4e5
```

### Datos del usuario actual

```http
GET /api/auth/me
Authorization: Bearer <token>
```

### Cerrar sesión

```http
POST /api/auth/logout
Authorization: Bearer <token>
```

---

## 2. Empleados

| Método | Endpoint | Descripción |
|--------|----------|-------------|
| GET    | `/api/empleados`               | Listar (filtros: `q`, `departamento`, `page`, `per_page`) |
| GET    | `/api/empleados/{id}`          | Obtener uno |
| POST   | `/api/empleados`               | Crear |
| PUT    | `/api/empleados/{id}`          | Actualizar |
| DELETE | `/api/empleados/{id}`          | Eliminar (soft → estado RETIRADO) |

### Ejemplo crear

```bash
curl -X POST http://localhost/cytid/api/empleados \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "codigo_empleado":"EMP-0011",
    "cedula":"011-1112223-4",
    "nombres":"Andrea",
    "apellidos":"Mejía",
    "departamento_id":3,
    "cargo_id":6,
    "tipo_empleado":"FIJO",
    "estado_laboral":"ACTIVO",
    "fecha_ingreso":"2026-05-01"
  }'
```

---

## 3. Carnets

| Método | Endpoint | Descripción |
|--------|----------|-------------|
| GET   | `/api/carnets`                          | Listar |
| GET   | `/api/carnets/{id}`                     | Obtener uno |
| POST  | `/api/carnets`                          | Emitir nuevo (requiere `empleado_id`) |
| PUT   | `/api/carnets/{id}/estado`              | Cambiar estado |
| POST  | `/api/carnets/{id}/imprimir`            | Registrar impresión |
| POST  | `/api/carnets/{id}/entregar`            | Registrar entrega |
| POST  | `/api/carnets/{id}/reportar-perdido`    | Marcar como extraviado |
| POST  | `/api/carnets/{id}/revocar`             | Revocar |

### Emitir un carnet

```bash
curl -X POST http://localhost/cytid/api/carnets \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "empleado_id": 1, "vigencia_anios": 2 }'
```

Respuesta:

```json
{
  "id": 11,
  "numero_carnet": "CM-2026-00011",
  "hash_validacion": "f1e2d3...",
  "url_validacion": "http://localhost/cytid/validar.php?token=f1e2d3...",
  "fecha_emision": "2026-05-13",
  "fecha_vencimiento": "2028-05-13",
  "estado": "EMITIDO"
}
```

### Cambiar estado

```bash
curl -X PUT http://localhost/cytid/api/carnets/11/estado \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "estado": "SUSPENDIDO", "motivo": "Falta administrativa" }'
```

---

## 4. Validación pública (sin token)

```http
GET /api/validacion/{hash_validacion}
```

```json
{
  "valido": true,
  "estado": "ENTREGADO",
  "mensaje": "ACTIVO",
  "numero_carnet": "CM-2026-00001",
  "empleado": {
    "nombre_completo": "Juan Carlos Pérez Rosario",
    "departamento": "Recursos Humanos",
    "cargo": "Director"
  },
  "fecha_emision": "2026-01-15",
  "fecha_vencimiento": "2028-01-15"
}
```

Cuando el carnet no es válido, el campo `mensaje` puede ser:
`ACTIVO | VENCIDO | REVOCADO | EXTRAVIADO | SUSPENDIDO`.

---

## 5. Impresiones y entregas

| Método | Endpoint | Descripción |
|--------|----------|-------------|
| GET | `/api/impresiones?desde=YYYY-MM-DD&hasta=YYYY-MM-DD` | Listar |
| GET | `/api/entregas?desde=YYYY-MM-DD&hasta=YYYY-MM-DD`   | Listar |

---

## 6. Reportes

| Endpoint | Descripción |
|----------|-------------|
| `GET /api/reportes/resumen`           | KPIs generales |
| `GET /api/reportes/vencimientos?dias=60` | Carnets vencidos / por vencer |
| `GET /api/reportes/reimpresiones`     | Reimpresiones por rango |
| `GET /api/reportes/extraviados`       | Carnets reportados perdidos |
| `GET /api/reportes/por-departamento`  | Conteo por departamento |

---

## 7. Auditoría

```http
GET /api/auditoria?modulo=CARNETS&desde=2026-01-01&hasta=2026-12-31&page=1&per_page=100
```

Solo accesible a Superadministrador y Supervisor.

---

## 8. Códigos HTTP

| Código | Significado |
|--------|-------------|
| 200    | OK |
| 201    | Creado |
| 400    | Petición inválida |
| 401    | Token requerido o inválido |
| 403    | Sin permisos para el rol actual |
| 404    | Recurso no encontrado |
| 405    | Método no permitido |
| 422    | Validación |
| 500    | Error interno |

Estructura de error:

```json
{ "error": true, "mensaje": "Descripción del error" }
```

---

## 9. Roles y permisos

| Rol ID | Nombre                  | Permisos |
|--------|-------------------------|----------|
| 1      | Superadministrador      | Todo |
| 2      | Administrador RRHH      | Empleados, carnets, reportes |
| 3      | Operador de Carnetización | Carnets, impresiones, entregas |
| 4      | Supervisor              | Reportes, auditoría, cambio de estado |
| 5      | Consulta / Seguridad    | Solo lectura |

---

## 10. Ejemplo de flujo completo (curl)

```bash
# 1) Login
TOKEN=$(curl -s -X POST http://localhost/cytid/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"usuario":"admin","password":"Admin@2026"}' | jq -r .token)

# 2) Crear empleado
curl -X POST http://localhost/cytid/api/empleados \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"codigo_empleado":"EMP-0099","cedula":"099-9999999-9","nombres":"Test","apellidos":"API"}'

# 3) Emitir carnet
curl -X POST http://localhost/cytid/api/carnets \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"empleado_id":99,"vigencia_anios":3}'

# 4) Validar públicamente (sin token)
curl http://localhost/cytid/api/validacion/<HASH>
```

---

## 11. Notas de seguridad

- Use HTTPS en producción.
- Cambie la `CM_SECRET_KEY` en `config/config.php`.
- Cambie la contraseña por defecto del usuario `admin`.
- Limite el acceso a `/api/` con un firewall si corresponde.
- Los tokens expiran a los 30 días por defecto.
