-- ===================================================================== -- FlatRender V2 — Database Setup -- Single PostgreSQL database with per-service schemas -- ===================================================================== -- Extensions CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- gen_random_uuid() CREATE EXTENSION IF NOT EXISTS "citext"; -- case-insensitive text (emails) CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- fuzzy text search -- ===================================================================== -- Schemas (one per microservice) -- ===================================================================== CREATE SCHEMA IF NOT EXISTS identity; CREATE SCHEMA IF NOT EXISTS content; CREATE SCHEMA IF NOT EXISTS studio; CREATE SCHEMA IF NOT EXISTS render; CREATE SCHEMA IF NOT EXISTS file_mgr; CREATE SCHEMA IF NOT EXISTS notification; -- ===================================================================== -- Service users (each microservice connects with limited grants) -- ===================================================================== -- Run separately by ops: -- CREATE USER svc_identity WITH PASSWORD '...'; -- CREATE USER svc_content WITH PASSWORD '...'; -- CREATE USER svc_studio WITH PASSWORD '...'; -- CREATE USER svc_render WITH PASSWORD '...'; -- CREATE USER svc_file WITH PASSWORD '...'; -- CREATE USER svc_notification WITH PASSWORD '...'; -- GRANT ALL ON SCHEMA identity TO svc_identity; -- GRANT ALL ON SCHEMA content TO svc_content; -- ... etc. -- Read-only cross-schema grants where needed (defined per service) -- ===================================================================== -- Common helper: auto-update updated_at on row update -- ===================================================================== CREATE OR REPLACE FUNCTION public.tg_set_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; -- ===================================================================== -- Common helper: soft-delete check (used in policies/views later) -- ===================================================================== -- Convention: every soft-deletable table has `deleted_at TIMESTAMPTZ NULL` -- Active rows: WHERE deleted_at IS NULL