Build the review console for cases 47 and 62. The route loads one case summary, shows status and review count, and offers an optional photo-annotation editor. Parse the API response from unknown data through one decoder before it reaches components. Switch between cases while responses complete in the wrong order; the screen and URL must still agree. The editor should not burden every queue visitor, so load it on the first annotation action and provide a visible wait, retry, and plain-note fallback if the module fails. A component boundary earns its place only when it makes the task easier to maintain.
Project: typed review console
Build contract
- Decode raw JSON into a narrow case model, rejecting malformed counts, missing IDs, and unsupported statuses before rendering.
- Use route data loading or an effect with cleanup; reject any stale success or error result after caseId changes.
- Move annotation code behind a task-level module split and test cold, warm, failed, and old-tab chunk requests.
Implementation checkpoint
function isCaseSummary(rawCase) {
return rawCase !== null && typeof rawCase === "object" &&
Number.isInteger(rawCase.caseId) && rawCase.caseId > 0 && Number.isInteger(rawCase.reviewCount) && rawCase.reviewCount >= 0 &&
(rawCase.status === "open" || rawCase.status === "closed");
}Cost and boundaries
Decoding an n-item list costs O(n) in record count. A route-level fetch can avoid a component waterfall; an unnecessary extra cache can add invalidation work. Deferring the editor reduces initial bytes but moves download and evaluation cost to first use. Record both queue load and editor-open timings. Keep server authorization and response status handling independent of frontend types; a valid JSON shape is not permission to read that case.
Failure drill
First return a numeric string for reviewCount and verify the console shows a controlled decode error. Then make case 62 finish before case 47 and confirm the panel stays on 62. Fail the old request after the route changes; its error must not replace the current case. Finally remove the editor chunk from a simulated old deployment and check that the user can retry or leave a plain note without losing context. These failures cross separate boundaries and need separate recovery states.
Acceptance checks
- Decode valid, malformed, and future-version raw JSON before any component receives it.
- Run both response orders and an old-request failure after route change.
- Measure cold first editor use and recover from a failed chunk request.
- Verify case-level authorization independently of successful decoding.
Common Mistakes
- Casting response JSON to a type without runtime checks.
- Protecting success but not error completion from an obsolete request.
- Calling smaller initial JavaScript a win without measuring first editor use.
Related lessons
TypeScript and Runtime API Boundaries; React Effects and Request Races; Web Components and Shadow Boundaries; Module Splitting and Interaction Budget; Authorization: check permission for this record on every request.
