# Especificación técnica — Mirada Empresa (Dashboard v3)
## Contrato para implementación · go-live

> Especificación de las 10 métricas de la Mirada Empresa, cada una con su query
> construible sobre el instrumento v3, regla de k-anonimato y shape de retorno.
> **Pendiente de validación del equipo** (especialmente la definición de CUIDADOR).
> Patrón: RPC `SECURITY DEFINER`, filtrable por `survey_id` y flag `p_all` (UUID cero),
> igual que las RPCs existentes. Reusa `_dash_responses` y `_dash_parse_filters`.

---

## Constante parametrizada — definición de CUIDADOR
**Decisión CERRADA (Maria, criterio UNFPA):** "Hijo menor sin discapacidad" SÍ cuenta como
cuidador activo. El cuidado de niñez es trabajo de cuidado, coherente con el enfoque de la
economía del cuidado y con un criterio explícitamente solicitado por UNFPA.

```
CUIDADOR_ACTIVO := respuesta a 4.1 contiene AL MENOS una opción
                   distinta de "Ninguna de las anteriores / No tengo vinculación de cuidado"
```

Es decir: las opciones 1..7 cuentan como cuidador; solo la opción 8 ("Ninguna...") excluye.
Todas las métricas que usan "cuidador" como población heredan esta definición desde este
único punto. Registrar en SEED_SPEC.md: "CUIDADOR incluye hijo menor sin discapacidad —
criterio UNFPA, validado por Maria (metodología), jun 2026."

**Nota de comparabilidad con v2:** esto ensancha la población "cuidador" respecto al dashboard
v2 (donde criar un niño sano no activaba los triggers de discapacidad/adulto mayor). Es un
cambio deliberado de definición, no un error de migración. Cualquier comparación con datos v2
debe tenerlo en cuenta.

---

## Núcleo mínimo viable (si el tiempo aprieta en implementación)
Marcadas **[NÚCLEO]** las imprescindibles para el cliente; **[SEC]** las secundarias.

---

## E1 — Prevalencia de cuidadores en la plantilla  [NÚCLEO]
**Responde:** ¿qué % de mis empleados tiene algún rol de cuidado?
**Pregunta v3:** 4.1
**Query (concepto):**
```sql
v_total := count(*) FROM _dash_responses(...)          -- denominador: toda la plantilla encuestada
v_cuid  := count(DISTINCT response_id) WHERE q.code='4.1'
           AND <CUIDADOR_ACTIVO>                         -- 4.1 contiene opción de cuidado
RETURN pct_cuidadores = round(v_cuid/v_total*100,1)
```
**k≥5:** si v_total < 5 → suppressed.
**Retorno:** `{status, n, pct_cuidadores}`

---

## E2 — Riesgo de rotación por cuidado  [NÚCLEO]
**Responde:** ¿qué % de cuidadores considera probable dejar/reducir su trabajo?
**Pregunta v3:** 7.6 (single_choice: Nada/Poco/Algo/Muy probable)
**Query:** denominador = cuidadores activos; numerador = 7.6 IN ('Algo probable','Muy probable').
**k≥5:** sobre cuidadores; si < 5 → suppressed.
**Retorno:** `{status, n_cuidadores, pct_riesgo, desglose:{algo, muy}}`

---

## E3 — Ausentismo atribuible al cuidado  [NÚCLEO]
**Responde:** ¿qué % faltó al trabajo por cuidado de forma recurrente?
**Pregunta v3:** 7.3 (Nunca / Pocas 1-3 / Varias 4-10 / Con frecuencia +10)
**Query:** numerador = 7.3 IN ('Varias veces (4–10 al año)','Con frecuencia (más de 10 al año)').
**Retorno:** `{status, n, pct_ausentismo_recurrente, desglose por categoría}`

---

## E4 — Presentismo (productividad reducida)  [NÚCLEO]
**Responde:** ¿a qué % se le afecta la concentración/rendimiento por cuidar?
**Pregunta v3:** 7.2 (Nunca / Algunas veces al mes / Varias veces por semana / Casi todos los días)
**Query:** numerador = 7.2 IN ('Varias veces por semana','Casi todos los días').
**Retorno:** `{status, n, pct_presentismo, desglose}`

---

## E5 — Carrera congelada  [SEC]
**Responde:** ¿qué % tuvo que frenar su carrera por cuidar?
**Pregunta v3:** 7.5 (multiple_choice: reducir jornada / rechazar ascenso / declinar / cambiar puesto / etc.)
**Query:** numerador = respondentes cuyo 7.5 contiene alguna opción distinta de "Ninguna de las anteriores".
**Retorno:** `{status, n, pct_carrera_congelada, top_opciones[]}`

---

## E6 — Punto ciego organizacional  [NÚCLEO]
**Responde:** brecha entre la carga real de cuidado y cuántos se sienten apoyados.
**Preguntas v3:** 4.1 (prevalencia, = E1) vs 9.1 (¿la empresa comprende?)
**Query:** carga_real = pct_cuidadores (E1); se_siente_apoyado = % con 9.1 = 'Sí, me siento acompañado/a'.
La métrica es la BRECHA entre ambos.
**Retorno:** `{status, n, carga_real_pct, apoyo_percibido_pct, brecha_pp}`
**Nota visual:** es el widget de contraste de dos barras del mockup.

---

## E7 — Demanda de apoyos priorizada  [NÚCLEO]
**Responde:** ¿qué apoyos pediría la gente? (para diseñar beneficios)
**Pregunta v3:** 9.2 (multiple_choice, máx 3)
**Query:** desagregar con jsonb_array_elements_text, contar por opción, ordenar desc.
**k≥5 por fila:** cada opción con cnt < 5 se omite (igual que rpc_apoyos_demandados v2).
**Retorno:** `{status, n, apoyos:[{apoyo, n, pct}] ordenado}`

---

## E8 — Intensidad de carga  [SEC]
**Responde:** ¿cuánta carga horaria soporta la plantilla cuidadora?
**Preguntas v3:** 6.1 (días/semana) × 6.2 (horas/día), + 6.4 (guardia)
**Query:** distribución de combinaciones; o un índice de intensidad (días×horas en rangos).
**Nota:** como son rangos (no números), se reporta distribución por bucket, no un promedio exacto.
**Retorno:** `{status, n, distribucion_intensidad[], pct_guardia_permanente}`

---

## E9 — Segmentación por nivel y modalidad  [SEC]
**Responde:** ¿dónde se concentra la carga? (jerarquía, presencial/remoto)
**Preguntas v3:** CUIDADOR cruzado con 2.6 (nivel) y 2.7 (modalidad)
**Query:** pct_cuidadores por cada valor de 2.6 y de 2.7.
**k≥5 por segmento:** cada nivel/modalidad con n < 5 → suppressed esa fila.
**Retorno:** `{status, por_nivel:[{nivel,n,pct}], por_modalidad:[{modalidad,n,pct}]}`

---

## E10 — Disposición a red de apoyo interna  [SEC]
**Responde:** ¿cuántos participarían de un grupo de apoyo / voluntariado?
**Preguntas v3:** 9.3 (grupo de apoyo) + 9.4 (voluntariado)
**Query:** % con 9.3 IN ('Sí, definitivamente','Tal vez...') ; % con 9.4 = 'Sí'.
**Retorno:** `{status, n, pct_grupo_apoyo, pct_voluntariado}`

---

## Métrica estrella compuesta — "Talento en riesgo"  [NÚCLEO]
**Responde:** el número que traduce cuidado a costo de negocio.
**Preguntas v3:** 7.6 + 7.3 + 7.5 (sobre población cuidadora)
**Definición propuesta (validar):** % de cuidadores que cumple AL MENOS 2 de 3 señales:
- riesgo de salida (7.6 IN Algo/Muy probable)
- ausentismo recurrente (7.3 IN 4-10 / +10)
- carrera congelada (7.5 contiene alguna opción de freno)
**Decisión pendiente:** ¿umbral de 2 de 3, o ponderado? Validar con el equipo.
**Retorno:** `{status, n_cuidadores, pct_talento_riesgo, criterios_promedio}`

---

## Reglas transversales (todas las RPCs)
1. **k-anonimato k≥5** en dos niveles: total (suppressed si n<5) y por-segmento (fila omitida/null si <5).
2. **Filtro survey_id + p_all:** delegado a `_dash_responses` (UUID cero = todos). No reimplementar.
3. **No exponer datos sensibles** (3.x salud propia, 4.2/4.3 disc. familiar) en Mirada Empresa.
   Mirada Empresa usa solo: 4.1 (existencia de vínculo, no el detalle médico), 6.x, 7.x, 9.x, 2.6, 2.7.
4. **Shape consistente:** `{status:'ok'|'suppressed', n, ...campos}`. Status suppressed nunca expone n<5 desglosado.
5. Reusar el patrón de migración 012 (las RPCs que SÍ migran limpio sirven de molde).

## Lo que Mirada Empresa NO necesita (queda para sprint de dashboard)
- Bienestar tipo rating (4.3 v2 no existe en v3) — no se usa acá.
- Score organizacional con 6.5 — no se usa acá.
- Métricas de instancia (4.2/4.3 detalle médico del familiar) — son de Mirada País/Humana.
- Las preguntas faltantes (horas no remuneradas, escolarización) — son de País/Humana.

## Gaps de datos para Mirada Empresa
Ninguno. Las 10 métricas + la estrella son 100% construibles con el instrumento v3 actual.