chore: update readme and prd
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
A clinical records digitization platform built with ASP.NET Core 8, PostgreSQL, MinIO, Redis, and a Vue 3 workstation UI. The domain models the scan-to-approved lifecycle at the center of any paper chart digitization system: scanned document upload, human data entry, dual-human verification with separation of duties, site-configurable clinical approval routing, atomic promotion to live clinical tables, and governed correction via supersession.
|
||||
|
||||
**Implementation status:** Phases 1–8 are complete. Phase 7 delivers the digitization workstation UI (`vigilcare-records-web`). Phase 8 adds Prometheus metrics, supervisor work-queue overview, cursor-paginated batch audit trails, promotion retry with exponential backoff, and a Docker monitoring stack (Prometheus on **9095**, Grafana on **3013**). Phase 9 (E2E verification and clinical scenario docs) is partially implemented. See [Implemented Phases](#implemented-phases) for the full breakdown.
|
||||
**Implementation status:** Phases 1–8 are complete. Phase 7 delivers the digitization workstation UI (`vigilcare-records-web`). Phase 8 adds Prometheus metrics, supervisor work-queue overview, cursor-paginated batch audit trails, promotion deferral with exponential backoff retry, and a Docker monitoring stack (Prometheus on **9095**, Grafana on **3013**). Phase 9 is partially complete: the E2E verification script (`scripts/run-vigilcare-records-verification-p9.sh`) and clinical scenario documentation ([digitization-workstation-guide.md](docs/digitization-workstation-guide.md)) are in place; extended demo seed data (patients and batches across all statuses) is not yet implemented. See [Implemented Phases](#implemented-phases) for the full breakdown.
|
||||
|
||||
## Domain Model — How It Maps to a Real Clinical System
|
||||
|
||||
@@ -192,7 +192,7 @@ VigilCareRecords/
|
||||
│ └── run-vigilcare-records-verification-p9.sh # E2E workflow + work queue overview smoke test
|
||||
└── docs/
|
||||
├── plans/ # Phase 1–9 implementation guides
|
||||
├── digitization-workstation-guide.md # Clerk workflow and UI reference
|
||||
├── digitization-workstation-guide.md # Clinical scenarios and clerk workflow reference
|
||||
└── vigilcare-records-prd.md # Product requirements and phase roadmap
|
||||
```
|
||||
|
||||
@@ -359,7 +359,9 @@ Open `http://localhost:3028`. The Vite dev server proxies `/api` requests to the
|
||||
| `verifier1` | `password` | `/verification` — field-level verification |
|
||||
| `admin1` | `password` | `/dashboard` — supervisor queue overview |
|
||||
|
||||
See [docs/digitization-workstation-guide.md](docs/digitization-workstation-guide.md) for the full clerk workflow.
|
||||
See [docs/digitization-workstation-guide.md](docs/digitization-workstation-guide.md) for clinical scenarios (backfill, live capture, corrections) and the full clerk workflow.
|
||||
|
||||
**Paper originals:** The scanned document is the working reference for entry and verification. The physical chart remains the legal original until jurisdiction-specific retention rules apply. Scans are never deleted on batch rejection.
|
||||
|
||||
Production build:
|
||||
|
||||
@@ -443,9 +445,8 @@ Error response:
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `accessToken` | string | JWT bearer token (15 min) |
|
||||
| `token` | string | JWT bearer token (15 min) |
|
||||
| `refreshToken` | string | Opaque refresh token (7 days) |
|
||||
| `expiresAt` | DateTimeOffset | Access token expiration |
|
||||
| `userId` | Guid | User ID |
|
||||
| `username` | string | Username |
|
||||
| `displayName` | string | Display name |
|
||||
@@ -570,7 +571,9 @@ Error response:
|
||||
| Method | Path | Auth | Description |
|
||||
|---|---|---|---|
|
||||
| POST | `/digitization-batches/{id}/approve` | Clinical Approver, Administrator | Approve and atomically promote draft data to live clinical tables |
|
||||
| POST | `/digitization-batches/{id}/promote` | Clinical Approver, Administrator | Manually promote an `APPROVED` batch (used after deferred promotion or by operators) |
|
||||
| GET | `/digitization-batches/{id}/promotion-result` | Any authenticated | Retrieve live entity IDs created during promotion |
|
||||
| GET | `/digitization-batches/{id}/events` | Administrator, Verifier, Clinical Approver | Cursor-paginated batch audit trail with actor username and full name |
|
||||
|
||||
**POST `/approve` headers:**
|
||||
|
||||
@@ -602,6 +605,7 @@ Error response:
|
||||
| Code | Meaning |
|
||||
|---|---|
|
||||
| 200 | Batch approved and promoted (or idempotent replay) |
|
||||
| 202 | Promotion deferred — batch stays `APPROVED`; `PromotionRetryService` retries automatically (`PROMOTION_DEFERRED`) |
|
||||
| 400 | Missing or invalid `Idempotency-Key` header |
|
||||
| 404 | Batch not found |
|
||||
| 409 | Illegal status transition or separation of duties violation |
|
||||
@@ -624,6 +628,27 @@ Error response:
|
||||
|
||||
All work queue endpoints support pagination via `?page=1&pageSize=20` (except `overview`).
|
||||
|
||||
### Batch Audit Trail
|
||||
|
||||
| Method | Path | Auth | Description |
|
||||
|---|---|---|---|
|
||||
| GET | `/digitization-batches/{id}/events` | Administrator, Verifier, Clinical Approver | Cursor-paginated digitization events for a batch |
|
||||
|
||||
Query parameters: `after` (ISO-8601 cursor from previous page's `nextCursor`), `pageSize` (default 50, max 200). Events are ordered chronologically (oldest first).
|
||||
|
||||
**Event object (`BatchEventResponse`):**
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `id` | Guid | Event ID |
|
||||
| `batchId` | Guid | Batch ID |
|
||||
| `eventType` | string | e.g. `uploaded`, `verified`, `promoted`, `promotion_retry_failed` |
|
||||
| `actorUserId` | Guid | User who performed the action |
|
||||
| `actorUsername` | string | Actor username |
|
||||
| `actorFullName` | string | Actor display name |
|
||||
| `occurredAt` | DateTimeOffset | Event timestamp |
|
||||
| `metadataJson` | string? | Optional JSON (field checks, rejection reason, etc.) |
|
||||
|
||||
**GET `/work-queue/overview` response:**
|
||||
|
||||
| Field | Type | Description |
|
||||
@@ -967,6 +992,20 @@ createdAt DateTimeOffset
|
||||
expiresAt DateTimeOffset 24-hour TTL
|
||||
```
|
||||
|
||||
### PromotionAttempt
|
||||
|
||||
Tracks each promotion attempt for deferred-retry batches. `PromotionRetryService` polls rows where `nextRetryAt <= now` and the batch is still `APPROVED`.
|
||||
|
||||
```
|
||||
id Guid PK
|
||||
batchId Guid FK → DigitizationBatch
|
||||
attemptNumber int 1-based attempt counter
|
||||
succeeded bool whether this attempt completed promotion
|
||||
errorMessage string? failure reason when succeeded = false
|
||||
attemptedAt DateTimeOffset
|
||||
nextRetryAt DateTimeOffset? scheduled retry time (null on success)
|
||||
```
|
||||
|
||||
### User
|
||||
|
||||
```
|
||||
@@ -1006,7 +1045,9 @@ occurredAt DateTimeOffset
|
||||
|
||||
## Pagination
|
||||
|
||||
List endpoints use offset pagination:
|
||||
### Offset pagination
|
||||
|
||||
List endpoints (batch list, work queues) use offset pagination:
|
||||
|
||||
| Param | Default | Description |
|
||||
|---|---|---|
|
||||
@@ -1025,11 +1066,31 @@ Response shape:
|
||||
}
|
||||
```
|
||||
|
||||
### Cursor pagination
|
||||
|
||||
`GET /digitization-batches/{id}/events` uses cursor pagination on `occurredAt`:
|
||||
|
||||
| Param | Default | Description |
|
||||
|---|---|---|
|
||||
| `after` | — | ISO-8601 timestamp cursor from the previous page's `nextCursor` |
|
||||
| `pageSize` | 50 | Events per page (max 200) |
|
||||
|
||||
Response shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"items": [],
|
||||
"pageSize": 50,
|
||||
"nextCursor": "2026-06-27T12:00:00Z",
|
||||
"hasMore": true
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implemented Phases
|
||||
|
||||
Phases 1–8 are fully implemented and verified via integration tests and per-phase scripts. Phase 9 (E2E verification and clinical scenario documentation) is partially implemented.
|
||||
Phases 1–8 are fully implemented and verified via integration tests and per-phase scripts. Phase 9 (E2E verification, clinical scenario docs, extended seed data) is partially complete.
|
||||
|
||||
| Phase | Feature | Status |
|
||||
|---|---|---|
|
||||
@@ -1041,4 +1102,4 @@ Phases 1–8 are fully implemented and verified via integration tests and per-ph
|
||||
| 6 | Track B live capture: `LiveCaptureController` with clinician-only endpoints, `AttestationService` (role + password re-confirm), synchronous promotion via `LiveCaptureService`, Redis-backed critical threshold evaluation, inline critical alerts + committed `ClinicalAlert` rows, `observation.recorded` and `alert.generated` outbox events, open-encounter + vitals outpatient workflow, `LiveCaptureIntegrationTests`, Phase 6 verification script | Done |
|
||||
| 7 | Digitization workstation UI (`vigilcare-records-web`): Vue 3 + Pinia + Tailwind, role-based routing, split-pane scan viewer, draft entry with auto-save, verification checkboxes, patient search, assign-clerk dialog, presigned URL refresh, supervisor dashboard shell | Done |
|
||||
| 8 | Prometheus metrics (`GET /metrics`), custom digitization gauges/histograms/counters, `MetricsCollectorService`, supervisor `GET /work-queue/overview`, cursor-paginated `GET /digitization-batches/:id/events`, promotion deferral (202 / `PROMOTION_DEFERRED`), `PromotionRetryService` with exponential backoff, Docker Prometheus (9095) + Grafana (3013), Phase 8 verification script | Done |
|
||||
| 9 | E2E verification script (`run-vigilcare-records-verification-p9.sh`), clinical scenario documentation | Partial |
|
||||
| 9 | E2E verification script (`run-vigilcare-records-verification-p9.sh`), clinical scenario docs (`docs/digitization-workstation-guide.md`); extended seed data (demo patients/batches across all statuses) | Partial |
|
||||
|
||||
Reference in New Issue
Block a user