All work

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.

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.

01Interaction

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.

Fast when healthy · recoverable when not
02Concurrency

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.

No silent last-write-wins overwrite
03Boundaries

Persistence stays behind the API

Database enums and records are mapped to stable transport contracts. Column titles remain presentation; stable keys carry behavior.

UI and storage can evolve independently
04Access

Authorization follows the data

Clerk identifies the session, while workspace membership is enforced at the service boundary before data is returned or changed.

Protected, user-scoped boards

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

Moves respond immediately. Failed writes roll back. Stale updates are rejected.