MOTIR-147Done
2.7.7 Vitest — schema + default map + picker default-seeding + loader mapping + filter facet
Estimate: 50m · Depends on: 2.7.3, 2.7.4, 2.7.5, 2.7.6
Lock the whole type/executor model with tests over a real Postgres (the project convention; tests/helpers/db.ts truncates between tests; the only allowed vi.mock is getSession()). Cover every piece the story adds:
- The default map (2.7.3).
defaultExecutorForTypereturns the right executor for EVERY one of the ten enum members (a table test over the full enum — proves the TOTAL function has no hole and matches 2.7.2’s map:code/test/deploy→ coding_agent;manual/decision/review→ human; the four "either" types → coding_agent). - Schema + leaf-only enforcement (2.7.3). A leaf (task/subtask/bug) persists a
type+executor; settingtypeon an epic/story is rejected with the typed error;typedefaults to null on a row that omits it. - Picker default-seeding (2.7.4). The seeding logic: choosing a type yields the default executor (and an override sticks) — tested at the service/helper boundary the picker calls (not a DOM test; that’s 2.7.8’s E2E).
- Loader mapping (2.7.5). Seeding a fixture plan leaf with a
type/executorwrites the STRUCTURED fields (asserted via a repository read) and the resulting description contains NO "Type:" / "Executor:" prose; a leaf with a type but no executor gets the default; an unknown type string aborts with a clear error. - Filter facet (2.7.6). A FilterAST with
type = manualreturns exactly the manual leaves;type in (code, test)composes;type is nullreturns epics/stories/untyped; a saved-view round-trip preserves thetypepredicate; an unknown type value in an AST is rejected.
Acceptance criteria
- All the above pass over a real Postgres (no mocks beyond
getSession()); the default-map test iterates the FULL enum (a new member with no mapping would fail the suite). - The loader-mapping test asserts BOTH the structured fields are set AND the prose is absent (the regression guard for 2.7.5’s "stop emitting prose").
- New service/repo code (the leaf-only enforcement, the default helper, the filter translation) respects the per-file coverage gate (
motir-core/CLAUDE.md§ coverage) — every branch of the empty-input guards has a direct test.
Context refs
- 2.7.3 / 2.7.4 / 2.7.5 / 2.7.6 — everything under test.
motir-core/CLAUDE.md§ tests-use-real-Postgres + § coverage gate.motir-core/lib/services/workItemsService.ts+ the FilterAST translator — the units asserted against.