This repo is the starter project for the live coding exercise:
Build a 4‑column ATS pipeline (Applied → Screen → Interview → Offer) with optimistic updates and conflict handling.
It includes:
- Vite + React + TypeScript
- React Query (server state) and Zustand (UI/ephemeral state)
- A mock API that simulates latency, random failures, and 409 version conflicts
- Minimal DnD scaffolding (dnd-kit) + keyboard move buttons as fallback
- React Query Devtools (open with the Devtools button)
# Node 18+ recommended
npm install
npm run dev
# open http://localhost:5173
- Fetch and render columns with candidates.
- Implement drag & drop (or the provided keyboard buttons) to move a candidate.
- On drop/click, perform an optimistic update and call the PATCH API.
- If the server returns 409 or fails, rollback and show an error message.
- Show loading / empty / error states and keep the UI responsive.
- Reorder within a column (persist
position
). - Virtualize large columns.
- Prefetch next column on hover.
- Filter by search term and keep it in URL.
- Add basic a11y enhancements (aria-live for errors, focus management).
GET /api/stages
→["Applied","Screen","Interview","Offer"]
GET /api/candidates?stage=Applied&cursor=<opt>
→{ items:[{ id, name, role, stage, position, version }], nextCursor:null|str }
PATCH /api/candidates/:id/move
body:{ fromStage, toStage, position, version }
- 200 →
{ ...candidate, version: version+1 }
- 409 →
{ error:"conflict", current:{ ...candidate, version } }
- Random delay (100–800ms); ~10% failures
- 200 →
Note: The mock API intercepts
fetch
calls for/api/*
requests. You can usefetch
OR the tinyapiClient
helpers.
src/components/Board.tsx
— DnD wiring (onDragEnd
) and basic layoutsrc/hooks/useMoveCandidate.ts
— Implement onMutate / onError / onSettled for optimistic updatessrc/components/StageColumn.tsx
— Render column, integrate keyboard move buttons
- Mixing server state and UI state in one store
- Mutating arrays in place (use pure updates)
- Wrong React Query keys (must include the stage)
- Forgetting rollback on error / conflict
- Not cancelling queries before optimistic updates
Good luck! Have fun and talk through your reasoning.