11 KiB
11 KiB
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)
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)
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)
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)
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)
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)
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)
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)
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
interface Percentage {
value: number; // 0-100
static fromDecimal(decimal: number): Percentage;
static toDecimal(percentage: Percentage): number;
static isAboveThreshold(p: Percentage, threshold: number): boolean;
}
Location
interface Location {
latitude: number;
longitude: number;
accuracy?: number;
timestamp?: Timestamp;
}
ComplianceSummary
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
interface ProjectRegisteredInProgram {
projectProgramId: UUID;
projectId: UUID;
programId: UUID;
registrationNumber?: string;
timestamp: Timestamp;
}
Compliance Events
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
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
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
- Un proyecto solo puede registrarse una vez por programa
- Los requisitos obligatorios no pueden marcarse como N/A sin justificacion
- El registro en programa requiere al menos datos basicos del proyecto
Compliance Rules
- El status solo puede avanzar: pending -> in_progress -> compliant
- Marcar como compliant requiere al menos una evidencia
- El porcentaje de cumplimiento excluye items N/A del calculo
- Cambios de status deben registrar historial
Audit Rules
- No se puede cerrar auditoria con hallazgos criticos abiertos
- Los hallazgos tienen plazos segun severidad (7/15/30 dias)
- Las acciones correctivas requieren verificacion antes de cerrar
- Una auditoria de seguimiento requiere auditoria previa completada
Evidence Rules
- Fotografias deben incluir metadata de fecha y ubicacion
- Documentos PDF deben ser legibles (no escaneados de baja calidad)
- Evidencias reemplazadas mantienen historial
- El tamaño maximo de archivo es 50MB
Invariantes
ProjectProgram.compliancePercentage = (compliantCount / (total - notApplicable)) * 100ProjectProgram.totalRequirements = compliantCount + nonCompliantCount + pendingCountAudit.findingsCount = criticalFindings + majorFindings + minorFindingsFinding.dueDate <= Finding.createdAt + severityDaysCorrectiveAction.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
Ultima actualizacion: 2025-12-05