fix(seed): allow 'seed' entitlement source so demo templates load (PMS-709) #438
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/PMS-709-seed-entitlement-source"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
PMS-709: Demo MSP seed load does nothing on staging
Failure point (traced from the button)
The admin "Load demo-msp" / "Load minimal" buttons (bunyip-web
/admin/seed) POST to/admin/seed/template-> APIPOST /v1/admin/seed/import?template=<name>->crate::seed::load. The load ran fine through groups, applications and users, then failed at the entitlements step:EntitlementRepository::grant(pool, user.id, app.id, None, "seed")insertssource = 'seed', but theapplication_entitlements_source_checkconstraint (from migration 20260605000010) only permitted'admin' | 'stripe' | 'backfill'. Every insert hit a check-constraint violation (SQLSTATE 23514).Why it looked silent: the shared
AppErrorFrom<sqlx::Error>logs the real error (constraint name and all) but collapses the API-facing message to the generic "A database error occurred", so the admin saw at most an unhelpful 500 and the specific cause was only in bunyip-api's logs. And becauseseed::loadis not transactional, the 3 groups + 8 apps + 42 users written before the failing step persisted as a partial seed with no entitlements and no feedback.Reproduced against a migrated throwaway Postgres:
load()returnedErr(Db(DatabaseError { message: "A database error occurred" }))withapplication_groups=3, applications=13, users=42, application_entitlements=0, feedback=0. The direct insert surfaced the true error:violates check constraint "application_entitlements_source_check".Fix
20260802000010_allow_seed_entitlement_source.sqlwidens the constraint to('admin','stripe','backfill','seed'). Non-destructive: every existing row already carries a now-permitted value, so re-adding the constraint validates cleanly; the constraint name is preserved.entitlement_source::SEEDconstant added so the loader stops passing a bare literal, matching the other call sites (ADMIN/STRIPE).bunyip-api/tests/pms709_repro.rs) that migrates a throwaway DB and asserts the whole documented demo-msp dataset loads (42 users, 8 apps, 3 groups, 6 entitlements, 7 feedback) with the 6 entitlements atsource='seed', plus idempotent re-load.Verification
Against a fresh database (sqlx applies all migrations including the new one),
seed::load(demo-msp)returnsLoadSummary { groups: 3, applications: 8, users: 42, entitlements: 6, feedback: 7 }.justmigration-immutability and migration-version checks,cargo fmt --check, andclippy -D warningson the touched crates all pass. Not yet run against live staging; that verification is the remaining acceptance item once this deploys.Notes / follow-ups (out of scope here)
dunite-coreAppErrorand is a deliberate posture (don't leak DB internals in API responses); the real error is logged. Making the admin-facing seed failure message specific would be a dunite-side change.seed::loadis not transactional, so a mid-load failure leaves a partial seed. Worth wrapping in a single transaction, but it touches many repository signatures and is left as a separate change.