feat(categories): data model + CRUD API (#6, slice 1) #50

Merged
rbrooks merged 1 commit from feat/v6.2-categories-api into main 2026-06-26 02:20:56 +00:00
Owner

First of three slices for #6 — Categories for motifs & entries (v6.2). Backend foundation only; UI follows in slices 2–3.

Per the design sign-off: many categories per item (junction tables) and one shared set for both entries and motifs, project-scoped (distinct from user-scoped freeform tags).

Changes

  • Migration 040categories (project_id NOT NULLprojects ON DELETE CASCADE, UNIQUE(project_id, name), optional color), plus entry_categories and motif_categories junction tables (PK on the pair, cascade on both sides). Indexed for lookup by project and by category.
  • routes/categories.tsGET (active-project-scoped, with entry_count/motif_count), POST, PATCH (rename/recolor), DELETE. Hex color normalized to #rrggbb (invalid → null); 409 on duplicate name; mutate paths verify project access via canAccessProject. Mounted at /api/categories after requireAuth.
  • Added categories to the integration-test cleanup (helpers.ts).

Drive-by fix

admin.test.ts hard-coded the installed version as '6.0.0'; the v6.1.0 release bump broke it (it's currently red on main, since the release commit was pushed directly, bypassing PR CI). It now asserts against getInstalledVersion() — the same source the endpoint reads — so future version bumps won't break it.

Verification (dev server)

  • Migration 040 applies cleanly ([test] migration applied: 040_categories.sql)
  • API tsc build clean
  • 8 new category tests · full API suite green (158)

No CHANGELOG entry yet — categories aren't user-visible until the UI slices land; I'll add it when the feature is usable (and it'll roll into the v6.2.0 release notes).

🤖 Generated with Claude Code

First of three slices for **#6 — Categories for motifs & entries** (v6.2). Backend foundation only; UI follows in slices 2–3. Per the design sign-off: **many categories per item** (junction tables) and **one shared set** for both entries and motifs, **project-scoped** (distinct from user-scoped freeform tags). ## Changes - **Migration 040** — `categories` (`project_id NOT NULL` → `projects` ON DELETE CASCADE, `UNIQUE(project_id, name)`, optional `color`), plus `entry_categories` and `motif_categories` junction tables (PK on the pair, cascade on both sides). Indexed for lookup by project and by category. - **`routes/categories.ts`** — `GET` (active-project-scoped, with `entry_count`/`motif_count`), `POST`, `PATCH` (rename/recolor), `DELETE`. Hex color normalized to `#rrggbb` (invalid → null); `409` on duplicate name; mutate paths verify project access via `canAccessProject`. Mounted at `/api/categories` after `requireAuth`. - Added `categories` to the integration-test cleanup (`helpers.ts`). ## Drive-by fix `admin.test.ts` hard-coded the installed version as `'6.0.0'`; the **v6.1.0 release bump broke it** (it's currently red on `main`, since the release commit was pushed directly, bypassing PR CI). It now asserts against `getInstalledVersion()` — the same source the endpoint reads — so future version bumps won't break it. ## Verification (dev server) - Migration 040 applies cleanly (`[test] migration applied: 040_categories.sql`) - API `tsc` build clean ✅ - 8 new category tests ✅ · **full API suite green (158)** ✅ No CHANGELOG entry yet — categories aren't user-visible until the UI slices land; I'll add it when the feature is usable (and it'll roll into the v6.2.0 release notes). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(categories): data model + CRUD API (#6, slice 1)
All checks were successful
CI / App — typecheck, test & build (push) Successful in 1m22s
CI / API — typecheck & tests (push) Successful in 2m14s
CI / API — typecheck & tests (pull_request) Successful in 2m10s
CI / App — typecheck, test & build (pull_request) Successful in 1m15s
e25200e3f5
First slice of categories — a curated, per-project taxonomy for entries and
motifs (distinct from user-scoped freeform tags).

- Migration 040: `categories` (project-scoped, UNIQUE(project_id, name),
  optional hex color) + `entry_categories` / `motif_categories` junction
  tables (many-to-many, shared set across both entry and motif types).
- `routes/categories.ts`: list (active-project-scoped, with usage counts),
  create, PATCH (rename/recolor), delete. Hex color normalized/validated;
  409 on duplicate name; project-access checks on mutate.
- Mounted at /api/categories; categories added to test cleanup.

Also fixes admin.test.ts pinning the installed version to a literal
('6.0.0') — it now asserts against getInstalledVersion() so release bumps
don't break it (the v6.1.0 bump had).

8 new tests; full API suite green (158).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
rbrooks deleted branch feat/v6.2-categories-api 2026-06-26 02:20:57 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rbrooks/TeaLeaves!50
No description provided.