Documentación de la API REST

Backend Laravel en la carpeta api. Todas las rutas definidas en routes/api.php llevan el prefijo /api (ver RouteServiceProvider).

Introducción

URL base: {BASE_URL}/api, donde {BASE_URL} es el origen de tu instalación (por ejemplo https://servidor.example.com).

Formato: salvo el endpoint de archivos en /api/v1/storage/…, las respuestas son JSON. Conviene enviar Accept: application/json en todas las peticiones.

CORS: debe configurarse en Laravel si el cliente es un navegador en otro origen.

Autenticación (Laravel Sanctum)

La mayoría de rutas bajo /api/v1/… usan el middleware auth:sanctum. Tras un login correcto, envía el token en la cabecera:

Authorization: Bearer {token}

Si falta el token o es inválido, Laravel suele responder 401 (a menudo HTML o JSON según cabeceras). Mantén Accept: application/json para respuestas JSON coherentes.

POST /api/login

Auth: no requiere token.

Headers: Content-Type: application/json (recomendado).

Body (JSON):

CampoTipoDescripción
correostringEmail del usuario (validación required|email).
clavestringContraseña (en la BD el campo de hash se compara vía Auth; el request usa la clave clave).
dispositivostringNombre del dispositivo para el token Sanctum (createToken($dispositivo)).

Respuesta exitosa (200): cuerpo con mensaje, estado: "success", codigo: 200, y en el mismo nivel: token (string), user (objeto resumido), permisos (array con conjunto, rol, propiedad y menus por permiso), cantidad (número de permisos).

Otros códigos: 400 validación de campos; 401 credenciales incorrectas; 403 correo no verificado, usuario inactivo o sin permisos; 500 error interno (en modo debug puede incluir debug en el JSON).

Formato de respuestas

El trait App\Http\Traits\ApiResponse estandariza muchas respuestas con:

Varios controladores también devuelven JSON directamente con las mismas claves mensaje, estado, codigo más datos específicos (propiedades, reservas, etc.). En algunos casos el campo codigo del cuerpo no coincide con el HTTP (p. ej. administración de zonas sociales); el cliente debe conocer esas rutas concretas.

Las peticiones con $request->validate() pueden generar respuesta 422 de Laravel con errors por campo si la excepción no se captura. Algunos métodos capturan validación y devuelven 400 con errores u otro formato.

Almacenamiento público (sin autenticación)

Prefijo: /api/v1. No requiere Authorization.

GET /api/v1/storage-ping

Respuesta (200): {"ok":true,"message":"Laravel recibe peticiones en /api/v1"}

GET /api/v1/storage/{path}

Sirve archivos del disco public de Laravel (storage/app/public). {path} puede incluir subcarpetas (p. ej. zona-social/imagen.jpg).

Respuesta: binario (imagen u otro MIME), no JSON. 404 si el archivo no existe.

Imágenes guardadas por la API suelen referenciarse como ruta relativa; el front puede construir la URL: {BASE_URL}/api/v1/storage/{ruta}.

Usuario actual (Sanctum)

GET /api/user

Auth: auth:sanctum.

Respuesta (200): objeto usuario de Laravel ($request->user()), según el modelo User.

Ingresos y código QR

Todas requieren Authorization: Bearer ….

GET /api/v1/ingresos/{conjunto}/{propiedad}

Respuesta (200): cantidad, data (lista de ingresos activos).

404: si no hay registros (respuestaNoEncontrado).

POST /api/v1/ingresos/{conjunto}/{propiedad}

Body (JSON):

{
  "tipo_persona": "string, max 15, requerido",
  "numero_identificacion": "string, max 15, requerido",
  "nombre": "string, max 60, requerido",
  "observacion": "string, max 255, opcional"
}

Respuesta (200): data con el ingreso creado (incluye qr_token, qr_vencimiento, etc.).

GET /api/v1/ingresos/{conjunto}/{propiedad}/{id}/qr-imagen

Respuesta (200): imagen — data URI PNG en base64 del QR (contenido del QR = valor de qr_token).

400 / 404: validaciones de estado del QR o ingreso no encontrado.

POST /api/v1/ingresos/{conjunto}/{propiedad}/registrar-uso

Body: {"token": "string, requerido, max 100"} — debe coincidir con qr_token.

Respuesta (200): data con ingreso actualizado (qr_estado pasa a Usado).

POST /api/v1/ingresos/{conjunto}/{propiedad}/{id}/cancelar

Body: vacío.

Respuesta (200): data con ingreso cancelado.

Zonas sociales

GET /api/v1/zonas-sociales/{conjunto}

Respuesta (200): zonaSocials, opcionalmente cantidad. Solo estado_id = 1.

GET /api/v1/zonas-sociales/{conjunto}/administrar

Nota: listado administrativo (incluye estado_id). El código actual puede devolver HTTP 236 con cuerpo que incluye codigo: 35 en éxito, o HTTP 200 con codigo: 234 cuando no hay datos. Integra según el comportamiento real probado en tu entorno.

GET /api/v1/zonas-sociales/{conjunto}/{id}

Respuesta (200): zonaSocial (detalle público activo).

GET /api/v1/zonas-sociales/{conjunto}/{id}/editar

Respuesta (200): zonaSocial para edición (sin filtrar por estado). 404 si no existe.

PUT /api/v1/zonas-sociales/{conjunto}/{id}

Body (JSON):

{
  "tipo_zona": "string|null, max 50",
  "nombre": "requerido, max 255",
  "descripcion": "requerido, string",
  "imagen": "opcional, data URL base64 image → se guarda en disco y en BD la ruta",
  "informacion_horarios": "string|null",
  "informacion_uso": "string|null",
  "se_reserva": "boolean",
  "dias_disponibles": "integer",
  "requiere_pago": "boolean",
  "estado_id": "requerido, integer",
  "usuario_id": "requerido, integer"
}

Respuesta (200): zonaSocial actualizado.

Horarios de zona social

GET /api/v1/zonas-sociales-horarios/{conjunto}/{id}

{id} = id de la zona social. Respuesta: zonaSocialHorarios (array).

POST /api/v1/zonas-sociales-horarios/{id}

Body (JSON): días ludo, fe (boolean opcionales); hora_inicio, hora_fin, franja_horas (string); cantidad_reservas_franja (int); usuario_id (int, requerido).

Respuesta (200): zonaSocialHorario creado.

PUT /api/v1/zonas-sociales-horarios/{id}

Body: {"estado_id": 1 o 2}.

Respuesta: 200 con horario; validación en algunos casos 422 con errores.

Reservas

GET /api/v1/zonas-sociales-reservas/{conjunto}/{zonaSocial}/{fecha}

{fecha} formato Y-m-d. Calcula el día (o fe si es festivo) y devuelve franjas: lista de hora, cantidad_reservas, cantidad_reservas_franja.

POST /api/v1/zonas-sociales-reservas

Body (JSON):

{
  "conjunto_id": "integer",
  "propiedad_id": "integer",
  "zona_social_id": "integer",
  "fecha_evento": "date",
  "hora_evento": "H:i",
  "usuario_id": "integer"
}

Respuesta (200): reserva. Si la zona requiere pago, estado puede ser Pendiente; si no, Autorizada.

400: propiedad ya con reserva activa, sin cupo, o propiedad no puede reservar.

GET /api/v1/mis-reservas/{conjunto}/{propiedad}

Respuesta (200): reservas desde hace 6 meses a futuro.

POST /api/v1/mis-reservas/cancelar

Body (JSON): conjunto_id, propiedad_id, id (reserva), usuario_id.

Respuesta (200): reserva con estado: "Cancelada". 404 si no aplica.

GET /api/v1/reservas-administrar/{conjunto}/{fechaInicio}/{fechaFin}

Respuesta (200): reservas en el rango de fechas.

POST /api/v1/reservas-autorizar

Body (JSON): conjunto_id, propiedad_id, id, usuario_id (quien autoriza). Opcionales validados: valor_pago, forma_pago, banco.

Condición: reserva en estado Pendiente. Respuesta (200): reserva con estado: "Autorizada".

Propiedades

GET /api/v1/propiedades/{conjunto}

Respuesta (200): propiedades, opcionalmente cantidad.

GET /api/v1/propiedades/{conjunto}/{id}

Respuesta (200): propiedad. 404 si no existe.

POST /api/v1/propiedades

Body: conjunto_id, tipo_propiedad, torre, piso, numero, direccion_completa, puede_reservar, usuario_id.

Respuesta (200): propiedad creada.

PUT /api/v1/propiedades/{conjunto}/{id}

Body: tipo_propiedad, torre, piso, numero, direccion_completa, puede_reservar, estado_id, usuario_id.

Usuarios

GET /api/v1/usuarios/{conjunto}

Respuesta (200): usuarios con rol y datos de propiedad vía conjunto_role_usuarios.

GET /api/v1/usuarios/{cedula}

Busca por numero_identidad. 404 si no hay usuario.

POST /api/v1/usuarios

Body: conjunto_id, role_id, propiedad_id, numero_identidad, nombre, apellido, correo, telefono, usuario_id (actor). Si el usuario no existe, se crea con clave inicial hasheada igual al número de identidad.

Respuesta (200): usuario; también crea vínculo en conjunto_role_usuarios.

PUT /api/v1/usuarios/{id}

Body: nombre, apellido, correo, telefono, estado_id.

Conjunto · rol · usuario

GET /api/v1/conjunto-rol-usuarios/{conjunto}/{usuario}

Respuesta (200): conjuntoRolUsuario (array de vínculos con nombres de rol, propiedad y usuario).

POST /api/v1/conjunto-rol-usuarios

Body: conjunto_id, role_id, propiedad_id, usuario_id, estado_id.

PUT /api/v1/conjunto-rol-usuarios/{id}

Body: mismos campos que POST; actualiza estado_id del registro coincidente. 404 si no encuentra fila.

Días festivos

GET /api/v1/dia-festivos

Respuesta (200): diaFestivos (todos los registros).

GET /api/v1/dia-festivos/{fecha}

Respuesta (200): diaFestivo (objeto o null si no hay fila para esa fecha).

Mensajería (plantillas, grupos, envíos)

Plantillas

GET /api/v1/mensaje-plantillas/{conjunto}

Respuesta (200): mensajePlantillas.

GET /api/v1/mensaje-plantillas/{conjunto}/{id}

Si no existe, devuelve 200 con mensajePlantilla: [] (comportamiento actual).

POST /api/v1/mensaje-plantillas

Body: conjunto_id, nombre, contenido, usuario_id.

PUT /api/v1/mensaje-plantillas/{id}

Body: conjunto_id, nombre, contenido, estado_id, usuario_id.

Grupos

GET /api/v1/listar-grupos/{conjunto}

Respuesta: mensajeGrupos.

GET /api/v1/ver-grupo/{conjunto}/{id}

Respuesta: mensajeGrupo.

POST /api/v1/crear-grupo

Body: conjunto_id, nombre, usuario_id.

PUT /api/v1/actualizar-grupo/{id}

Body: conjunto_id, nombre, estado_id, usuario_id.

Detalle de grupo (propiedades en el grupo)

GET /api/v1/listar-grupo-detalles/{conjunto}/{grupo}

Respuesta: mensajeGrupoDetalles.

POST /api/v1/crear-grupo-detalle

Body: conjunto_id, grupo_id, propiedad_id, usuario_id.

PUT /api/v1/actualizar-grupo-detalle/{id}

Body: conjunto_id, grupo_id, propiedad_id, estado_id, usuario_id.

Mensajes

GET /api/v1/listar-mensajes/{conjunto}

Respuesta: mensajes con grupo_nombre, propiedad_direccion_completa.

GET /api/v1/ver-mensaje/{conjunto}/{id}

Respuesta: clave mensaje (objeto o [] si no existe).

POST /api/v1/crear-mensaje

Body: conjunto_id, grupo_id y propiedad_id opcionales; asunto, descripcion, usuario_id requeridos; imagen opcional (data URL PNG/JPG/JPEG → guardado en storage, o string corto ≤100 como ruta).

422: formato de imagen no permitido.

PUT /api/v1/actualizar-mensaje/{id}

Body: conjunto_id, grupo_id, propiedad_id, asunto, descripcion, imagen (max 100, sin subida base64 en update), estado_id, usuario_id.

Documentación generada a partir de api/routes/api.php y controladores en api/app/Http/Controllers. Si actualizas rutas o validaciones, revisa este archivo en la carpeta ayuda.