Spec: F17 — Demo Seed Data
Status: shipped · Audited: 2026-07-19 · Contract: partial; see F17 seed audit
1. Problem & CEO Job
Internal feature, external job: the demo is the sales pitch. A CEO evaluating Lumi must see believable Vietnamese SME data — named people, real-sounding customers, overdue debts, a waiting decision — not “Test Task 1”. As the substrate for E2E tests and screenshots, seed stability is a test contract.
2. User Stories & Acceptance Criteria
- As a salesperson/developer, I want one command to produce a living demo org, so that any environment can demo in seconds.
-
make seedcreates the demo org with six demo accounts (ceo/admin/sales/finance/ops/staff @demo.local, passworddemo123456) and data across every feature: projects, tasks (some overdue, some money-tagged), recurring templates, submitted pulses, extracted commitments/risks/decisions with evidence, a generated brief.staff@demo.local(is_staff=True, org roleadmin) is the F43 Admin HQ E2E identity and appears in both canonical demo-account tables. -
make seed-resetwipes and reseeds idempotently — running twice never duplicates or errors.
-
- As the E2E suite, I want stable names, so that assertions don’t flake.
- Renaming browser-stable seeded objects is a breaking change to the split
lumi.part*.spec.tssuite.contracts/fixtures/F17-demo-seed.jsonis consumed by the split Playwright fixtures and asserted against the seeded database byF17.AC001.MANIFEST, so a seed rename requires a same-PR manifest and browser update.
- Renaming browser-stable seeded objects is a breaking change to the split
- Demo content is native Vietnamese (real name patterns, VND amounts, “công nợ” scenarios) — it must pass a Vietnamese founder’s sniff test.
3. Scope Boundaries
- In:
seed_demo_lumimanagement command, demo accounts, full-feature data coverage, reset. - Out: multi-org seed scenarios, anonymized-production import, load-test data volumes.
4. Data Model
None — writes existing models only, through the same code paths as real usage where practical (so seed exercises real logic).
5. API Contract
None. CLI: make seed, make seed-reset.
6. UI / UX
Indirect: every screenshot in frontend/screenshots/ renders seed data — the seed is the product’s portfolio. Thin or fake-looking data here makes every visual audit lie.
7. Test Plan
| # | Case | Type | Where |
|---|---|---|---|
| 1 | Command runs and expected objects exist | backend | backend/tests/api/test_scheduled_jobs.py::TestSeedCommand |
| 2 | Reset-twice produces identical record counts + no error | backend | backend/tests/platform/test_seed.py::TestSeedIdempotency |
| 3 | Vietnamese content sniff test (VND, names, “công nợ”) | backend | backend/tests/platform/test_seed.py::TestSeedIdempotency::test_seed_vietnamese_content |
| 4 | Seed completeness: all features, evidence lineage, 6 accounts, brief | backend | backend/tests/platform/test_seed.py::TestSeedCompleteness |
| 5 | Shared canonical fixture names match the seeded database | backend/contract | tests/platform/test_seed.py::TestSeedCompleteness::test_seed_names_match_shared_browser_manifest |
| 6 | Whole split E2E suite runs against seed | e2e | frontend/tests/e2e/lumi.part*.spec.ts |
The repository backend coverage gate is ≥97%; the shared manifest gate is deterministic, while the whole split browser suite remains the separate runtime proof.
8. Current Behavior
Shipped. make seed creates a reproducible demo org for local development and demos. make seed-reset wipes and reseeds idempotently. The seed data is the substrate for all 65+ E2E tests — stable object names are a test contract.
9. Error States
- Database connection failure.
make seedfails with a connection error if the database is unreachable. The CLI has no retry logic; the user sees the raw Django/psycopg error message. - Duplicate key on reset race. If a second shell runs
make seedbefore a concurrentmake seed-reset’s teardown completes, a unique-key collision (duplicate email, duplicate org slug) may occur. No lock or serialization is documented. - Migration missing during seed. If
make migratehas not been run,make seedfails with a table-not-found error. The spec assumesmake devruns migrations first (per CLAUDE.md), but runningmake seedstandalone without prior migrations is not handled. - Seed fails mid-write. The command wraps its reset/create phase in
transaction.atomic; an induced late failure rolls back the demo organizations and users. External systems or writes performed outside the database transaction are not claimed by this fixture boundary. - Password change invalidates demo accounts. If
ceo@demo.local’s password is changed manually after seed, subsequent E2E runs may fail login assertions — the seed does not force-reset passwords for existing accounts on re-run. - Locale mismatch in test assertions. Browser-stable entity names come from the shared F17 manifest, but localized interface copy remains owned by the locale catalogs and browser environment rather than this seed contract.
10. Diagrams & Docs Touched
Keep the human-readable README demo accounts and the
machine-owned F17-demo-seed.json manifest in
sync with the command; root AGENTS.md links to these owners rather than duplicating the table.
11. Implementation Audit (2026-06-14)
| # | Claim | Status | Evidence |
|---|---|---|---|
| 1 | make seed creates 6 demo accounts (ceo/admin/sales/finance/ops/staff @demo.local) | ✅ match | seed_demo_lumi.py DEMO_EMAILS has 6 entries; staff@demo.local is is_staff=True, org role admin, used by F43 Admin HQ E2E; F17.AC001.MANIFEST asserts all six identities, names, and roles |
| 2 | make seed-reset is idempotent — running twice produces identical counts, no errors | ✅ match | tests/test_seed.py::TestSeedIdempotency (reset-twice tests) |
| 3 | Seed covers all features: projects, tasks (overdue + money-tagged), recurring, pulses, commitments/risks/decisions w/ EvidenceSource, a reusable sent web follow-up, brief | ✅ match | Bug logs 2026-06-13 and 2026-07-16; TestSeedCompleteness::test_seed_covers_all_features; test_seed_creates_reusable_sent_follow_up_for_ceo |
| 4 | Seed creates EvidenceSource before extraction so AI items carry evidence lineage | ✅ match | Bug log 2026-06-13 fix note |
| 5 | Vietnamese content: VND amounts, multi-word names, “công nợ” scenarios | ✅ match | TestSeedIdempotency::test_seed_vietnamese_content |
| 6 | TestSeedCommand in backend/tests/api/test_scheduled_jobs.py | ✅ match | §7 Test Plan; F17.AC001.HAPPY |
| 7 | TestSeedIdempotency + TestSeedCompleteness in backend/tests/platform/test_seed.py | ✅ match | Focused F17 backend regression |
| 8 | Root AGENTS.md resolves demo-account readers to the six-account source | ✅ match | contracts/fixtures/F17-demo-seed.json declares all six identities; README.md renders the human-readable table; root AGENTS.md links to those owners instead of copying account data |
Gaps flagged:
- Partial-write atomicity — resolved:
Command.handleis wrapped intransaction.atomic, andTestSeedIdempotency.test_seed_rolls_back_all_writes_when_late_step_failsproves the induced-failure rollback boundary. - Stable-name contract enforcement — resolved: the shared F17 JSON manifest is asserted against the seeded database by
F17.AC001.MANIFESTand consumed by the split Playwright fixtures.
12. Open Questions / Decisions
- None outstanding. (Previous open questions resolved by 2026-06-13 seed-completeness work.)
13. Bug / Change Log
2026-08-07 — Move demo-account ownership out of root AGENTS.md
Type: Documentation ownership correction
Summary:
- Kept the F17 fixture manifest and README table as the machine-readable and human-readable owners.
- Replaced the root guide’s duplicate account snapshot with links to those sources.
Impact:
- No seed or credential change; future account changes have one fewer mutable copy to synchronize.
2026-07-19 — Shared stable-name manifest
Type: Test + contract repair
Summary:
- Added
contracts/fixtures/F17-demo-seed.jsonas the canonical set of browser-stable demo identities and fixture names. - Added
F17.AC001.MANIFEST, which seeds the database and checks every declared identity/name is present; derived AI records may add rows but cannot replace canonical fixtures. - Updated the split Playwright fixtures to consume the same manifest for demo credentials and representative Commitment, Risk, Team, and Company assertions.
- Corrected stale references to the removed
lumi.spec.tsmonolith. Browser execution remains a separate explicit gap.
2026-07-16 — Seed command transaction boundary
Type: Reliability fix
Summary:
- Wrapped
seed_demo_lumiin a database transaction so a late failure cannot leave partial demo organizations or users. - Added an induced-failure rollback proof and registered
F17.AC001.ATOMIC.
2026-07-16 — Seed one reusable sent follow-up for INT-07
Type: Test + Fix
Summary:
- Added a focused red/green seed regression requiring one tenant-scoped
sentweb follow-up assigned toceo@demo.local, created by the demo admin, and backed by the existing CEO performance-review task. - The seed uses the production
create_follow_up()andsend_follow_up()services so source validation, snapshot shape, duplicate protection, and transition timestamps match real behavior without external delivery. - Added
FollowUpRequestto reset-twice record counts. The emulator flow cancels its dialog, leaving this fixture reusable.
Tests:
backend/tests/platform/test_seed.py::TestSeedCompleteness::test_seed_creates_reusable_sent_follow_up_for_ceo.
2026-07-14 — Contract Graph ownership and honest seed boundaries
Type: Verification
Summary:
- Added the F17 CUE contract for the
make seed/make seed-resetcommand boundary and its backend proof suite. - Made the unexecuted browser compatibility claim, command-level atomicity, and stable-name enforcement explicit blocking gaps.
Impact:
- F17 is no longer represented as an unqualified shipped row while its operational and E2E evidence remain incomplete.
2026-07-02 — Add staff@demo.local to canonical CLAUDE.md/AGENTS.md demo-account tables
Type: Documentation Fix
Summary:
staff@demo.localadded to the “Demo Accounts” table inCLAUDE.mdand rootAGENTS.mdso the canonical tables match the seed command.- Account details: password
demo123456,OrganizationMember.role="admin",is_staff=True. Used by F43 Admin HQ E2E tests (frontend/tests/e2e/admin-hq.spec.ts) to access the/admin-hqsurface gated onis_staff=True. - §11 row 8 updated from ⚠️ partial to ✅ match.
- Prior 2026-07-02 log entry below noted this account was “correctly omitted” — that decision is superseded; including it keeps the developer-facing reference complete.
2026-07-02 — Correct demo account count: 5→6, document staff@demo.local (batch-2 spec audit)
Type: Documentation Fix
Summary:
- §2 AC and §11 row 1: corrected “five demo accounts” to six.
seed_demo_lumi.pyDEMO_EMAILSlist (lines 22–29) has always had 6 entries:ceo/admin/sales/finance/ops/staff @demo.local. staff@demo.localpurpose:is_staff=TrueDjango staff user,OrganizationMember.role="admin"in demo-org-A, seeded at line 106–145. Used exclusively byfrontend/tests/e2e/admin-hq.spec.ts(test.describe('F43 Admin HQ')) to test the/admin-hqsurface gated onis_staff=True. It is correctly omitted from the public CLAUDE.md/AGENTS.md demo-account table (not a product-facing role). §11 row 8 stale drift note corrected: both CLAUDE.md and AGENTS.md now list 5 (not 4 and 5 respectively).- §7 row 4 updated to say 6 accounts.
2026-06-14 — Restructure to TEMPLATE.md section order (SP fleet)
Type: Documentation Change
Summary:
- Renumbered all sections to match TEMPLATE.md (§8 Current Behavior, §9 Error States, §10 Diagrams, §11 Implementation Audit, §12 Open Questions, §13 Bug / Change Log).
- Expanded §11 from 1-line verdict to 8-row audit table.
- Absorbed edge cases into §11 gaps and §9 error states.
Reason:
- Section order was non-standard — §12 was Error States, §9 was thin audit.
Impact:
- No behavior change. Spec more useful as audit reference.
Tests:
- No code changes.
2026-06-13 — Verified seed completeness across every feature (C-r29)
Type: Test + Fix
Summary:
- Created
TestSeedCompleteness::test_seed_covers_all_featuresinbackend/tests/test_seed.py— asserts all 5 demo accounts with correct roles, at least one Project/Task (overdue)/Task (money-tagged)/RecurringTemplate, submitted pulses, Commitments/Risks/DecisionRequests each with linked EvidenceSource, and a generated Brief. - Fixed
seed_demo_lumicommand: pulse extraction now createsEvidenceSourcerecords before callingextract_pulse_entry, so AI-extracted commitments/risks/decisions carry evidence lineage. - Checked off
[x]for §2 “every feature” AC. - Updated §7 Test Plan table with new test.
- Verified
make seed-resettwice produces identical record counts with zero errors. - Confirmed seed data passes Vietnamese founder’s sniff test: VND amounts, multi-word Vietnamese names, “công nợ” scenarios.
Tests:
tests/test_seed.py— 3 tests (reset-twice identical counts, reset-twice no error, Vietnamese content sniff).
2026-06-12 — Added Edge Cases and Error States sections (CMD fleet agent D, round 11)
Type: Documentation Change
Summary:
- Added Edge Cases, Error States, and changelog section.