KeiSeiKit-1.0/skills/schema-design/phase-5-seed.md
Parfii-bot 0be354a920 KeiSeiKit-public — clean state
Single-commit clean baseline after security scrub of niche-tells,
project codenames, internal jargon, and contributor-email leaks.

Contents:
- 100 Rust crates (_primitives/_rust/)
- 37 agent manifests (_manifests/) + generated specs (_generated/)
- 67 user-invocable skills (skills/)
- 33 hooks (hooks/)
- Composition blocks (_blocks/)
- Documentation (docs/, README.md)
- TS adapter packages (_ts_packages/)
- Assembler (_assembler/)
- Roles (_roles/)
- Templates (_templates/)
- Forgejo CI (.forgejo/)

Author: Denis Parfionovich <info@greendragon.info>

License: see LICENSE.
2026-05-01 12:09:03 +08:00

92 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 5 — Optional seed data + test fixtures
Emit `db/seed.sql` with deterministic, safe-to-re-run seed rows, OR skip
this phase entirely. Single `AskUserQuestion` to decide.
## 5a — Seed decision (AskUserQuestion)
```json
{
"questions": [
{
"question": "Seed data for dev / tests?",
"header": "Seed",
"multiSelect": false,
"options": [
{"label": "Smoke fixture (1 row per entity)", "description": "Minimal — proves schema loads and FKs resolve. Recommended default."},
{"label": "Rich dev seed (520 rows per entity)", "description": "Realistic playground for local dev; deterministic IDs from a fixed seed"},
{"label": "Test fixtures only (for integration tests)", "description": "Small, labelled datasets keyed by test-case name"},
{"label": "Skip — no seed data", "description": "Schema-only delivery; tests will use mocks or runtime factories"}
]
}
]
}
```
Store as `SEED`.
## 5b — Generate `db/seed.sql` (inline, no AskUserQuestion)
Rules, regardless of choice (unless Skip):
- **Idempotent** — every `INSERT` uses `ON CONFLICT DO NOTHING` (PG/MySQL)
or `INSERT OR IGNORE` (SQLite). Re-running seed is safe.
- **Deterministic PKs** — use explicit IDs (`1`, `2`, ...) not relying on
sequences. For UUIDs, use fixed values from a documented seed (e.g.
`uuid_generate_v5(...)` or hard-coded dev-only UUIDs).
- **No secrets** — no real emails (use `user1@example.test`), no real
phone numbers, no real names. RULE 0.8 still applies: nothing in seed
should be or look like a production token.
- **Respect FK order** — insert parents before children, junctions last.
- **One file** — `db/seed.sql`. Not split per entity (ordering matters).
Smoke-fixture shape:
```sql
-- Generated by /schema-design Phase 5 — <YYYY-MM-DD>
-- Smoke fixture: one row per entity, deterministic IDs.
INSERT INTO users (id, email, name) VALUES (1, 'user1@example.test', 'Seed User')
ON CONFLICT (id) DO NOTHING;
INSERT INTO organizations (id, name) VALUES (1, 'Seed Org')
ON CONFLICT (id) DO NOTHING;
INSERT INTO organization_users (user_id, organization_id, role)
VALUES (1, 1, 'owner') ON CONFLICT DO NOTHING;
```
For "Rich dev seed" — use counted loops in SQL (PG: `generate_series`;
SQLite: recursive CTE; MySQL: `WITH RECURSIVE`) to produce 520 rows per
non-junction entity, with FK references wrapping modulo the parent count.
For "Test fixtures" — group by test name via SQL comments:
```sql
-- fixture: test_user_signup
INSERT INTO users (id, email, name) VALUES (101, 'signup@example.test', 'Signup') ...
-- fixture: test_org_invite
INSERT INTO users (id, email, name) VALUES (201, 'invitee@example.test', 'Invitee') ...
```
## 5c — Test-First hook (inline)
If `SEED ≠ Skip`, emit a smoke-test snippet tailored to `DB`:
```bash
# Smoke-test: load schema + seed, assert row counts.
kei-migrate --database-url "$DATABASE_URL" --dir migrations up
psql "$DATABASE_URL" -f db/seed.sql # or: sqlite3 <file> < db/seed.sql
psql "$DATABASE_URL" -c "SELECT count(*) FROM users;"
```
Remind the user: this is a smoke test, not a Test-First contract. Real
integration tests live in the project's test suite — see
`_blocks/rule-test-first.md`.
## Verify-criterion
- If `SEED = Skip`: `db/seed.sql` is NOT created; state records "seed
skipped".
- Otherwise: `db/seed.sql` exists, is idempotent, respects FK order, and
uses `@example.test` (or equivalent RFC 2606 reserved) emails only.
- Smoke-test snippet printed inline in chat (once).
- Final report can now be emitted (see `SKILL.md` index).