caudallmvp

Modelo de datos — Caudall MVP

Este documento define las entidades, relaciones y reglas de integridad del sistema. Es la fuente de verdad para el schema de Prisma (prisma/schema.prisma) y para toda decisión de persistencia.

Principios de diseño

Cuatro principios que gobiernan todo el modelo:

  1. Multi-tenant desde la raíz. Toda entidad que contenga data de empresa o empleado lleva tenantId. No hay tabla global de empleados; hay empleados de un tenant.
  2. Barrera empresa-empleado infranqueable. Las entidades quedan clasificadas por visibilidad. La barrera se enforce con Row-Level Security en PostgreSQL, no solo con lógica de aplicación.
  3. Toda evidencia tiene provenance. Nada llega al scoring sin source, confidence y primaryOwner.
  4. Versionado por diseño. Metodología, banco de preguntas, scoring e intervenciones son entidades versionadas. Un empleado siempre está atado a la versión con la que respondió.

Bloque 1 — Multi-tenant y usuarios

Tenant — cada empresa cliente

Campos:

Segment — subdivisiones dentro de una empresa

Departamentos, sedes, roles. Permite jerarquía.

Campos: id, tenantId, name, type (department, location, role, custom), parentSegmentId, createdAt

Employee — el usuario final del beneficio

Visibilidad: la empresa nunca ve esta entidad individual; solo agregados que la deriven.

Campos:

EmployeeSegment — relación N:M empleado-segmento

Un empleado puede pertenecer a más de un segmento.

Campos: employeeId, segmentId, assignedAt

TenantAdmin — usuarios del portal de RRHH

Campos: id, tenantId, email, role (viewer, admin), createdAt, lastActiveAt

PlatformUser — usuarios del admin interno de Caudall

Roles (spec §53): platform_owner, methodologist, product_admin, analyst, viewer.

Campos: id, email, role, createdAt, lastActiveAt


Bloque 2 — Metodología y banco (versionado)

Methodology (versionada)

Campos: id, version, status (draft, active, deprecated), publishedAt, publishedById, createdAt

Dimension

Las 5 dimensiones del CFHI.

Campos:

Construct

Constructos dentro de dimensiones (spec §5).

Campos:

Variable

Variables maestras (spec §10-14, 17).

Campos:

QuestionBank (versionada)

Campos: id, version, status, createdAt

Question

Preguntas del banco adaptativo (spec §22, §43).

Campos:

AnswerOption

Opciones de respuesta con la evidencia que producen.

Campos: id, questionId, textI18nKey, evidenceProduced (JSON: qué Evidence genera)

ScoringConfig (versionada)

Configuración de pesos y reglas de N/A (spec §45).

Campos: id, version, status, dimensionWeights (JSON), constructWeights (JSON), naRedistributionRule (JSON)

ForbiddenInference

Inferencias explícitamente prohibidas (spec §9).

Campos: id, sourceVariableCode, sourceValue, targetVariableCode, targetValue, reason


Bloque 3 — Estado vivo del empleado

Evidence — cada dato que llega al sistema

El corazón de la spec. Nunca se borra; los cambios generan nueva Evidence, no sobreescriben.

Campos:

VariableState — valor computado actual de cada variable para un empleado

Campos:

ConstructScore

Campos: employeeId, constructId, score (0–100), confidence, computedAt

DimensionScore

Campos:

FinancialState — snapshot vivo por empleado (spec §15)

Campos:

SafetyFlag

Independiente del score (spec §19).

Campos: id, employeeId, flagCode (ej. CRITICAL_DEBT, DEBT_PAYMENT_STRESS), raisedAt, evidenceIds (array), resolvedAt (nullable)


Bloque 4 — Intervenciones y contenido

InterventionCatalog (maestro, versionado — ADR-004)

Campos: id, version, status, createdAt

Intervention

Parte del catálogo maestro.

Campos:

TenantInterventionOverride (ADR-004)

Campos: tenantId, interventionId, status (enabled, disabled)

En MVP solo activar/desactivar; contenido propio de tenant es fase posterior.

EmployeeIntervention — instancia asignada

Campos:


Bloque 5 — Auditoría, versionado y aprendizaje

Version — tabla genérica para versionables

Campos: id, entityType (methodology, question_bank, scoring, intervention_catalog), entityId, versionNumber, status (draft, in_review, active, rollback), createdById, publishedById, publishedAt

AuditLog — cambios estructurales (spec §52)

Campos: id, whoId, who (JSON con nombre y rol), what, when, previousValue (JSON), newValue (JSON), entityType, entityId

LearningEvent — señales para el motor de aprendizaje (Fase 8 spec)

Campos: id, eventType (question_shown, question_abandoned, intervention_completed, outcome_reported), employeeId (nullable para anonimizar), tenantId, context (JSON), timestamp


Bloque 6 — Reglas de integridad enforced por el sistema

Estas son las que la spec repite y que el modelo debe blindar:

  1. N/A no es 100. Cuando DEBT_APPLICABILITY = NONE, la dimensión Debt se excluye del denominador del CFHI y se redistribuyen pesos entre las aplicables. No se pone score = 100.
  2. Primary Owner no admite double counting. Una Evidence puede informar varias variables, pero solo penaliza el CFHI a través de su primary owner. El scoring engine debe verificarlo.
  3. Provenance obligatorio. Ninguna Evidence entra al sistema sin source, reliability, confidence. Constraint a nivel de aplicación y validación en zod.
  4. Versionado consistente. Un empleado tiene atada su respuesta a methodologyVersionId y questionBankVersionId específicos. Los cambios de versión no reescriben respuestas históricas.
  5. Inferencias prohibidas (spec §9). El motor consulta ForbiddenInference antes de propagar inferencias.
  6. Umbral de agregación aplicado en query. Toda query servida al TenantAdmin pasa por un helper que verifica que el segmento consultado tenga al menos tenant.aggregationMinSegmentSize empleados. Si no, devuelve INSUFFICIENT_ANONYMITY.

Bloque 7 — Row-Level Security (RLS) en PostgreSQL

La barrera empresa-empleado (ADR-001) no puede depender solo de la lógica de aplicación. Se enforce a nivel de base de datos:

Las políticas de RLS se definen en migraciones de Prisma con SQL raw cuando Prisma no las soporta nativamente.


Lo que este modelo NO incluye (deliberadamente diferido)

Estos son fases posteriores. No agregar tablas para ellos ahora.