erp-construccion/docs/04-modelado/domain-models/COMPLIANCE-CONTEXT.md

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

  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


Ultima actualizacion: 2025-12-05