Card docs/backlog/10-seed-data.md · Milestone M2 · Blocked-by: M1 (PR #1)
Seed data is a deliverable, not a finishing chore: every demo of this app is only as convincing as the rows behind it, and the funnel chart and the calendar are both driven entirely from here.
Scope
src/data/demo-en/*.seed.ts, src/data/demo-zh/*.seed.ts, src/data/index.ts selecting by OS_SEED_LOCALE (default en); wire data in objectstack.config.ts. Load objectstack-data §Seed Data (defineSeed(), externalId, relationship references by natural key, dynamic CEL dates).
Spec — counts and shape per DESIGN.md §06
Dictionaries first (60 skills across the five categories; 15 credential types with realistic issuers and validity_months), then:
| Object |
Count |
Shape |
ats_employer |
12 |
Industries spread across the enum; 2 pending, 1 suspended. Each needs a platform organization and its members — see below. |
ats_job |
40 |
All statuses; 6 pending_review; 4 featured; plausible salary ranges per role |
ats_candidate |
80 |
Graded experience and skills |
ats_application |
200 |
Distributed exactly: applied 88 · screening 46 · interview 28 · offer 14 · hired 9 · rejected 15 |
ats_interview |
40 |
scheduled_at spread over the next 14 days from seed time — dynamic CEL, never fixed dates, or the calendar is empty a week later |
ats_offer |
14 |
3 pending_approval so the approval queue has something in it |
ats_report |
6 |
Mixed target types |
ats_candidate_credential |
30 |
5 expiring within 90 days, so is_expiring is exercised |
ats_employer_member |
12 × 1 admin + 1–2 recruiters |
|
Organizations are load-bearing. Each employer needs a platform organization and its staff as members: employer_org IN (current_user.accessible_org_ids) is the whole isolation model, and an employer whose org is missing shows zero rows to its own staff. Seed ats_employer.organization, the sys_organization row and the memberships together.
Fill display_name mirrors and the denormalised employer / employer_org / candidate_user fields explicitly — the stamp hooks run on writes, but a seed that depends on them is a seed that breaks silently if a hook changes.
demo-zh mirrors demo-en row for row with Chinese company, candidate and job names and cities. No real company or person names. No vertical-industry vocabulary in any object or field name — industries live only in these values.
avatar stays empty. Do not hot-link a placeholder service.
Acceptance
pnpm validate && pnpm lint && pnpm typecheck green; paste the three tails in the PR.
pnpm dev boots with the seed; the kanban shows the funnel shape; the calendar shows upcoming interviews.
OS_SEED_LOCALE=zh boots the Chinese set.
- Two employer accounts see disjoint pipelines — the check that proves the isolation model, and the one worth a screenshot.
Out of scope
Views, label translations (that is i18n, #9).
Card
docs/backlog/10-seed-data.md· Milestone M2 · Blocked-by: M1 (PR #1)Seed data is a deliverable, not a finishing chore: every demo of this app is only as convincing as the rows behind it, and the funnel chart and the calendar are both driven entirely from here.
Scope
src/data/demo-en/*.seed.ts,src/data/demo-zh/*.seed.ts,src/data/index.tsselecting byOS_SEED_LOCALE(defaulten); wiredatainobjectstack.config.ts. Loadobjectstack-data§Seed Data (defineSeed(),externalId, relationship references by natural key, dynamic CEL dates).Spec — counts and shape per
DESIGN.md§06Dictionaries first (60 skills across the five categories; 15 credential types with realistic issuers and
validity_months), then:ats_employerpending, 1suspended. Each needs a platform organization and its members — see below.ats_jobpending_review; 4 featured; plausible salary ranges per roleats_candidateats_applicationats_interviewscheduled_atspread over the next 14 days from seed time — dynamic CEL, never fixed dates, or the calendar is empty a week laterats_offerpending_approvalso the approval queue has something in itats_reportats_candidate_credentialis_expiringis exercisedats_employer_memberOrganizations are load-bearing. Each employer needs a platform organization and its staff as members:
employer_org IN (current_user.accessible_org_ids)is the whole isolation model, and an employer whose org is missing shows zero rows to its own staff. Seedats_employer.organization, thesys_organizationrow and the memberships together.Fill
display_namemirrors and the denormalisedemployer/employer_org/candidate_userfields explicitly — the stamp hooks run on writes, but a seed that depends on them is a seed that breaks silently if a hook changes.demo-zhmirrorsdemo-enrow for row with Chinese company, candidate and job names and cities. No real company or person names. No vertical-industry vocabulary in any object or field name — industries live only in these values.avatarstays empty. Do not hot-link a placeholder service.Acceptance
pnpm validate && pnpm lint && pnpm typecheckgreen; paste the three tails in the PR.pnpm devboots with the seed; the kanban shows the funnel shape; the calendar shows upcoming interviews.OS_SEED_LOCALE=zhboots the Chinese set.Out of scope
Views, label translations (that is i18n, #9).