# Sensitive dashboard review workspaces: master-detail UI and navigation

Use this pattern when long review queues or document timelines must become desktop/mobile master-detail workspaces without changing trust, authorization, persistence, or worker semantics.

## Contract-first inventory

Before editing UI, identify and freeze:

- bounded list/pagination limits;
- opaque row identity and exact-match rules;
- current CSRF, action-inbox, worker and validation boundaries;
- original-file allowlists/descriptor streaming;
- review-status, extraction-status and search/FTS distinctions;
- authenticated bootstrap/session behavior;
- current URL/history owners and contextual-header controls.

Do not introduce schema migrations, extraction work, automatic review transitions, fuzzy matching, or medical conclusions in a UI-only slice.

## Master-detail construction

### Mapping/review queues

- Desktop: compact master list plus one selected detail; only the selected row owns an editable form.
- Mobile: list first, selection opens detail, and an explicit back action clears the selected-route state and restores focus to the list.
- Keep product/user labels primary. Put method, source version, provenance and worker details under a collapsed “Details und Datenherkunft” section.
- Derive friendly statuses from existing safe fields; do not invent worker completion or approval state.
- Keep completed/unsupported filter outcomes honest when only a bounded open page is available. Never imply an empty client-filtered page means no records exist globally.
- Preserve action forms verbatim where possible so CSRF, exact queue keys, validation shape and worker semantics do not drift during layout work.

### Document workspaces

- Master row: date, semantic document category/type, institution, file format and one combined status sentence.
- Do not render repeated chips that collapse technical availability, extraction, content review and verified search into one state.
- Detail actions are allowlist-driven: original, extracted text and day navigation appear only when the existing contract allows them.
- An extracted-but-unreviewed preview must say it has not been checked against the original. Technical availability never implies medical/content approval.
- Advanced filters can be collapsed by default, but open automatically when an advanced filter is active.
- Client-only filters over a bounded page must be labeled as page-local or use a server contract; do not silently claim global completeness.

## URL/history ownership

Use one canonical route state per workspace. For example:

- top-level view;
- workspace/subview;
- filter and sort state;
- opaque selected item key.

Rules:

1. Validate scalar query parameters, reject duplicates, and allowlist enum values.
2. Invalid or stale selected keys clear fail-closed.
3. Selection writes history before rendering detail.
4. Reload, Back and Forward recreate the same visible master/detail state.
5. Mobile back writes a list state with no selected key; do not merely hide detail with CSS while leaving a contradictory selected URL.
6. Focus the selected detail heading after keyboard/pointer activation and return focus to the list after mobile back.
7. Do not use a closed `<details>` element as the route-restoration primitive. `<details>` is suitable only for secondary technical disclosure.
8. Task/deep-link routing should set the explicit open filter and select the last still-valid opaque key or first bounded open item.

## Contextual header

Treat range controls as owned by the subview where they actually affect data:

- hide global range controls in day, today, records/documents and mapping queues;
- show them in cockpit/explorer and chart subviews where range changes requests/series;
- update visibility during route restoration, not only on direct clicks;
- verify no stale period label or reserved blank header space remains.

## Read-only frontend/browser audit pitfalls

When auditing an existing workspace before implementation, map **rendered UI, dormant handlers, provider output, API policy, and historical specs separately**. A click handler for a task or review route is not proof that the provider can emit that task, and a synthetic fixture that injects one can hide the gap. Explicitly compare current provider semantics with every browser expectation; flag contradictory tests instead of selecting whichever contract is convenient.

For document search and candidate review:

- Reviewed search must be the default. Machine-extracted or unreviewed search requires an explicit, visibly labelled opt-in and a current-state review join; do not merge both result sets silently.
- Verify that snippets and match metadata returned by the API are actually rendered and navigable. An unused `openMatches`-style helper or section-only search without `<mark>` highlighting is not a completed search UX.
- Highlight only by splitting text nodes and inserting safe `<mark>` elements; never rebuild database text with `innerHTML`.
- Keep review candidates read-only until an explicit CSRF-protected action-queue/worker contract exists. Do not infer approval from opening an original, previewing extracted text, or completing technical processing.
- Do not relabel an image/observation capture upload as a document import. PDF/document intake needs its own allowlist, quarantine, queue and worker semantics.
- Before proposing an embedded compare view, inspect original-response framing policy. If originals use `X-Frame-Options: DENY` or `frame-ancestors 'none'`, preserve that boundary and use a separate original window plus an in-app extracted-text pane, or require a dedicated bounded raster/preview endpoint.

For task deep links, inventory both the Today renderer and the data provider. Only user-decision work belongs in Today; OCR, indexing and extraction remain system preparation. Canonical task routes should restore filter, selection, mobile list/detail state and focus through reload and Back/Forward.

## Focused verification

For a bounded UI/navigation slice, prefer:

- changed-file Python/JS syntax and lint;
- focused data-provider/renderer/router/session/original/action tests;
- one dedicated browser group covering desktop, 390px mobile, touch targets, filter/sort, selection, reload/back/forward, task routing, document original, contextual header, global search/navigation, console/network errors and page overflow;
- targeted historical groups for action/CSRF, original access, authentication and main navigation.

Update historical browser tests to the new user-visible contract rather than preserving obsolete selectors such as open review `<details>` cards. Do not treat screenshots generated by historical tests as product changes; restore incidental tracked binary changes unless the sprint explicitly requests new visual evidence. Run the full repository suite only at the planned milestone gate, unless central auth, file-access safety, schema or API semantics changed.

## Release discipline

- Run one final, non-redundant review round split by domain (security/data contract and accessibility/release integrity).
- Consume every dispatched review result before commit/release.
- Re-run only the smallest affected gate after a late product fix.
- Verify frozen legacy artifact checksum, exact changed-file set, clean diff, runtime-source parity, private authenticated HTTP, original access and no external browser requests before reporting release.
