Data Model — 006 Referencia temporal compartida

Fuente: spec.md FR-001…FR-011 + research D1…D7. Esta feature NO crea tablas ni endpoints (FR-011). El modelo describe (a) valores efímeros, (b) la enmienda S-06 a la entidad Clínica de la 001 y (c) fórmulas derivadas con nombre. Dinero fuera de alcance; tiempo en timestamptz, zona Europe/Madrid, idioma es-ES.

1. Instante «ahora» (efímero, sin persistencia)

Aspecto Regla
Captura capturarAhora() una vez por operación desde el reloj del servidor; truncarAMinuto(new Date()) (FR-001/FR-002, Q1/A)
Propagación parámetro explícito a todas las validaciones de la operación; la BD usa el valor propagado, nunca now() (FR-001)
Igualdad dos instantes del mismo minuto son el mismo minuto (FR-002)
Cambio DST las comparaciones son sobre instantes UTC; la hora ambigua se resuelve con el desplazamiento vigente en el «ahora» (edge spec)

Sin columna, sin tabla, sin endpoint. En tests se inyecta (ahora fijado, p. ej. 30/09/2026 10:00).

2. Jornada y calendario — enmienda S-06 a Clínica (001)

Propiedad de la 001; aquí solo migración + semilla (MAPA: aplicada en spec + data-model de la 001, falta semilla y código).

Campo Tipo Reglas
jornadaInicio / jornadaFin text HH:MM (existentes) configurable; defecto 09:00/20:00; validación ESQUEMA_HORA (FR-008)
diasLaborables Int[] NUEVO días ISO 1=lunes…7=domingo; defecto {1,2,3,4,5}; reconfigurable vía semilla en v1 (sin endpoint en 001); festivos fuera de v1 → abiertos salvo exclusión explícita (Q2/A)
nombre, telefono, claveHash, seedVersion existentes sin cambio

Prisma: diasLaborables Int[] @default([1, 2, 3, 4, 5]). Semilla Eleva: incluir el defecto.

3. Ventanas derivadas (definidas una sola vez aquí — FR-010)

Nombre Fórmula (precisión minuto, Europe/Madrid) Consumidores
RN2 pasado (FR-004) inicio < ahora (igual no es pasado) 001 FR-009
Antelación cancelación (FR-005) inicio − ahora ≥ 24 h (24 h 00 min dentro; 23 h 59 min fuera; sin tope) cancelarCita (005), portal, recordatorios
Ventana recordatorios (FR-006) 24 h ≤ inicio − ejecución ≤ 48 h (ambos incluidos) recordatorios FR-001 (el horario 00:00 configurable vive allí)
Analítica 8 semanas (FR-007) semana en curso = semana natural lunes–domingo con hoy en Madrid, recalculada en cada llamada; marco siempre lunes–domingo (diasLaborables no altera bordes); historia = 8 anteriores cerradas S-8…S-1; la en curso nunca entra analítica FR-005

Nueva ventana futura: se define aquí primero y luego se referencia (edge spec).

4. Denominador de ocupación (FR-008)

denominadorMin = minutosJornada × nºDíasLaborables × 8 con la configuración vigente, mostrado junto a cada porcentaje (etiquetarJornada). Prohibido hardcodear 26.400 en ningún caso (con defecto se calcula igual: 660 × 5 × 8). Reconfiguración a mitad de periodo: vigente + declaración, sin historia (edge spec). Ejemplo por defecto: 26.400 min/profesional, «09:00–20:00, Lun–Vie» (US3-AS1); con sábados: 660 × 6 × 8 = 31.680 (US3-AS2).

5. Etiquetado (FR-003, FR-009, Q4/A)

  • Tramo: DD/MM/AAAA, HH:MM–HH:MM 24 h (formatearTramo existente).
  • Semana: S-N: DD/MM/AAAA–DD/MM/AAAA derivada de la ventana calculada, nunca constante.
  • Jornada/días del denominador siempre visibles junto a ocupaciones.

6. Diagrama (texto)

operación ──capturarAhora()──► ahora ──┬──► esPasado (FR-004)
                                       ├──► cancelacionEnPlazo (FR-005)
                                       ├──► enVentanaRecordatorios (FR-006)
                                       └──► semanasAnalitica (FR-007) ──► denominadorOcupacion (FR-008, lee Clinica vigente)
Clinica(001) ──enmienda S-06──► + diasLaborables Int[] ──► determina semana natural y denominador
Consumidoras (001/002/003/004/005) ──solo referencian──► 006 FR-004…FR-009 (redefinir = defecto, FR-010)