shipped

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 seed creates the demo org with six demo accounts (ceo/admin/sales/finance/ops/staff @demo.local, password demo123456) 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 role admin) is the F43 Admin HQ E2E identity and appears in both canonical demo-account tables.
    • make seed-reset wipes 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.ts suite. contracts/fixtures/F17-demo-seed.json is consumed by the split Playwright fixtures and asserted against the seeded database by F17.AC001.MANIFEST, so a seed rename requires a same-PR manifest and browser update.
  • 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_lumi management 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

#CaseTypeWhere
1Command runs and expected objects existbackendbackend/tests/api/test_scheduled_jobs.py::TestSeedCommand
2Reset-twice produces identical record counts + no errorbackendbackend/tests/platform/test_seed.py::TestSeedIdempotency
3Vietnamese content sniff test (VND, names, “công nợ”)backendbackend/tests/platform/test_seed.py::TestSeedIdempotency::test_seed_vietnamese_content
4Seed completeness: all features, evidence lineage, 6 accounts, briefbackendbackend/tests/platform/test_seed.py::TestSeedCompleteness
5Shared canonical fixture names match the seeded databasebackend/contracttests/platform/test_seed.py::TestSeedCompleteness::test_seed_names_match_shared_browser_manifest
6Whole split E2E suite runs against seede2efrontend/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 seed fails 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 seed before a concurrent make 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 migrate has not been run, make seed fails with a table-not-found error. The spec assumes make dev runs migrations first (per CLAUDE.md), but running make seed standalone 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)

#ClaimStatusEvidence
1make seed creates 6 demo accounts (ceo/admin/sales/finance/ops/staff @demo.local)✅ matchseed_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
2make seed-reset is idempotent — running twice produces identical counts, no errors✅ matchtests/test_seed.py::TestSeedIdempotency (reset-twice tests)
3Seed covers all features: projects, tasks (overdue + money-tagged), recurring, pulses, commitments/risks/decisions w/ EvidenceSource, a reusable sent web follow-up, brief✅ matchBug logs 2026-06-13 and 2026-07-16; TestSeedCompleteness::test_seed_covers_all_features; test_seed_creates_reusable_sent_follow_up_for_ceo
4Seed creates EvidenceSource before extraction so AI items carry evidence lineage✅ matchBug log 2026-06-13 fix note
5Vietnamese content: VND amounts, multi-word names, “công nợ” scenarios✅ matchTestSeedIdempotency::test_seed_vietnamese_content
6TestSeedCommand in backend/tests/api/test_scheduled_jobs.py✅ match§7 Test Plan; F17.AC001.HAPPY
7TestSeedIdempotency + TestSeedCompleteness in backend/tests/platform/test_seed.py✅ matchFocused F17 backend regression
8Root AGENTS.md resolves demo-account readers to the six-account source✅ matchcontracts/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.handle is wrapped in transaction.atomic, and TestSeedIdempotency.test_seed_rolls_back_all_writes_when_late_step_fails proves the induced-failure rollback boundary.
  • Stable-name contract enforcement — resolved: the shared F17 JSON manifest is asserted against the seeded database by F17.AC001.MANIFEST and 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.json as 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.ts monolith. Browser execution remains a separate explicit gap.

2026-07-16 — Seed command transaction boundary

Type: Reliability fix

Summary:

  • Wrapped seed_demo_lumi in 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 sent web follow-up assigned to ceo@demo.local, created by the demo admin, and backed by the existing CEO performance-review task.
  • The seed uses the production create_follow_up() and send_follow_up() services so source validation, snapshot shape, duplicate protection, and transition timestamps match real behavior without external delivery.
  • Added FollowUpRequest to 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-reset command 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.local added to the “Demo Accounts” table in CLAUDE.md and root AGENTS.md so 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-hq surface gated on is_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.py DEMO_EMAILS list (lines 22–29) has always had 6 entries: ceo/admin/sales/finance/ops/staff @demo.local.
  • staff@demo.local purpose: is_staff=True Django staff user, OrganizationMember.role="admin" in demo-org-A, seeded at line 106–145. Used exclusively by frontend/tests/e2e/admin-hq.spec.ts (test.describe('F43 Admin HQ')) to test the /admin-hq surface gated on is_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_features in backend/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_lumi command: pulse extraction now creates EvidenceSource records before calling extract_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-reset twice 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.