-- dashboard_ro_role.sql — dedicated read-only LOGIN role for dashboard_api.
--
-- Run as the postgres SUPERUSER (CREATE ROLE), NOT via run_migrations.py (which
-- connects as the app role and may lack CREATEROLE). Apply with
-- scripts/bootstrap_dashboard_ro.sh, which supplies the password as the psql
-- variable :ro_pw from a host-only 0600 file — so no secret lives in this repo.
--
-- Purpose: a least-privilege role that can serve the FULL dashboard_api read
-- surface, so it backs BOTH the staging instance now (stage 1) AND the live prod
-- connection later (stage 2 — migrate fleetapi.rahamafresh.com off the app role).
-- It therefore grants exactly what the API reads:
--   * SELECT on reporting.* and tracksolid.* (tables + views)
--   * SELECT on the reporting.v_trips MATERIALIZED VIEW — matviews are NOT
--     covered by GRANT ... ON ALL TABLES, so it must be named explicitly
--   * EXECUTE on the reporting.fn_* map functions (fn_live_positions, etc.)
--   * DEFAULT PRIVILEGES so future objects created by the migration role are
--     auto-readable ("dynamic" — no re-grant when we add views)
-- Read-only: no INSERT/UPDATE/DELETE and not the matview owner, so dashboard_ro
-- can never write or REFRESH. Idempotent -> safe to re-apply (also rotates pw).

\set ON_ERROR_STOP on

DO $role$
BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'dashboard_ro') THEN
    CREATE ROLE dashboard_ro LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE;
  END IF;
END $role$;

ALTER ROLE dashboard_ro WITH LOGIN PASSWORD :'ro_pw';

GRANT CONNECT ON DATABASE tracksolid_db TO dashboard_ro;
GRANT USAGE ON SCHEMA reporting, tracksolid TO dashboard_ro;

GRANT SELECT  ON ALL TABLES    IN SCHEMA reporting  TO dashboard_ro;  -- tables + views
GRANT SELECT  ON ALL TABLES    IN SCHEMA tracksolid TO dashboard_ro;  -- tables + views
GRANT SELECT  ON reporting.v_trips TO dashboard_ro;                   -- MATERIALIZED VIEW (not in ALL TABLES)
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA reporting  TO dashboard_ro;

-- "dynamic": future objects created by the migration role (tracksolid_owner)
-- are auto-granted. NOTE: matviews are still never covered — a new matview needs
-- its own explicit GRANT SELECT (as above for v_trips).
ALTER DEFAULT PRIVILEGES FOR ROLE tracksolid_owner IN SCHEMA reporting  GRANT SELECT  ON TABLES    TO dashboard_ro;
ALTER DEFAULT PRIVILEGES FOR ROLE tracksolid_owner IN SCHEMA tracksolid GRANT SELECT  ON TABLES    TO dashboard_ro;
ALTER DEFAULT PRIVILEGES FOR ROLE tracksolid_owner IN SCHEMA reporting  GRANT EXECUTE ON FUNCTIONS TO dashboard_ro;
