Build a review queue for accounts 29 and 62. A direct visit to case 47 must show useful server-rendered HTML before application code loads; hydration must use precisely the same first snapshot. The client receives only the fields needed for that first interaction, including record version and retrieval time. When reviewer 29 resolves case 47, update the detail and both queue memberships immediately with a pending marker, then reconcile from the server response. Reopen the case in another tab and force version conflicts. A late read from before the edit must not put 47 back into Pending. The project is complete only when account switching clears private cache entries and a shared server cache cannot leak case 47 to account 62.
Project: server-rendered case queue
Build contract
- Render server HTML and first client tree from one request-scoped snapshot; test two time zones and a stored preference change.
- Bootstrap a minimal client record with a freshness deadline, then measure cold-entry duplicate requests and return-route revalidation.
- Key detail and queue entries by account, record, filter, and page; map each write to the affected views.
- Use a conditional version and stable retry identity; settle two mutations in reverse order and repair a conflict from the server record.
Implementation checkpoint
function canApplyCaseResponse(response, activeAccountId, currentVersion) {
return response.accountId === activeAccountId && response.version >= currentVersion;
}
console.log(canApplyCaseResponse({ accountId: 29, version: 6 }, 29, 7));
// Output: falseCost and boundaries
Rendering n queue rows is O(n) for the first tree and consumes corresponding DOM memory. A bootstrap snapshot adds bytes to the HTML, but avoids an immediate duplicate fetch when its freshness window is still valid. Updating m cache views can trigger m reads or local transformations; broad invalidation is easier to reason about and may cost more network traffic. An optimistic before-image consumes extra memory until confirmation. Document the first-content and interaction timings alongside stale-view defects so a fast screen is not accepted while it displays the wrong case.
Failure drill
First make the server render Pending while a stored client value says Resolved. Capture the hydration warning and fix the first-render source. Next reuse a request cache across two accounts and inspect the resulting HTML for private data; the cache must be scoped before any browser reconciliation. Delay an old Pending fetch until after a successful Resolve write and ensure its response cannot restore old membership. Finally time out the mutation after a server commit, retry with the same identity, and verify one accepted transition. A version conflict should present the new server record and a clear recovery choice, never an unexplained silent rollback.
Acceptance checks
- Initial HTML and hydration agree across locale and stored-preference changes.
- Account 62 never sees account 29's server HTML or client cache rows.
- A late read and a reverse-order write response cannot overwrite a newer accepted version.
- Timeout retry produces one server mutation and an honest final UI state.
Common Mistakes
- Reading browser-only data during the initial server-matched render.
- Using a shared private server cache across requests.
- Invalidating only the detail view after a queue-changing write.
- Rolling back a failed mutation over a later accepted change.
Related lessons
Hydration and Deterministic First Render; Server Data Bootstrap and Freshness; Client Cache Keys and Invalidation; Optimistic Mutations and Rollback; Authorization: check permission for this record on every request.
