db: Drizzle schemas on domain Postgres schemas, baseline migration, reorg SQL

- pgSchema tables for auth, money, house, ref, games, cs, animaldex, site, meta
  (lists excluded via schemaFilter; runtime list tables are managed by meta.*)
- drizzle/ baseline matches the reorged DB exactly (catalog diff = 0 on rehearsal)
- db/reorg: one-time SQL that moves the flat public schema (rehearsed on a prod copy)
- scripts/db-migrate.ts: migrator with --init to record the baseline and a guard
  against running the baseline on a non-empty, unrecorded database
This commit is contained in:
2026-10-23 22:03:42 +00:00
parent f94e3dc8ac
commit 64fb8df262
29 changed files with 12507 additions and 189 deletions

17
db/reorg/01_roles.sql Normal file
View File

@@ -0,0 +1,17 @@
-- 01_roles.sql: cluster-level roles. Run as a superuser (postgres). Idempotent.
-- In prod: needs `sudo docker exec -i <pg-container> psql -U postgres`; set passwords separately (\password), never in this file.
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'personal_app') THEN
CREATE ROLE personal_app LOGIN; -- app, ned-collector, house worker
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'personal_ddl') THEN
CREATE ROLE personal_ddl NOLOGIN; -- owns schema lists; only reachable via SECURITY DEFINER fns
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'personal_ro') THEN
CREATE ROLE personal_ro LOGIN; -- read-only for audits/agents/pgAdmin
END IF;
END $$;
ALTER ROLE personal_ro SET default_transaction_read_only = on;
ALTER ROLE personal_app SET search_path = '$user'; -- force schema-qualified names in app SQL
ALTER ROLE personal_ro SET search_path = '$user';