All work

TaskFlux

Team workspaces with four permission tiers and real-time collaboration.

Role
Design & engineering
Year
2025
Discipline
Full-stack application
Status
On GitHub
Stack
Next.js · Node.js · TypeScript · Zustand · Tailwind CSS · Prisma · JWT
Links
Source
TaskFlux: Task Management Web App

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.