Files
mexus-app/docs/API.md
Mexus 86bfbd2039 feat: Initial commit - Mexus App
Sistema de Gestión de Obras de Construcción completo con:
- Dashboard con KPIs y gráficos
- Módulo de obras con fases y tareas
- Control financiero (gastos, presupuestos)
- Gestión de recursos (personal, subcontratistas)
- Inventario de materiales con alertas de stock
- Reportes con exportación CSV
- Autenticación con roles (NextAuth.js v5)
- API REST completa
- Documentación de API y base de datos
- Configuración Docker para despliegue

Stack: Next.js 14+, TypeScript, Tailwind CSS, Prisma, PostgreSQL

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 01:10:55 +00:00

10 KiB

Documentación de API - Mexus App

Esta documentación describe todos los endpoints disponibles en la API REST de Mexus App.

Base URL

Desarrollo: http://localhost:3000/api
Producción: https://tu-dominio.com/api

Autenticación

La API utiliza NextAuth.js para la autenticación. Las peticiones autenticadas requieren una cookie de sesión válida.

Headers requeridos

Content-Type: application/json
Cookie: authjs.session-token=<token>

Endpoints de Autenticación

Obtener token CSRF

GET /api/auth/csrf

Respuesta exitosa (200):

{
  "csrfToken": "0ee47c595b90ef7b0356521f5354695cfe22a5797fa30cecba0a279ce28a9719"
}

Iniciar sesión

POST /api/auth/callback/credentials
Content-Type: application/x-www-form-urlencoded

Parámetros:

Campo Tipo Requerido Descripción
csrfToken string Token CSRF obtenido previamente
email string Correo electrónico del usuario
password string Contraseña del usuario

Respuesta exitosa (302): Redirección a dashboard con cookie de sesión

Obtener sesión actual

GET /api/auth/session

Respuesta exitosa (200):

{
  "user": {
    "id": "cmkk6tf3y00025x5stdh7x2f9",
    "email": "admin@demo.com",
    "nombre": "Admin",
    "apellido": "Demo",
    "role": "ADMIN",
    "empresaId": "cmkk6ter000005x5smacuuh5x"
  },
  "expires": "2026-01-20T00:25:19.994Z"
}

Cerrar sesión

POST /api/auth/signout

Endpoints de Obras

Listar obras

GET /api/obras

Respuesta exitosa (200):

[
  {
    "id": "cmkk6tf4900085x5semza5bzu",
    "codigo": "OBR-2024-001",
    "nombre": "Edificio Residencial Aurora",
    "descripcion": "Construcción de edificio de 8 niveles",
    "cliente": "Inmobiliaria del Norte S.A.",
    "ubicacion": "Col. Centro, Ciudad",
    "estado": "EN_PROGRESO",
    "presupuestoTotal": 15000000,
    "fechaInicio": "2024-01-15T00:00:00.000Z",
    "fechaFinEstimada": "2025-06-30T00:00:00.000Z",
    "avanceGeneral": 35,
    "_count": {
      "fases": 4,
      "gastos": 12
    }
  }
]

Crear obra

POST /api/obras
Content-Type: application/json

Body:

{
  "codigo": "OBR-2024-002",
  "nombre": "Casa Habitación López",
  "descripcion": "Construcción de casa de 2 niveles",
  "cliente": "Juan López García",
  "ubicacion": "Fracc. Las Palmas #123",
  "presupuestoTotal": 2500000,
  "fechaInicio": "2024-03-01",
  "fechaFinEstimada": "2024-09-30"
}

Campos:

Campo Tipo Requerido Descripción
codigo string Código único de la obra
nombre string Nombre del proyecto
descripcion string No Descripción detallada
cliente string Nombre del cliente
ubicacion string No Dirección o ubicación
presupuestoTotal number Presupuesto en MXN
fechaInicio date Fecha de inicio
fechaFinEstimada date No Fecha estimada de finalización

Respuesta exitosa (201):

{
  "id": "cmkk7tf4900085x5semza5bzu",
  "codigo": "OBR-2024-002",
  "nombre": "Casa Habitación López",
  "estado": "PLANEACION",
  "avanceGeneral": 0,
  "createdAt": "2024-01-20T10:30:00.000Z"
}

Obtener obra por ID

GET /api/obras/{id}

Parámetros de URL:

Parámetro Tipo Descripción
id string ID de la obra

Respuesta exitosa (200):

{
  "id": "cmkk6tf4900085x5semza5bzu",
  "codigo": "OBR-2024-001",
  "nombre": "Edificio Residencial Aurora",
  "descripcion": "Construcción de edificio de 8 niveles",
  "estado": "EN_PROGRESO",
  "presupuestoTotal": 15000000,
  "avanceGeneral": 35,
  "fases": [
    {
      "id": "fase1",
      "nombre": "Cimentación",
      "orden": 1,
      "avance": 100,
      "estado": "COMPLETADA"
    }
  ],
  "gastos": [
    {
      "id": "gasto1",
      "concepto": "Compra de cemento",
      "monto": 45000,
      "estado": "APROBADO"
    }
  ]
}

Actualizar obra

PUT /api/obras/{id}
Content-Type: application/json

Body: (campos opcionales)

{
  "nombre": "Edificio Residencial Aurora - Fase 2",
  "estado": "EN_PROGRESO",
  "avanceGeneral": 45
}

Respuesta exitosa (200): Objeto obra actualizado

Eliminar obra

DELETE /api/obras/{id}

Respuesta exitosa (200):

{
  "message": "Obra eliminada exitosamente"
}

Endpoints de Gastos

Listar gastos

GET /api/gastos

Query Parameters:

Parámetro Tipo Descripción
obraId string Filtrar por obra específica
estado string Filtrar por estado (PENDIENTE, APROBADO, RECHAZADO)

Respuesta exitosa (200):

[
  {
    "id": "cmkk6tf5r000k5x5sxwf04qji",
    "concepto": "Compra de materiales",
    "descripcion": "Cemento y varilla para cimentación",
    "monto": 85000,
    "categoria": "MATERIALES",
    "estado": "APROBADO",
    "fecha": "2024-01-20T00:00:00.000Z",
    "comprobante": "FAC-12345",
    "obra": {
      "id": "obra1",
      "nombre": "Edificio Aurora"
    },
    "usuario": {
      "nombre": "Juan",
      "apellido": "Pérez"
    }
  }
]

Crear gasto

POST /api/gastos
Content-Type: application/json

Body:

{
  "concepto": "Pago de mano de obra",
  "descripcion": "Pago semanal de albañiles",
  "monto": 25000,
  "categoria": "MANO_OBRA",
  "fecha": "2024-01-20",
  "obraId": "cmkk6tf4900085x5semza5bzu",
  "comprobante": "REC-001"
}

Campos:

Campo Tipo Requerido Descripción
concepto string Concepto del gasto
descripcion string No Descripción detallada
monto number Monto en MXN
categoria enum MATERIALES, MANO_OBRA, SUBCONTRATO, EQUIPO, TRANSPORTE, ADMINISTRATIVO, OTROS
fecha date Fecha del gasto
obraId string ID de la obra asociada
comprobante string No Número de factura/recibo

Respuesta exitosa (201): Objeto gasto creado

Aprobar gasto

PATCH /api/gastos/{id}/aprobar
Content-Type: application/json

Body:

{
  "estado": "APROBADO"
}

Valores permitidos para estado: APROBADO, RECHAZADO

Respuesta exitosa (200): Objeto gasto actualizado

Eliminar gasto

DELETE /api/gastos/{id}

Respuesta exitosa (200):

{
  "message": "Gasto eliminado exitosamente"
}

Endpoints de Materiales

Listar materiales

GET /api/materiales

Respuesta exitosa (200):

[
  {
    "id": "cmkk6tf6f000x5x5s413dejgf",
    "codigo": "CEM-001",
    "nombre": "Cemento Portland",
    "descripcion": "Cemento gris tipo I",
    "unidad": "BOLSA",
    "precioUnitario": 180,
    "stockMinimo": 100,
    "stockActual": 250,
    "ubicacion": "Bodega A",
    "activo": true
  }
]

Crear material

POST /api/materiales
Content-Type: application/json

Body:

{
  "codigo": "VAR-002",
  "nombre": "Varilla corrugada 1/2",
  "descripcion": "Varilla de acero corrugado",
  "unidad": "PIEZA",
  "precioUnitario": 180,
  "stockMinimo": 200,
  "ubicacion": "Bodega B"
}

Campos:

Campo Tipo Requerido Descripción
codigo string Código único del material
nombre string Nombre del material
descripcion string No Descripción
unidad enum PIEZA, METRO, METRO_CUADRADO, METRO_CUBICO, KILOGRAMO, LITRO, BOLSA, BULTO, ROLLO, CAJA, UNIDAD
precioUnitario number Precio por unidad
stockMinimo number No Stock mínimo para alertas
ubicacion string No Ubicación en bodega

Respuesta exitosa (201): Objeto material creado

Actualizar material

PUT /api/materiales/{id}
Content-Type: application/json

Body: (campos opcionales)

{
  "precioUnitario": 195,
  "stockMinimo": 150
}

Eliminar material

DELETE /api/materiales/{id}

Registrar movimiento de inventario

POST /api/materiales/movimiento
Content-Type: application/json

Body:

{
  "materialId": "cmkk6tf6f000x5x5s413dejgf",
  "tipo": "SALIDA",
  "cantidad": 50,
  "motivo": "Envío a obra Edificio Aurora",
  "obraId": "cmkk6tf4900085x5semza5bzu"
}

Campos:

Campo Tipo Requerido Descripción
materialId string ID del material
tipo enum ENTRADA, SALIDA, AJUSTE
cantidad number Cantidad del movimiento
motivo string No Razón del movimiento
obraId string No Obra destino (para salidas)

Respuesta exitosa (201):

{
  "id": "mov123",
  "tipo": "SALIDA",
  "cantidad": 50,
  "motivo": "Envío a obra Edificio Aurora",
  "materialId": "cmkk6tf6f000x5x5s413dejgf",
  "obraId": "cmkk6tf4900085x5semza5bzu",
  "createdAt": "2024-01-20T15:30:00.000Z"
}

Nota: El stock del material se actualiza automáticamente según el tipo de movimiento.


Códigos de Error

Código Descripción
400 Bad Request - Datos inválidos
401 Unauthorized - No autenticado
403 Forbidden - Sin permisos
404 Not Found - Recurso no encontrado
500 Internal Server Error

Formato de error:

{
  "error": "Descripción del error"
}

Ejemplos con cURL

Login y obtener materiales

# 1. Obtener CSRF token
CSRF=$(curl -s -c cookies.txt http://localhost:3000/api/auth/csrf | grep -oP '"csrfToken":"[^"]*"' | cut -d'"' -f4)

# 2. Login
curl -s -b cookies.txt -c cookies.txt \
  -X POST "http://localhost:3000/api/auth/callback/credentials" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "csrfToken=$CSRF&email=admin@demo.com&password=admin123"

# 3. Obtener materiales
curl -s -b cookies.txt http://localhost:3000/api/materiales

Crear un gasto

curl -X POST http://localhost:3000/api/gastos \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{
    "concepto": "Compra de cemento",
    "monto": 15000,
    "categoria": "MATERIALES",
    "fecha": "2024-01-20",
    "obraId": "cmkk6tf4900085x5semza5bzu"
  }'

Registrar entrada de material

curl -X POST http://localhost:3000/api/materiales/movimiento \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{
    "materialId": "cmkk6tf6f000x5x5s413dejgf",
    "tipo": "ENTRADA",
    "cantidad": 100,
    "motivo": "Compra a proveedor"
  }'