Add a `seed-demo` subcommand (cmd/seed_demo.go + internal/demoseed/) that inserts a fixed reference catalog into the member-console DB so the operator panel has rows to walk through for UX research. Catalog: 6 demo-* products (4 by product_type + 2 extra plans), 1 plan ladder with 3 tiers, 1 entitlement set with 2 rules (limit + boolean), and 1 grant on Alice's personal org (once she's logged in). Person rows for bob/carlos/diana are seeded via provisioning.AutoProvision keyed on the pinned Keycloak UUIDs — no longer fragile now that seed-keycloak.sh's partialImport switch preserves the pinned id. Alice is intentionally NOT pre-seeded so the lazy-creation OIDC flow stays exercised on every fresh stack. Idempotency: list+filter by `name` for catalog rows, by `oidc_subject` for persons. Re-running is a no-op for created rows; warns + skips the grant if alice hasn't logged in yet. Host-side invocation only — run `./test/seed-demo.sh` after bootstrap-stack.sh. Mirrors how member-console itself runs on the host (config + secrets live under test/). Two OpenSpec changes folded in: 2026-05-10-member-console-demo-seeder (the seeder) and 2026-05-11-demo-seeder-persons (the persons follow-up unlocked by the Keycloak fix).
Test Environment
This directory contains the Docker Compose setup and test data for local development.
LLM agents: read AGENTS.md first. All commands below are run from this
test/directory. If you are working in a git worktree alongside other worktrees of this repo, you must run./bootstrap-stack.shbeforedocker compose upto avoid host port collisions.
Quick Start
cd test
./bootstrap-stack.sh
docker compose up -d
set -a; . .env; set +a
go run .. start --config mc-config.yaml
Running multiple isolated stacks (parallel worktrees)
compose.yaml accepts per-stack overrides via .env. The
bootstrap-stack.sh helper generates one with a deterministic, collision-free
port allocation derived from the worktree's directory name. Run the four
Quick Start commands above in worktree A and worktree B — the two stacks
coexist on disjoint host ports under separate COMPOSE_PROJECT_NAME
namespaces.
To return a worktree to a clean state (containers + volumes + .env +
secrets/ + testdata/):
./teardown-stack.sh
See AGENTS.md for the full contract, including the Stripe webhook constraint when running stacks in parallel.
Services
| Service | URL | Credentials |
|---|---|---|
| Member Console | http://localhost:8081 | (via Keycloak) |
| Keycloak | http://keycloak.localhost:8080 | admin / admin |
| Temporal UI | http://localhost:8233 | (via Keycloak) |
| FedWiki | http://admin.localtest.me | (see mc-config.yaml) |
| PostgreSQL | localhost:5432 | member_console / member_console |
| Valkey | localhost:6379 | — |
Test Data
The testdata/ directory is named like that so that gopls can ignore it by default. It contains sample data for testing the Member Console, such as:
Keycloak
Keycloak state is managed declaratively via data/keycloak/master-realm.json. On every docker compose up, Keycloak imports this realm file into a fresh ephemeral H2 database — no persistent volume is needed.
The realm includes:
- Clients: fedwiki, member-console, temporal, temporal-ui
- Users: admin, litianmei, and service accounts
To update the realm config after making changes in the Keycloak admin UI:
docker compose stop keycloak
docker compose run --rm \
-v ./data/keycloak:/tmp/export \
keycloak export --dir /tmp/export --users realm_file
# This overwrites data/keycloak/master-realm.json
docker compose up -d keycloak
FedWiki
FedWiki runtime data lives in data/fedwiki/ (gitignored status/ dirs). Seed data for owner files and access tokens is committed in seed/fedwiki/.
A fedwiki-init container automatically copies seed files into data/fedwiki/ on docker compose up without overwriting existing files (cp -rn). This means:
- Fresh clone: seed data is copied in automatically, no manual steps needed.
- Existing setup: your local data is preserved.
To update seed data after making changes (e.g., new tokens or wiki sites):
# Copy the relevant files from data/fedwiki/ to seed/fedwiki/
cp data/fedwiki/<site>/status/owner.json seed/fedwiki/<site>/status/
cp data/fedwiki/<site>/status/user-access-tokens.json seed/fedwiki/<site>/status/