feature: Digitization Workstation UI
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
```markdown
|
||||
# VigilCare Records — Digitization Workstation Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This guide describes three primary clinical workflows supported by the VigilCare
|
||||
Records digitization platform: historical backfill, live bedside capture, and
|
||||
corrections. Each workflow maps to a real operational scenario in a paper-based
|
||||
hospital or clinic.
|
||||
|
||||
---
|
||||
|
||||
## Workflow 1: Historical Backfill (Track A)
|
||||
|
||||
**Scenario:** District General Hospital has 200 active patients with paper charts.
|
||||
The facility is deploying VigilCareClinical for real-time alerting. Before alerts
|
||||
can fire, historical vital signs and lab results must be digitized into the system.
|
||||
|
||||
**Actors:** Intake Clerk, Data Entry Clerk, Verifier, Clinical Approver (for
|
||||
high-stakes batch types)
|
||||
|
||||
**Steps:**
|
||||
|
||||
### 1. Intake (Intake Clerk)
|
||||
|
||||
The intake clerk receives a stack of patient charts from the ward. For each chart
|
||||
section:
|
||||
|
||||
1. Scan the page(s) using a flatbed scanner or document camera
|
||||
2. Log in to the workstation as `intake1`
|
||||
3. Navigate to **Intake** view
|
||||
4. Upload the scan (PDF, JPEG, or PNG; max 25 MB)
|
||||
5. Select the batch type:
|
||||
- **Vitals Sheet** — vital signs from nursing observation charts
|
||||
- **Lab Results** — laboratory test result reports
|
||||
- **Patient Registration** — face sheet with demographics
|
||||
- **Encounter Summary** — admission/discharge summaries
|
||||
- **Allergy Update** — allergy documentation
|
||||
- **Medication List** — current medication records
|
||||
6. Set track to **Backfill** (default)
|
||||
7. Optionally link to an existing patient by searching MRN or name
|
||||
8. Click **Upload and Create Batch**
|
||||
|
||||
The batch is created in `uploaded` status. The SHA-256 hash prevents duplicate
|
||||
uploads of the same document for the same patient within 24 hours.
|
||||
|
||||
### 2. Data Entry (Data Entry Clerk)
|
||||
|
||||
The entry clerk opens the batch from their **Entry** queue:
|
||||
|
||||
1. Log in as `entry1`
|
||||
2. Click the batch to open the split-pane workstation
|
||||
3. **Left pane:** The scanned document is displayed with zoom, pan, and rotate
|
||||
controls. The clerk reads the handwritten or printed values from the scan.
|
||||
4. **Right pane:** Structured form fields for:
|
||||
- Patient demographics (name, DOB, sex, blood type, emergency contact)
|
||||
- Encounter context (admission date, department, room/bed, admission reason)
|
||||
- Observations (one row per vital sign or lab result)
|
||||
|
||||
**Observation entry rules:**
|
||||
- Each observation requires a code (e.g., `HEART_RATE`), numeric value, unit, and
|
||||
`recordedAt` timestamp taken from the chart (not scan time)
|
||||
- Plausibility validation fires on save:
|
||||
- Heart rate: 20-300 bpm
|
||||
- Temperature: 25-45 C
|
||||
- SpO2: 0-100 %
|
||||
- Potassium: 1.5-10.0 mEq/L
|
||||
- Glucose: 20-800 mg/dL
|
||||
- Out-of-range values return `422 OBSERVATION_OUT_OF_PLAUSIBLE_RANGE`
|
||||
- This catches the most common digitization error: decimal misplacement (5.2 vs 52)
|
||||
|
||||
5. Click **Submit for Verification** when all fields are complete
|
||||
6. The batch transitions to `pending_verification`
|
||||
|
||||
### 3. Verification (Verifier)
|
||||
|
||||
The verifier reviews the entry against the original scan:
|
||||
|
||||
1. Log in as `verifier1` (must be a different person than the entry clerk)
|
||||
2. Open the batch from the **Verification** queue
|
||||
3. **Left pane:** Same scan viewer
|
||||
4. **Right pane:** Each field has a verification checkbox
|
||||
- Compare each entered value against the scan
|
||||
- Check the checkbox when the value matches
|
||||
- Progress bar shows completion percentage
|
||||
5. If all fields match: click **Approve - Verified**
|
||||
6. If any field is wrong: click **Reject** with a mandatory reason
|
||||
|
||||
**Separation of duties:** The system enforces that `enteredByUserId !== verifiedByUserId`.
|
||||
If the entry clerk tries to verify their own batch, the API returns `409
|
||||
SEPARATION_OF_DUTIES_VIOLATION`.
|
||||
|
||||
**On rejection:** The batch returns to `rejected` status. The entry clerk sees the
|
||||
rejection reason and can correct the draft, then resubmit for verification.
|
||||
|
||||
### 4. Approval and Promotion
|
||||
|
||||
Track A has **two human gates** before live records exist:
|
||||
|
||||
1. **Verifier** — scan comparison (`verify` / `reject` on `pending_verification`)
|
||||
2. **Clinical approver** — promotion authorization (`approve` on `verified` or `awaiting_clinical_approval`)
|
||||
|
||||
After verification passes, site configuration routes the batch:
|
||||
|
||||
| batchType | Default: next status after verify |
|
||||
|---|---|
|
||||
| `patient_registration`, `allergy_update` | `verified` → clinical approver calls `approve` |
|
||||
| `encounter_summary`, `vitals_sheet`, `lab_results`, `medication_list`, `mixed` | `awaiting_clinical_approval` → clinical approver reviews in **Clinical Approval** queue, then calls `approve` |
|
||||
|
||||
Log in as `approver1` for the approval step. Verifiers (`verifier1`) never call `approve`.
|
||||
|
||||
On approval:
|
||||
1. The promotion service runs atomically:
|
||||
- Create or update Patient in VigilCareClinical
|
||||
- Create or match Encounter
|
||||
- Insert each DraftObservation as a live Observation
|
||||
- Write outbox events (alerting suppressed for backfill unless
|
||||
`enableRetroactiveAlerts: true`)
|
||||
2. Batch status transitions to `promoted`
|
||||
3. All observations are now visible in VigilCareClinical's ward dashboard
|
||||
|
||||
**Alert suppression for backfill:** By default, backfilled observations do not
|
||||
trigger real-time alerts. A historical potassium of 6.2 mEq/L from three days ago
|
||||
should not page the on-call physician today. The facility can override this per
|
||||
batch by setting `enableRetroactiveAlerts: true`.
|
||||
|
||||
---
|
||||
|
||||
## Workflow 2: Live Bedside Capture (Track B)
|
||||
|
||||
**Scenario:** A nurse or physician enters vital signs at the bedside using a tablet.
|
||||
The observation needs to reach VigilCareClinical's alert pipeline immediately.
|
||||
|
||||
**Actor:** Clinician
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. Log in as `clinician1`
|
||||
2. Navigate to the live capture endpoint
|
||||
3. Select or create the encounter
|
||||
4. Enter observation values with `clinicianAttestation: true`
|
||||
5. Confirm with password re-entry or PIN
|
||||
|
||||
**What happens:**
|
||||
- A `DigitizationBatch` is created with `track: live_capture` and lands in `promoted` immediately (workflow states skipped, audit unit retained)
|
||||
- `DraftObservation` rows and `DigitizationEvent` entries (`live_capture_attested`, `promoted`) are written in the same transaction as live observations
|
||||
- No verification queue — the clinician's attestation replaces verify + approve for that batch only
|
||||
- The batch is promoted synchronously
|
||||
- If a critical value is entered (e.g., potassium 6.8 mEq/L), the synchronous
|
||||
alert fires before the response returns
|
||||
- The observation appears in VigilCareClinical's ward dashboard immediately
|
||||
|
||||
**When to use Track B vs Track A:**
|
||||
- Track B: Current patient encounter, values just measured, clinician is at bedside
|
||||
- Track A: Historical charts, bulk digitization, values from past encounters
|
||||
|
||||
---
|
||||
|
||||
## Workflow 3: Corrections
|
||||
|
||||
**Scenario:** After promotion, a reviewer discovers that the SpO2 value was entered
|
||||
as 94% but the chart actually shows 95%. The promoted observation must be corrected.
|
||||
|
||||
**Rule:** Approved records are never silently edited. Corrections go through the
|
||||
full pipeline.
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. Create a new batch with `supersedesBatchId` pointing to the original batch
|
||||
2. Re-enter the corrected values
|
||||
3. Submit for verification (new entry, new verifier review)
|
||||
4. On approval and promotion:
|
||||
- The corrected observations are inserted as new live records
|
||||
- The original observations are marked `superseded` (soft flag, not deleted)
|
||||
- The audit trail shows: original values, correction request, new values,
|
||||
who made each change and when
|
||||
|
||||
**Why not just edit the original?** Clinical audit integrity. A regulator must be
|
||||
able to see what was originally entered, when it was corrected, and by whom. Silent
|
||||
edits destroy this chain.
|
||||
|
||||
---
|
||||
|
||||
## Staffing Considerations
|
||||
|
||||
- In a small facility, one person may serve as both intake clerk and data entry clerk
|
||||
- The system **never** allows one person to both enter and verify the same batch,
|
||||
even if they hold both roles
|
||||
- Minimum staff for full workflow: 2 people (one enters, one verifies)
|
||||
- The system tracks clerk throughput via the work queue overview endpoint and
|
||||
Prometheus metrics
|
||||
|
||||
---
|
||||
|
||||
## Common Issues and Resolution
|
||||
|
||||
| Issue | Cause | Resolution |
|
||||
|---|---|---|
|
||||
| `409 DUPLICATE_DOCUMENT` | Same PDF uploaded for same patient within 24h | Check if batch already exists; use a different scan if needed |
|
||||
| `409 SEPARATION_OF_DUTIES_VIOLATION` | Entry clerk trying to verify own batch | Assign to a different verifier |
|
||||
| `422 OBSERVATION_OUT_OF_PLAUSIBLE_RANGE` | Value outside allowed range | Check for decimal misplacement (52 vs 5.2) |
|
||||
| `409 ILLEGAL_STATUS_TRANSITION` | Trying to skip a workflow step | Follow the status machine: uploaded -> in_entry -> pending_verification -> verified -> approved -> promoted |
|
||||
| High rejection rate (>15%) | Scan quality or training issues | Review rejection reasons; improve scanner resolution or provide entry clerk training |
|
||||
| Batch stuck in `approved` | VigilCareClinical unreachable | Promotion retry worker handles this automatically with exponential backoff |
|
||||
```
|
||||
Reference in New Issue
Block a user