Add clinical device registry, browser wedge scan, and local agent API.
Deploy Ladill Care / deploy (push) Successful in 1m39s
Deploy Ladill Care / deploy (push) Successful in 1m39s
Branch-scoped Care devices with hashed agent tokens, patient barcode lookup/labels, and provenance-aware vitals from a minimal device agent (Pro for agent hardware; wedge free). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# Care clinical devices
|
||||
|
||||
Ladill Care supports two realistic hardware paths:
|
||||
|
||||
| Device | Connection | Plan |
|
||||
|--------|------------|------|
|
||||
| USB barcode / QR scanner | **Browser keyboard wedge** — scan into Patients or Lab | All plans |
|
||||
| Badge / label printer | Browser print CSS (patient ID label) | All plans |
|
||||
| Thermometer, BP monitor, pulse ox, scale, lab analyzer | **Care Device Agent** (local machine) | Pro / Enterprise |
|
||||
|
||||
Browser pages cannot open serial ports or most BLE clinical devices without a local helper. The agent holds the vendor/serial connection and posts readings to Care with a device token.
|
||||
|
||||
## Device registry
|
||||
|
||||
**Settings → Devices** (hospital admin):
|
||||
|
||||
1. Register a device (branch-scoped).
|
||||
2. For agent types, Care shows a **plaintext token once** (create / regenerate). The DB stores only `device_token_hash`.
|
||||
3. Status updates from agent heartbeats (`active` + `last_seen_at`).
|
||||
|
||||
## Browser wedge (patients)
|
||||
|
||||
1. Open **Patients**.
|
||||
2. Focus the scan field (or scan while not typing in another input).
|
||||
3. Scan a patient ID label (`patient_number`) → Care opens the patient record.
|
||||
4. From the patient page, **Print ID label** for browser print.
|
||||
|
||||
Lab **Collect sample** accepts a scanned `sample_barcode` before submit.
|
||||
|
||||
## Agent API
|
||||
|
||||
Base URL: `{APP_URL}/api/v1/device-agent`
|
||||
|
||||
Auth (any one):
|
||||
|
||||
- Header `X-Care-Device-Token: <plaintext token>`
|
||||
- Header `Authorization: Bearer <plaintext token>`
|
||||
- Header `X-Device-Token: <plaintext token>` (compat)
|
||||
|
||||
Rate limit: 60 requests / minute / token.
|
||||
|
||||
### Heartbeat
|
||||
|
||||
```bash
|
||||
curl -sS -X POST "$CARE_URL/api/v1/device-agent/heartbeat" \
|
||||
-H "X-Care-Device-Token: $DEVICE_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-d '{"agent_version":"0.1.0","hostname":"nurse-station-1"}'
|
||||
```
|
||||
|
||||
### Post vitals
|
||||
|
||||
Provide `consultation_uuid` **or** `visit_uuid` (latest consultation on that visit). Readings create a `care_vital_signs` row with `source=device` and `device_id`.
|
||||
|
||||
```bash
|
||||
curl -sS -X POST "$CARE_URL/api/v1/device-agent/vitals" \
|
||||
-H "X-Care-Device-Token: $DEVICE_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-d '{
|
||||
"consultation_uuid":"'"$CONSULTATION_UUID"'",
|
||||
"vitals":{"temperature":36.8,"pulse":72,"spo2":98},
|
||||
"raw":{"driver":"stub","unit":"C"}
|
||||
}'
|
||||
```
|
||||
|
||||
Typed consultation vitals remain the source of truth for clinicians; agent posts append provenance-aware rows.
|
||||
|
||||
### Collect sample barcode
|
||||
|
||||
```bash
|
||||
curl -sS -X POST "$CARE_URL/api/v1/device-agent/samples/collect" \
|
||||
-H "X-Care-Device-Token: $DEVICE_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-d '{"investigation_uuid":"'"$INVESTIGATION_UUID"'","sample_barcode":"SMP-001"}'
|
||||
```
|
||||
|
||||
## Minimal agent (demo)
|
||||
|
||||
See `deployment/care-device-agent/`.
|
||||
|
||||
```bash
|
||||
cd deployment/care-device-agent
|
||||
cp .env.example .env # set CARE_URL + DEVICE_TOKEN
|
||||
npm install # optional; Node 18+ has fetch built-in
|
||||
FAKE_READING=1 npm start
|
||||
```
|
||||
|
||||
With `FAKE_READING=1` the agent heartbeats and posts a stub temperature every interval (no serial hardware). Point `CONSULTATION_UUID` at an open consultation for a live demo.
|
||||
Reference in New Issue
Block a user