chore(docker): seeder service pre-creates unprefixed 'admin' user row
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.
This commit is contained in:
41
deploy/docker/postgres-init.sql
Normal file
41
deploy/docker/postgres-init.sql
Normal file
@@ -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 $$;
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user