{
  "openapi": "3.0.3",
  "info": {
    "title": "API - Sistema de Carnetización Municipal Inteligente",
    "description": "API REST para gestionar empleados, carnets, impresiones, entregas y validación pública de carnets municipales. Orientado a ayuntamientos de República Dominicana.",
    "version": "1.0.0",
    "contact": {
      "name": "Soporte Técnico Municipal",
      "email": "soporte@municipal.gob.do"
    }
  },
  "servers": [
    { "url": "http://localhost/cytid/api", "description": "Local" },
    { "url": "https://dominio.gob.do/cytid/api", "description": "Producción" }
  ],
  "tags": [
    {"name": "Autenticación"},
    {"name": "Empleados"},
    {"name": "Carnets"},
    {"name": "Validación"},
    {"name": "Impresiones"},
    {"name": "Entregas"},
    {"name": "Reportes"},
    {"name": "Auditoría"}
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Token"
      },
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-TOKEN"
      }
    },
    "schemas": {
      "Empleado": {
        "type": "object",
        "properties": {
          "id":               {"type": "integer", "example": 1},
          "codigo_empleado":  {"type": "string",  "example": "EMP-0001"},
          "cedula":           {"type": "string",  "example": "001-1234567-8"},
          "nombres":          {"type": "string",  "example": "Juan Carlos"},
          "apellidos":        {"type": "string",  "example": "Pérez Rosario"},
          "sexo":             {"type": "string",  "enum": ["M","F","O"]},
          "fecha_nacimiento": {"type": "string",  "format": "date"},
          "telefono":         {"type": "string"},
          "correo":           {"type": "string",  "format": "email"},
          "direccion":        {"type": "string"},
          "departamento_id":  {"type": "integer"},
          "cargo_id":         {"type": "integer"},
          "tipo_empleado":    {"type": "string",  "enum": ["FIJO","CONTRATADO","TEMPORAL","PASANTE","HONORIFICO"]},
          "estado_laboral":   {"type": "string",  "enum": ["ACTIVO","LICENCIA","SUSPENDIDO","RETIRADO","VACACIONES"]},
          "fecha_ingreso":    {"type": "string",  "format": "date"},
          "tipo_sangre":      {"type": "string"},
          "contacto_emergencia":  {"type": "string"},
          "telefono_emergencia":  {"type": "string"}
        }
      },
      "Carnet": {
        "type": "object",
        "properties": {
          "id":                  {"type": "integer"},
          "empleado_id":         {"type": "integer"},
          "numero_carnet":       {"type": "string", "example": "CM-2026-00001"},
          "codigo_qr":           {"type": "string"},
          "hash_validacion":     {"type": "string"},
          "fecha_emision":       {"type": "string", "format": "date"},
          "fecha_vencimiento":   {"type": "string", "format": "date"},
          "estado": {"type": "string", "enum": ["PENDIENTE","EMITIDO","IMPRESO","ENTREGADO","SUSPENDIDO","REVOCADO","EXTRAVIADO","VENCIDO","REEMPLAZADO"]},
          "motivo_estado":       {"type": "string"},
          "observaciones":       {"type": "string"}
        }
      },
      "RespuestaError": {
        "type": "object",
        "properties": {
          "error":   {"type": "boolean"},
          "mensaje": {"type": "string"}
        }
      }
    }
  },
  "security": [{ "BearerAuth": [] }],
  "paths": {
    "/auth/login": {
      "post": {
        "tags": ["Autenticación"],
        "summary": "Iniciar sesión y obtener token",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["usuario","password"],
                "properties": {
                  "usuario":  {"type":"string","example":"admin"},
                  "password": {"type":"string","example":"Admin@2026"}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Login exitoso",
            "content": {"application/json": {"example": {
              "token": "a1b2c3...",
              "tipo": "Bearer",
              "expira_en": "2026-06-12 12:00:00",
              "usuario": {"id":1,"usuario":"admin","rol_id":1}
            }}}
          },
          "401": { "description": "Credenciales inválidas", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RespuestaError"}}} }
        }
      }
    },
    "/auth/logout": {
      "post": {
        "tags": ["Autenticación"],
        "summary": "Revocar el token actual",
        "responses": {"200": {"description": "OK"}}
      }
    },
    "/auth/me": {
      "get": {
        "tags": ["Autenticación"],
        "summary": "Datos del usuario autenticado",
        "responses": {"200": {"description": "OK"}}
      }
    },

    "/empleados": {
      "get": {
        "tags": ["Empleados"],
        "summary": "Listar empleados",
        "parameters": [
          {"name":"q","in":"query","schema":{"type":"string"},"description":"Búsqueda"},
          {"name":"departamento","in":"query","schema":{"type":"integer"}},
          {"name":"page","in":"query","schema":{"type":"integer"}},
          {"name":"per_page","in":"query","schema":{"type":"integer"}}
        ],
        "responses": {"200": {"description": "OK",
          "content": {"application/json": {"example": {
            "data":[{"id":1,"codigo_empleado":"EMP-0001","nombres":"Juan","apellidos":"Pérez"}],
            "paginacion":{"total":1,"page":1,"per_page":50,"paginas":1}
          }}}
        }}
      },
      "post": {
        "tags": ["Empleados"],
        "summary": "Crear empleado",
        "requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Empleado"}}}},
        "responses": {"201":{"description":"Creado"}, "422":{"description":"Validación"}}
      }
    },
    "/empleados/{id}": {
      "parameters": [{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],
      "get":  { "tags":["Empleados"], "summary":"Obtener empleado por id", "responses":{"200":{"description":"OK"},"404":{"description":"No encontrado"}} },
      "put":  { "tags":["Empleados"], "summary":"Actualizar empleado",
                "requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Empleado"}}}},
                "responses":{"200":{"description":"OK"}} },
      "delete":{ "tags":["Empleados"], "summary":"Retirar empleado (soft delete)", "responses":{"200":{"description":"OK"}} }
    },

    "/carnets": {
      "get": {
        "tags": ["Carnets"],
        "summary": "Listar carnets",
        "parameters": [
          {"name":"estado","in":"query","schema":{"type":"string"}},
          {"name":"q","in":"query","schema":{"type":"string"}}
        ],
        "responses": {"200": {"description": "OK"}}
      },
      "post": {
        "tags": ["Carnets"],
        "summary": "Emitir carnet",
        "requestBody":{"required":true,"content":{"application/json":{"schema":{
          "type":"object","required":["empleado_id"],
          "properties": {
            "empleado_id":{"type":"integer","example":1},
            "vigencia_anios":{"type":"integer","example":2},
            "plantilla_id":{"type":"integer"},
            "observaciones":{"type":"string"}
          }
        }}}},
        "responses": {"201":{"description":"Creado",
          "content":{"application/json":{"example":{
            "id":11,"numero_carnet":"CM-2026-00011","hash_validacion":"abcd...",
            "url_validacion":"http://localhost/cytid/validar.php?token=abcd...",
            "fecha_emision":"2026-05-13","fecha_vencimiento":"2028-05-13","estado":"EMITIDO"
          }}}}
        }
      }
    },
    "/carnets/{id}": {
      "parameters": [{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],
      "get": { "tags":["Carnets"], "summary":"Obtener carnet", "responses":{"200":{"description":"OK"}} }
    },
    "/carnets/{id}/estado": {
      "parameters": [{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],
      "put": {
        "tags": ["Carnets"], "summary": "Cambiar estado del carnet",
        "requestBody":{"required":true,"content":{"application/json":{"schema":{
          "type":"object","required":["estado"],
          "properties":{
            "estado":{"type":"string","enum":["PENDIENTE","EMITIDO","IMPRESO","ENTREGADO","SUSPENDIDO","REVOCADO","EXTRAVIADO","VENCIDO","REEMPLAZADO"]},
            "motivo":{"type":"string"}
          }
        }}}},
        "responses": {"200":{"description":"Estado actualizado"}}
      }
    },
    "/carnets/{id}/imprimir": {
      "parameters": [{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],
      "post": {
        "tags":["Carnets"],"summary":"Registrar impresión",
        "requestBody":{"content":{"application/json":{"schema":{
          "type":"object",
          "properties":{
            "motivo_impresion":{"type":"string","enum":["PRIMERA","REIMPRESION","DETERIORO","EXTRAVIO","CORRECCION","OTRO"]},
            "equipo":{"type":"string"},
            "observaciones":{"type":"string"}
          }
        }}}},
        "responses":{"200":{"description":"OK"}}
      }
    },
    "/carnets/{id}/entregar": {
      "parameters": [{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],
      "post": {
        "tags":["Carnets"],"summary":"Registrar entrega",
        "requestBody":{"required":true,"content":{"application/json":{"schema":{
          "type":"object","required":["recibido_por"],
          "properties":{
            "recibido_por":{"type":"string"},
            "documento_identidad":{"type":"string"},
            "observaciones":{"type":"string"}
          }
        }}}},
        "responses":{"200":{"description":"OK"}}
      }
    },
    "/carnets/{id}/reportar-perdido": {
      "parameters": [{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],
      "post":{"tags":["Carnets"],"summary":"Reportar carnet como extraviado","responses":{"200":{"description":"OK"}}}
    },
    "/carnets/{id}/revocar": {
      "parameters": [{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],
      "post":{"tags":["Carnets"],"summary":"Revocar carnet","responses":{"200":{"description":"OK"}}}
    },

    "/validacion/{token}": {
      "parameters": [{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],
      "get": {
        "tags":["Validación"],
        "summary":"Validar carnet por hash (público, sin token)",
        "security": [],
        "responses": {
          "200": {"description":"Resultado de validación",
            "content":{"application/json":{"example":{
              "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"
            }}}}
        }
      }
    },

    "/impresiones": {
      "get": {"tags":["Impresiones"],"summary":"Listar impresiones",
        "parameters":[
          {"name":"desde","in":"query","schema":{"type":"string","format":"date"}},
          {"name":"hasta","in":"query","schema":{"type":"string","format":"date"}}
        ],
        "responses":{"200":{"description":"OK"}}}
    },
    "/entregas": {
      "get": {"tags":["Entregas"],"summary":"Listar entregas","responses":{"200":{"description":"OK"}}}
    },

    "/reportes/resumen":          { "get": {"tags":["Reportes"],"summary":"Resumen general (KPIs)","responses":{"200":{"description":"OK"}}} },
    "/reportes/vencimientos":     { "get": {"tags":["Reportes"],"summary":"Carnets vencidos o por vencer","parameters":[{"name":"dias","in":"query","schema":{"type":"integer","default":60}}],"responses":{"200":{"description":"OK"}}} },
    "/reportes/reimpresiones":    { "get": {"tags":["Reportes"],"summary":"Reimpresiones por rango","responses":{"200":{"description":"OK"}}} },
    "/reportes/extraviados":      { "get": {"tags":["Reportes"],"summary":"Carnets extraviados","responses":{"200":{"description":"OK"}}} },
    "/reportes/por-departamento": { "get": {"tags":["Reportes"],"summary":"Distribución por departamento","responses":{"200":{"description":"OK"}}} },

    "/auditoria": {
      "get": {
        "tags":["Auditoría"],
        "summary":"Listar registros de auditoría",
        "parameters":[
          {"name":"modulo","in":"query","schema":{"type":"string"}},
          {"name":"usuario_id","in":"query","schema":{"type":"integer"}},
          {"name":"desde","in":"query","schema":{"type":"string","format":"date"}},
          {"name":"hasta","in":"query","schema":{"type":"string","format":"date"}},
          {"name":"page","in":"query","schema":{"type":"integer"}},
          {"name":"per_page","in":"query","schema":{"type":"integer"}}
        ],
        "responses":{"200":{"description":"OK"}}
      }
    }
  }
}
