Add infrastructure skeleton for review (refs #21)
check / flake-check (pull_request) Has been cancelled
check / flake-check (pull_request) Has been cancelled
Lays out the agreed shape from the design discussion: one flake at the root with three nixosConfigurations (mqtt-ingest, db-host, app-host), vendored Supabase docker-compose pointed at the external db-host, Caddy → Kong → PostgREST/GoTrue, a Go MQTT→Postgres ingester stub, deploy-rs node map, and a Gitea Actions workflow that deploys in db → app → ingest order on push to main. No real implementation yet — every host module has TODOs marking the gaps (real hardware config, actual hostnames, HiveMQ packaging, vendor the full upstream Supabase compose, etc.).
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
-- Gebos Postgres bootstrap.
|
||||
-- Runs once via services.postgresql.initialScript on db-host.
|
||||
--
|
||||
-- Sets up:
|
||||
-- * Extensions Supabase + TimescaleDB need
|
||||
-- * Supabase's expected schemas and admin roles
|
||||
-- * The gebos_ingest role (BYPASSRLS) used by the MQTT ingester
|
||||
-- * A telemetry hypertable with tenant_id column for RLS
|
||||
--
|
||||
-- TODO: split into ordered files once it grows. For the skeleton, one file is fine.
|
||||
|
||||
create extension if not exists timescaledb;
|
||||
create extension if not exists pgcrypto;
|
||||
create extension if not exists pgjwt;
|
||||
create extension if not exists pg_graphql;
|
||||
create extension if not exists pgsodium;
|
||||
-- create extension if not exists supabase_vault; -- TODO: vendor or package
|
||||
|
||||
-- Supabase schemas
|
||||
create schema if not exists auth;
|
||||
create schema if not exists storage;
|
||||
create schema if not exists _analytics;
|
||||
create schema if not exists _supavisor;
|
||||
|
||||
-- Roles Supabase services connect as. Passwords come from secrets.env, not here.
|
||||
do $$ begin
|
||||
create role anon nologin noinherit;
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
do $$ begin
|
||||
create role authenticated nologin noinherit;
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
do $$ begin
|
||||
create role service_role nologin noinherit bypassrls;
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
do $$ begin
|
||||
create role authenticator noinherit login;
|
||||
grant anon, authenticated, service_role to authenticator;
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
do $$ begin
|
||||
create role supabase_admin login createrole createdb replication bypassrls;
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
do $$ begin
|
||||
create role supabase_auth_admin login createrole;
|
||||
grant usage on schema auth to supabase_auth_admin;
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
-- Ingester writes telemetry; bypasses RLS because at write time no user is
|
||||
-- authenticated. Trust boundary is the broker ACL ("who can publish to what
|
||||
-- tenant's topic"), not the database.
|
||||
do $$ begin
|
||||
create role gebos_ingest login bypassrls;
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
-- Telemetry hypertable. Tenant lives on the row so standard RLS works.
|
||||
create table if not exists public.telemetry (
|
||||
ts timestamptz not null,
|
||||
tenant_id uuid not null,
|
||||
device_id uuid not null,
|
||||
metric text not null,
|
||||
value double precision,
|
||||
payload jsonb
|
||||
);
|
||||
|
||||
select create_hypertable('public.telemetry', 'ts', if_not_exists => true);
|
||||
|
||||
create index if not exists telemetry_tenant_device_ts_idx
|
||||
on public.telemetry (tenant_id, device_id, ts desc);
|
||||
|
||||
alter table public.telemetry enable row level security;
|
||||
|
||||
create policy telemetry_tenant_isolation on public.telemetry
|
||||
for select
|
||||
using (tenant_id = current_setting('app.tenant_id', true)::uuid);
|
||||
|
||||
grant select on public.telemetry to authenticated;
|
||||
grant insert on public.telemetry to gebos_ingest;
|
||||
Reference in New Issue
Block a user