Worklist enhancements: Procedure Requested/Performed + per-status review history
1. Overview
Enhance the study-reviewer worklist so each work item carries a structured Requested Procedure (what the requester wants assessed) and Performed Procedure (what the reviewer actually did), and so that every status transition — not just rejection — can carry a reviewer note. The full arc (requested → status changes + notes → performed) is surfaced as a chronological history in the Study Details drawer.
Naming and structure track the DICOM Requested Procedure module and Performed Procedure Step (MPPS / UPS) attributes, consistent with the plugin's existing habit of mirroring DICOM. No new DB schema — all state lives in the work item's existing orthanc JSONB (already round-tripped to clients as Meta).
Chain: builds on the now-closed study-review UI design study oak-tree/medical-imaging/ohif-viewers#73.
2. Problem & rationale
Today a worklist request is effectively "please look at this," and the reviewer marks it complete. Two gaps:
- No requested-vs-performed record. There's no structured statement of what assessment was asked for, nor of what the reviewer actually did — only an opaque status flip. Thin for clinical accountability and useless for downstream analytics.
- Notes only on rejection. Reviewers can explain a rejection but cannot annotate an approval, an in-progress hand-off, or a completion ("confirmed landmarks, alignment within spec"). The reasoning behind most state changes is lost.
3. Business value
- Clinical accountability & quality. A first-class requested/performed pair makes each review self-documenting — who asked for what, who did what, and why — the substrate for reviewer QA, second-read programs, and discrepancy tracking.
- Audit & regulatory posture. A per-transition history with attributable notes advances the review/approval evidence regulated customers expect (a step toward the open SN MS2 "audit logs and compliance hooks" item — see §7).
-
Agentic-AI enablement. The requested/performed split is exactly the contract an AI reviewer needs: read the Requested Procedure, act, write back a Performed Procedure + note. Aligns with
oak-tree/medical-imaging/imaging-development-env#94. - Interoperability & integration. Modeling on DICOM MWL Requested Procedure and MPPS Performed Procedure Step shortens the path to RIS/order-system integration and keeps the data speakable in standard terms.
- Commercial differentiation. "Structured, coded, auditable review workflow" is a credible enterprise-imaging talking point versus open viewers that only toggle a status flag.
Success indicators: % of completed work items carrying a performed procedure; % of transitions with an attached note; ability to answer "what was requested vs. done" for any study without leaving the drawer.
4. Concepts
4.1 Requested Procedure
The clinical ask captured when a study is placed on a worklist. Mirrors the DICOM Requested Procedure module: a coded Requested Procedure Code Sequence (0032,1064) and/or a free-text Requested Procedure Description (0032,1060), with optional Requested Procedure Priority (0040,1003) and Reason for the Requested Procedure (0040,1002). Coded concepts use the DICOM Code Sequence Macro (Code Value / Coding Scheme Designator / Code Meaning), sourced from the group's existing ImagingTag library.
4.2 Performed Procedure
What the reviewer actually did, captured as the item advances/completes. Mirrors the DICOM Performed Procedure Step: a coded Procedure Code Sequence (0008,1032) and/or a free-text Performed Procedure Step Description (0040,0254), with optional Performed Procedure Step Status (0040,0252) and start/end timestamps (0040,0244/0245) / (0040,0250/0251).
5. Technical requirements
Functional
- FR-1 — Requested Procedure capture. On "Request Review," allow an optional Requested Procedure (coded sequence and/or description, optional priority/reason).
- FR-2 — Performed Procedure capture. On any reviewer update (typically completion), allow an optional Performed Procedure (coded sequence and/or description).
- FR-3 — Optional procedure description (explicit). Each procedure facet accepts a free-text description independently of coded concepts. A facet is valid if it has at least one of {coded concept, description}; neither is individually mandatory and both may be supplied. Description-only and code-only procedures are both first-class.
-
FR-4 — Note on every transition. Allow an optional free-text note on any status change (not only Rejected), persisted via the existing
Commentpath and linked to that transition. - FR-5 — Status history. Record an entry on item creation and on every state change: previous state, new state, actor, timestamp, linked note (if any).
-
FR-6 — Unified history retrieval. The merged chronological history (transitions + procedures + comments) is retrievable by clients from the worklist item's
Metaplus the existing comments API, gated by existing ACL. (A dedicated server endpoint is deferred to #55.) -
FR-7 — Namespace integrity. Prevent clients from forging or overwriting server-owned procedure/history attributes via the general
Metachannel.
Non-functional
-
NFR-1 — No schema change. Pure
orthancJSONB; no columns, tables, or migration. - NFR-2 — DICOM alignment. Attribute keys and structure mirror the Requested Procedure module, Performed Procedure Step, and Code Sequence Macro (see §6.2).
- NFR-3 — Backward compatible. Absence of procedure/history is valid; existing worklist clients unaffected.
- NFR-4 — Audit caveat. JSONB history is mutable (not tamper-evident); designed to be promotable to an append-only store later without changing the client contract.
- NFR-5 — ACL parity with the rest of the drawer.
6. System specification
6.1 Storage model
Three reserved, server-owned keys inside the work item's orthanc JSONB (surfaced inside Meta): RequestedProcedure, PerformedProcedure, ReviewHistory.
orthanc = {
// ...free-form client Meta (reserved keys below are server-owned)...
"RequestedProcedure": {
"RequestedProcedureID": "RP-00123", // (0040,1001) SH, optional
"RequestedProcedureDescription": "Review TKA alignment", // (0032,1060) LO, optional free text
"RequestedProcedureCodeSequence": [ // (0032,1064) SQ
{ "CodeValue": "P5-12345", "CodingSchemeDesignator": "SRT", "CodeMeaning": "TKA plan review" }
],
"RequestedProcedurePriority": "ROUTINE", // (0040,1003) SH, optional
"ReasonForTheRequestedProcedure": "Pre-op planning", // (0040,1002) LO, optional
"RequestedBy": 222, "RequestedDateTime": "<iso>" // plugin metadata
},
"PerformedProcedure": {
"PerformedProcedureStepID": "PPS-00123", // (0040,0253) SH, optional
"PerformedProcedureStepDescription": "Confirmed femoral/tibial landmarks", // (0040,0254) LO, optional free text
"ProcedureCodeSequence": [ // (0008,1032) SQ
{ "CodeValue": "P5-12346", "CodingSchemeDesignator": "SRT", "CodeMeaning": "Landmark verification" }
],
"PerformedProcedureStepStatus": "COMPLETED", // (0040,0252) CS, optional
"PerformedProcedureStepStartDateTime": "<iso>", // (0040,0244)+(0040,0245)
"PerformedProcedureStepEndDateTime": "<iso>", // (0040,0250)+(0040,0251)
"PerformedBy": 222
},
"ReviewHistory": [ // plugin construct; echoes worklist `State`
{ "PreviousState": "scheduled", "State": "in-progress", "User": 222, "Timestamp": "<iso>", "CommentUID": null },
{ "PreviousState": "in-progress", "State": "completed", "User": 222, "Timestamp": "<iso>", "CommentUID": "<uuid>" }
]
}
6.2 Attribute → DICOM tag mapping
| JSON key | DICOM attribute | Tag | VR |
|---|---|---|---|
RequestedProcedureID |
Requested Procedure ID | (0040,1001) | SH |
RequestedProcedureDescription |
Requested Procedure Description | (0032,1060) | LO |
RequestedProcedureCodeSequence |
Requested Procedure Code Sequence | (0032,1064) | SQ |
RequestedProcedurePriority |
Requested Procedure Priority | (0040,1003) | SH |
ReasonForTheRequestedProcedure |
Reason for the Requested Procedure | (0040,1002) | LO |
PerformedProcedureStepID |
Performed Procedure Step ID | (0040,0253) | SH |
PerformedProcedureStepDescription |
Performed Procedure Step Description | (0040,0254) | LO |
ProcedureCodeSequence |
Procedure Code Sequence | (0008,1032) | SQ |
PerformedProtocolCodeSequence |
Performed Protocol Code Sequence | (0040,0260) | SQ |
PerformedProcedureStepStatus |
Performed Procedure Step Status | (0040,0252) | CS |
PerformedProcedureStepStartDateTime |
PPS Start Date / Time | (0040,0244)/(0040,0245) | DA/TM |
PerformedProcedureStepEndDateTime |
PPS End Date / Time | (0040,0250)/(0040,0251) | DA/TM |
Code Sequence Macro item (used by every *CodeSequence), with mapping to the existing ImagingTag columns:
| JSON key | DICOM attribute | Tag |
ImagingTag field |
|---|---|---|---|
CodeValue |
Code Value | (0008,0100) | value |
CodingSchemeDesignator |
Coding Scheme Designator | (0008,0102) | scheme_designator |
CodingSchemeVersion |
Coding Scheme Version | (0008,0103) | scheme_version |
CodeMeaning |
Code Meaning | (0008,0104) | meaning |
6.3 Request/response contract
Worklist create/update accepts an optional Procedure block alongside the existing State, Meta, and Comment:
PUT .../studies/{id}/worklist/{wid}
{
"State": "completed",
"Comment": { "Text": "Reviewed; alignment within spec." }, // optional, existing path
"Procedure": {
"PerformedProcedure": {
"ProcedureCodeSequence": [ { "CodeValue": "P5-12346", "CodingSchemeDesignator": "SRT", "CodeMeaning": "Landmark verification" } ],
"PerformedProcedureStepDescription": "Confirmed femoral/tibial landmarks."
}
}
}
On create, the Procedure block normally carries only RequestedProcedure. Because orthanc already serializes to clients as Meta, the reserved keys ride along in the standard worklist response — no serializer change.
6.4 Namespace protection
The worklist form maps inbound Meta → orthanc, so a client could otherwise overwrite the reserved keys. The server strips RequestedProcedure / PerformedProcedure / ReviewHistory from any inbound Meta and re-applies the server-owned values; procedure writes come only through the validated Procedure block.
6.5 History timeline retrieval
Clients assemble the timeline client-side from the worklist item's Meta (reserved keys ReviewHistory, RequestedProcedure, PerformedProcedure) merged with the existing comments API, gated by existing ACL. A dedicated server-side endpoint (GET .../studies/{id}/history) is deferred to #55 and is out of scope for this issue.
7. Design decision & trade-offs (locked 2026-06-29: pure orthanc JSONB)
No new columns/tables/migration. Trade-offs accepted: last-write-wins on the blob; mutable, non-append-only history (so this does not by itself satisfy the SN MS2 audit-log item). ReviewHistory is shaped so it can be promoted to a dedicated append-only table later without changing the client/Meta contract. The existing ProcedureStep table is intentionally left unused.
8. Implementation checklist
Server (oak-tree/medical-imaging/orthanc-sonador)
-
Validate the optional
Procedureblock (RequestedProcedure/PerformedProcedure; coded sequence and/or description per FR-3) — !54 (merged) -
Write procedures into the
RequestedProcedure/PerformedProcedurereserved keys (no columns) — !54 (merged) -
Append a
ReviewHistoryentry on create and on every status transition, with optionalCommentUID— !54 (merged) -
Strip/re-apply reserved keys to protect them from client
Metaoverwrites (FR-7) — !54 (merged) -
Fix latent
NameErrorinWorklistItemValidationForm.clean()(readsstatebefore assignment) — !54 (merged) -
Redact the copied "Performed Procedure step" docstring noted in
oak-tree/medical-imaging/orthanc-sonador#41— !54 (merged)
Client (oak-tree/medical-imaging/ohif-viewers — stand-alone web app; all worklist UI under platform/viewer/src/. Scope note: agent work is limited to this repo and the server repo; do not modify other repositories or submodule pins — downstream integration into the Sonador web application is handled manually.)
-
Create Worklist Item dialog: capture "Reason for Review" (free text, stored as
RequestedProcedure.ReasonForTheRequestedProcedure) and optionalRequestedProcedureDescription. Coded-concept entry (ImagingTag-backed picker) is out of scope for this issue. —oak-tree/medical-imaging/ohif-viewers!58 -
Rapid Review Toolbar: note input on every status change — optional for all transitions, required for Cancelled (existing behavior unchanged); capture Performed Procedure (description) on completion —
oak-tree/medical-imaging/ohif-viewers!58 -
Details Drawer: render the unified history timeline (available client-side via
Meta) — deferred pending a design round: the timeline component andMeta/comments data plumbing landed inoak-tree/medical-imaging/ohif-viewers!58(StudyItemExpandedNG/components/ReviewHistory) but are intentionally not rendered; a three-column drawer proved unusable for history-heavy studies
Testing (per oak-tree/medical-imaging/imaging-development-env#87) — implemented in oak-tree/medical-imaging/sonador-ftests!10 (tests_ext_worklist_procedures)
-
Unit: procedure validation incl. description-only and code-only facets (FR-3) — covered at the API level: acceptance (
test_procedure_facets_description_or_code) and rejection paths (test_procedure_validation_rejected) -
Integration: one
ReviewHistoryentry per transition; note links viaCommentUID; reserved keys survive a clientMetaupdate (FR-7); completed/cancelled stay locked; timeline ordering + ACL denial —test_meta_reserved_keys_protected,test_cancelled_with_note_locked,test_comment_only_update_appends_history,test_history_acl_parity -
Functional arc: request (with Requested Procedure) → process → complete (with Performed Procedure + note) → history timeline via
Meta—test_review_history_full_arc(+ DICOMweb variant)
9. Related / lineage
- Predecessor design study (closed):
oak-tree/medical-imaging/ohif-viewers#73 - Workflow concept:
oak-tree/medical-imaging/imaging-development-env#46 - Study-list status API:
oak-tree/medical-imaging/imaging-development-env#74,oak-tree/medical-imaging/imaging-development-env#75 - Agentic-AI review loop:
oak-tree/medical-imaging/imaging-development-env#94 - Worklist testing plan:
oak-tree/medical-imaging/imaging-development-env#87 - Foundational worklist API:
oak-tree/medical-imaging/orthanc-sonador#19 - Docstring cleanup:
oak-tree/medical-imaging/orthanc-sonador#41
10. Milestone
Assigned to Sonador Studylist UI Refinements Round 2. Intentionally not part of Secure Resource Sharing & Worklists (SN MS2) — that milestone is being closed out, not expanded.