Add categories for motifs and entries #6
Labels
No labels
bug
duplicate
enhancement
future
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
rbrooks/TeaLeaves#6
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
It would be very handy to have categories for motifs and entries to make them easier to navigate.
Progress — building in 3 slices
Design (decided):
project_id NOT NULL), distinct from tags (which are user-scoped + freeform). Tags label; categories file.parent_idhierarchy can come later). User-created, with an optional#rrggbbcolor (also sets up the v6.2 #7 charts).✅ Slice 1 — data model + CRUD API — DONE (merged in #50)
api/src/db/migrations/040_categories.sql):categories(UNIQUE(project_id, name), optionalcolor) +entry_categories/motif_categoriesjunction tables (cascade both sides).api/src/routes/categories.ts:GET /api/categories(active-project scoped, returnsentry_count/motif_count),POST,PATCH(rename/recolor),DELETE. Hex color normalized (invalid → null),409on dup name, project-access checks on mutate. Mounted inapi/src/app.tsat/api/categories.api/src/test/integration/categories.test.ts(8).categoriesadded toclearEntryDatainhelpers.ts. Also fixedadmin.test.tsto assertgetInstalledVersion()instead of a hard-coded version.⬜ Slice 2 — assign categories on entries/motifs + display
category_ids: string[](replace-set into the junction tables, inside the existing write transaction); includecategories(id/name/color) in entry & motif read payloads.app/src/pages/Entries/EntryForm.tsxand the motif form; category badges (colored) onEntryCard,EntryDetailPage, motif list/detail. NewGET /api/categoriesalready provides the options list.⬜ Slice 3 — filter + management UI
category_id— extend the existing list query params (GET /api/entriesalready takes filters) and the filter panel UI.TagManagementcomponent.Resume notes (for a fresh machine)
main; verify on the dev server viassh docker-test(Node at$HOME/.nvm/versions/node/v24.14.1/bin). Test DB applies migrations on run; if the API suite shows cascading 429/"Too Many Requests" failures,docker exec tealeaves-redis-test-1 redis-cli FLUSHALL(rate-limit exhaustion, not a real failure).mainis green and deployed at v6.1.0; migration 040 is inmainbut not yet on the deployed image (no redeploy needed until the UI slices land).🤖 Tracked by Claude Code
✅ Slice 2 — assign categories on entries/motifs + display — DONE (merged in #51)
lib/categoryAssign.ts:applyCategories(project-contained replace-set intoentry_categories/motif_categories, audited by category name, no-ops on absent field),fetchCategoriesFor, andcategoriesJsonSql. Entry & motif create/update acceptcategory_ids: string[]; reads (entry list/detail, motif list/detail, entries-within-motif) includecategories(id/name/color) via a correlated subquery (no JOIN → no cartesian blow-up of the tag agg). Only ids in the owner's own project are applied (IDOR-safe); unknown/malformed ids are dropped.CategoryBadge(contrast-aware colored chip) +CategorySelect(multi-select with create-on-the-fly viaPOST /api/categories, mirroring the tag input). Wired intoEntryFormand the motif edit form; badges onEntryCard,EntryDetailPage,MotifListPage,MotifDetailPage(incl. entries-within).categoriesadded to theEntry/MotifSummary/MotifEntrytypes; public graph adapters + test fixtures updated.categoryAssign.test.ts). Verified on the dev server: 168 api / 63 app passing, both production builds green. CI green on #51./healthok,/api/categoriesgated (401 unauth).⬜ Slice 3 — filter + management UI (remaining)
category_id(extend existing list query params + filter panel).TagManagement.🤖 Tracked by Claude Code
✅ Slice 3 — filter + management UI — DONE (merged in #53). Feature complete.
GET /api/entriesandGET /api/motifsaccept a UUID-validated, parameterizedcategory_id.CategoryFilterSelecton the entry list, motif list, and timeline filter panel (timeline URL-synced); hidden when a project has no categories.All three slices merged, CHANGELOG updated for v6.2.0, deployed to the dev server (health ok, no errors). Closing — categories for entries & motifs is done. 🎉