panels-origin/db/provision/README.md
Cursor Agent b87b0205a8
db: migrar infraestructura de BD a Postgres (fase 0-1)
- Fase 0: scripts de aprovisionamiento (db/provision/) para roles, dos
  bases de datos separadas (panels_platform / panels_product con
  esquemas iam+core) y ACLs de Redis por modulo, con verificacion
  automatizada de aislamiento (verify-isolation.sh) y setup local
  reproducible (dev-local.sh).
- Fase 1: changelogs de Liquibase reescritos para Postgres
  (db/platform, db/iam, db/core reemplazan db/app + los changesets
  SQLite de platform). Baseline como estado final (no replay literal),
  tipos traducidos (IDENTITY, TIMESTAMPTZ/DATE, NUMERIC, BOOLEAN,
  CITEXT), contexts dev vs. schema/catalogos, RLS por tenant_id como
  defensa en profundidad, uploaded_by/created_by como snapshot
  desnormalizado (sin FK hacia iam).
- Migraciones ya no corren en el arranque de la API: paso explicito de
  deploy via db/update.sh con credenciales _owner.

Verificado end-to-end contra Postgres 16 + Redis local.

Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
2026-09-02 20:00:49 +00:00

80 lines
3.2 KiB
Markdown

# Aprovisionamiento de infraestructura (Fase 0)
Scripts para dejar Postgres y Redis listos, en cualquier ambiente (dev local,
staging o producción en Coolify), antes de correr Liquibase o levantar la API.
Ver el plan de migración para el diseño completo: dos bases de datos
(`panels_platform`, `panels_product`) y, dentro de `panels_product`, dos
esquemas (`iam`, `core`).
## Orden de ejecución (Postgres)
Contra el servidor Postgres del ambiente (uno por dev/staging/producción),
como usuario superusuario/admin:
```bash
SUPERUSER_URL="postgresql://postgres:adminpass@HOST:5432/postgres"
# 1. Roles cluster-wide (genera una clave distinta por rol y por ambiente:
# openssl rand -hex 24). Pasar los valores SIN comillas propias -- el
# script usa :'var' internamente para escaparlos como literal SQL.
psql "$SUPERUSER_URL" \
-v platform_owner_pw="..." -v platform_app_pw="..." \
-v iam_owner_pw="..." -v iam_app_pw="..." \
-v core_owner_pw="..." -v core_app_pw="..." \
-f 01-roles.sql
# 2. Bases de datos (panels_platform, panels_product)
psql "$SUPERUSER_URL" -f 02-databases.sql
# 3. Privilegios dentro de panels_platform
psql "${SUPERUSER_URL%/postgres}/panels_platform" -f 03-platform-database.sql
# 4. Esquemas + privilegios dentro de panels_product
psql "${SUPERUSER_URL%/postgres}/panels_product" -f 04-product-database.sql
```
Las conexiones que usará la API (secrets por ambiente):
| Secret | Apunta a | Usuario |
|---|---|---|
| `DATABASE_URL_PLATFORM` | `panels_platform` | `panels_platform_app` |
| `DATABASE_URL_IAM` | `panels_product` (search_path=iam) | `panels_iam_app` |
| `DATABASE_URL_CORE` | `panels_product` (search_path=core) | `panels_core_app` |
Liquibase (paso de deploy, no en runtime) usa los roles `_owner`:
`DATABASE_URL_PLATFORM_OWNER`, `DATABASE_URL_IAM_OWNER`, `DATABASE_URL_CORE_OWNER`.
## Redis
```bash
REDIS_ADMIN_URL="redis://:adminpass@HOST:6379" \
IAM_REDIS_PASSWORD="$(openssl rand -base64 32)" \
CORE_REDIS_PASSWORD="$(openssl rand -base64 32)" \
./05-redis-acl.sh
```
Secrets resultantes: `REDIS_URL_IAM` (`redis://panels_iam_redis:<pw>@HOST:6379`),
`REDIS_URL_CORE` (`redis://panels_core_redis:<pw>@HOST:6379`).
El script verifica automáticamente que cruzar de módulo devuelva `NOPERM`
(ver "Riesgos y mitigaciones" del plan: un prefijo de llave sin ACL detrás
no aísla nada).
## Qué falta hacer manualmente en Coolify (staging/producción)
Estos scripts asumen que ya existe un servidor Postgres y un servidor Redis
accesibles (el recurso gestionado de Coolify por ambiente). El agente no
tiene acceso a la cuenta de Coolify del usuario, así que:
1. Crear el recurso Postgres gestionado en Coolify para el ambiente.
2. Crear el recurso Redis gestionado en Coolify para el ambiente.
3. Correr estos scripts contra ambos usando las credenciales admin que da Coolify.
4. Cargar los secrets resultantes (`DATABASE_URL_*`, `REDIS_URL_*`) en la
configuración del servicio `api` de ese ambiente.
## Desarrollo local
`db/provision/dev-local.sh` reproduce estos mismos pasos contra un Postgres
y Redis instalados en la máquina de desarrollo (sin Coolify), generando
`.env.dev-local` con las URLs resultantes — útil para correr la API y los
tests sin depender de infraestructura externa.