Skip to content

Instantly share code, notes, and snippets.

@fer-ri
Created August 20, 2026 11:51
Show Gist options
  • Select an option

  • Save fer-ri/079c27d23ef224d6c2e9e644ad76e785 to your computer and use it in GitHub Desktop.

Select an option

Save fer-ri/079c27d23ef224d6c2e9e644ad76e785 to your computer and use it in GitHub Desktop.
Resolution: #26 typed category page (tabs, locked rows, client sort)

#26 — Typed category page: tabs, locked rows, client sort preference — RESOLVED

Commit 958e7b3 on main. All six acceptance criteria met.

What shipped

  • Tabs: Expense | Income | Debt/Loan (Tabs added to @repo/ui). "Create Category" entry point renders only under Expense/Income; Debt/Loan tab renders exactly the four locked system rows (Debt, Repayment, Loan, Debt Collection) read-only — no create/edit/delete affordances anywhere on them.
  • Typed create: createCategory stamps root type from the active tab (expense/income only — debt_loan rejected), children inherit their parent's type; UI never offers a type input. Shared rule lives in apps/web/lib/categories/category-type.ts (client lib throws; upload route rejects the op).
  • No drag: dnd-kit removed from the page. Display sort = Alphabetical | Most Used | Last Updated, computed client-side from local data (Most Used counts live transactions per category), persisted per-user in localStorage (expense-tracker:category-sort:<userId>).
  • Budgets picker: ORDER BY name — no dependency on the dropped sort_order column.
  • Upload route as authoritative write gate: category PUTs validate the claimed type against the tab/inheritance rule + parent ownership/aliveness; PATCHes reject type/is_system outright.

Tests

299/299 pass (pnpm --filter web exec vitest run), typecheck + lint clean. New coverage: type stamped on create, inheritance + mismatch rejection, debt_loan root rejection, sort preference ordering (alphabetical / most-used with tie-breaks / last-updated), Debt/Loan tab contents (exactly 4 rows, all is_system), localStorage read/fallback, shared rule unit tests.

Review notes

Two-axis code review done (Standards + Spec). Findings addressed: shared type rule deduplicated client/server, comparator naming, private storage key, diff churn removed. Known non-blockers: same-type enforcement on transaction category-move (server) not extended — beyond this ticket's ACs; "Most Used" counts include shared-wallet transactions (matches "computed from local data").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment