From d88bede09775f4d62c09f3c4db35c3a0c9c2b5c4 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Mon, 20 Apr 2026 16:18:07 +0200 Subject: [PATCH] chore(docker): seeder service pre-creates unprefixed 'admin' user row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alerting + outbound controllers resolve acting user via authentication.name with 'user:' prefix stripped → 'admin'. But UserRepository.upsert stores env-admin as 'user:admin' (JWT sub format). The resulting FK mismatch manifests as 500 'alert_rules_created_by_fkey' on any create operation in a fresh docker stack. Workaround: run-once 'cameleer-seed' compose service runs psql against deploy/docker/postgres-init.sql after the server is healthy (i.e. after Flyway migrations have created tenant_default.users), inserting user_id='admin' idempotently. The root-cause fix belongs in the backend (either stop stripping the prefix in alerting/outbound controllers, or normalise storage to the unprefixed form) and is out of scope for Plan 03. --- deploy/docker/postgres-init.sql | 41 +++++++++++++++++++++++++++++++++ docker-compose.yml | 19 +++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 deploy/docker/postgres-init.sql diff --git a/deploy/docker/postgres-init.sql b/deploy/docker/postgres-init.sql new file mode 100644 index 00000000..6bfc53fb --- /dev/null +++ b/deploy/docker/postgres-init.sql @@ -0,0 +1,41 @@ +-- Dev-stack seed: pre-create the `admin` user row without the `user:` prefix. +-- +-- Why: the UI login controller stores the local admin as `user_id='user:admin'` +-- (JWT `sub` format), but the alerting + outbound controllers resolve the FK +-- via `authentication.name` with the `user:` prefix stripped, i.e. `admin`. +-- In k8s these controllers happily insert `admin` because production admins are +-- provisioned through the admin API with unprefixed user_ids. In the local +-- docker stack there's no such provisioning step, so the FK check fails with +-- "alert_rules_created_by_fkey violation" on the first rule create. +-- +-- Seeding a row with `user_id='admin'` here bridges the gap so E2E smokes, +-- API probes, and manual dev sessions can create alerting rows straight away. +-- Flyway owns the schema in tenant_default; this script only INSERTs idempotently +-- and is gated on the schema existing. + +DO $$ +DECLARE + schema_exists bool; + table_exists bool; +BEGIN + SELECT EXISTS( + SELECT 1 FROM information_schema.schemata WHERE schema_name = 'tenant_default' + ) INTO schema_exists; + IF NOT schema_exists THEN + RAISE NOTICE 'tenant_default schema not yet migrated — skipping admin seed (Flyway will run on server start)'; + RETURN; + END IF; + + SELECT EXISTS( + SELECT 1 FROM information_schema.tables + WHERE table_schema = 'tenant_default' AND table_name = 'users' + ) INTO table_exists; + IF NOT table_exists THEN + RAISE NOTICE 'tenant_default.users not yet migrated — skipping admin seed'; + RETURN; + END IF; + + INSERT INTO tenant_default.users (user_id, provider, email, display_name) + VALUES ('admin', 'local', '', 'admin') + ON CONFLICT (user_id) DO NOTHING; +END $$; diff --git a/docker-compose.yml b/docker-compose.yml index 2b4420da..6f4ff657 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -130,6 +130,25 @@ services: retries: 10 restart: unless-stopped + # Run-once seeder: waits for the server to be healthy (i.e. Flyway migrations + # finished) and inserts a `user_id='admin'` row (without the `user:` prefix) + # so alerting-controller FKs succeed. See deploy/docker/postgres-init.sql for + # the full rationale. Idempotent — exits 0 if the row already exists. + cameleer-seed: + image: postgres:16 + container_name: cameleer-seed + depends_on: + cameleer-server: + condition: service_healthy + environment: + PGPASSWORD: cameleer_dev + volumes: + - ./deploy/docker/postgres-init.sql:/seed.sql:ro + entrypoint: ["sh", "-c"] + command: + - "psql -h cameleer-postgres -U cameleer -d cameleer -v ON_ERROR_STOP=1 -f /seed.sql" + restart: "no" + volumes: cameleer-pgdata: cameleer-chdata: