- project_members (viewer/editor) makes a project + everything in it visible
to someone before they own anything there; editors can edit any task's
content/status in the project (not its list/project/assignment, which stay
owner/cap-gated) via a new loadEditable() alongside the existing
loadOwned/loadVisible.
- project_statuses lets a project define its own status pipeline instead of
the shared global one. Dropped the FK tasks.status had to the global
statuses table (a project-only value would violate it) and added a
task_statuses view that resolves each task's status against its project's
pipeline if it has one, else the global one -- this is also why new tasks
in a custom-pipeline project now default to that project's own first
non-done status instead of the hardcoded 'todo'.
- pinned_today column + GET /api/tasks?view=today no longer requires a due
date, so the frontend can show pinned/undated tasks there too.
Verified against a throwaway Postgres: 20 assertions covering nullable
list_id, pin, broadened today view, custom status default/resolution/
cross-project leakage, and the full viewer/editor/owner/stranger permission
matrix on a shared project.
Sharing (tag/assign/reallocate) is now a collapsed-by-default section in
the task drawer with a one-line summary, since it's a lesser-used function
that was eating space on every task.
list_id is now optional on task creation -- the task lands unfiled (same
state assign/reallocate already use), scoped only by project_id. Projects
are a cross-cutting grouping, not a list replacement, and the only way to
add a task to a project was previously to create it elsewhere and set the
Project field from the drawer. Added a "+ New task" input directly on
ProjectDetailView. Verified against a throwaway Postgres: unfiled creation,
distinct sort_order per unfiled task, project detail lists them, and
existing validation (bad list_id, missing title) still rejects.
- Backend: GET /api/tasks accepts ?search=, ILIKE on title/notes
- Generalized CategoryFilter into a reusable FilterChips component,
added ProjectFilter alongside it (both now on Board/List/Today)
- New Shared-with-me / Assigned-to-me nav views (FilteredListView),
surfacing the view=shared/view=assigned params that already existed
backend-side but had no UI
- Global debounced (300ms) search bar in the layout header, wired into
Board/List/Today/Dispatch's task fetches via SearchContext
Personal-first lists/tasks/reminders/recurrence, plus an admin-editable status
pipeline, shared categories, project containers, and a three-tier permission
model for cross-user work: assign (hand off your own tasks), reallocate
(dispatcher — move anyone's tasks), admin (reserved, full manage-all).