Los triggers 1.1, 1.6, 1.13 muestran solo Sí · No (sin "Prefiero no decir")
Al responder "No" en las tres, el formulario salta a 6.4 (no muestra secciones 2-5 ni 6.1-6.3) La pregunta 6.6 aparece antes del cierre Las preguntas multiple_choice muestran el hint "Podés marcar más de una opción"
This commit is contained in:
178
migrate-claude/ESTADO_PROYECTO_JUNIO_2026.md
Normal file
178
migrate-claude/ESTADO_PROYECTO_JUNIO_2026.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# 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=<JWT anon>
|
||||
- SUPABASE_SERVICE_ROLE_KEY=<JWT service_role> (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)
|
||||
70
migrate-claude/PROMPT_NUEVA_SESION.md
Normal file
70
migrate-claude/PROMPT_NUEVA_SESION.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# PROMPT DE CONTINUIDAD — nueva sesión de dirección técnica
|
||||
## Datos País sobre el Cuidado
|
||||
|
||||
> Pegá este prompt al inicio de una nueva conversación con Claude.
|
||||
> Actualizado: junio 2026.
|
||||
|
||||
---
|
||||
|
||||
Sos el copiloto técnico del proyecto "Datos País sobre el Cuidado" — una plataforma soberana de encuestas sobre economía del cuidado en Paraguay. Ya tenemos múltiples sesiones de trabajo juntos. Este mensaje te pone al día antes de continuar.
|
||||
|
||||
## Contexto del proyecto
|
||||
|
||||
Plataforma de dos caras: formulario web anónimo + dashboard analítico con k-anonimato. Marca RE, Fundación Solidaridad, powered by InQuality.
|
||||
|
||||
- **Stack:** Next.js 15.3.3 + TypeScript + Tailwind CSS + Supabase self-hosted
|
||||
- **Deploy:** Dokploy v0.29.4 en VPS (IP VPN: 172.20.5.11)
|
||||
- **URL producción:** https://economia-cuidado.inqualityhq.com
|
||||
- **Repos:** app en `git.inquality.com.py/marcos/motor-de-encuestas`, Supabase stack en `git.inquality.com.py/marcos/supabase-motor-fomularios`
|
||||
- **API Supabase:** https://db.inqualityhq.com (Kong con SSL)
|
||||
|
||||
## Estado actual — Sprint 3 COMPLETADO
|
||||
|
||||
El formulario y el dashboard están operativos con Supabase self-hosted. Las 12 migraciones están aplicadas. Backups locales configurados con retención GFS. El formulario carga y permite completar la encuesta end-to-end.
|
||||
|
||||
## Deuda técnica abierta (ver TECH_DEBT.md en el repo)
|
||||
|
||||
- **TECH-DEBT-006** — Backup remoto S3 — BLOQUEANTE antes del primer dato real de empresa
|
||||
- **TECH-DEBT-007** — auth.jwt() deprecado en GoTrue v2.189+ — no bloqueante para el piloto
|
||||
- **CVE-2025-66478** — Next.js 15.3.3 con vulnerabilidad crítica — BLOQUEANTE antes del primer dato real
|
||||
|
||||
## Decisiones tomadas — no reabrir
|
||||
|
||||
1. Supabase en Dokploy siempre via modo Git (docker raw no tiene ./volumes/db/)
|
||||
2. POSTGRES_PASSWORD siempre con openssl rand -hex (evita caracteres problemáticos)
|
||||
3. kong.yml: una sola entrada por bloque keyauth_credentials
|
||||
4. SMTP_PORT=587 siempre explícito aunque SMTP esté desactivado
|
||||
5. GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED=false siempre explícito
|
||||
6. LUA_AUTH_EXPR con prefijo "Bearer " en kong-entrypoint.sh rama legacy
|
||||
7. NEXT_PUBLIC_SUPABASE_URL via Build Argument en Dokploy (no Environment Setting)
|
||||
8. App Next.js conecta a Supabase por URL pública https://db.inqualityhq.com
|
||||
|
||||
## Prompts pendientes de ejecutar en Claude Code
|
||||
|
||||
1. **ETAPA 2G** — `sprints/sprint-2/ETAPA_2G_PROMPT.md` — cierre Sprint 2, formaliza patrones C.8, AP.10, AP.11 en el método
|
||||
2. **ETAPA 3V** — `sprints/sprint-3-infra/ETAPA_3V_PROMPT.md` — vista /admin/responses para control operativo
|
||||
|
||||
## Próximos pasos en orden
|
||||
|
||||
1. TECH-DEBT-006 (S3 backup) — bloqueante
|
||||
2. CVE-2025-66478 (Next.js update) — bloqueante
|
||||
3. Ejecutar ETAPA 2G en Claude Code
|
||||
4. Ejecutar ETAPA 3V en Claude Code
|
||||
5. RE Index — confirmar mapeo G1/G2/G4/G5 → códigos seed antes de implementar
|
||||
6. Informe descargable — prometido en deck comercial, no existe aún
|
||||
|
||||
## Método de trabajo
|
||||
|
||||
Usamos niveles de autonomía explícitos en los prompts (Nivel 1 = reportar antes de hacer, Nivel 3 = ejecutar con validación al final). Los prompts de Claude Code están en `sprints/`. Las decisiones arquitecturales se documentan como ADRs en `docs/adr/`. Las reglas no negociables del proyecto están en `CLAUDE.md` del repo.
|
||||
|
||||
## Preguntas frecuentes de contexto
|
||||
|
||||
**¿Por qué Supabase self-hosted y no Cloud?** Soberanía del dato — datos de cuidadores paraguayos no deben vivir en servidores de terceros fuera de control del proyecto. Decisión tomada antes de ingresar el primer dato real.
|
||||
|
||||
**¿Por qué k-anonimato k≥5?** Regla no negociable del sistema. En empresas chicas, un cruce demográfico de menos de 5 personas puede reidentificar a un individuo aunque el nombre nunca se haya guardado.
|
||||
|
||||
**¿Por qué el dashboard usa service_role?** Porque las políticas de org_admin con JWT custom claims no están implementadas (TECH-DEBT-007). Para el piloto, el dashboard es herramienta interna y service_role es aceptable. Cuando haya org_admin real, hay que resolver TECH-DEBT-007 primero.
|
||||
|
||||
---
|
||||
|
||||
¿Listo para continuar? El próximo paso es [COMPLETAR CON LO QUE VAYAS A HACER].
|
||||
48
migrate-claude/TECH_DEBT_ACTUALIZADO.md
Normal file
48
migrate-claude/TECH_DEBT_ACTUALIZADO.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# TECH_DEBT.md — actualización junio 2026
|
||||
## Para aplicar en el repo del proyecto
|
||||
|
||||
> Reemplazar el contenido existente de TECH_DEBT.md en el repo con este bloque,
|
||||
> o mergear los ítems nuevos si ya existe el archivo con otros ítems previos.
|
||||
|
||||
---
|
||||
|
||||
## Deuda técnica abierta
|
||||
|
||||
### TECH-DEBT-006 — Backup remoto S3
|
||||
**Estado:** ABIERTO — BLOQUEANTE antes del primer dato real de empresa
|
||||
**Descripción:** Los backups locales están configurados y funcionando (GFS, 3AM diario, retención 3 días + domingos 14 días). Pero los backups viven solo en el mismo VPS. Si el VPS muere, se pierden datos Y backups.
|
||||
**Solución:** rsync nocturno a S3-compatible (Backblaze B2 o Wasabi, ~USD 5/mes) usando rclone.
|
||||
**Referencia:** BACKUP_STRATEGY.md sección 5 — TECH-DEBT-006.
|
||||
|
||||
### TECH-DEBT-007 — auth.jwt() deprecado en GoTrue v2.189+
|
||||
**Estado:** ABIERTO — no bloqueante para el piloto
|
||||
**Descripción:** Las funciones helper `current_app_role()` y `current_org_id()` en migration 003 usan `auth.jwt()` que fue eliminado en GoTrue v2.189+. Las políticas que dependen de estas funciones no se crearon:
|
||||
- `org_select_own` en organizations
|
||||
- `surveys_select_auth` en surveys
|
||||
- `questions_select_auth` en questions
|
||||
**Impacto actual:** ninguno — el dashboard usa service_role que bypasa RLS. Los respondentes usan anon que tiene las políticas básicas de INSERT.
|
||||
**Impacto futuro:** org_admin no podrá autenticarse con custom claims (app_role, org_id) hasta resolver esto.
|
||||
**Solución:** migrar a auth.session() o implementar JWT claims via hook de GoTrue v2.
|
||||
**NO resolver hasta tener caso de uso real de org_admin autenticado.**
|
||||
|
||||
### CVE-2025-66478 — Next.js 15.3.3 con vulnerabilidad de seguridad
|
||||
**Estado:** ABIERTO — BLOQUEANTE antes del primer dato real de empresa
|
||||
**Descripción:** Next.js 15.3.3 tiene una vulnerabilidad de seguridad crítica. El build lo reporta explícitamente: "This version has a security vulnerability. Please upgrade to a patched version."
|
||||
**Solución:** actualizar next en package.json a la versión parcheada disponible, correr npm install, hacer redeploy.
|
||||
**Referencia:** https://nextjs.org/blog/CVE-2025-66478
|
||||
|
||||
---
|
||||
|
||||
## Deuda técnica cerrada en Sprint 3
|
||||
|
||||
### TECH-DEBT-002 — KPI NPS eliminado ✅
|
||||
KPI NPS eliminado — instrumento no tiene pregunta NPS.
|
||||
|
||||
### TECH-DEBT-003 — Brecha de políticas ✅
|
||||
Widget W6 redefinido como demanda-only (6.2), sin oferta. Documentado.
|
||||
|
||||
### TECH-DEBT-004 — Intención directa de salida no capturada
|
||||
Intención directa de salida laboral no capturada en el instrumento v2. No resuelto pero documentado como gap conocido.
|
||||
|
||||
### TECH-DEBT-005 — A1 País vs A1b ✅
|
||||
Cerrado: A1 ya es Departamento (18 opciones Paraguay) en el instrumento final.
|
||||
Reference in New Issue
Block a user