feat(seed): embedded template library + import-by-name (PSA-57 part 1) #346

Merged
nrupard merged 4 commits from feat/PSA-57-template-library into main 2026-07-06 20:08:11 +02:00
Owner

The API half of Yousif's first-run setup choices: an embedded template library and load-by-name. The web setup panel + the empty-instance dashboard prompt land in part 2.

What's here

  • SeedTemplate registry (SEED_TEMPLATES): each template's JSON is compiled in via include_str!, so a template is always available without a filesystem path. Ships demo-msp (PSA-51) and a new minimal template (the app catalog + a few users, no bulk volume). find_template(name) resolves one.
  • GET /v1/admin/seed/templates (AdminUser): each template's name, description, and section counts, for the setup picker. A malformed embedded template is skipped rather than 500-ing the list; a test asserts every one parses.
  • POST /v1/admin/seed/import?template=<name> loads the named embedded template through the shared loader instead of the request body; an unknown name is a 400. The body path is unchanged.

Tests

Every embedded template parses + validates; find_template resolves known names and rejects unknown; the minimal template is a small baseline (3 users, 2 groups, 3 apps, no feedback/entitlements, 1 admin).

Verification

just check-container green (fmt + clippy -D warnings + cargo test --workspace --all-targets; seed lib 57 tests incl. the 3 new). Endpoint wiring is compile/clippy-checked; the DB load path runs against a dev database.

AC status (this PR)

Covered: embedded demo-msp + minimal templates, GET /templates, import-by-name with unknown-name 400, the minimal template + its validation, template-list test (ACs 1-3 + part of 6). Open in part 2: the /admin/seed setup panel (start empty / load template / custom) and the empty-catalog dashboard prompt (ACs 4-5).

Part 2 (follow-up)

The /admin/seed setup panel and the dashboard prompt linking to it when the app catalog is empty.

#PSA-57

The API half of Yousif's first-run setup choices: an embedded template library and load-by-name. The web setup panel + the empty-instance dashboard prompt land in part 2. ## What's here - **`SeedTemplate` registry** (`SEED_TEMPLATES`): each template's JSON is compiled in via `include_str!`, so a template is always available without a filesystem path. Ships `demo-msp` (PSA-51) and a new `minimal` template (the app catalog + a few users, no bulk volume). `find_template(name)` resolves one. - **`GET /v1/admin/seed/templates`** (AdminUser): each template's name, description, and section counts, for the setup picker. A malformed embedded template is skipped rather than 500-ing the list; a test asserts every one parses. - **`POST /v1/admin/seed/import?template=<name>`** loads the named embedded template through the shared loader instead of the request body; an unknown name is a 400. The body path is unchanged. ## Tests Every embedded template parses + validates; `find_template` resolves known names and rejects unknown; the `minimal` template is a small baseline (3 users, 2 groups, 3 apps, no feedback/entitlements, 1 admin). ## Verification `just check-container` green (fmt + clippy `-D warnings` + `cargo test --workspace --all-targets`; seed lib 57 tests incl. the 3 new). Endpoint wiring is compile/clippy-checked; the DB load path runs against a dev database. ## AC status (this PR) Covered: embedded `demo-msp` + `minimal` templates, `GET /templates`, import-by-name with unknown-name 400, the `minimal` template + its validation, template-list test (ACs 1-3 + part of 6). Open in part 2: the `/admin/seed` setup panel (start empty / load template / custom) and the empty-catalog dashboard prompt (ACs 4-5). ## Part 2 (follow-up) The `/admin/seed` setup panel and the dashboard prompt linking to it when the app catalog is empty. #PSA-57
feat(seed): embedded template library + import-by-name (PSA-57 part 1)
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 24s
Check / fmt + clippy + build + tests (pull_request) Successful in 9m34s
5c2384de5f
The API half of the first-run setup choices. Embeds a named template library and lets an admin load one by name; the web setup panel and the empty-instance dashboard prompt land in part 2.

- `SeedTemplate` registry (`SEED_TEMPLATES`): each template's JSON is compiled in via `include_str!`, so a template is always available without a filesystem path. Ships `demo-msp` (PSA-51) and a new `minimal` (the app catalog + a few users, no bulk volume) template. `find_template(name)` looks one up.
- `GET /v1/admin/seed/templates` (AdminUser): lists each template's name, description, and section counts for the setup picker. A malformed embedded template is skipped rather than 500-ing the list; a test asserts every one parses, so that never happens in practice.
- `POST /v1/admin/seed/import?template=<name>` loads the named embedded template through the shared loader instead of the request body; an unknown name is a 400. The body path is unchanged.

Tests: every embedded template parses + validates; `find_template` resolves known names and rejects unknown; the `minimal` template is a small baseline (3 users, 2 groups, 3 apps, no feedback/entitlements, 1 admin).

Verified: just check-container green (fmt + clippy -D warnings + cargo test --workspace --all-targets; seed lib 57 tests incl. the 3 new). The endpoint wiring is compile- and clippy-checked; the DB load path runs against a dev database.

Part 2 (follow-up): the `/admin/seed` setup panel (start empty / load a named template / custom upload) and the dashboard prompt linking to it when the app catalog is empty.

#PSA-57
Merge remote-tracking branch 'origin/main' into feat/PSA-57-template-library
Some checks failed
E2E / Playwright against deployment (pull_request) Successful in 28s
Check / fmt + clippy + build + tests (pull_request) Has been cancelled
5494c42b45
# Conflicts:
#	bunyip-api/src/seed.rs
fix(seed): declare owns on the minimal template and drop the orphan restricted app
Some checks failed
E2E / Playwright against deployment (pull_request) Successful in 36s
Check / fmt + clippy + build + tests (pull_request) Has been cancelled
eb77d7e2a2
Review follow-ups on PSA-57 part 1, aligning with PSA-56 (now merged).

- The `minimal` template now declares `owns: {domains: ["demo.psa-systems.test"]}` explicitly, matching demo-msp and the PSA-56 convention that every seed file declares its own reclaim scope, instead of leaning on the effective_owns() default.
- Dropped `restricted: true` on the `vault` app. With no entitlements in the minimal template, a restricted app is invisible to every seeded user; a baseline should not ship an app nobody can open. It is now a plain add-on visible to all.

Verified: just check-container green (seed lib 64 tests; the minimal-template shape test still holds - owns and restricted do not change the section counts).

#PSA-57
feat(admin-web): first-run setup panel and empty-catalog prompt (PSA-57 part 2)
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 25s
Check / fmt + clippy + build + tests (pull_request) Successful in 8m42s
Create release / Create release from merged PR (pull_request) Has been skipped
2183539d91
The web half of the first-run setup choices, on top of part 1's template API.

- The /admin/seed page gains a "Set up this environment" card: it lists the embedded templates (name, description, section counts from GET /v1/admin/seed/templates) and offers a "Load <name>" button for each. Starting empty is the do-nothing default; loading a template is idempotent and demo-domain-scoped, so it only ever adds or refreshes demo rows. The existing export and paste-import cards are unchanged.
- New POST /admin/seed/template handler forwards the chosen name to the API loader (POST /v1/admin/seed/import?template=<name>) and reports the section counts (or the error) back on the page, mirroring the paste-import flow.
- The admin dashboard shows an empty-catalog prompt linking to /admin/seed when it positively knows the catalog is empty (stats fetched and zero applications), so a fresh instance is nudged toward setup. The prompt is suppressed when the stats call fails, to avoid a misleading banner.
- API client: `seed_templates` (GET) and `import_seed_template` (POST with the name as `?template=`, no body); `SeedTemplateInfo` type.

Verified: just check-container green (fmt + clippy -D warnings + cargo test --workspace --all-targets; bunyip-web bin compiles + tests pass). The handlers and API wiring are compile- and clippy-checked; the rendered page and the live template-load round trip run against a dev stack.

This completes PSA-57 (AC 4-5); part 1 covered the template API (AC 1-3).

#PSA-57
nrupard deleted branch feat/PSA-57-template-library 2026-07-06 20:08:11 +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!346
No description provided.