first commit

This commit is contained in:
2026-08-14 17:35:24 -03:00
commit 04472fcd2b
118 changed files with 19173 additions and 0 deletions
@@ -0,0 +1,53 @@
-- Migration manual: roles de aplicação usadas pela Etapa 2 (Autenticação/RLS).
--
-- Por que duas roles novas em vez de reaproveitar a role do DATABASE_URL
-- (`seconectai`, dono das tabelas): a role criada pelo `POSTGRES_USER` do
-- docker-compose é a role bootstrap do initdb, portanto é SUPERUSER — e
-- superusers do Postgres **sempre** ignoram Row Level Security, mesmo com
-- `ENABLE ROW LEVEL SECURITY`/`FORCE ROW LEVEL SECURITY` nas tabelas. Se a
-- aplicação continuasse consultando o banco com essa role em runtime, o
-- isolamento por tenant seria só decorativo. Por isso:
--
-- * `app_master` — LOGIN + BYPASSRLS, mas SEM ser superuser. Usada via
-- `DATABASE_URL_MASTER` pelo painel master (enxerga todos os tenants),
-- como pedido no prompt da etapa.
-- * `app_tenant` — LOGIN comum, SEM BYPASSRLS e SEM ser superuser. Usada
-- via `DATABASE_URL_TENANT` para toda query autenticada como
-- tenant_user, dentro da transação que executa
-- `SET LOCAL app.current_tenant_id`; é essa role que faz as policies de
-- RLS (`prisma/migrations/20260812161100_rls_views_constraints`) valerem
-- de fato. (Desvio registrado em Etapas/09-controle-de-progresso.md: o
-- prompt original só citava `DATABASE_URL_MASTER`.)
--
-- `DATABASE_URL` (role `seconectai`) continua sendo usada só para
-- migrations e para o `PrismaService` "admin" (health check, bootstrap de
-- login antes de existir um tenant_id de sessão — ver AuthService).
--
-- As senhas abaixo são placeholders de desenvolvimento, no mesmo espírito
-- de `POSTGRES_PASSWORD`/`JWT_SECRET` em `.env.example`: troque-as em
-- produção com `ALTER ROLE ... WITH PASSWORD '...'` e atualize
-- `DATABASE_URL_MASTER`/`DATABASE_URL_TENANT` de acordo.
DO $$
BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'app_master') THEN
CREATE ROLE app_master WITH LOGIN PASSWORD 'app_master_changeme' NOSUPERUSER BYPASSRLS;
END IF;
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'app_tenant') THEN
CREATE ROLE app_tenant WITH LOGIN PASSWORD 'app_tenant_changeme' NOSUPERUSER NOBYPASSRLS;
END IF;
END
$$;
GRANT USAGE ON SCHEMA public TO app_master, app_tenant;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_master, app_tenant;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_master, app_tenant;
-- Cobre tabelas/sequences criadas por migrations futuras (etapas 3+),
-- desde que aplicadas com a mesma role que rodou esta migration.
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_master, app_tenant;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE, SELECT ON SEQUENCES TO app_master, app_tenant;