Sprint 1 cerrado: seed real (34 preguntas) + REVOKE consent SELECT + validado en Cloud
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -2,6 +2,7 @@
|
||||
.env
|
||||
.env.*
|
||||
.env.local
|
||||
!.env.example
|
||||
|
||||
# Claude Code — settings locales (allow personales del usuario)
|
||||
.claude/settings.local.json
|
||||
@@ -12,4 +13,8 @@ supabase/.temp/
|
||||
|
||||
# Node
|
||||
node_modules/
|
||||
package-lock.json
|
||||
|
||||
# Supabase — claves y credenciales
|
||||
*.key
|
||||
service_role*
|
||||
.env.production
|
||||
@@ -150,3 +150,18 @@ granted_at timestamptz not null default now()
|
||||
- `agg_segment(survey_id, dimensions[])` → agregación que **suprime** automáticamente celdas con
|
||||
`count < k_threshold` (devuelve "n insuficiente" en lugar del valor).
|
||||
- Un trigger/constraint que rechaza `respondent_id` no nulo cuando `is_anonymous = true`.
|
||||
|
||||
---
|
||||
|
||||
## Decisiones ratificadas en ejecución (Sprint 1)
|
||||
- **`options` en preguntas `rating` (F3, G4):** se guarda como objeto
|
||||
`{"min":1,"max":5,"min_label":"...","max_label":"..."}`, NO como array. El frontend (Sprint 2)
|
||||
debe manejar dos formas de `options`: array para `single_choice`/`multiple_choice`, objeto para
|
||||
`rating`.
|
||||
- **`required = false` en todas las preguntas seeded:** la obligatoriedad real se define en Sprint 2
|
||||
(validación del formulario). Nota: B1 estaba marcada obligatoria en el mockup; revisar al construir
|
||||
el formulario.
|
||||
- **Policies de `org_admin` presentes pero inertes en v1:** las policies RLS para `org_admin`
|
||||
(acceso multi-tenant por empresa) existen en migración 003, pero v1 NO tiene login de cliente
|
||||
("nosotros presentamos a cada empresa"). El acceso real lo hace el analyst vía `service_role`. El
|
||||
camino `org_admin` queda reservado para un futuro de auto-servicio, no operado en v1.
|
||||
|
||||
147
package-lock.json
generated
Normal file
147
package-lock.json
generated
Normal file
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"name": "Motor de encuestas",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"supabase": "^2.102.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/cli-darwin-arm64": {
|
||||
"version": "2.102.0",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/cli-darwin-arm64/-/cli-darwin-arm64-2.102.0.tgz",
|
||||
"integrity": "sha512-DzQetP1iOnxAmbarZJLoFr3yMtyDrfOC/T2aNpYEASykFGnvCb87CbWMQhjp9zDdA0pFfDYgzM5yESg7cC/anw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@supabase/cli-darwin-x64": {
|
||||
"version": "2.102.0",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/cli-darwin-x64/-/cli-darwin-x64-2.102.0.tgz",
|
||||
"integrity": "sha512-jJxyULNvgBuWxDrjVySwIB76IUlWOf5lYd/2Zz/Lrop8r1sr7aKJFULz7l1A1vk09ImbvnbkM9IBtH8rNdmBUg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@supabase/cli-linux-arm64": {
|
||||
"version": "2.102.0",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/cli-linux-arm64/-/cli-linux-arm64-2.102.0.tgz",
|
||||
"integrity": "sha512-vOEdz4mWoqSpygXliGysYsDobtTlZLMhC2KpDsoYio9vQuQPRgaK2kW4fIGPKfagR4Odv3PycgjoNfdsg7TYUQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@supabase/cli-linux-arm64-musl": {
|
||||
"version": "2.102.0",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.102.0.tgz",
|
||||
"integrity": "sha512-VCEJiXK4JhDRXPR32UcIijKdsVT0zg81EoIt6ydmNDJ9vfPI+eFRIzJpeEST1XobTMAVzbJEBw/b/zq5BywR5w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@supabase/cli-linux-x64": {
|
||||
"version": "2.102.0",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/cli-linux-x64/-/cli-linux-x64-2.102.0.tgz",
|
||||
"integrity": "sha512-Jcekp6NOWlLuj8vs/ToR11bbqGWhlijs0rmMRyQvDRocWFgeDWX5IBWZwCXZX2xxr7pICJaSdRZx6V8uW2XVEQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@supabase/cli-linux-x64-musl": {
|
||||
"version": "2.102.0",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/cli-linux-x64-musl/-/cli-linux-x64-musl-2.102.0.tgz",
|
||||
"integrity": "sha512-KFzdivlbk8rnMHebxFa//AlQE3uxCWF6ZNIWkYUjE+1EBVXJr/j2Mr1SxkJJyt9h/8jztBUUPJgzuRzIJW0GyA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@supabase/cli-windows-arm64": {
|
||||
"version": "2.102.0",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/cli-windows-arm64/-/cli-windows-arm64-2.102.0.tgz",
|
||||
"integrity": "sha512-yY3qbHhMtQFI2TBXbU611UI7b0TaShxGwbunMUwmTUyaCLDTSsxOjxwbpCyfvgY7eDEeYI0WnkbBKHKxknKVDQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@supabase/cli-windows-x64": {
|
||||
"version": "2.102.0",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/cli-windows-x64/-/cli-windows-x64-2.102.0.tgz",
|
||||
"integrity": "sha512-PpIBXxGRi3bk0Zj2JeDCsr2edDt2qd5j31aaixuxHSsPJh0A052kDEDw4jSOWFHBL1UEai6rGF7zWuX/F3gNiw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/supabase": {
|
||||
"version": "2.102.0",
|
||||
"resolved": "https://registry.npmjs.org/supabase/-/supabase-2.102.0.tgz",
|
||||
"integrity": "sha512-PMoWgoQOb1/mZ3Y+e/HIIvWmEfui20cWELXYURrb6s66Swvo1jnkBmRvtCtSA8lan+aHtkgVQAyekocugle2eg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"supabase": "dist/supabase.js"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@supabase/cli-darwin-arm64": "2.102.0",
|
||||
"@supabase/cli-darwin-x64": "2.102.0",
|
||||
"@supabase/cli-linux-arm64": "2.102.0",
|
||||
"@supabase/cli-linux-arm64-musl": "2.102.0",
|
||||
"@supabase/cli-linux-x64": "2.102.0",
|
||||
"@supabase/cli-linux-x64-musl": "2.102.0",
|
||||
"@supabase/cli-windows-arm64": "2.102.0",
|
||||
"@supabase/cli-windows-x64": "2.102.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
sprints/sprint-1/ETAPA_1C_PROMPT.md
Normal file
82
sprints/sprint-1/ETAPA_1C_PROMPT.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# ETAPA 1C — Cierre de la fundación: REVOKE del GRANT peligroso + documentación
|
||||
|
||||
> Prompt versionado (Patrón B.1). Cierra la auditoría de la Etapa 1B con el único cambio bloqueante
|
||||
> que encontró y documenta tres decisiones que el agente tomó por iniciativa. Claude Code lo ejecuta
|
||||
> tras leer `CLAUDE.md`, `DATA_MODEL.md` y este prompt.
|
||||
|
||||
## 1. Objetivo
|
||||
Quitar el `GRANT SELECT ON consent_records TO authenticated` (puerta apoyada-sin-llave: hoy inerte,
|
||||
peligrosa si alguien suma una policy SELECT a futuro), **confirmar en ejecución que no rompe el flujo
|
||||
de envío de la encuesta** (la FK `responses.consent_record_id`), y documentar en `DATA_MODEL.md` tres
|
||||
decisiones tomadas en la 1B.
|
||||
|
||||
## 2. Contexto previo
|
||||
La 1B aplicó las migraciones 001-006 a Supabase Cloud y la auditoría aprobó la fundación de datos
|
||||
salvo este punto. La migración **006 ya está aplicada en Cloud** → **NO se edita** (rompería el
|
||||
historial de migraciones). El cambio va en una migración nueva, 007.
|
||||
|
||||
## 3. Decisiones ya tomadas (no consultar de nuevo)
|
||||
- El cambio es un `REVOKE`, en migración **nueva** 007. NO editar 001-006.
|
||||
- El `GRANT INSERT ON consent_records TO anon, authenticated` **se mantiene** (el envío del formulario
|
||||
lo necesita). Solo se revoca el SELECT.
|
||||
- NO se agrega ninguna policy SELECT a `consent_records`. El analyst lee vía `service_role` (que
|
||||
bypassa RLS y no necesita GRANTs).
|
||||
- No se toca el resto del esquema, ni las policies, ni `service_role`.
|
||||
|
||||
## 4. Tareas
|
||||
1. Crear la migración con `supabase migration new revoke_consent_select` y poner como contenido:
|
||||
```sql
|
||||
-- 007: Revoca el SELECT sobre consent_records a authenticated.
|
||||
-- Auditoría 1B: GRANT inerte hoy (no hay policy SELECT) pero peligroso si a futuro alguien
|
||||
-- agrega una policy SELECT para org_admin → expondría quién consintió qué, vector de
|
||||
-- correlación con respuestas en encuesta anónima. El analyst lee vía service_role.
|
||||
REVOKE SELECT ON public.consent_records FROM authenticated;
|
||||
```
|
||||
2. Aplicar a Cloud: `supabase db push` (usar `npx supabase ...` si el CLI no es global).
|
||||
3. Correr las validaciones de la sección 6 contra la base real.
|
||||
4. Documentar en `DATA_MODEL.md` las tres decisiones (texto exacto en la sección 5 de este prompt).
|
||||
|
||||
## 5. Texto EXACTO a agregar al final de `DATA_MODEL.md` (sección nueva)
|
||||
```markdown
|
||||
## Decisiones ratificadas en ejecución (Sprint 1)
|
||||
- **`options` en preguntas `rating` (F3, G4):** se guarda como objeto
|
||||
`{"min":1,"max":5,"min_label":"...","max_label":"..."}`, NO como array. El frontend (Sprint 2)
|
||||
debe manejar dos formas de `options`: array para `single_choice`/`multiple_choice`, objeto para
|
||||
`rating`.
|
||||
- **`required = false` en todas las preguntas seeded:** la obligatoriedad real se define en Sprint 2
|
||||
(validación del formulario). Nota: B1 estaba marcada obligatoria en el mockup; revisar al construir
|
||||
el formulario.
|
||||
- **Policies de `org_admin` presentes pero inertes en v1:** las policies RLS para `org_admin`
|
||||
(acceso multi-tenant por empresa) existen en migración 003, pero v1 NO tiene login de cliente
|
||||
("nosotros presentamos a cada empresa"). El acceso real lo hace el analyst vía `service_role`. El
|
||||
camino `org_admin` queda reservado para un futuro de auto-servicio, no operado en v1.
|
||||
```
|
||||
|
||||
## 6. Validaciones automatizadas mandatorias (contra la base Cloud)
|
||||
La central es la #1 — confirma que revocar el SELECT NO rompe el envío:
|
||||
- **FK intacta:** simulando rol `anon` (SET ROLE anon + claims, o vía anon key), `INSERT` en
|
||||
`consent_records` → obtener su id → `INSERT` en `responses` referenciando ese `consent_record_id`
|
||||
(con `survey_id` de una encuesta `status='live'` y `respondent_id` NULL) → **debe insertar sin
|
||||
error**. Esto prueba que la verificación de FK no requiere SELECT sobre `consent_records`.
|
||||
- **REVOKE efectivo:** como `authenticated`, `SELECT FROM consent_records` → ahora "permission
|
||||
denied" (ya no "0 filas"). Confirma que el revoke aplicó.
|
||||
- **Sin regresión:** re-correr las claves de la 1B → RLS sobre `responses`/`answers` = 0 filas para
|
||||
org_admin; `agg_segment` n=3 → suprimido, n=5 → valor; inmutabilidad de `consent_records` (UPDATE/
|
||||
DELETE → error) sigue vigente.
|
||||
- Si CUALQUIERA falla: **NO declarar lista la etapa.** Reportar y esperar. En especial, si la #1
|
||||
fallara (la FK SÍ necesitaba el SELECT), **detenerse y reportar** — sería el caso que invalida el
|
||||
cambio.
|
||||
|
||||
## 7. Qué reportar
|
||||
- **Verificado:** salida concreta de cada validación (el INSERT anónimo que efectivamente insertó, el
|
||||
"permission denied" del SELECT como authenticated, y las 3 de no-regresión).
|
||||
- **Asumido / Hallazgos / Decisiones por iniciativa** (clasificadas por nivel).
|
||||
- **`git diff --name-only HEAD`:** debe contener solo la migración 007 nueva + `DATA_MODEL.md`.
|
||||
|
||||
## 8. Qué NO hacer
|
||||
- NO editar las migraciones 001-006 (006 ya está en Cloud).
|
||||
- NO agregar policy SELECT a `consent_records`.
|
||||
- NO tocar `service_role`, ni las policies de org_admin, ni el resto del esquema.
|
||||
- NO usar `respondent_id` ni exponer texto libre.
|
||||
- Ante conflicto entre una restricción y "que aplique limpio": **detenerse y reportar**, no resolver
|
||||
unilateralmente.
|
||||
BIN
supabase/.DS_Store
vendored
Normal file
BIN
supabase/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
-- 007: Revoca el SELECT sobre consent_records a authenticated.
|
||||
-- Auditoría 1B: GRANT inerte hoy (no hay policy SELECT) pero peligroso si a futuro alguien
|
||||
-- agrega una policy SELECT para org_admin → expondría quién consintió qué, vector de
|
||||
-- correlación con respuestas en encuesta anónima. El analyst lee vía service_role.
|
||||
REVOKE SELECT ON public.consent_records FROM authenticated;
|
||||
@@ -1,32 +1,25 @@
|
||||
-- ============================================================
|
||||
-- Seed: Etapa 1 — Encuesta de Mapeo de Cuidadores
|
||||
-- seed.sql — Encuesta "Mapeo de Cuidadores" — 34 preguntas
|
||||
-- Fuente autoritativa: SEED_SPEC.md
|
||||
-- Reemplaza el seed inventado de Etapa 1 (9 preguntas, tipos incorrectos)
|
||||
-- Etapa 1B — 2026-06-02
|
||||
--
|
||||
-- Carga:
|
||||
-- 1. 1 organización de prueba
|
||||
-- 2. 1 consent_version v1 (scopes: operativo + macro_n1)
|
||||
-- 3. 1 encuesta "Mapeo de Cuidadores" (anónima, sensible, confidencial, Modo A)
|
||||
-- 4. 9 preguntas con códigos del mockup:
|
||||
-- B1 (yes_no), B2, B4, B5 — situación de cuidado (B5 is_sensitive=true)
|
||||
-- C1 (yes_no) — impacto laboral
|
||||
-- D1 (yes_no) — apoyo recibido
|
||||
-- G4 (single_choice) — frecuencia de estrés [condicional a C1=yes]
|
||||
-- H1 (multiple_choice, max_select=3) — apoyo preferido
|
||||
-- H3 (text_long) — comentarios libres
|
||||
-- 5. conditional_rules: B1 → show B2/B4/B5; C1 → show G4
|
||||
-- Convenciones (SEED_SPEC.md §Convenciones):
|
||||
-- - conditional_rules en la pregunta DEPENDIENTE (no en el trigger)
|
||||
-- - B1/C1/D1 son single_choice de 3 opciones; solo "Sí" dispara el bloque
|
||||
-- - Valor de opción "Sí" = literal "Sí" (coincide con conditional_rules)
|
||||
-- - is_sensitive=true en las preguntas marcadas en SEED_SPEC.md (11 total)
|
||||
-- - H3 (text_long) NO exponer en agg_segment (regla 4 CLAUDE.md)
|
||||
--
|
||||
-- UUIDs fijos para reproducibilidad y referencia desde tests.
|
||||
-- Nota: el mockup original no estaba disponible; los textos de pregunta
|
||||
-- son diseñados según el contexto "mapeo de cuidadores". Ver ETAPA_1_PROMPT.md.
|
||||
-- ============================================================
|
||||
|
||||
-- UUIDs de referencia:
|
||||
-- UUIDs fijos:
|
||||
-- org: 10000000-0000-0000-0000-000000000001
|
||||
-- consent_v1: 20000000-0000-0000-0000-000000000001
|
||||
-- cv-v1: 20000000-0000-0000-0000-000000000001
|
||||
-- survey: 30000000-0000-0000-0000-000000000001
|
||||
-- q_B1..q_H3: 4000...0001 al 4000...0009
|
||||
-- preguntas 40000000-0000-0000-0000-000000000001 .. 000000000034
|
||||
-- ============================================================
|
||||
|
||||
-- ============================================================
|
||||
-- 1. Organización de prueba
|
||||
-- 1. Organización demo
|
||||
-- ============================================================
|
||||
INSERT INTO public.organizations (id, name, sector, size_bucket)
|
||||
VALUES (
|
||||
@@ -34,13 +27,10 @@ VALUES (
|
||||
'Empresa Demo S.A.',
|
||||
'Servicios',
|
||||
'100-500'
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
) ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 2. Versión de consentimiento v1
|
||||
-- Scopes ofrecidos: operativo (dashboard empresa) + macro_n1 (estudio país anonimizado)
|
||||
-- NO incluye macro_n3 (atribuible) — decisión de v1 (ADR-001)
|
||||
-- ============================================================
|
||||
INSERT INTO public.consent_versions (id, version, body, scopes)
|
||||
VALUES (
|
||||
@@ -49,259 +39,659 @@ VALUES (
|
||||
'Esta encuesta es completamente anónima: no registramos tu nombre, número de documento '
|
||||
'ni ningún dato que permita identificarte personalmente. '
|
||||
'Tus respuestas se usarán con dos propósitos: '
|
||||
'(1) Ayudar a tu empresa a comprender la situación de cuidado de sus colaboradores y '
|
||||
'diseñar apoyos más adecuados (uso operativo, solo agregados). '
|
||||
'(2) Contribuir a un estudio de alcance nacional sobre la "economía del cuidado" en Paraguay, '
|
||||
'utilizando únicamente datos anonimizados e irreversiblemente desvinculados de cualquier empresa '
|
||||
'(Nivel 1 anonimizado). '
|
||||
'(1) Ayudar a tu empresa a comprender la situación de cuidado de sus colaboradores y diseñar '
|
||||
'apoyos más adecuados (uso operativo, solo agregados). '
|
||||
'(2) Contribuir a un estudio de alcance nacional sobre la economía del cuidado en Paraguay, '
|
||||
'utilizando únicamente datos anonimizados e irreversiblemente desvinculados de cualquier empresa. '
|
||||
'Una vez enviada tu respuesta, al ser anónima, no es posible retirarla ni modificarla. '
|
||||
'Podés elegir qué propósitos autorizás marcando las casillas a continuación.',
|
||||
'["operativo", "macro_n1"]'::jsonb
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
'["operativo","macro_n1"]'::jsonb
|
||||
) ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 3. Encuesta: Mapeo de Cuidadores
|
||||
-- Anónima + Sensible (contiene datos de salud/discapacidad) + Confidencial
|
||||
-- Modo A: nosotros como responsables del tratamiento
|
||||
-- k_threshold=5: ninguna celda expuesta con n<5
|
||||
-- 3. Encuesta — anónima / sensible / confidencial / Modo A / k=5
|
||||
-- ============================================================
|
||||
INSERT INTO public.surveys (
|
||||
id, org_id, title, status,
|
||||
is_anonymous, data_sensitivity, security_class, controller_role,
|
||||
id, org_id, title, status, is_anonymous,
|
||||
data_sensitivity, security_class, controller_role,
|
||||
consent_version_id, k_threshold
|
||||
)
|
||||
VALUES (
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'10000000-0000-0000-0000-000000000001',
|
||||
'Mapeo de Cuidadores — Edición 2026',
|
||||
'Mapeo de Cuidadores — 2026',
|
||||
'draft',
|
||||
true, -- anónima (regla no negociable #2: respondent_id siempre NULL)
|
||||
'sensible', -- contiene preguntas de salud/discapacidad (B5)
|
||||
'confidencial', -- acceso restringido a la empresa y analistas internos
|
||||
'A', -- Modo A: InQ es responsable del tratamiento (v1 solo Modo A)
|
||||
true,
|
||||
'sensible',
|
||||
'confidencial',
|
||||
'A',
|
||||
'20000000-0000-0000-0000-000000000001',
|
||||
5 -- umbral k-anonimato por defecto
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
5
|
||||
) ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 4. Preguntas de la encuesta
|
||||
-- Orden: position define el flujo de presentación
|
||||
-- conditional_rules en el formato: [{ if_question, op, value, action, target }]
|
||||
-- if_question = code de la pregunta trigger
|
||||
-- target = code de la pregunta afectada
|
||||
-- 4. Preguntas (34) — DELETE+INSERT para idempotencia total
|
||||
--
|
||||
-- Estructura condicional (SEED_SPEC §Estructura):
|
||||
-- cond-B: B2-B5 visibles si B1 = 'Sí'
|
||||
-- cond-C: C2-C5 visibles si C1 = 'Sí'
|
||||
-- cond-D: D2-D5 visibles si D1 = 'Sí'
|
||||
-- Resto: siempre visible (top-level)
|
||||
-- ============================================================
|
||||
DELETE FROM public.questions
|
||||
WHERE survey_id = '30000000-0000-0000-0000-000000000001';
|
||||
|
||||
-- B1: Pregunta disparadora — ¿Tenés persona a cargo?
|
||||
-- Si es "yes" → se despliegan B2, B4, B5
|
||||
INSERT INTO public.questions (
|
||||
id, survey_id, code, type, prompt, position,
|
||||
is_sensitive, required, conditional_rules
|
||||
)
|
||||
|
||||
-- ══════════════════════════════════════════════════
|
||||
-- SECCIÓN A — Datos Generales (cuasi-identificadores)
|
||||
-- qi_sector ← A1 · qi_age_bucket ← A2 · qi_zone = NULL
|
||||
-- ══════════════════════════════════════════════════
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000001',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'B1',
|
||||
'yes_no',
|
||||
'¿Tenés a cargo a una o más personas con discapacidad permanente o adultos mayores '
|
||||
'(60 años o más) que requieran cuidados especiales de forma regular?',
|
||||
1,
|
||||
false,
|
||||
true,
|
||||
'A1', 'single_choice',
|
||||
'¿En qué área o gerencia trabajás?',
|
||||
1, false, false,
|
||||
'[
|
||||
{"if_question": "B1", "op": "eq", "value": "yes", "action": "show", "target": "B2"},
|
||||
{"if_question": "B1", "op": "eq", "value": "yes", "action": "show", "target": "B4"},
|
||||
{"if_question": "B1", "op": "eq", "value": "yes", "action": "show", "target": "B5"}
|
||||
{"value":"Operaciones/Producción","label":"Operaciones/Producción"},
|
||||
{"value":"Comercial/Ventas","label":"Comercial/Ventas"},
|
||||
{"value":"Administración/Finanzas","label":"Administración/Finanzas"},
|
||||
{"value":"RRHH/Cultura","label":"RRHH/Cultura"},
|
||||
{"value":"Tecnología/Sistemas","label":"Tecnología/Sistemas"},
|
||||
{"value":"Logística/Distribución","label":"Logística/Distribución"},
|
||||
{"value":"Otra área","label":"Otra área"}
|
||||
]'::jsonb
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
);
|
||||
|
||||
-- B2: ¿Cuántas personas a cargo? (condicional a B1=yes)
|
||||
INSERT INTO public.questions (
|
||||
id, survey_id, code, type, prompt, position,
|
||||
is_sensitive, required, options
|
||||
)
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000002',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'B2',
|
||||
'single_choice',
|
||||
'¿Cuántas personas a tu cargo requieren cuidado especial?',
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
'A2', 'single_choice',
|
||||
'¿Cuántos años tenés?',
|
||||
2, false, false,
|
||||
'[
|
||||
{"value": "1", "label": "1 persona"},
|
||||
{"value": "2", "label": "2 personas"},
|
||||
{"value": "3+", "label": "3 o más personas"}
|
||||
{"value":"Menos de 25","label":"Menos de 25"},
|
||||
{"value":"25-34","label":"25-34"},
|
||||
{"value":"35-44","label":"35-44"},
|
||||
{"value":"45-54","label":"45-54"},
|
||||
{"value":"55+","label":"55+"},
|
||||
{"value":"Prefiero no decir","label":"Prefiero no decir"}
|
||||
]'::jsonb
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
);
|
||||
|
||||
-- B4: Relación con la persona a cargo (condicional a B1=yes)
|
||||
INSERT INTO public.questions (
|
||||
id, survey_id, code, type, prompt, position,
|
||||
is_sensitive, required, options
|
||||
)
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000003',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'B4',
|
||||
'single_choice',
|
||||
'¿Cuál es tu relación con la principal persona que cuidás?',
|
||||
3,
|
||||
false,
|
||||
false,
|
||||
'A3', 'single_choice',
|
||||
'¿Con qué género te identificás?',
|
||||
3, false, false,
|
||||
'[
|
||||
{"value": "hijo_a", "label": "Hijo/a"},
|
||||
{"value": "padre_madre", "label": "Padre, madre o suegro/a"},
|
||||
{"value": "conyuge", "label": "Cónyuge o pareja"},
|
||||
{"value": "hermano_a", "label": "Hermano/a"},
|
||||
{"value": "otro_familiar", "label": "Otro familiar"},
|
||||
{"value": "otra", "label": "Otra relación"}
|
||||
{"value":"Femenino","label":"Femenino"},
|
||||
{"value":"Masculino","label":"Masculino"},
|
||||
{"value":"No binario/Otro","label":"No binario/Otro"},
|
||||
{"value":"Prefiero no decir","label":"Prefiero no decir"}
|
||||
]'::jsonb
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
);
|
||||
|
||||
-- B5: Tipo de discapacidad/condición (condicional a B1=yes)
|
||||
-- is_sensitive=true: contiene datos de salud (categoría especial Ley 7593/2025)
|
||||
INSERT INTO public.questions (
|
||||
id, survey_id, code, type, prompt, position,
|
||||
is_sensitive, required, options
|
||||
)
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000004',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'B5',
|
||||
'multiple_choice',
|
||||
'¿Qué tipo de discapacidad o condición tiene la persona que cuidás? '
|
||||
'(Podés marcar más de una opción)',
|
||||
4,
|
||||
true, -- SENSIBLE: dato de salud/discapacidad (Ley 7593, categoría especial)
|
||||
false,
|
||||
'A4', 'single_choice',
|
||||
'¿Cuál es tu modalidad de trabajo actual?',
|
||||
4, false, false,
|
||||
'[
|
||||
{"value": "fisica", "label": "Física o motriz"},
|
||||
{"value": "visual", "label": "Visual"},
|
||||
{"value": "auditiva", "label": "Auditiva"},
|
||||
{"value": "mental", "label": "Mental o psicosocial"},
|
||||
{"value": "intelectual", "label": "Intelectual o cognitiva"},
|
||||
{"value": "am_sin_cert", "label": "Adulto mayor sin discapacidad certificada"},
|
||||
{"value": "otra", "label": "Otra condición"}
|
||||
{"value":"Presencial","label":"Presencial"},
|
||||
{"value":"Remoto","label":"Remoto"},
|
||||
{"value":"Híbrido","label":"Híbrido"}
|
||||
]'::jsonb
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
);
|
||||
|
||||
-- C1: Impacto laboral
|
||||
-- Si es "yes" → se despliega G4
|
||||
INSERT INTO public.questions (
|
||||
id, survey_id, code, type, prompt, position,
|
||||
is_sensitive, required, conditional_rules
|
||||
)
|
||||
|
||||
-- ══════════════════════════════════════════════════
|
||||
-- SECCIÓN B — ¿Vivís con discapacidad? (is_sensitive=true: B1-B5)
|
||||
-- cond-B: B2-B5 se muestran si B1 = 'Sí'
|
||||
-- ══════════════════════════════════════════════════
|
||||
|
||||
-- B1: trigger — single_choice, is_sensitive=true, sin conditional_rules
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000005',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'C1',
|
||||
'yes_no',
|
||||
'¿Sentís que tu rol de cuidador/a afecta tu asistencia, puntualidad o rendimiento '
|
||||
'en el trabajo?',
|
||||
5,
|
||||
false,
|
||||
true,
|
||||
'B1', 'single_choice',
|
||||
'¿Vos mismo/a tenés alguna discapacidad o condición de salud permanente o de largo plazo?',
|
||||
5, true, false,
|
||||
'[
|
||||
{"if_question": "C1", "op": "eq", "value": "yes", "action": "show", "target": "G4"}
|
||||
{"value":"Sí","label":"Sí"},
|
||||
{"value":"No","label":"No"},
|
||||
{"value":"Prefiero no decir","label":"Prefiero no decir"}
|
||||
]'::jsonb
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
);
|
||||
|
||||
-- D1: Apoyo recibido de la empresa
|
||||
-- Declarada como trigger de sub-preguntas; sub-preguntas se agregan en iteración posterior
|
||||
INSERT INTO public.questions (
|
||||
id, survey_id, code, type, prompt, position,
|
||||
is_sensitive, required, conditional_rules
|
||||
)
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000006',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'D1',
|
||||
'yes_no',
|
||||
'¿Tu empresa te ofrece actualmente algún apoyo o beneficio pensado para personas que '
|
||||
'cuidan a familiares con discapacidad o adultos mayores?',
|
||||
6,
|
||||
false,
|
||||
true,
|
||||
'[]'::jsonb -- sub-preguntas a agregar en iteración posterior (mockup pendiente)
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
'B2', 'multiple_choice',
|
||||
'¿Qué tipo de discapacidad tenés? (podés marcar más de una)',
|
||||
6, true, false,
|
||||
'[
|
||||
{"value":"Física/motriz","label":"Física/motriz"},
|
||||
{"value":"Visual","label":"Visual"},
|
||||
{"value":"Auditiva","label":"Auditiva"},
|
||||
{"value":"Intelectual","label":"Intelectual"},
|
||||
{"value":"TEA","label":"TEA"},
|
||||
{"value":"Psicosocial","label":"Psicosocial"},
|
||||
{"value":"Condición crónica","label":"Condición crónica"},
|
||||
{"value":"Otra","label":"Otra"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"B1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
-- G4: Frecuencia de estrés (condicional a C1=yes)
|
||||
INSERT INTO public.questions (
|
||||
id, survey_id, code, type, prompt, position,
|
||||
is_sensitive, required, options
|
||||
)
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000007',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'G4',
|
||||
'single_choice',
|
||||
'¿Con qué frecuencia la situación de cuidado te genera preocupación o estrés '
|
||||
'durante tu jornada laboral?',
|
||||
7,
|
||||
false,
|
||||
false,
|
||||
'B3', 'single_choice',
|
||||
'¿Contás con certificado oficial de discapacidad?',
|
||||
7, true, false,
|
||||
'[
|
||||
{"value": "nunca", "label": "Nunca"},
|
||||
{"value": "raramente", "label": "Raramente (1-2 veces por mes)"},
|
||||
{"value": "a_veces", "label": "A veces (1-2 veces por semana)"},
|
||||
{"value": "frecuentemente","label": "Frecuentemente (casi todos los días)"},
|
||||
{"value": "siempre", "label": "Siempre (todos los días)"}
|
||||
]'::jsonb
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
{"value":"Sí","label":"Sí"},
|
||||
{"value":"En trámite","label":"En trámite"},
|
||||
{"value":"No","label":"No"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"B1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
-- H1: Apoyo preferido (max_select=3)
|
||||
INSERT INTO public.questions (
|
||||
id, survey_id, code, type, prompt, position,
|
||||
is_sensitive, required, max_select, options
|
||||
)
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000008',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'H1',
|
||||
'multiple_choice',
|
||||
'¿Qué tipos de apoyo de parte de la empresa valorarías más? '
|
||||
'Elegí hasta 3 opciones.',
|
||||
8,
|
||||
false,
|
||||
false,
|
||||
3, -- max_select=3 (mockup H1)
|
||||
'B4', 'single_choice',
|
||||
'¿Tu discapacidad afecta tu desempeño o comodidad en el trabajo?',
|
||||
8, true, false,
|
||||
'[
|
||||
{"value": "horario_flex", "label": "Horarios flexibles o trabajo híbrido"},
|
||||
{"value": "teletrabajo", "label": "Teletrabajo permanente"},
|
||||
{"value": "licencias", "label": "Licencias especiales para situaciones de cuidado"},
|
||||
{"value": "apoyo_eco", "label": "Apoyo económico o subsidio"},
|
||||
{"value": "orientacion", "label": "Orientación o asesoramiento profesional"},
|
||||
{"value": "grupos_apoyo", "label": "Grupos de apoyo entre pares"},
|
||||
{"value": "recursos_ext", "label": "Conexión con servicios o recursos externos"},
|
||||
{"value": "otro", "label": "Otro (especificar en comentarios)"}
|
||||
]'::jsonb
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
{"value":"Sí, significativamente","label":"Sí, significativamente"},
|
||||
{"value":"Sí, aspectos puntuales","label":"Sí, aspectos puntuales"},
|
||||
{"value":"No, bien gestionada","label":"No, bien gestionada"},
|
||||
{"value":"Prefiero no decir","label":"Prefiero no decir"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"B1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
-- H3: Texto libre — NO expuesto en el store analítico crudo (regla #4 CLAUDE.md)
|
||||
INSERT INTO public.questions (
|
||||
id, survey_id, code, type, prompt, position,
|
||||
is_sensitive, required
|
||||
)
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000009',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'H3',
|
||||
'text_long',
|
||||
'Si querés compartir algo más sobre tu situación o tenés sugerencias para la empresa, '
|
||||
'podés hacerlo acá. (Opcional — tu respuesta es anónima)',
|
||||
9,
|
||||
false,
|
||||
false
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
'B5', 'single_choice',
|
||||
'¿La empresa conoce tu situación?',
|
||||
9, true, false,
|
||||
'[
|
||||
{"value":"Sí, con apoyo","label":"Sí, con apoyo"},
|
||||
{"value":"Sí, sin apoyo","label":"Sí, sin apoyo"},
|
||||
{"value":"No, privado","label":"No, privado"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"B1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
|
||||
-- ══════════════════════════════════════════════════
|
||||
-- SECCIÓN C — Familiares con Discapacidad
|
||||
-- is_sensitive=true: C1-C4 | C5: NOT sensitive
|
||||
-- cond-C: C2-C5 se muestran si C1 = 'Sí'
|
||||
-- ══════════════════════════════════════════════════
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000010',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'C1', 'single_choice',
|
||||
'¿Tenés algún familiar cercano que viva con discapacidad?',
|
||||
10, true, false,
|
||||
'[
|
||||
{"value":"Sí","label":"Sí"},
|
||||
{"value":"No","label":"No"},
|
||||
{"value":"Prefiero no decir","label":"Prefiero no decir"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000011',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'C2', 'multiple_choice',
|
||||
'¿Cuál es el vínculo? (podés marcar más de una)',
|
||||
11, true, false,
|
||||
'[
|
||||
{"value":"Hijo/a","label":"Hijo/a"},
|
||||
{"value":"Cónyuge/pareja","label":"Cónyuge/pareja"},
|
||||
{"value":"Padre/madre","label":"Padre/madre"},
|
||||
{"value":"Hermano/a","label":"Hermano/a"},
|
||||
{"value":"Otro familiar","label":"Otro familiar"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"C1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000012',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'C3', 'multiple_choice',
|
||||
'¿Qué tipo de discapacidad tiene? (podés marcar más de una)',
|
||||
12, true, false,
|
||||
'[
|
||||
{"value":"Física/motriz","label":"Física/motriz"},
|
||||
{"value":"Visual","label":"Visual"},
|
||||
{"value":"Auditiva","label":"Auditiva"},
|
||||
{"value":"Intelectual","label":"Intelectual"},
|
||||
{"value":"TEA","label":"TEA"},
|
||||
{"value":"Psicosocial","label":"Psicosocial"},
|
||||
{"value":"Condición crónica","label":"Condición crónica"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"C1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000013',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'C4', 'single_choice',
|
||||
'¿Esta persona requiere apoyo o cuidado cotidiano?',
|
||||
13, true, false,
|
||||
'[
|
||||
{"value":"Alta dependencia","label":"Alta dependencia"},
|
||||
{"value":"Apoyo parcial","label":"Apoyo parcial"},
|
||||
{"value":"Autónomo/a","label":"Autónomo/a"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"C1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000014',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'C5', 'single_choice',
|
||||
'¿Quién es el responsable principal del cuidado?',
|
||||
14, false, false,
|
||||
'[
|
||||
{"value":"Yo principal","label":"Yo principal"},
|
||||
{"value":"Compartido","label":"Compartido"},
|
||||
{"value":"Cuidador pagado","label":"Cuidador pagado"},
|
||||
{"value":"Institución","label":"Institución"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"C1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
|
||||
-- ══════════════════════════════════════════════════
|
||||
-- SECCIÓN D — Adultos Mayores a Cargo
|
||||
-- is_sensitive=true: D3, D4 | D1, D2, D5: NOT sensitive
|
||||
-- cond-D: D2-D5 se muestran si D1 = 'Sí'
|
||||
-- ══════════════════════════════════════════════════
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000015',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'D1', 'single_choice',
|
||||
'¿Tenés algún adulto mayor (60+) a tu cuidado?',
|
||||
15, false, false,
|
||||
'[
|
||||
{"value":"Sí","label":"Sí"},
|
||||
{"value":"No","label":"No"},
|
||||
{"value":"Prefiero no decir","label":"Prefiero no decir"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000016',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'D2', 'single_choice',
|
||||
'¿Cuántos adultos mayores están bajo tu cuidado?',
|
||||
16, false, false,
|
||||
'[
|
||||
{"value":"1","label":"1"},
|
||||
{"value":"2","label":"2"},
|
||||
{"value":"3+","label":"3+"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"D1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000017',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'D3', 'single_choice',
|
||||
'¿Qué nivel de dependencia tiene/n?',
|
||||
17, true, false,
|
||||
'[
|
||||
{"value":"Supervisión","label":"Supervisión"},
|
||||
{"value":"Dependencia leve","label":"Dependencia leve"},
|
||||
{"value":"Dependencia moderada","label":"Dependencia moderada"},
|
||||
{"value":"Dependencia severa","label":"Dependencia severa"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"D1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000018',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'D4', 'multiple_choice',
|
||||
'¿Tiene condición diagnosticada? (podés marcar más de una)',
|
||||
18, true, false,
|
||||
'[
|
||||
{"value":"Demencia/Alzheimer","label":"Demencia/Alzheimer"},
|
||||
{"value":"ACV/Parálisis","label":"ACV/Parálisis"},
|
||||
{"value":"Enf. crónica","label":"Enf. crónica"},
|
||||
{"value":"Movilidad reducida","label":"Movilidad reducida"},
|
||||
{"value":"Deterioro cognitivo","label":"Deterioro cognitivo"},
|
||||
{"value":"Ninguna específica","label":"Ninguna específica"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"D1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options, conditional_rules)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000019',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'D5', 'single_choice',
|
||||
'¿La persona vive con vos o en otra vivienda?',
|
||||
19, false, false,
|
||||
'[
|
||||
{"value":"Vive conmigo","label":"Vive conmigo"},
|
||||
{"value":"Otra vivienda","label":"Otra vivienda"},
|
||||
{"value":"Institución","label":"Institución"}
|
||||
]'::jsonb,
|
||||
'[{"if_question":"D1","op":"eq","value":"Sí","action":"show"}]'::jsonb
|
||||
);
|
||||
|
||||
|
||||
-- ══════════════════════════════════════════════════
|
||||
-- SECCIÓN E — Tu Rol como Cuidador/a (top-level)
|
||||
-- ══════════════════════════════════════════════════
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000020',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'E1', 'single_choice',
|
||||
'¿Cuántas horas por día dedicás, en promedio, al cuidado directo?',
|
||||
20, false, false,
|
||||
'[
|
||||
{"value":"Menos de 1h","label":"Menos de 1h"},
|
||||
{"value":"1-3h","label":"1-3h"},
|
||||
{"value":"3-6h","label":"3-6h"},
|
||||
{"value":"Más de 6h","label":"Más de 6h"},
|
||||
{"value":"Variable","label":"Variable"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000021',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'E2', 'multiple_choice',
|
||||
'¿En qué momentos realizás principalmente el cuidado? (podés marcar más de una)',
|
||||
21, false, false,
|
||||
'[
|
||||
{"value":"Antes del trabajo","label":"Antes del trabajo"},
|
||||
{"value":"Durante horario laboral","label":"Durante horario laboral"},
|
||||
{"value":"Al llegar","label":"Al llegar"},
|
||||
{"value":"Durante la noche","label":"Durante la noche"},
|
||||
{"value":"Fines de semana","label":"Fines de semana"},
|
||||
{"value":"Continuo","label":"Continuo"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000022',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'E3', 'single_choice',
|
||||
'¿Contás con apoyo de otras personas para el cuidado?',
|
||||
22, false, false,
|
||||
'[
|
||||
{"value":"Apoyo familiar suficiente","label":"Apoyo familiar suficiente"},
|
||||
{"value":"Apoyo insuficiente","label":"Apoyo insuficiente"},
|
||||
{"value":"Único responsable","label":"Único responsable"},
|
||||
{"value":"Apoyo contratado","label":"Apoyo contratado"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000023',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'E4', 'single_choice',
|
||||
'¿Tuviste que faltar al trabajo por el cuidado en el último año?',
|
||||
23, false, false,
|
||||
'[
|
||||
{"value":"Nunca","label":"Nunca"},
|
||||
{"value":"Pocas veces (1-3)","label":"Pocas veces (1-3)"},
|
||||
{"value":"Varias veces (4-10)","label":"Varias veces (4-10)"},
|
||||
{"value":"Con frecuencia (10+)","label":"Con frecuencia (10+)"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
|
||||
-- ══════════════════════════════════════════════════
|
||||
-- SECCIÓN F — Impacto Económico (top-level)
|
||||
-- ══════════════════════════════════════════════════
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000024',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'F1', 'single_choice',
|
||||
'¿Cuánto estimás que gastás mensualmente en el cuidado?',
|
||||
24, false, false,
|
||||
'[
|
||||
{"value":"Sin gastos significativos","label":"Sin gastos significativos"},
|
||||
{"value":"Menos de 500k","label":"Menos de 500k"},
|
||||
{"value":"500k-1.5M","label":"500k-1.5M"},
|
||||
{"value":"1.5M-3M","label":"1.5M-3M"},
|
||||
{"value":"3M-6M","label":"3M-6M"},
|
||||
{"value":"Más de 6M","label":"Más de 6M"},
|
||||
{"value":"Prefiero no decir","label":"Prefiero no decir"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000025',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'F2', 'multiple_choice',
|
||||
'¿Qué servicios o apoyos utilizás actualmente? (podés marcar más de una)',
|
||||
25, false, false,
|
||||
'[
|
||||
{"value":"Terapias especializadas","label":"Terapias especializadas"},
|
||||
{"value":"Cuidador particular","label":"Cuidador particular"},
|
||||
{"value":"Centro de día","label":"Centro de día"},
|
||||
{"value":"Transporte adaptado","label":"Transporte adaptado"},
|
||||
{"value":"Medicación alto costo","label":"Medicación alto costo"},
|
||||
{"value":"Tecnología asistiva","label":"Tecnología asistiva"},
|
||||
{"value":"Apoyo ONG","label":"Apoyo ONG"},
|
||||
{"value":"Sin servicios formales","label":"Sin servicios formales"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
-- F3: rating — escala 1-5 (Sin impacto → Muy alto impacto)
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000026',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'F3', 'rating',
|
||||
'¿Los gastos de cuidado impactan en tu situación económica personal?',
|
||||
26, false, false,
|
||||
'{"min":1,"max":5,"min_label":"Sin impacto","max_label":"Muy alto impacto"}'::jsonb
|
||||
);
|
||||
|
||||
|
||||
-- ══════════════════════════════════════════════════
|
||||
-- SECCIÓN G — Bienestar y Descanso (top-level)
|
||||
-- ══════════════════════════════════════════════════
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000027',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'G1', 'single_choice',
|
||||
'¿Cómo describirías tu nivel de descanso habitual?',
|
||||
27, false, false,
|
||||
'[
|
||||
{"value":"Descanso bien","label":"Descanso bien"},
|
||||
{"value":"Descanso irregular","label":"Descanso irregular"},
|
||||
{"value":"Me cuesta descansar","label":"Me cuesta descansar"},
|
||||
{"value":"Muy poco descanso","label":"Muy poco descanso"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000028',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'G2', 'single_choice',
|
||||
'En los últimos 3 meses, ¿con qué frecuencia el cuidado afectó tu concentración o rendimiento laboral?',
|
||||
28, false, false,
|
||||
'[
|
||||
{"value":"Nunca/casi nunca","label":"Nunca/casi nunca"},
|
||||
{"value":"Algunas veces al mes","label":"Algunas veces al mes"},
|
||||
{"value":"Varias veces por semana","label":"Varias veces por semana"},
|
||||
{"value":"Casi todos los días","label":"Casi todos los días"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000029',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'G3', 'multiple_choice',
|
||||
'¿Qué aspectos de tu vida se ven más afectados? (podés marcar más de una)',
|
||||
29, false, false,
|
||||
'[
|
||||
{"value":"Tiempo libre","label":"Tiempo libre"},
|
||||
{"value":"Sueño y descanso","label":"Sueño y descanso"},
|
||||
{"value":"Vida social","label":"Vida social"},
|
||||
{"value":"Vida en pareja/familia","label":"Vida en pareja/familia"},
|
||||
{"value":"Salud física","label":"Salud física"},
|
||||
{"value":"Salud emocional","label":"Salud emocional"},
|
||||
{"value":"Desarrollo profesional","label":"Desarrollo profesional"},
|
||||
{"value":"Situación económica","label":"Situación económica"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
-- G4: rating — escala 1-5 (Muy mal → Muy bien)
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000030',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'G4', 'rating',
|
||||
'¿Cómo evaluás tu bienestar general en este momento?',
|
||||
30, false, false,
|
||||
'{"min":1,"max":5,"min_label":"Muy mal","max_label":"Muy bien"}'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000031',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'G5', 'single_choice',
|
||||
'¿Sentís que tu empresa comprende la realidad de ser cuidador/a?',
|
||||
31, false, false,
|
||||
'[
|
||||
{"value":"Sí, acompañado/a","label":"Sí, acompañado/a"},
|
||||
{"value":"Parcialmente","label":"Parcialmente"},
|
||||
{"value":"No, invisible","label":"No, invisible"},
|
||||
{"value":"Nunca lo supo","label":"Nunca lo supo"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
|
||||
-- ══════════════════════════════════════════════════
|
||||
-- SECCIÓN H — Necesidades (top-level)
|
||||
-- ══════════════════════════════════════════════════
|
||||
|
||||
-- H1: multiple_choice con max_select = 3
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, max_select, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000032',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'H1', 'multiple_choice',
|
||||
'¿Qué tipo de apoyo de tu empresa te ayudaría más? (hasta 3 opciones)',
|
||||
32, false, false, 3,
|
||||
'[
|
||||
{"value":"Flexibilidad horaria/remoto","label":"Flexibilidad horaria/remoto"},
|
||||
{"value":"Info recursos y servicios","label":"Info recursos y servicios"},
|
||||
{"value":"Apoyo psicológico","label":"Apoyo psicológico"},
|
||||
{"value":"Espacio de escucha","label":"Espacio de escucha"},
|
||||
{"value":"Convenios descuentos","label":"Convenios descuentos"},
|
||||
{"value":"Grupos de pares","label":"Grupos de pares"},
|
||||
{"value":"Capacitación autocuidado","label":"Capacitación autocuidado"},
|
||||
{"value":"Nada, estoy bien","label":"Nada, estoy bien"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required, options)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000033',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'H2', 'single_choice',
|
||||
'¿Estarías dispuesto/a a participar en un grupo de apoyo para cuidadores?',
|
||||
33, false, false,
|
||||
'[
|
||||
{"value":"Sí, definitivamente","label":"Sí, definitivamente"},
|
||||
{"value":"Tal vez","label":"Tal vez"},
|
||||
{"value":"No por ahora","label":"No por ahora"},
|
||||
{"value":"Prefiero privacidad","label":"Prefiero privacidad"}
|
||||
]'::jsonb
|
||||
);
|
||||
|
||||
-- H3: text_long — opcional, NO exponer en store analítico crudo (regla 4 CLAUDE.md)
|
||||
INSERT INTO public.questions
|
||||
(id, survey_id, code, type, prompt, position, is_sensitive, required)
|
||||
VALUES (
|
||||
'40000000-0000-0000-0000-000000000034',
|
||||
'30000000-0000-0000-0000-000000000001',
|
||||
'H3', 'text_long',
|
||||
'¿Querés compartir algo más sobre tu experiencia como cuidador/a? (opcional)',
|
||||
34, false, false
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user