# 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 | | email | 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) | | email | 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 total - `GERENTE` - Gerente de proyectos - `SUPERVISOR` - Supervisor de obra - `CONTADOR` - Contador/finanzas - `EMPLEADO` - 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ón - `EN_PROGRESO` - En ejecución - `PAUSADA` - Pausada temporalmente - `COMPLETADA` - Finalizada - `CANCELADA` - 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 iniciada - `EN_PROGRESO` - En ejecución - `COMPLETADA` - Finalizada - `CANCELADA` - 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 iniciada - `EN_PROGRESO` - En ejecución - `COMPLETADA` - Finalizada - `BLOQUEADA` - 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 materiales - `MANO_OBRA` - Pago de mano de obra - `SUBCONTRATO` - Pagos a subcontratistas - `EQUIPO` - Renta/compra de equipo - `TRANSPORTE` - Fletes y transporte - `ADMINISTRATIVO` - Gastos administrativos - `OTROS` - Otros gastos **Enum EstadoGasto:** - `PENDIENTE` - Pendiente de aprobación - `APROBADO` - Aprobado - `RECHAZADO` - 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 cliente - `RECIBIDA` - Factura de proveedor **Enum EstadoFactura:** - `PENDIENTE` - Pendiente de pago - `PAGADA` - Pagada - `VENCIDA` - Vencida - `CANCELADA` - 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` - Pieza - `METRO` - Metro lineal - `METRO_CUADRADO` - Metro cuadrado - `METRO_CUBICO` - Metro cúbico - `KILOGRAMO` - Kilogramo - `LITRO` - Litro - `BOLSA` - Bolsa - `BULTO` - Bulto - `ROLLO` - Rollo - `CAJA` - Caja - `UNIDAD` - 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 material - `SALIDA` - Salida de material - `AJUSTE` - 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 | | email | String? | Email | | 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 | | email | String? | Email | | 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 ```bash # 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 1. **Multi-tenant**: Todas las queries filtran por `empresaId` del usuario autenticado 2. **Índices**: Se han creado índices en campos frecuentemente consultados 3. **Cascade**: Las eliminaciones en cascada están configuradas para mantener integridad 4. **Soft delete**: Los registros importantes usan campo `activo` en lugar de eliminación física