# 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; 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; } ``` --- ## 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*