
The problem
A task app for one person is a list. A task app for a team is an authorisation problem wearing a list's clothing. The moment two people share a workspace, every read and every write has to answer who is allowed to do this, and getting that wrong is the difference between a tool and a liability.
What I built
Permissions are modelled as four roles (Owner, Admin, Member, Viewer) scoped to a workspace rather than to the account. A user is not globally an admin; they hold a role in a particular workspace, which is the model that actually matches how teams work and the one that avoids privilege leaking between workspaces.
Prisma owns the schema, which keeps the permission model in one reviewable place rather than spread across route handlers. Authorisation is checked server-side on every mutation; the client's copy of a user's role only decides what to render, never what is allowed.
Client state is Zustand rather than a server-cache library. For an app where most views are a filtered projection of the same workspace data, a single store that components subscribe to slices of is simpler than coordinating a dozen independent queries. The trade-off is giving up automatic background revalidation, which has to be handled explicitly.
Tasks carry priorities, due dates, and project grouping, with a calendar view over the same data rather than a separate model behind it: one source of truth, several projections.
A detail worth explaining
Authorisation belongs next to the data, not in the handler
The failure mode in role-based systems is a route that forgets its check. Scattering permission logic across handlers means every new endpoint is a chance to omit one, and omissions are invisible until someone finds them. Resolving the caller's workspace role once per request and deriving capability from it, rather than re-deriving it ad hoc in each handler, turns a per-route discipline problem into a single thing to get right and review.
Outcome
TaskFlux runs as a full-stack Next.js application with JWT authentication, four-tier workspace permissions, and task, project, and calendar views over a shared Prisma schema. The source is public.