570 lines
11 KiB
Markdown
570 lines
11 KiB
Markdown
# DOMAIN MODEL: Compliance Context (INFONAVIT)
|
|
|
|
**Version:** 1.0.0
|
|
**Fecha:** 2025-12-05
|
|
**Modulos:** MAI-011
|
|
|
|
---
|
|
|
|
## Descripcion
|
|
|
|
El contexto de Compliance gestiona el cumplimiento normativo para proyectos de vivienda bajo programas INFONAVIT. Incluye registro de proyectos en programas, checklists de requisitos, evidencias y auditorias.
|
|
|
|
---
|
|
|
|
## Agregados
|
|
|
|
### 1. Program Aggregate
|
|
|
|
```
|
|
InfonavitProgram (Aggregate Root)
|
|
|
|
|
+-- ProgramRequirement (Entity)
|
|
| +-- EvidenceType (Value Object)
|
|
|
|
|
+-- RequirementCategory (Value Object)
|
|
```
|
|
|
|
#### InfonavitProgram (Root)
|
|
```typescript
|
|
interface InfonavitProgram {
|
|
id: UUID;
|
|
tenantId: UUID;
|
|
|
|
code: string;
|
|
name: string;
|
|
description?: string;
|
|
programType: ProgramType;
|
|
|
|
validFrom?: Date;
|
|
validTo?: Date;
|
|
|
|
isActive: boolean;
|
|
requirementsCount: number;
|
|
|
|
requirements: ProgramRequirement[];
|
|
}
|
|
|
|
enum ProgramType {
|
|
EVC = 'evc', // Esquemas de Valor Compartido
|
|
TRADITIONAL = 'traditional', // Credito tradicional
|
|
COFINAVIT = 'cofinavit', // Credito mixto
|
|
INFONAVIT_TOTAL = 'infonavit_total', // Con subsidio
|
|
APOYO_INFONAVIT = 'apoyo_infonavit', // Solo subsidio
|
|
MEJORAVIT = 'mejoravit', // Mejora de vivienda
|
|
UNAMOS_CREDITOS = 'unamos_creditos' // Creditos combinados
|
|
}
|
|
```
|
|
|
|
#### ProgramRequirement (Entity)
|
|
```typescript
|
|
interface ProgramRequirement {
|
|
id: UUID;
|
|
programId: UUID;
|
|
|
|
code: string;
|
|
name: string;
|
|
description?: string;
|
|
|
|
category: RequirementCategory;
|
|
subcategory?: string;
|
|
|
|
// Evidence required
|
|
evidenceRequired: string[];
|
|
evidenceDescription?: string;
|
|
|
|
sortOrder: number;
|
|
parentId?: UUID;
|
|
|
|
isMandatory: boolean;
|
|
isActive: boolean;
|
|
|
|
children: ProgramRequirement[];
|
|
}
|
|
|
|
enum RequirementCategory {
|
|
TECHNICAL = 'technical', // Requisitos tecnicos
|
|
URBAN = 'urban', // Requisitos urbanos
|
|
SERVICES = 'services', // Requisitos de servicios
|
|
LEGAL = 'legal', // Requisitos legales
|
|
ENVIRONMENTAL = 'environmental' // Requisitos ambientales
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 2. ProjectCompliance Aggregate
|
|
|
|
```
|
|
ProjectProgram (Aggregate Root)
|
|
|
|
|
+-- ComplianceItem (Entity)
|
|
| +-- ComplianceEvidence (Entity)
|
|
|
|
|
+-- ComplianceStatus (Value Object)
|
|
```
|
|
|
|
#### ProjectProgram (Root)
|
|
```typescript
|
|
interface ProjectProgram {
|
|
id: UUID;
|
|
tenantId: UUID;
|
|
projectId: UUID;
|
|
programId: UUID;
|
|
|
|
registrationNumber?: string;
|
|
registrationDate?: Date;
|
|
|
|
validFrom?: Date;
|
|
validTo?: Date;
|
|
|
|
// Compliance statistics
|
|
compliancePercentage: Percentage;
|
|
totalRequirements: number;
|
|
compliantCount: number;
|
|
nonCompliantCount: number;
|
|
pendingCount: number;
|
|
|
|
status: string;
|
|
|
|
items: ComplianceItem[];
|
|
}
|
|
```
|
|
|
|
#### ComplianceItem (Entity)
|
|
```typescript
|
|
interface ComplianceItem {
|
|
id: UUID;
|
|
projectProgramId: UUID;
|
|
requirementId: UUID;
|
|
|
|
status: RequirementStatus;
|
|
previousStatus?: RequirementStatus;
|
|
|
|
// Verification
|
|
verifiedBy?: UUID;
|
|
verifiedAt?: Timestamp;
|
|
verificationNotes?: string;
|
|
|
|
// Dates
|
|
dueDate?: Date;
|
|
completedDate?: Date;
|
|
|
|
notes?: string;
|
|
isNotApplicable: boolean;
|
|
naReason?: string;
|
|
|
|
evidence: ComplianceEvidence[];
|
|
}
|
|
|
|
enum RequirementStatus {
|
|
PENDING = 'pending',
|
|
IN_PROGRESS = 'in_progress',
|
|
COMPLIANT = 'compliant',
|
|
NON_COMPLIANT = 'non_compliant',
|
|
NOT_APPLICABLE = 'not_applicable'
|
|
}
|
|
```
|
|
|
|
#### ComplianceEvidence (Entity)
|
|
```typescript
|
|
interface ComplianceEvidence {
|
|
id: UUID;
|
|
complianceItemId: UUID;
|
|
|
|
fileUrl: string;
|
|
fileName: string;
|
|
fileSize?: number;
|
|
mimeType?: string;
|
|
thumbnailUrl?: string;
|
|
|
|
evidenceType: EvidenceType;
|
|
description?: string;
|
|
|
|
takenAt?: Timestamp;
|
|
location?: Location;
|
|
metadata?: Record<string, any>;
|
|
|
|
status: EvidenceStatus;
|
|
|
|
// Review
|
|
reviewedBy?: UUID;
|
|
reviewedAt?: Timestamp;
|
|
reviewNotes?: string;
|
|
}
|
|
|
|
enum EvidenceType {
|
|
DOCUMENT = 'document',
|
|
PHOTO = 'photo',
|
|
VIDEO = 'video',
|
|
CERTIFICATE = 'certificate'
|
|
}
|
|
|
|
enum EvidenceStatus {
|
|
ACTIVE = 'active',
|
|
REPLACED = 'replaced',
|
|
REJECTED = 'rejected'
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 3. Audit Aggregate
|
|
|
|
```
|
|
Audit (Aggregate Root)
|
|
|
|
|
+-- AuditFinding (Entity)
|
|
| +-- CorrectiveAction (Entity)
|
|
|
|
|
+-- AuditResult (Value Object)
|
|
```
|
|
|
|
#### Audit (Root)
|
|
```typescript
|
|
interface Audit {
|
|
id: UUID;
|
|
tenantId: UUID;
|
|
projectId: UUID;
|
|
|
|
auditNumber: string;
|
|
auditType: AuditType;
|
|
|
|
// Schedule
|
|
scheduledDate: Date;
|
|
scheduledTime?: Time;
|
|
actualDate?: Date;
|
|
|
|
// Auditor
|
|
auditorName?: string;
|
|
auditorCompany?: string;
|
|
auditorContact?: string;
|
|
|
|
status: AuditStatus;
|
|
|
|
// Results
|
|
overallCompliancePercentage?: Percentage;
|
|
findingsCount: number;
|
|
criticalFindings: number;
|
|
majorFindings: number;
|
|
minorFindings: number;
|
|
|
|
reportUrl?: string;
|
|
notes?: string;
|
|
|
|
closedAt?: Timestamp;
|
|
closedBy?: UUID;
|
|
|
|
findings: AuditFinding[];
|
|
}
|
|
|
|
enum AuditType {
|
|
INITIAL = 'initial',
|
|
PROGRESS = 'progress',
|
|
FINAL = 'final',
|
|
SPECIAL = 'special',
|
|
RANDOM = 'random'
|
|
}
|
|
|
|
enum AuditStatus {
|
|
SCHEDULED = 'scheduled',
|
|
IN_PROGRESS = 'in_progress',
|
|
COMPLETED = 'completed',
|
|
FOLLOW_UP = 'follow_up',
|
|
CANCELLED = 'cancelled'
|
|
}
|
|
```
|
|
|
|
#### AuditFinding (Entity)
|
|
```typescript
|
|
interface AuditFinding {
|
|
id: UUID;
|
|
auditId: UUID;
|
|
complianceItemId?: UUID;
|
|
|
|
findingNumber: string;
|
|
severity: FindingSeverity;
|
|
|
|
title: string;
|
|
description: string;
|
|
evidenceRefs?: string[];
|
|
|
|
// Failed requirement
|
|
requirementCode?: string;
|
|
requirementName?: string;
|
|
|
|
// Responsible
|
|
responsibleName?: string;
|
|
responsibleArea?: string;
|
|
|
|
dueDate: Date;
|
|
resolutionDate?: Date;
|
|
|
|
status: FindingStatus;
|
|
|
|
correctiveActions: CorrectiveAction[];
|
|
}
|
|
|
|
enum FindingSeverity {
|
|
MINOR = 'minor', // 30 days to correct
|
|
MAJOR = 'major', // 15 days to correct
|
|
CRITICAL = 'critical' // 7 days to correct
|
|
}
|
|
|
|
enum FindingStatus {
|
|
OPEN = 'open',
|
|
IN_PROGRESS = 'in_progress',
|
|
RESOLVED = 'resolved',
|
|
VERIFIED = 'verified',
|
|
CLOSED = 'closed'
|
|
}
|
|
```
|
|
|
|
#### CorrectiveAction (Entity)
|
|
```typescript
|
|
interface CorrectiveAction {
|
|
id: UUID;
|
|
findingId: UUID;
|
|
|
|
actionNumber: string;
|
|
description: string;
|
|
actionType: ActionType;
|
|
|
|
// Assignment
|
|
assignedTo?: UUID;
|
|
assignedToName?: string;
|
|
assignedAt?: Timestamp;
|
|
|
|
dueDate: Date;
|
|
completedDate?: Date;
|
|
|
|
status: ActionStatus;
|
|
|
|
// Verification
|
|
verifiedBy?: UUID;
|
|
verifiedAt?: Timestamp;
|
|
verificationNotes?: string;
|
|
}
|
|
|
|
enum ActionType {
|
|
CORRECTION = 'correction',
|
|
PREVENTION = 'prevention',
|
|
IMPROVEMENT = 'improvement'
|
|
}
|
|
|
|
enum ActionStatus {
|
|
PENDING = 'pending',
|
|
IN_PROGRESS = 'in_progress',
|
|
COMPLETED = 'completed',
|
|
VERIFIED = 'verified'
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Value Objects
|
|
|
|
### Percentage
|
|
```typescript
|
|
interface Percentage {
|
|
value: number; // 0-100
|
|
|
|
static fromDecimal(decimal: number): Percentage;
|
|
static toDecimal(percentage: Percentage): number;
|
|
static isAboveThreshold(p: Percentage, threshold: number): boolean;
|
|
}
|
|
```
|
|
|
|
### Location
|
|
```typescript
|
|
interface Location {
|
|
latitude: number;
|
|
longitude: number;
|
|
accuracy?: number;
|
|
timestamp?: Timestamp;
|
|
}
|
|
```
|
|
|
|
### ComplianceSummary
|
|
```typescript
|
|
interface ComplianceSummary {
|
|
totalRequirements: number;
|
|
compliantCount: number;
|
|
pendingCount: number;
|
|
nonCompliantCount: number;
|
|
notApplicableCount: number;
|
|
|
|
byCategory: Record<RequirementCategory, {
|
|
total: number;
|
|
compliant: number;
|
|
percentage: Percentage;
|
|
}>;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Domain Events
|
|
|
|
### Program Events
|
|
```typescript
|
|
interface ProjectRegisteredInProgram {
|
|
projectProgramId: UUID;
|
|
projectId: UUID;
|
|
programId: UUID;
|
|
registrationNumber?: string;
|
|
timestamp: Timestamp;
|
|
}
|
|
```
|
|
|
|
### Compliance Events
|
|
```typescript
|
|
interface ComplianceItemStatusChanged {
|
|
complianceItemId: UUID;
|
|
projectProgramId: UUID;
|
|
previousStatus: RequirementStatus;
|
|
newStatus: RequirementStatus;
|
|
changedBy: UUID;
|
|
timestamp: Timestamp;
|
|
}
|
|
|
|
interface EvidenceUploaded {
|
|
evidenceId: UUID;
|
|
complianceItemId: UUID;
|
|
evidenceType: EvidenceType;
|
|
fileName: string;
|
|
uploadedBy: UUID;
|
|
timestamp: Timestamp;
|
|
}
|
|
|
|
interface ComplianceThresholdReached {
|
|
projectProgramId: UUID;
|
|
projectId: UUID;
|
|
compliancePercentage: Percentage;
|
|
threshold: Percentage;
|
|
timestamp: Timestamp;
|
|
}
|
|
```
|
|
|
|
### Audit Events
|
|
```typescript
|
|
interface AuditScheduled {
|
|
auditId: UUID;
|
|
projectId: UUID;
|
|
auditType: AuditType;
|
|
scheduledDate: Date;
|
|
timestamp: Timestamp;
|
|
}
|
|
|
|
interface AuditCompleted {
|
|
auditId: UUID;
|
|
projectId: UUID;
|
|
overallCompliance: Percentage;
|
|
findingsCount: number;
|
|
criticalCount: number;
|
|
timestamp: Timestamp;
|
|
}
|
|
|
|
interface FindingCreated {
|
|
findingId: UUID;
|
|
auditId: UUID;
|
|
severity: FindingSeverity;
|
|
dueDate: Date;
|
|
timestamp: Timestamp;
|
|
}
|
|
|
|
interface CorrectiveActionCompleted {
|
|
actionId: UUID;
|
|
findingId: UUID;
|
|
completedBy: UUID;
|
|
timestamp: Timestamp;
|
|
}
|
|
```
|
|
|
|
### Alert Events
|
|
```typescript
|
|
interface RequirementDueSoon {
|
|
complianceItemId: UUID;
|
|
projectId: UUID;
|
|
dueDate: Date;
|
|
daysRemaining: number;
|
|
timestamp: Timestamp;
|
|
}
|
|
|
|
interface FindingOverdue {
|
|
findingId: UUID;
|
|
auditId: UUID;
|
|
severity: FindingSeverity;
|
|
dueDate: Date;
|
|
daysOverdue: number;
|
|
timestamp: Timestamp;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Business Rules
|
|
|
|
### Program Rules
|
|
1. Un proyecto solo puede registrarse una vez por programa
|
|
2. Los requisitos obligatorios no pueden marcarse como N/A sin justificacion
|
|
3. El registro en programa requiere al menos datos basicos del proyecto
|
|
|
|
### Compliance Rules
|
|
1. El status solo puede avanzar: pending -> in_progress -> compliant
|
|
2. Marcar como compliant requiere al menos una evidencia
|
|
3. El porcentaje de cumplimiento excluye items N/A del calculo
|
|
4. Cambios de status deben registrar historial
|
|
|
|
### Audit Rules
|
|
1. No se puede cerrar auditoria con hallazgos criticos abiertos
|
|
2. Los hallazgos tienen plazos segun severidad (7/15/30 dias)
|
|
3. Las acciones correctivas requieren verificacion antes de cerrar
|
|
4. Una auditoria de seguimiento requiere auditoria previa completada
|
|
|
|
### Evidence Rules
|
|
1. Fotografias deben incluir metadata de fecha y ubicacion
|
|
2. Documentos PDF deben ser legibles (no escaneados de baja calidad)
|
|
3. Evidencias reemplazadas mantienen historial
|
|
4. El tamaño maximo de archivo es 50MB
|
|
|
|
---
|
|
|
|
## Invariantes
|
|
|
|
1. `ProjectProgram.compliancePercentage = (compliantCount / (total - notApplicable)) * 100`
|
|
2. `ProjectProgram.totalRequirements = compliantCount + nonCompliantCount + pendingCount`
|
|
3. `Audit.findingsCount = criticalFindings + majorFindings + minorFindings`
|
|
4. `Finding.dueDate <= Finding.createdAt + severityDays`
|
|
5. `CorrectiveAction.dueDate <= Finding.dueDate`
|
|
|
|
---
|
|
|
|
## Integraciones
|
|
|
|
### Con Project Context
|
|
- Proyectos se registran en programas
|
|
- Avances de obra se usan como evidencia
|
|
- Viviendas se vinculan a requisitos
|
|
|
|
### Con Documents Context
|
|
- Evidencias se almacenan en DMS
|
|
- Reportes de auditoria como documentos
|
|
- Planos como evidencia tecnica
|
|
|
|
### Con INFONAVIT (Externo)
|
|
- Sincronizacion de programas vigentes
|
|
- Reporte de cumplimiento
|
|
- Notificacion de auditorias
|
|
|
|
---
|
|
|
|
## Referencias
|
|
|
|
- [DDL-SPEC-compliance.md](../database-design/schemas/DDL-SPEC-compliance.md)
|
|
- [EPIC-MAI-011](../../08-epicas/EPIC-MAI-011-infonavit.md)
|
|
|
|
---
|
|
|
|
*Ultima actualizacion: 2025-12-05*
|