feat(seed): demo-msp template generator and committed template (PSA-51) #343

Merged
nrupard merged 2 commits from feat/PSA-51-demo-seed-template into main 2026-07-06 17:05:01 +02:00
Owner

Adds gen-demo-seed, a deterministic generator for the demo seed template the video needs (PSA-49), plus the committed bunyip-api/seed/demo-msp.json it produces. Load it with the PSA-50 loader to populate every admin and member surface:

BUNYIP_SEED_ALLOW=true ENVIRONMENT=development seed import bunyip-api/seed/demo-msp.json

Deterministic by construction

The generator is a pure function of fixed input data (name pools, app catalog, index-driven status/tier assignment) with no RNG and no clock, so its output is byte-stable: re-running regenerates an identical file. It only writes JSON; it never touches a database.

demo-msp contents

  • 3 groups (Core / Add-ons / Beta) and 8 apps (2 restricted, entitlement-gated).
  • 42 users under @demo.psa-systems.test sharing one password: 2 admins, 3 lifetime, 3 past-due, 2 grace, 2 canceled, 3 no-membership, the rest active; 12 early-adopter price-locked; 2 unverified.
  • 6 entitlement grants for the restricted apps.
  • A 7-entry support inbox including one obvious spam.

(No per-user created_at: the schema has no such field, so seeded users take the loader's insert time. Noted as a limitation - a future schema addition could spread signups.)

Tests (run in the gate, no DB)

  • committed_template_is_up_to_date: the committed demo-msp.json exactly equals the generator's output, so an edit to the generator without regenerating fails CI.
  • generated_template_parses_and_validates: the template parses and validates against the real PSA-50 schema, with the expected section counts and distributions (42 users, 8 apps, 3 groups, 6 entitlements, 7 feedback, 3 lifetime, 12 price-locked, 2 admins, 1 spam).

Verification

just check-container green (fmt + clippy -D warnings + cargo test --workspace --all-targets).

Stacking

Stacked on the PSA-50 branch (feat/PSA-50-seed-import-foundation) because it uses seed::parse. Base this PR on that branch; it retargets to main once PSA-50 (#342) merges.

Fixes PSA-51.

Adds `gen-demo-seed`, a deterministic generator for the demo seed template the video needs (PSA-49), plus the committed `bunyip-api/seed/demo-msp.json` it produces. Load it with the PSA-50 loader to populate every admin and member surface: ``` BUNYIP_SEED_ALLOW=true ENVIRONMENT=development seed import bunyip-api/seed/demo-msp.json ``` ## Deterministic by construction The generator is a pure function of fixed input data (name pools, app catalog, index-driven status/tier assignment) with no RNG and no clock, so its output is byte-stable: re-running regenerates an identical file. It only writes JSON; it never touches a database. ## demo-msp contents - 3 groups (Core / Add-ons / Beta) and 8 apps (2 restricted, entitlement-gated). - 42 users under `@demo.psa-systems.test` sharing one password: 2 admins, 3 lifetime, 3 past-due, 2 grace, 2 canceled, 3 no-membership, the rest active; 12 early-adopter price-locked; 2 unverified. - 6 entitlement grants for the restricted apps. - A 7-entry support inbox including one obvious spam. (No per-user `created_at`: the schema has no such field, so seeded users take the loader's insert time. Noted as a limitation - a future schema addition could spread signups.) ## Tests (run in the gate, no DB) - `committed_template_is_up_to_date`: the committed `demo-msp.json` exactly equals the generator's output, so an edit to the generator without regenerating fails CI. - `generated_template_parses_and_validates`: the template parses and validates against the real PSA-50 schema, with the expected section counts and distributions (42 users, 8 apps, 3 groups, 6 entitlements, 7 feedback, 3 lifetime, 12 price-locked, 2 admins, 1 spam). ## Verification `just check-container` green (fmt + clippy `-D warnings` + `cargo test --workspace --all-targets`). ## Stacking Stacked on the PSA-50 branch (`feat/PSA-50-seed-import-foundation`) because it uses `seed::parse`. Base this PR on that branch; it retargets to main once PSA-50 (#342) merges. Fixes PSA-51.
feat(seed): demo-msp template generator and committed template (PSA-51)
Some checks failed
E2E / Playwright against deployment (pull_request) Successful in 27s
Check / fmt + clippy + build + tests (pull_request) Has been cancelled
d4589e3331
Adds `gen-demo-seed`, a deterministic generator for the demo seed template the video needs, plus the committed `bunyip-api/seed/demo-msp.json` it produces. Load it with the PSA-50 loader (`seed import bunyip-api/seed/demo-msp.json`) to populate every admin and member surface.

The generator is a pure function of fixed input data (names, app catalog, index-driven status/tier assignment) with no RNG or clock, so the output is byte-stable: re-running regenerates an identical file. It only writes JSON; it never touches a database.

demo-msp contents: 3 groups (Core / Add-ons / Beta) and 8 apps (2 restricted); 42 users under @demo.psa-systems.test sharing one password - 2 admins, 3 lifetime, 3 past-due, 2 grace, 2 canceled, 3 no-membership, the rest active, 12 early-adopter price-locked, 2 unverified; 6 entitlement grants for the restricted apps; a 7-entry support inbox including one obvious spam.

Tests (run in the gate, no DB needed): the committed file exactly equals the generator's output (so an un-regenerated edit fails), and the template parses + validates against the real PSA-50 schema with the expected section counts and distributions.

Verified: just check-container green (fmt + clippy -D warnings + cargo test --workspace --all-targets).

Stacked on the PSA-50 branch (it uses `seed::parse`); retargets to main once PSA-50 merges.

#PSA-51
fix(seed): keep demo admins off member tiers; note key-order determinism
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 27s
Check / fmt + clippy + build + tests (pull_request) Successful in 18m41s
Create release / Create release from merged PR (pull_request) Has been skipped
b0e451d920
Review follow-ups on the demo-msp generator.

- Admin demo accounts are now seeded with no membership (status none, tier free) instead of falling into the "first 12 active" price-locked early-adopter cohort. Staff accounts reading as price-locked paying members was unrealistic on the admin members list. The `status == "active"` gate now excludes them from price-lock automatically. Distributions still hold: 3 lifetime, 12 price-locked (all subscribers now), 2 admins.
- Added a comment documenting that byte-stability also relies on serde_json's default (sorted) key order, and that the committed-template test fails loudly if that ever drifts (e.g. if `preserve_order` is enabled), so a needed regeneration can never go unnoticed.

Regenerated demo-msp.json accordingly.

Verified: just check-container green (fmt + clippy -D warnings + cargo test --workspace --all-targets).

#PSA-51
nrupard scheduled this pull request to auto merge when all checks succeed 2026-07-06 16:48:52 +02:00
nrupard deleted branch feat/PSA-51-demo-seed-template 2026-07-06 17:05:01 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!343
No description provided.