Quickstart — Validación de la 004 (guía de ejecución, sin código de implementación)
Prerrequisitos: repo en 004-panel-analitica, Node 22, Postgres 16, dependencias instaladas. Semilla v1 (SEMILLA_PRNG=1, npx prisma db seed): 409 en historia (335 completadas, 41 no_asistidas, 33 canceladas) + 82 futuras. Clave demo eleva-2026 (o CLAVE_PANEL_DEMO). Oráculos numéricos SOLO válidos con semilla v1 cargada en la semana natural del 28/09/2026 (Assumptions S-08); fuera de esa ventana los tests cuadran contra la historia realmente cargada (SC-003), no contra la tabla de US4.
QS-1 — Tasa de no asistencia por profesional (US1, FR-002, SC-003)
- Cargar semilla v1 en la semana del 28/09/2026; entrar con la clave en
/analitica. - Esperado: María 11/150 = «7,3 %», Jorge 16/127 = «12,6 %», Lucía 14/132 = «10,6 %», clínica 41/409 = «10,0 %»; gráfico de barras con etiquetas en español, sin jerga; a 390 px legible sin desplazamiento horizontal. Regenerar la semilla en la misma semana ⇒ mismos valores bit a bit.
QS-2 — Ocupación semanal, un número por profesional (US3, FR-003/FR-008)
- Misma ventana; leer ocupación junto a la jornada declarada.
- Esperado: María 6.615/26.400 = «25,1 %», Jorge 4.935/26.400 = «18,7 %», Lucía 4.125/26.400 = «15,6 %», con «09:00–20:00» visible.
cancelada/no_asistida= 0 min. Reconfigurar jornada (vía semilla) cambia el denominador víadenominadorOcupaciony se declara (nunca 26.400 literal en código).
QS-3 — Ingresos por servicio al céntimo (US2, FR-004/FR-007, SC-002)
- Leer ingresos: solo
completada × precioCongeladoCentimos. - Esperado: sesión fisio 126 × 40,00 € = «5.040,00 €»; primera visita fisio 98 × 50,00 € = «4.900,00 €»; consulta nutrición 58 × 35,00 € = «2.030,00 €»; primera nutrición 53 × 45,00 € = «2.385,00 €»; total «14.355,00 €». Formato es-ES con €.
cancelada/no_asistida= 0,00 €. Cambiar la tarifa de un servicio y recargar ⇒ los ingresos de la ventana NO se mueven (precio congelado).
QS-4 — Evolución 8 semanas (US4, FR-005/FR-008)
- Leer las 8 filas S-8 (antigua) … S-1 (reciente) con etiqueta
S-N: DD/MM/AAAA–DD/MM/AAAAderivada. - Esperado (ventana de referencia): S-8 48/41/2/5/1.750,00 €; S-7 46/35/7/4/1.490,00 €; S-6 56/51/4/1/2.145,00 €; S-5 49/41/4/4/1.815,00 €; S-4 53/41/8/4/1.745,00 €; S-3 59/43/9/7/1.845,00 €; S-2 49/42/4/3/1.820,00 €; S-1 49/41/3/5/1.745,00 €. Suma = 409 e 14.355,00 €. Las 82 futuras NO aparecen. Cada fila muestra su rango de días laborables.
QS-5 — Interfaz moderna comprobable (FR-009, SC-001/SC-007)
- Abrir
/analiticaa 1440 px y 390 px; cronómetro manual: distinguir las 4 métricas en < 10 s (SC-001, no aserción auto). - Verificación automática: 4/4 gráficos presentes con eje + valores;
font-size ≥ 16 pxa 390 px; contraste texto ≥ 4,5:1 y gráfico ≥ 3:1;grep -r "dataset\|serie\|KPI\|coeficiente\|métrica\|agregado" app/(panel)/analitica components/grafico-barras.tsx⇒ cero hits; 100 % es-ES (npm run comprobar:es).
QC-6 — Aislamiento entre clínicas (US5, FR-001, SC-006)
- Crear clínica B con profesional/servicio/citas propios; entrar con la clave de A en
/api/analiticay/analitica. - Esperado: 100 % cifras de A, 0 % de B: ningún nombre, contador, total ni importe de B aparece. Verificable con
npm run test -- test_analitica_aislamiento.
QC-7 — Solo lectura (US5, FR-006/FR-010, SC-004)
- Volcar BD antes, navegar + recargar
/analitica(cambiar de gráfico, recargar), volcar después y comparar. - Esperado: cero citas/profesionales/servicios/pacientes creados, modificados o eliminados.
POST/PATCH/DELETE /api/analitica⇒ 405. Clave incorrecta ⇒ aviso genérico es-ES sin revelar claves válidas.
Comandos (tras /speckit.tasks + implementación)
npx prisma migrate dev
npx prisma db seed
npm run test -- test_analitica test_analitica_aislamiento test_analitica_get
npm run typecheck && npm run lint && npm run format:check
npm run comprobar:es