The card moves before the network round-trip completes.
02 / Independent product · Async reliability
Reliable Kanban
A full-stack Kanban system built to make drag-and-drop feel immediate while protecting task state when requests fail, sessions overlap, or clients fall behind.
- Role
- Product engineer
- Period
- 2026
- Scale
- Web + API + database
- Status
- Live
01 / Product tension
Moving a card is easy. Keeping the move trustworthy is the work.
A board can change instantly in the browser while the request is still travelling. During that gap, the API can fail, another session can edit the same task, or access can change. The product needed to feel immediate without presenting hopeful UI as durable truth.
Task update / reliability loop System observing
Each task owns its pending state, so unrelated work stays available.
The API rejects a write when the client is behind the durable task.
Success becomes server truth; failure restores the precise snapshot.
Client intentDurable task state
02 / Reliability decisions
Four boundaries make the board feel simple.
Reliability is expressed through product behavior: what updates immediately, what waits for authority, and what happens when the two disagree.
Optimism with an exit route
Every optimistic move carries enough local context to reverse itself. Failure is visible beside the affected task rather than hidden in a global toast.
Stale writes are rejected
Task versions turn concurrent edits into an explicit conflict instead of allowing an older browser session to silently replace newer work.
Persistence stays behind the API
Database enums and records are mapped to stable transport contracts. Column titles remain presentation; stable keys carry behavior.
Authorization follows the data
Clerk identifies the session, while workspace membership is enforced at the service boundary before data is returned or changed.
03 / Production shape
A deployed independent product, with inspectable recovery.
The repository keeps web, API, contracts, persistence, tests, and delivery visible as parts of the same product. That makes the reliability claims inspectable rather than decorative.
Consider two sessions editing the same task. The first move is accepted; the second submits an older version. The API rejects the stale write, the UI explains the conflict, and newer state is protected. A failed request restores the affected task’s snapshot while other tasks remain available.
Unit, component, API, and database tests cover the mutation, permission, and persistence boundaries. The live app and source below make the implementation available for review.
04 / Outcome