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>
15 KiB
Documentación de Base de Datos - Mexus App
Este documento describe el esquema de base de datos utilizado en Mexus App.
Diagrama de Relaciones
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Empresa │───────│ User │───────│ Gasto │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Obra │───────│ FaseObra │───────│ TareaObra │
└─────────────┘ └─────────────┘ └─────────────┘
│
├──────────────┬──────────────┬──────────────┐
▼ ▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Presupuesto │ │ Empleado │ │Subcontratist│ │ Material │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Partida │ │ Movimiento │
│ Presupuesto │ │ Inventario │
└─────────────┘ └─────────────┘
Modelos de Datos
Empresa
Representa una empresa en el sistema (multi-tenant).
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| nombre | String | Nombre de la empresa |
| rfc | String? | RFC (único) |
| direccion | String? | Dirección |
| telefono | String? | Teléfono |
| String? | Email de contacto | |
| logo | String? | URL del logo |
| activo | Boolean | Estado activo (default: true) |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Relaciones:
usuarios→ User[] (1:N)obras→ Obra[] (1:N)materiales→ Material[] (1:N)empleados→ Empleado[] (1:N)subcontratistas→ Subcontratista[] (1:N)
User
Usuarios del sistema con roles y permisos.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| String | Email (único) | |
| password | String | Contraseña hasheada |
| nombre | String | Nombre |
| apellido | String | Apellido |
| telefono | String? | Teléfono |
| role | Role | Rol del usuario |
| activo | Boolean | Estado activo (default: true) |
| empresaId | String | ID de la empresa |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Enum Role:
ADMIN- Administrador con acceso totalGERENTE- Gerente de proyectosSUPERVISOR- Supervisor de obraCONTADOR- Contador/finanzasEMPLEADO- Empleado general
Relaciones:
empresa→ Empresa (N:1)gastos→ Gasto[] (1:N)obrasCreadas→ Obra[] (1:N)
Obra
Proyectos de construcción.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| codigo | String | Código único de obra |
| nombre | String | Nombre del proyecto |
| descripcion | String? | Descripción |
| cliente | String | Nombre del cliente |
| ubicacion | String? | Dirección/ubicación |
| estado | EstadoObra | Estado actual |
| presupuestoTotal | Float | Presupuesto total MXN |
| fechaInicio | DateTime | Fecha de inicio |
| fechaFinEstimada | DateTime? | Fecha fin estimada |
| fechaFinReal | DateTime? | Fecha fin real |
| avanceGeneral | Float | Porcentaje de avance (0-100) |
| empresaId | String | ID de la empresa |
| creadoPorId | String | ID del usuario creador |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Enum EstadoObra:
PLANEACION- En planeaciónEN_PROGRESO- En ejecuciónPAUSADA- Pausada temporalmenteCOMPLETADA- FinalizadaCANCELADA- Cancelada
Relaciones:
empresa→ Empresa (N:1)creadoPor→ User (N:1)fases→ FaseObra[] (1:N)gastos→ Gasto[] (1:N)presupuestos→ Presupuesto[] (1:N)empleadosAsignados→ EmpleadoObra[] (1:N)subcontratistasAsignados→ SubcontratistaObra[] (1:N)movimientosInventario→ MovimientoInventario[] (1:N)
FaseObra
Fases o etapas de una obra.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| nombre | String | Nombre de la fase |
| descripcion | String? | Descripción |
| orden | Int | Orden de ejecución |
| fechaInicio | DateTime? | Fecha de inicio |
| fechaFin | DateTime? | Fecha de fin |
| avance | Float | Porcentaje de avance (default: 0) |
| estado | EstadoFase | Estado de la fase |
| obraId | String | ID de la obra |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Enum EstadoFase:
PENDIENTE- No iniciadaEN_PROGRESO- En ejecuciónCOMPLETADA- FinalizadaCANCELADA- Cancelada
Relaciones:
obra→ Obra (N:1)tareas→ TareaObra[] (1:N)
TareaObra
Tareas específicas dentro de una fase.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| nombre | String | Nombre de la tarea |
| descripcion | String? | Descripción |
| fechaInicio | DateTime? | Fecha de inicio |
| fechaFin | DateTime? | Fecha de fin |
| estado | EstadoTarea | Estado de la tarea |
| faseId | String | ID de la fase |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Enum EstadoTarea:
PENDIENTE- No iniciadaEN_PROGRESO- En ejecuciónCOMPLETADA- FinalizadaBLOQUEADA- Bloqueada por dependencia
Relaciones:
fase→ FaseObra (N:1)
Presupuesto
Presupuestos asociados a obras.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| nombre | String | Nombre del presupuesto |
| version | Int | Número de versión (default: 1) |
| montoTotal | Float | Monto total calculado |
| aprobado | Boolean | Estado de aprobación |
| fechaAprobacion | DateTime? | Fecha de aprobación |
| obraId | String | ID de la obra |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Relaciones:
obra→ Obra (N:1)partidas→ PartidaPresupuesto[] (1:N)
PartidaPresupuesto
Líneas de detalle de un presupuesto.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| concepto | String | Concepto/descripción |
| unidad | String | Unidad de medida |
| cantidad | Float | Cantidad |
| precioUnitario | Float | Precio por unidad |
| subtotal | Float | Subtotal calculado |
| presupuestoId | String | ID del presupuesto |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Relaciones:
presupuesto→ Presupuesto (N:1)
Gasto
Registro de gastos de obra.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| concepto | String | Concepto del gasto |
| descripcion | String? | Descripción detallada |
| monto | Float | Monto en MXN |
| categoria | CategoriaGasto | Categoría |
| fecha | DateTime | Fecha del gasto |
| comprobante | String? | Número de comprobante |
| estado | EstadoGasto | Estado de aprobación |
| obraId | String | ID de la obra |
| usuarioId | String | ID del usuario que registra |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Enum CategoriaGasto:
MATERIALES- Compra de materialesMANO_OBRA- Pago de mano de obraSUBCONTRATO- Pagos a subcontratistasEQUIPO- Renta/compra de equipoTRANSPORTE- Fletes y transporteADMINISTRATIVO- Gastos administrativosOTROS- Otros gastos
Enum EstadoGasto:
PENDIENTE- Pendiente de aprobaciónAPROBADO- AprobadoRECHAZADO- Rechazado
Relaciones:
obra→ Obra (N:1)usuario→ User (N:1)
Factura
Facturas emitidas y recibidas.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| numero | String | Número de factura |
| tipo | TipoFactura | Tipo (emitida/recibida) |
| cliente | String? | Nombre del cliente |
| proveedor | String? | Nombre del proveedor |
| subtotal | Float | Subtotal |
| iva | Float | IVA |
| total | Float | Total |
| fechaEmision | DateTime | Fecha de emisión |
| fechaVencimiento | DateTime? | Fecha de vencimiento |
| estado | EstadoFactura | Estado de pago |
| obraId | String | ID de la obra |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Enum TipoFactura:
EMITIDA- Factura a clienteRECIBIDA- Factura de proveedor
Enum EstadoFactura:
PENDIENTE- Pendiente de pagoPAGADA- PagadaVENCIDA- VencidaCANCELADA- Cancelada
Relaciones:
obra→ Obra (N:1)
Material
Catálogo de materiales de construcción.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| codigo | String | Código único |
| nombre | String | Nombre del material |
| descripcion | String? | Descripción |
| unidad | UnidadMedida | Unidad de medida |
| precioUnitario | Float | Precio por unidad |
| stockMinimo | Float | Stock mínimo para alertas |
| stockActual | Float | Stock actual (default: 0) |
| ubicacion | String? | Ubicación en bodega |
| activo | Boolean | Estado activo (default: true) |
| empresaId | String | ID de la empresa |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Enum UnidadMedida:
PIEZA- PiezaMETRO- Metro linealMETRO_CUADRADO- Metro cuadradoMETRO_CUBICO- Metro cúbicoKILOGRAMO- KilogramoLITRO- LitroBOLSA- BolsaBULTO- BultoROLLO- RolloCAJA- CajaUNIDAD- Unidad
Relaciones:
empresa→ Empresa (N:1)movimientos→ MovimientoInventario[] (1:N)
Índice único: @@unique([codigo, empresaId])
MovimientoInventario
Registro de movimientos de inventario.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| tipo | TipoMovimiento | Tipo de movimiento |
| cantidad | Float | Cantidad |
| motivo | String? | Motivo/descripción |
| materialId | String | ID del material |
| obraId | String? | ID de la obra (opcional) |
| createdAt | DateTime | Fecha de creación |
Enum TipoMovimiento:
ENTRADA- Entrada de materialSALIDA- Salida de materialAJUSTE- Ajuste de inventario
Relaciones:
material→ Material (N:1)obra→ Obra (N:1, opcional)
Empleado
Personal de la empresa.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| codigo | String | Código de empleado |
| nombre | String | Nombre |
| apellido | String | Apellido |
| curp | String? | CURP |
| rfc | String? | RFC |
| telefono | String? | Teléfono |
| String? | ||
| puesto | String | Puesto/cargo |
| salarioDiario | Float | Salario diario |
| fechaIngreso | DateTime | Fecha de ingreso |
| activo | Boolean | Estado activo (default: true) |
| empresaId | String | ID de la empresa |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Relaciones:
empresa→ Empresa (N:1)obrasAsignadas→ EmpleadoObra[] (1:N)jornadas→ JornadaLaboral[] (1:N)
Subcontratista
Empresas subcontratadas.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| nombre | String | Nombre/razón social |
| rfc | String? | RFC |
| contacto | String? | Persona de contacto |
| telefono | String? | Teléfono |
| String? | ||
| especialidad | String | Especialidad/giro |
| activo | Boolean | Estado activo (default: true) |
| empresaId | String | ID de la empresa |
| createdAt | DateTime | Fecha de creación |
| updatedAt | DateTime | Fecha de actualización |
Relaciones:
empresa→ Empresa (N:1)obrasAsignadas→ SubcontratistaObra[] (1:N)
Tablas de Relación (N:M)
EmpleadoObra
Asignación de empleados a obras.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| empleadoId | String | ID del empleado |
| obraId | String | ID de la obra |
| fechaAsignacion | DateTime | Fecha de asignación |
| fechaFin | DateTime? | Fecha de fin |
| activo | Boolean | Asignación activa |
SubcontratistaObra
Asignación de subcontratistas a obras.
| Campo | Tipo | Descripción |
|---|---|---|
| id | String | ID único (CUID) |
| subcontratistaId | String | ID del subcontratista |
| obraId | String | ID de la obra |
| descripcionTrabajo | String | Descripción del trabajo |
| montoContrato | Float | Monto del contrato |
| fechaInicio | DateTime | Fecha de inicio |
| fechaFin | DateTime? | Fecha de fin |
| estado | EstadoContrato | Estado del contrato |
Comandos de Prisma
# Generar cliente Prisma
npx prisma generate
# Crear migración
npx prisma migrate dev --name descripcion_cambio
# Aplicar migraciones en producción
npx prisma migrate deploy
# Ver base de datos en navegador
npx prisma studio
# Ejecutar seed
npx prisma db seed
# Resetear base de datos (desarrollo)
npx prisma migrate reset
Consideraciones de Seguridad
- Multi-tenant: Todas las queries filtran por
empresaIddel usuario autenticado - Índices: Se han creado índices en campos frecuentemente consultados
- Cascade: Las eliminaciones en cascada están configuradas para mantener integridad
- Soft delete: Los registros importantes usan campo
activoen lugar de eliminación física