Skip to main content

Base de datos

La API usa Supabase (PostgreSQL) como base de datos, con Row Level Security (RLS) habilitado en tablas sensibles. Las migraciones se gestionan con archivos SQL en apps/backend/src/database/migrations/.

Tablas principales

Users y autenticación

Tabla users:

Chat

Community

Surveys

Tabla surveys: Tabla survey_responses: Índices y constraints:
  • Partial unique index: máximo 1 versión active por survey_type_id
  • Índices en survey_responses: por survey_id + status, scope_id + survey_id, respondent_id
  • Unique constraint: 1 reward por response, 1 recommendation por response, 1 action plan por survey + scope

Notificaciones e inbox

Tabla inbox_messages:

Permisos

Sync (Windmill)

AI / Insights

Tabla survey_insights:

Integraciones

Row Level Security (RLS)

Las tablas sensibles tienen políticas RLS habilitadas:
  • inbox_messages: Los usuarios solo pueden leer y actualizar sus propios mensajes. Los admin pueden acceder a todos. El service role puede insertar mensajes (para integraciones y notificaciones del sistema).
  • Otras tablas con datos de usuario siguen patrones similares.
El backend usa el service role de Supabase para operaciones del servidor, lo que permite bypasear RLS. Las operaciones directas desde el cliente no están habilitadas.

Migraciones

Las migraciones SQL se encuentran en apps/backend/src/database/migrations/ y se ejecutan en orden numérico. Cada migración crea tablas, índices y políticas RLS necesarias.

Política de migraciones

No editar migraciones ya mergeadas a main. Una vez aplicada en cualquier entorno, una migración queda registrada en _supabase.schema_migrations y supabase db push no la vuelve a correr. Si el archivo cambia luego, los entornos donde ya corrió quedan con el schema viejo.Caso real (2026-05-14): 072_create_domain_events.sql fue editada en sitio para agregar columnas event_id y deleted_at. Como el DDL es CREATE TABLE IF NOT EXISTS, dev (que ya tenía la tabla creada) skipeó silenciosamente las nuevas columnas. El QA quedó bloqueado hasta que se aplicó una migración de recovery 088_alter_domain_events_event_id_deleted_at.sql.
Reglas:
  1. Una migración se commitea una vez. Después solo se modifican comentarios.
  2. Cambios estructurales = nueva migración con ALTER TABLE / ALTER INDEX / DROP COLUMN / etc. Siempre con IF NOT EXISTS cuando sea posible para que sea idempotente.
  3. Antes de mergear a develop: ejecutar pnpm --filter @vivla-tools/backend db:migrate localmente contra una copia de dev para confirmar que corre limpia.
  4. Tras el merge: aplicar a dev inmediatamente.
Enforcement: el pre-commit hook apps/backend/scripts/check-migration-edits.sh bloquea commits que tocan .sql ya presentes en origin/main (excepto cambios solo en comentarios). Bypass con git commit --no-verify solo para hotfixes reales.

Migraciones de Surveys (050-066)