20 KiB
Documentacion de Modulos Backend
Este documento detalla la implementacion de cada modulo del backend.
Indice
- Auth Module
- Budgets Module (MAI-003)
- Progress Module (MAI-005)
- Estimates Module (MAI-008)
- Construction Module (MAI-002)
- HR Module (MAI-007)
- HSE Module (MAA-017)
- Core Module
Auth Module
Ubicacion: backend/src/modules/auth/
Descripcion
Modulo de autenticacion JWT con refresh tokens y soporte multi-tenant.
Estructura
auth/
├── dto/
│ └── auth.dto.ts # DTOs de autenticacion
├── services/
│ └── auth.service.ts # Logica de autenticacion
├── middleware/
│ └── auth.middleware.ts # Middleware JWT
└── index.ts # Exports
DTOs
// LoginDto
{
email: string; // Email del usuario
password: string; // Password
}
// RegisterDto
{
email: string;
password: string;
firstName: string;
lastName: string;
tenantId: string; // Tenant al que pertenece
}
// RefreshTokenDto
{
refreshToken: string;
}
// AuthResponse
{
user: UserDto;
accessToken: string;
refreshToken: string;
expiresIn: number;
}
AuthService
| Metodo | Descripcion | Parametros | Retorna |
|---|---|---|---|
login |
Autentica usuario | LoginDto |
AuthResponse |
register |
Registra nuevo usuario | RegisterDto |
AuthResponse |
refresh |
Renueva tokens | RefreshTokenDto |
AuthResponse |
logout |
Revoca refresh token | token: string |
boolean |
changePassword |
Cambia password | ChangePasswordDto |
boolean |
validateToken |
Valida JWT | token: string |
JwtPayload |
AuthMiddleware
| Metodo | Descripcion |
|---|---|
authenticate |
Valida JWT (requerido) |
optionalAuthenticate |
Valida JWT (opcional) |
authorize(...roles) |
Autoriza por roles |
requireAdmin |
Solo admin/super_admin |
requireSupervisor |
Solo supervisores+ |
setRLSContext |
Configura tenant en sesion PostgreSQL |
Ejemplo de Uso
// Login
const auth = await authService.login({
email: 'user@example.com',
password: 'securePassword123'
});
// Usar token en requests
headers: {
'Authorization': `Bearer ${auth.accessToken}`
}
// Refresh cuando expire
const newAuth = await authService.refresh({
refreshToken: auth.refreshToken
});
Budgets Module (MAI-003)
Ubicacion: backend/src/modules/budgets/
Descripcion
Gestion de catalogos de conceptos y presupuestos de obra.
Estructura
budgets/
├── entities/
│ ├── concepto.entity.ts
│ ├── presupuesto.entity.ts
│ └── presupuesto-partida.entity.ts
├── services/
│ ├── concepto.service.ts
│ └── presupuesto.service.ts
└── index.ts
Entidades
Concepto
Catalogo jerarquico de conceptos de obra.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador multi-tenant |
code |
string | Codigo unico (ej: "01.02.003") |
name |
string | Nombre del concepto |
description |
string | Descripcion detallada |
unit |
string | Unidad de medida (M2, ML, PZA) |
unitPrice |
decimal | Precio unitario |
parentId |
UUID | Concepto padre (null=raiz) |
level |
number | Nivel jerarquico (0=raiz) |
path |
string | Ruta completa (ej: "01/02/003") |
isActive |
boolean | Activo para uso |
Relaciones:
parent→ Concepto (auto-referencial)children→ Concepto[] (hijos)
Presupuesto
Presupuesto versionado de obra.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador |
fraccionamientoId |
UUID | Proyecto asociado |
code |
string | Codigo del presupuesto |
name |
string | Nombre descriptivo |
version |
number | Version (1, 2, 3...) |
status |
enum | draft/submitted/approved |
totalAmount |
decimal | Total calculado |
approvedAt |
timestamp | Fecha de aprobacion |
approvedById |
UUID | Usuario que aprobo |
Relaciones:
fraccionamiento→ Fraccionamientopartidas→ PresupuestoPartida[]
PresupuestoPartida
Lineas de presupuesto.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
presupuestoId |
UUID | Presupuesto padre |
conceptoId |
UUID | Concepto referenciado |
quantity |
decimal | Cantidad |
unitPrice |
decimal | Precio unitario |
totalAmount |
decimal | GENERADO: quantity * unitPrice |
ConceptoService
| Metodo | Descripcion |
|---|---|
createConcepto(ctx, dto) |
Crea concepto, calcula nivel/path |
findRootConceptos(ctx) |
Conceptos raiz (nivel 0) |
findChildren(ctx, parentId) |
Hijos de un concepto |
getConceptoTree(ctx, rootId?) |
Arbol completo/parcial |
search(ctx, term) |
Busqueda por codigo/nombre |
PresupuestoService
| Metodo | Descripcion |
|---|---|
createPresupuesto(ctx, dto) |
Crea presupuesto |
findByFraccionamiento(ctx, id) |
Por proyecto |
findWithPartidas(ctx, id) |
Con lineas cargadas |
addPartida(ctx, presupuestoId, dto) |
Agregar linea |
updatePartida(ctx, partidaId, dto) |
Modificar linea |
removePartida(ctx, partidaId) |
Eliminar linea |
recalculateTotal(ctx, presupuestoId) |
Recalcular total |
createNewVersion(ctx, presupuestoId) |
Crear version nueva |
approve(ctx, presupuestoId) |
Aprobar presupuesto |
Progress Module (MAI-005)
Ubicacion: backend/src/modules/progress/
Descripcion
Control de avances fisicos, bitacora y programacion de obra.
Estructura
progress/
├── entities/
│ ├── avance-obra.entity.ts
│ ├── foto-avance.entity.ts
│ ├── bitacora-obra.entity.ts
│ ├── programa-obra.entity.ts
│ └── programa-actividad.entity.ts
├── services/
│ ├── avance-obra.service.ts
│ └── bitacora-obra.service.ts
└── index.ts
Entidades
AvanceObra
Registro de avance fisico con workflow.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador |
loteId |
UUID | Lote donde se registro |
departamentoId |
UUID | Departamento (opcional) |
conceptoId |
UUID | Concepto de catalogo |
quantity |
decimal | Cantidad ejecutada |
progressDate |
date | Fecha de avance |
status |
enum | captured/reviewed/approved/rejected |
capturedById |
UUID | Usuario que capturo |
reviewedAt |
timestamp | Fecha de revision |
approvedAt |
timestamp | Fecha de aprobacion |
rejectionReason |
string | Motivo de rechazo |
notes |
string | Notas adicionales |
FotoAvance
Evidencia fotografica con geolocalización.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
avanceObraId |
UUID | Avance asociado |
fileName |
string | Nombre del archivo |
filePath |
string | Ruta en storage |
fileSize |
number | Tamano en bytes |
mimeType |
string | Tipo MIME |
latitude |
decimal | Latitud GPS |
longitude |
decimal | Longitud GPS |
takenAt |
timestamp | Fecha de captura |
description |
string | Descripcion |
BitacoraObra
Bitacora diaria de obra.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador |
fraccionamientoId |
UUID | Proyecto |
entryNumber |
number | Numero secuencial |
entryDate |
date | Fecha de entrada |
weather |
string | Clima del dia |
temperature |
decimal | Temperatura |
workersCount |
number | Personal en obra |
activities |
text | Actividades realizadas |
incidents |
text | Incidentes |
observations |
text | Observaciones |
createdById |
UUID | Usuario que creo |
AvanceObraService
| Metodo | Descripcion |
|---|---|
createAvance(ctx, dto) |
Crear avance en status captured |
findByLote(ctx, loteId) |
Avances de un lote |
findByDepartamento(ctx, deptoId) |
Avances de departamento |
findWithFilters(ctx, filters) |
Busqueda con filtros |
findWithFotos(ctx, id) |
Avance con fotos |
addFoto(ctx, avanceId, dto) |
Agregar foto |
review(ctx, id) |
Workflow: revisar |
approve(ctx, id) |
Workflow: aprobar |
reject(ctx, id, reason) |
Workflow: rechazar |
getAccumulatedProgress(ctx) |
Acumulado por concepto |
BitacoraObraService
| Metodo | Descripcion |
|---|---|
createEntry(ctx, dto) |
Crear entrada (numero automatico) |
findByFraccionamiento(ctx, id) |
Entradas de proyecto |
findWithFilters(ctx, id, filters) |
Con filtros |
findByDate(ctx, id, date) |
Por fecha especifica |
findLatest(ctx, id) |
Ultima entrada |
getStats(ctx, id) |
Estadisticas |
Estimates Module (MAI-008)
Ubicacion: backend/src/modules/estimates/
Descripcion
Estimaciones periodicas con workflow de aprobacion completo.
Estructura
estimates/
├── entities/
│ ├── estimacion.entity.ts
│ ├── estimacion-concepto.entity.ts
│ ├── generador.entity.ts
│ ├── anticipo.entity.ts
│ ├── amortizacion.entity.ts
│ ├── retencion.entity.ts
│ ├── fondo-garantia.entity.ts
│ └── estimacion-workflow.entity.ts
├── services/
│ └── estimacion.service.ts
└── index.ts
Entidades
Estimacion
Estimacion periodica principal.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador |
contratoId |
UUID | Contrato asociado |
number |
number | Numero secuencial |
periodStart |
date | Inicio del periodo |
periodEnd |
date | Fin del periodo |
status |
enum | draft/submitted/reviewed/approved/rejected |
subtotal |
decimal | Suma de conceptos |
iva |
decimal | IVA calculado |
retentions |
decimal | Retenciones |
amortization |
decimal | Amortizacion de anticipo |
totalAmount |
decimal | Total neto |
submittedAt |
timestamp | Fecha de envio |
reviewedAt |
timestamp | Fecha de revision |
approvedAt |
timestamp | Fecha de aprobacion |
rejectionReason |
string | Motivo de rechazo |
EstimacionConcepto
Lineas de estimacion con acumulados.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
estimacionId |
UUID | Estimacion padre |
conceptoId |
UUID | Concepto de catalogo |
contractQuantity |
decimal | Cantidad contratada |
previousQuantity |
decimal | Cantidad acumulada anterior |
currentQuantity |
decimal | Cantidad este periodo |
accumulatedQuantity |
decimal | GENERADO: previous + current |
pendingQuantity |
decimal | GENERADO: contract - accumulated |
unitPrice |
decimal | Precio unitario |
currentAmount |
decimal | GENERADO: current * price |
accumulatedAmount |
decimal | GENERADO: accumulated * price |
Generador
Numeros generadores (desglose de cantidades).
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
estimacionConceptoId |
UUID | Linea de estimacion |
description |
string | Descripcion del calculo |
length |
decimal | Largo |
width |
decimal | Ancho |
height |
decimal | Alto |
quantity |
decimal | Cantidad/Piezas |
partial |
decimal | GENERADO: formula |
formula |
string | Formula aplicada |
Anticipo
Anticipos de contrato.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
contratoId |
UUID | Contrato |
type |
enum | obra/materiales |
percentage |
decimal | Porcentaje del contrato |
amount |
decimal | Monto del anticipo |
grantedDate |
date | Fecha de otorgamiento |
amortizedAmount |
decimal | Monto ya amortizado |
pendingAmount |
decimal | GENERADO |
status |
enum | pending/partial/completed |
FondoGarantia
Fondo de garantia acumulado.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
contratoId |
UUID | Contrato |
percentage |
decimal | Porcentaje retenido |
accumulatedAmount |
decimal | Monto acumulado |
releasedAmount |
decimal | Monto liberado |
pendingAmount |
decimal | GENERADO |
EstimacionService
| Metodo | Descripcion |
|---|---|
createEstimacion(ctx, dto) |
Crear con numero automatico |
findByContrato(ctx, contratoId) |
Estimaciones de contrato |
findWithFilters(ctx, filters) |
Busqueda con filtros |
findWithDetails(ctx, id) |
Con todas las relaciones |
addConcepto(ctx, estimacionId, dto) |
Agregar linea |
addGenerador(ctx, conceptoId, dto) |
Agregar generador |
recalculateTotals(ctx, id) |
Recalcular totales |
submit(ctx, id) |
Workflow: enviar |
review(ctx, id) |
Workflow: revisar |
approve(ctx, id) |
Workflow: aprobar |
reject(ctx, id, reason) |
Workflow: rechazar |
getContractSummary(ctx, contratoId) |
Resumen financiero |
Construction Module (MAI-002)
Ubicacion: backend/src/modules/construction/
Descripcion
Gestion de proyectos y estructura organizacional.
Entidades
Proyecto
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador |
code |
string | Codigo del proyecto |
name |
string | Nombre |
description |
text | Descripcion |
status |
enum | planning/in_progress/completed/cancelled |
startDate |
date | Fecha inicio |
endDate |
date | Fecha fin |
budget |
decimal | Presupuesto total |
location |
geography | Ubicacion GPS |
address |
string | Direccion |
city |
string | Ciudad |
state |
string | Estado |
Fraccionamiento
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador |
proyectoId |
UUID | Proyecto padre |
code |
string | Codigo |
name |
string | Nombre |
totalLots |
number | Total de lotes |
builtLots |
number | Lotes construidos |
soldLots |
number | Lotes vendidos |
HR Module (MAI-007)
Ubicacion: backend/src/modules/hr/
Descripcion
Gestion de recursos humanos y asignaciones.
Entidades
Employee
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador |
employeeNumber |
string | Numero de empleado |
firstName |
string | Nombre |
lastName |
string | Apellidos |
email |
string | |
phone |
string | Telefono |
hireDate |
date | Fecha de contratacion |
puestoId |
UUID | Puesto |
status |
enum | active/inactive/terminated |
dailyRate |
decimal | Salario diario |
imssNumber |
string | Numero IMSS |
curp |
string | CURP |
rfc |
string | RFC |
Puesto
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador |
code |
string | Codigo |
name |
string | Nombre del puesto |
department |
string | Departamento |
level |
number | Nivel jerarquico |
baseSalary |
decimal | Salario base |
EmployeeFraccionamiento
Asignacion de empleados a proyectos.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
employeeId |
UUID | Empleado |
fraccionamientoId |
UUID | Proyecto |
role |
string | Rol en el proyecto |
startDate |
date | Fecha inicio |
endDate |
date | Fecha fin (null=activo) |
HSE Module (MAA-017)
Ubicacion: backend/src/modules/hse/
Descripcion
Seguridad, salud y medio ambiente.
Entidades
Incidente
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador |
fraccionamientoId |
UUID | Proyecto |
incidentNumber |
string | Numero de reporte |
incidentDate |
timestamp | Fecha y hora |
type |
enum | accident/near_miss/incident |
severity |
enum | low/medium/high/critical |
description |
text | Descripcion |
location |
string | Ubicacion |
immediateActions |
text | Acciones inmediatas |
rootCause |
text | Causa raiz |
status |
enum | reported/investigating/closed |
reportedById |
UUID | Quien reporto |
IncidenteInvolucrado
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
incidenteId |
UUID | Incidente |
employeeId |
UUID | Empleado (opcional) |
name |
string | Nombre (si no es empleado) |
role |
enum | victim/witness/reporter |
injuryType |
string | Tipo de lesion |
treatmentRequired |
boolean | Requirio tratamiento |
IncidenteAccion
Acciones correctivas.
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
incidenteId |
UUID | Incidente |
description |
text | Descripcion de la accion |
responsibleId |
UUID | Responsable |
dueDate |
date | Fecha limite |
completedAt |
timestamp | Fecha de cierre |
status |
enum | pending/in_progress/completed |
Capacitacion
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
tenantId |
UUID | Discriminador |
name |
string | Nombre del curso |
type |
enum | induction/specific/recertification |
duration |
number | Duracion en horas |
validityMonths |
number | Vigencia en meses |
instructor |
string | Instructor |
scheduledDate |
date | Fecha programada |
status |
enum | scheduled/completed/cancelled |
Core Module
Ubicacion: backend/src/modules/core/
Descripcion
Entidades base del sistema (usuarios, tenants).
Entidades
User
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
email |
string | Email unico |
passwordHash |
string | Password hasheado |
firstName |
string | Nombre |
lastName |
string | Apellidos |
role |
enum | Rol del sistema |
isActive |
boolean | Usuario activo |
lastLoginAt |
timestamp | Ultimo acceso |
emailVerifiedAt |
timestamp | Email verificado |
Tenant
| Campo | Tipo | Descripcion |
|---|---|---|
id |
UUID | Primary key |
code |
string | Codigo unico |
name |
string | Nombre de la empresa |
subdomain |
string | Subdominio |
plan |
enum | basic/professional/enterprise |
isActive |
boolean | Tenant activo |
settings |
jsonb | Configuraciones |
createdAt |
timestamp | Fecha de creacion |
Shared: BaseService
Ubicacion: backend/src/shared/services/base.service.ts
Descripcion
Servicio base abstracto que proporciona operaciones CRUD multi-tenant.
Interface ServiceContext
interface ServiceContext {
tenantId: string;
userId: string;
}
Interface PaginatedResult
interface PaginatedResult<T> {
data: T[];
total: number;
page: number;
limit: number;
totalPages: number;
}
Metodos
| Metodo | Descripcion | Retorna |
|---|---|---|
findAll(ctx, options?) |
Listado paginado | PaginatedResult<T> |
findById(ctx, id) |
Por ID | T | null |
findOne(ctx, where) |
Por condicion | T | null |
find(ctx, options) |
Por opciones | T[] |
create(ctx, data) |
Crear registro | T |
update(ctx, id, data) |
Actualizar | T | null |
softDelete(ctx, id) |
Borrado logico | boolean |
hardDelete(ctx, id) |
Borrado fisico | boolean |
count(ctx, where?) |
Contar registros | number |
exists(ctx, where) |
Verificar existencia | boolean |
Ejemplo de Uso
class MiService extends BaseService<MiEntity> {
constructor(repository: Repository<MiEntity>) {
super(repository);
}
// Metodos personalizados
async findActive(ctx: ServiceContext): Promise<MiEntity[]> {
return this.find(ctx, {
where: { isActive: true },
order: { createdAt: 'DESC' },
});
}
}
// Uso
const ctx = { tenantId: 'uuid', userId: 'uuid' };
const items = await miService.findAll(ctx, { page: 1, limit: 10 });
const item = await miService.findById(ctx, 'item-uuid');
const created = await miService.create(ctx, { name: 'Nuevo' });
Ultima actualizacion: 2025-12-12