# ESTADO DEL PROYECTO — Datos País sobre el Cuidado ## Documento de continuidad — junio 2026 > Generado al cierre de una sesión extendida de dirección técnica. > Propósito: minimizar pérdida de contexto al abrir una nueva conversación. > Director: Marcos (Roy) · Metodología: Maria Mersan · Contacto Fundación: Valeria Arce --- ## 1. Qué es el proyecto Plataforma soberana de encuestas sobre economía del cuidado en Paraguay. - **Producto:** formulario anónimo + dashboard analítico con k-anonimato. - **Marca:** RE (Responsabilidad y Empatía Empresarial) · Fundación Solidaridad · InQuality. - **URL producción:** https://economia-cuidado.inqualityhq.com - **Survey demo:** https://economia-cuidado.inqualityhq.com/?s=30000000-0000-0000-0000-000000000001 --- ## 2. Infraestructura actual — OPERATIVA ✅ ### Stack - **App:** Next.js 15.3.3 + TypeScript + Tailwind CSS - **DB:** Supabase self-hosted en Dokploy (stack oficial clonado) - **Deploy:** Dokploy v0.29.4 en VPS inq-mart-2 (IP VPN: 172.20.5.11) - **Repos:** - App: `git.inquality.com.py/marcos/motor-de-encuestas` (migrado desde GitHub InqGit) - Supabase stack: `git.inquality.com.py/marcos/supabase-motor-fomularios` - **Dominio API Supabase:** `db.inqualityhq.com` (Kong expuesto con SSL via Traefik/Let's Encrypt) ### Supabase self-hosted — detalles técnicos - Stack corriendo desde repo Gitea (modo Git, NO docker raw — docker raw no tiene ./volumes/db/) - Kong conectado a `dokploy-network` (persistente en docker-compose.yml del repo) - Fix aplicado: `LUA_AUTH_EXPR` en `kong-entrypoint.sh` con prefijo `Bearer ` para PostgREST JWT propagation - Variables de entorno en Dokploy: ANON_KEY, SERVICE_ROLE_KEY, SUPABASE_ANON_KEY, SUPABASE_SERVICE_KEY (nombres que usa kong.yml) - SMTP_PORT=587 requerido aunque SMTP esté desactivado (GoTrue lo exige como int) - GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED=false (GoTrue lo exige como bool explícito) - Backups: script GFS en /usr/local/bin/supabase-backup.sh, cron 3AM root, retención 3 días diarios + domingos 14 días - Studio: solo accesible via SSH tunnel `ssh -L 3001:localhost:3001 administrator@172.20.5.11` ### Variables de entorno de la app Next.js (Build Arguments en Dokploy) - NEXT_PUBLIC_SUPABASE_URL=https://db.inqualityhq.com - NEXT_PUBLIC_SUPABASE_ANON_KEY= - SUPABASE_SERVICE_ROLE_KEY= (Environment Setting, no Build Arg) --- ## 3. Estado del código — Sprint 2 COMPLETADO, Sprint 3 COMPLETADO ### Migraciones aplicadas (12 en total, en orden) 1. 20260531000001_create_tables.sql — 7 tablas 2. 20260531000002_enable_rls.sql 3. 20260531000003_rls_policies.sql — PARCIAL (ver TECH-DEBT-007) 4. 20260531000004_constraints_triggers.sql 5. 20260531000005_agg_segment.sql 6. 20260531000006_grants.sql 7. 20260602111851_revoke_consent_select.sql 8. 20260604200932_fix_answers_insert_policy.sql 9. 20260605093948_dashboard_rpc.sql 10. 20260605093949_rls_deny_sensitive.sql 11. 20260605140000_011_truncate_testing_data.sql 12. 20260605140001_012_dashboard_rpc_v2.sql — 11 RPCs v2 del dashboard ### Políticas RLS activas (7) - answers_insert, deny_sensitive_answers - consent_records_insert, consent_versions_select_all - questions_select_live, responses_insert - surveys_select_live_anon ### Políticas RLS que fallaron (TECH-DEBT-007) - org_select_own, surveys_select_auth, questions_select_auth - Causa: auth.jwt() deprecado en GoTrue v2.189+ — no es bloqueante para el piloto ### Dashboard — widgets y códigos reales del instrumento | Widget | Códigos reales | Subtítulo | |---|---|---| | K1 Cuidadores activos | 1.6 + 1.13 | % plantilla con responsabilidades de cuidado | | K2 Frecuencia ausentismo | 5.2 | % con 4+ ausencias al año | | K3 Bienestar | 4.3 (rating 1-5) | autorreporte bienestar general | | W1 Prevalencia por depto | A1 (Departamento) | % cuidadores activos por departamento | | W2 Perfil población | 1.1+1.6+1.13 | composición no excluyente | | W3 Madurez organizacional | 6.1(×0.7)+6.5(×0.3) | score 0-100 | | W4 Horas×Ausentismo | 2.2×5.2 | correlación intensidad/ausentismo | | W5 Pirámide demográfica | A5×A6 | etario por género (k≥5) | | W6 Apoyos demandados | 6.2 | top 8 multi-select | | W7 Intensidad vs Bienestar | 2.2×4.3 | bins k≥5 | | W8 Saturación cuidador | 4.3+5.1+5.2 | indicador compuesto | --- ## 4. Deuda técnica registrada | ID | Descripción | Bloqueante | |---|---|---| | TECH-DEBT-006 | Backup remoto S3 (Backblaze B2 o Wasabi ~$5/mes) | **SÍ — antes del primer dato real** | | TECH-DEBT-007 | auth.jwt() deprecado en GoTrue v2.189+ — current_app_role() y current_org_id() no funcionales | No (service_role bypasa RLS) | | CVE-2025-66478 | Next.js 15.3.3 con vulnerabilidad de seguridad crítica | **SÍ — antes del primer dato real** | --- ## 5. Prompts pendientes de ejecutar en Claude Code ### ETAPA 2G — Cierre Sprint 2 (método) **Archivo:** `sprints/sprint-2/ETAPA_2G_PROMPT.md` **Qué hace:** promueve Patrón C.8 a estable + documenta AP.10 y AP.11 en method/ANTI_PATTERNS.md con casos reales del proyecto. ### ETAPA 3V — Vista de control /admin/responses **Archivo:** `sprints/sprint-3-infra/ETAPA_3V_PROMPT.md` **Qué hace:** crea ruta Next.js /admin/responses que muestra tabla de todas las respuestas ordenadas por fecha descendente, sin auth, usando service_role. --- ## 6. Contexto comercial - **2 empresas comprometidas** para piloto (no en producción aún) - **Cronograma deck:** JUN 2026 inicio · JUL-AGO relevamiento · SEP análisis · OCT primer informe + evento - **Meta:** 20 empresas pioneras - **Precios:** Gs. 4.5M (≤50) · 7.5M (≤200) · 12M (≤400) - **GAPs deck vs. producto:** - RE Index no implementado (fórmula: Bienestar×0.35 + Concentración×0.25 + Descanso×0.25 + Apoyo×0.15) - Informe descargable prometido en el deck, no existe todavía - **Contacto Fundación:** Valeria Arce — ddff@fundacionsolidaridad.org.py · +595 991 854333 --- ## 7. Documentos producidos en estas sesiones | Archivo | Descripción | |---|---| | INSTALL_SUPABASE.md | Guía instalación self-hosted (384 líneas) — con tabla de errores conocidos | | BACKUP_STRATEGY.md | Estrategia backup GFS (335 líneas) — con procedimiento de restore | | DOCUMENTACION_PLATAFORMA.md | Doc conceptual con 3 diagramas Mermaid | | DatoPais_DocumentacionConceptual.docx | Word con 3 PNGs de diagramas embebidos | | DatoPais_DimensionamientoEconomico.docx | Word con 5 charts económicos | | DatoPais_ValidacionInstrumento.xlsx | Planilla colaborativa 4 hojas | | sprints/sprint-2/ETAPA_2G_PROMPT.md | Cierre Sprint 2 — PENDIENTE ejecución | | sprints/sprint-3-infra/ETAPA_3V_PROMPT.md | Vista /admin/responses — PENDIENTE ejecución | --- ## 8. Decisiones clave tomadas (no reabrir) 1. **docker raw de Dokploy es incompatible con Supabase** — usar siempre modo Git; el compose oficial necesita ./volumes/db/ que docker raw no tiene. 2. **POSTGRES_PASSWORD siempre con openssl rand -hex** — base64 tiene caracteres especiales que rompen el escaping de Docker Compose. 3. **kong.yml: una sola entrada por bloque keyauth_credentials** — dos entradas con el mismo valor JWT causa uniqueness violation. 4. **SMTP_PORT=587 siempre explícito** aunque SMTP esté desactivado — GoTrue lo parsea como int y falla si está vacío. 5. **GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED=false siempre explícito** — GoTrue lo parsea como bool y falla si está vacío. 6. **LUA_AUTH_EXPR con prefijo "Bearer "** en kong-entrypoint.sh rama legacy — sin el prefijo PostgREST recibe JWT vacío. 7. **kong.yml usa $ANON_KEY y $SERVICE_ROLE_KEY** — alineado con los nombres de variables en Dokploy; SUPABASE_ANON_KEY y SUPABASE_SERVICE_KEY son aliases adicionales. 8. **App Next.js conecta a Supabase por URL pública** (https://db.inqualityhq.com) — las variables NEXT_PUBLIC_* se embeben en el bundle en build time y el navegador no puede resolver nombres Docker internos. 9. **NEXT_PUBLIC_SUPABASE_URL va como Build Argument** en Dokploy, no como Environment Setting — se embebe en el bundle de JavaScript durante el build. 10. **Repos en Gitea** (migrado desde GitHub InqGit) — VS Code configurado apuntando a git.inquality.com.py. --- ## 9. Patrones y anti-patrones del método (pendiente formalización en 2G) ### C.8 — Verificación de códigos contra fuente única (PROMOVER A ESTABLE) Todos los widget subtitles y RPC mappings deben verificarse contra el instrumento real (SEED_SPEC.md). El drift silencioso entre instrumento e implementación es un failure mode de alto costo. ### AP.10 — Propagación silenciosa de inconsistencia entre fuentes Caso real: Etapa 2D tenía subtítulos con códigos incorrectos que no se detectaron hasta auditoría explícita. Los errores de mapeo de códigos no generan errores en tiempo de compilación. ### AP.11 — Contrato desactualizado por código Caso real: Etapa 1D dejó SEED_SPEC.md desactualizado respecto al seed.sql. El documento de referencia divergió del código sin señal visible. --- ## 10. Próximos pasos en orden de prioridad 1. **TECH-DEBT-006** — Backup remoto S3 (bloqueante antes del primer dato real) 2. **CVE-2025-66478** — Actualizar Next.js antes del primer dato real 3. **ETAPA 2G** — Ejecutar en Claude Code (método, no infraestructura) 4. **ETAPA 3V** — Ejecutar en Claude Code (vista /admin/responses) 5. **RE Index** — Implementar como widget real (confirmar mapeo G1/G2/G4/G5 → códigos seed con Marcos primero) 6. **Informe descargable** — Prometido en deck comercial, no existe 7. **Onboarding 2 empresas comprometidas** — cuando validación esté lista 8. **Validación instrumento** — Respuestas equipo de salud en DatoPais_ValidacionInstrumento.xlsx (12 preguntas metodológicas abiertas)