- 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.