-- tradein_fdw_reader role + v_tradein_cad_buildings view -- Used by tradein-postgres via postgres_fdw to read live cad_buildings. -- Password is set by .forgejo/workflows/deploy.yml ALTER ROLE bootstrap step -- reading GENDESIGN_FDW_PASSWORD from backend/.env.runtime — never embed password in SQL. BEGIN; DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'tradein_fdw_reader') THEN CREATE ROLE tradein_fdw_reader LOGIN; END IF; END$$; COMMENT ON ROLE tradein_fdw_reader IS 'FDW reader from tradein-postgres. Password set by .forgejo/workflows/deploy.yml from env GENDESIGN_FDW_PASSWORD post-migration step. Never embed password in SQL migrations.'; -- Defense-in-depth: explicit REVOKE perimeter (any existing PUBLIC grants ignored). REVOKE ALL ON ALL TABLES IN SCHEMA public FROM tradein_fdw_reader; REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM tradein_fdw_reader; REVOKE ALL ON ALL FUNCTIONS IN SCHEMA public FROM tradein_fdw_reader; GRANT CONNECT ON DATABASE gendesign TO tradein_fdw_reader; GRANT USAGE ON SCHEMA public TO tradein_fdw_reader; CREATE OR REPLACE VIEW v_tradein_cad_buildings AS SELECT cad_num, NULLIF(trim(readable_address), '') AS readable_address, NULLIF(floors, 0) AS floors, CASE WHEN year_built BETWEEN 1800 AND 2100 THEN year_built END AS year_built, round(COALESCE(build_record_area, area), 2)::numeric AS area_m2, purpose, ST_Y(ST_Centroid(geom))::double precision AS lat, ST_X(ST_Centroid(geom))::double precision AS lon FROM cad_buildings WHERE cad_num LIKE '66:41:%' AND geom IS NOT NULL AND readable_address IS NOT NULL; GRANT SELECT ON v_tradein_cad_buildings TO tradein_fdw_reader; COMMENT ON VIEW v_tradein_cad_buildings IS 'FDW source for tradein-mvp (postgres_fdw). Flat 8-col EKB-only slice of cad_buildings. tradein.gendesign_cad_buildings maps here.'; COMMIT;