From 19c9e8ba1e1cbc98408cf2e4f4847e97b62eb09c Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 8 May 2026 23:32:39 +0200 Subject: [PATCH] docs align memory and audio backup behavior --- docs/ai-providers.md | 8 +++++--- docs/api-reference.md | 29 ++++------------------------- docs/database.md | 13 ++++++++----- docs/developer-guide-extended.md | 2 +- docs/developer-guide.md | 29 ++++++++++++----------------- docs/logic/ai-and-voice.md | 9 ++++----- docs/logic/architecture.md | 19 ++++++++++--------- docs/logic/clinical-notes.md | 4 ++-- 8 files changed, 46 insertions(+), 67 deletions(-) diff --git a/docs/ai-providers.md b/docs/ai-providers.md index c817371..a76fe96 100644 --- a/docs/ai-providers.md +++ b/docs/ai-providers.md @@ -124,9 +124,11 @@ Applied to: `soap.js`, `hpi.js`, `refine.js`, `sickVisit.js`, `wellVisit.js`, ### Physician memories -Saved corrections are injected into prompts as `[STYLE HINTS (low priority)]` -with 200-character snippets. The low-priority wording prevents smaller models -from hallucinating content from the correction examples into the current note. +Saved templates and prompt preferences are injected into prompts as +`[STYLE HINTS (low priority)]` when they belong to AI-context categories. The +low-priority wording prevents smaller models from hallucinating content from a +stored template into the current note. `custom` memories and legacy +`correction_*` rows are not prompt context. ## API call logging diff --git a/docs/api-reference.md b/docs/api-reference.md index 81d8a0c..7d91bb0 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -844,36 +844,15 @@ Delete a memory. ### GET /api/memories/context -Retrieve all memories formatted for injection into AI generation prompts. +Retrieve AI-context template/preference rows formatted for injection into AI +generation prompts. `custom` rows and legacy `correction_*` rows are excluded. - **Auth required:** Yes - **Response:** ```json { - "context": "string" - } - ``` - ---- - -### POST /api/memories/correction - -Automatically save a style correction as a memory. Used when the physician corrects AI output. - -- **Auth required:** Yes -- **Request body:** - ```json - { - "section": "string", - "original_snippet": "string", - "corrected_snippet": "string" - } - ``` -- **Response:** - ```json - { - "success": true, - "id": "number" + "success": true, + "context": "string" } ``` diff --git a/docs/database.md b/docs/database.md index e563524..42ae874 100644 --- a/docs/database.md +++ b/docs/database.md @@ -138,20 +138,23 @@ Draft/complete encounter workspace. Auto-expires (default 7 d, ### `user_memories` -Per-user clinical-style hints injected into AI prompts. +Per-user template and preference rows. Only selected categories are injected +into AI generation through `/api/memories/context`; `custom` rows are stored +for the user but not included in prompt context. | Column | Type | Notes | |---|---|---| | id | SERIAL PK | | | user_id | INTEGER FK users.id ON DELETE CASCADE | | -| category | TEXT NOT NULL DEFAULT 'custom' | `physical_exam`, `ros`, `encounter_format`, `custom`, `template_*`, `correction_*` | -| name | TEXT NOT NULL | | -| content | TEXT NOT NULL | | +| category | TEXT NOT NULL DEFAULT 'custom' | Valid categories: `physical_exam`, `ros`, `encounter_format`, `family_history`, `assessment_plan`, `custom`, `template_soap`, `template_hpi`, `template_wellvisit`, `template_sickvisit`, `template_ed`. Legacy `correction_*` rows may exist but are filtered out. | +| name | TEXT NOT NULL | Encrypted with `enc1:` for new rows | +| content | TEXT NOT NULL | Encrypted with `enc1:` for new rows | | created_at, updated_at | TIMESTAMPTZ DEFAULT NOW() | | ### `audio_backups` -Retry store for failed-transcription audio. +Optional 24-hour encrypted recovery store for recordings when transcription +fails, so users can retry without re-recording. | Column | Type | Notes | |---|---|---| diff --git a/docs/developer-guide-extended.md b/docs/developer-guide-extended.md index 12cf9cd..452beec 100644 --- a/docs/developer-guide-extended.md +++ b/docs/developer-guide-extended.md @@ -278,7 +278,7 @@ Important keys: Draft encounters (7-day auto-expiry). Columns: `label`, `enc_type`, `transcript`, `generated_note`, `partial_data` (JSON), `status`, `expires_at`. #### `user_memories` -User templates fed into AI generation. `category` is one of: `physical_exam`, `ros`, `encounter_format`, `family_history`, `assessment_plan`, `custom`. +User templates and preferences. `/api/memories/context` injects only AI-context categories: `physical_exam`, `ros`, `encounter_format`, `family_history`, `assessment_plan`, `template_soap`, `template_hpi`, `template_wellvisit`, `template_sickvisit`, `template_ed`. `custom` rows are user-visible storage but are not prompt context. Legacy `correction_*` rows may exist but are filtered out. ### Learning Hub Tables diff --git a/docs/developer-guide.md b/docs/developer-guide.md index 0971246..f5bdf1f 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -243,24 +243,19 @@ docker exec -w /app pediatric-ai-scribe npm run migrate:new -- add_my_table 3. Admin-editable automatically through `PUT /api/admin/config` which accepts arbitrary keys. -## Physician memory / correction tracker +## Physician Templates And Preferences -1. On note generation, `trackAIOutput(elementId, text)` captures the original - output in memory. -2. User edits the note in a contenteditable field. -3. On Save, `saveCorrection(elementId, section)` diffs current vs. original. -4. If changed by > 2 words or > 20 characters, `POST /api/memories/correction` - stores the before/after in `user_memories` with category - `correction_{section}`. -5. Next generation: `GET /api/memories/context` fetches the 10 most recent per - category and `src/utils/prompts.js` injects them as - `[STYLE HINTS (low priority)]` 200-character snippets. - -Tabs with correction capture: Live Encounter, SOAP, Dictation, Sick Visit, -Well Visit (Hospital Course and Chart Review save corrections when available -but don't always have a trackable single output element). - -Maximum 20 corrections retained per category (oldest deleted). +1. Settings saves user templates/preferences through `/api/memories` into + `user_memories`. +2. New rows encrypt `name` and `content` with the shared `enc1:` string format. +3. `GET /api/memories/context` decrypts rows and returns only AI-context + categories: `physical_exam`, `ros`, `encounter_format`, `family_history`, + `assessment_plan`, `template_soap`, `template_hpi`, `template_wellvisit`, + `template_sickvisit`, and `template_ed`. +4. `custom` rows remain visible in settings but are not included in prompt + context. +5. Legacy `correction_*` rows from the removed correction-learning feature are + filtered out rather than deleted. ## Route reference diff --git a/docs/logic/ai-and-voice.md b/docs/logic/ai-and-voice.md index afc950b..ff882eb 100644 --- a/docs/logic/ai-and-voice.md +++ b/docs/logic/ai-and-voice.md @@ -916,16 +916,15 @@ signatures are simple and the provider branches are well-isolated. A worked example of how the layers compose. Tab: Sick Visit. 1. **Frontend collects inputs.** `sickVisit.js` reads: - - The transcript area (which holds either browser-whisper output or - the result of `transcribeAudio` after recording stop). + - The transcript area, populated by the configured transcription API or + the explicit opt-in browser speech-recognition fallback. - The structured ROS / PE radio buttons (NORMAL / ABNORMAL / NOT REVIEWED + free-text per-system notes). - Patient age and chief complaint. - The selected model (`getSelectedModel()` — tab-level dropdown wins over global). -2. **Optional memory injection.** If user memories are enabled, - `getUserMemoryContext()` pulls saved style hints (with the - `[STYLE HINTS (low priority)]` framing — see `docs/ai-providers.md`). +2. **Optional template injection.** `getUserMemoryContext()` pulls saved + AI-context templates and preferences from `/api/memories/context`. 3. **POST to /api/sick-visit.** The route: - Wraps every user-derived chunk in `` blocks via `wrapUserText`. diff --git a/docs/logic/architecture.md b/docs/logic/architecture.md index 4f72a44..62afe63 100644 --- a/docs/logic/architecture.md +++ b/docs/logic/architecture.md @@ -744,7 +744,7 @@ From `server.js:229–303`: | `routes/refine.js` | `/api` | Take a draft note + correction prompt, return refined note | | `routes/logs.js` | `/api` | Client-side error log ingest (`/api/logs/client-error`) | | `routes/encounters.js` | `/api` | **Sacred.** Save / load / list / delete `saved_encounters`. Optimistic lock + idempotency. See section 13 | -| `routes/memories.js` | `/api` | CRUD on `user_memories` (style hints, templates) | +| `routes/memories.js` | `/api` | CRUD on `user_memories` (templates and prompt preferences) | | `routes/notes.js` | `/api` | CRUD on `personal_notes` + voice-to-AI-note + trash/restore | | `routes/documents.js` | `/api` | S3 doc upload / list / download / delete (metadata in `user_documents`) | | `routes/audioBackups.js` | `/api` | Server-side audio retry store (encrypted gzip, 24h TTL) | @@ -979,9 +979,10 @@ Nextcloud or are exported. Created via migration `1777003849000_add-personal-notes.js`, soft-delete added via `1777090000000_notes-trash.js`. -**Distinct from `user_memories`.** Memories are AI prompt fuel -(templates / style hints) — they get injected into LLM calls. Notes -are pure clinician text that never goes to an AI. Both are encrypted. +**Distinct from `user_memories`.** Memories store user templates and +preferences. Only the AI-context categories are injected into LLM calls; +`custom` rows are stored but excluded from prompt context. Notes are pure +clinician text that never goes to an AI. Both are encrypted. ### `user_memories` — AI prompt fuel @@ -989,7 +990,7 @@ are pure clinician text that never goes to an AI. Both are encrypted. | ------ | ---- | ----- | | `id` | SERIAL PK | | | `user_id` | INTEGER FK (CASCADE) | | -| `category` | TEXT NOT NULL DEFAULT 'custom' | `physical_exam`, `ros`, `encounter_format`, `family_history`, `assessment_plan`, `custom`, `template_soap`, `template_hpi`, `template_wellvisit`, `template_sickvisit`, `template_ed`, legacy `correction_*` (filtered out) | +| `category` | TEXT NOT NULL DEFAULT 'custom' | `physical_exam`, `ros`, `encounter_format`, `family_history`, `assessment_plan`, `custom`, `template_soap`, `template_hpi`, `template_wellvisit`, `template_sickvisit`, `template_ed`. Legacy `correction_*` rows may exist but are filtered out. | | `name` | TEXT NOT NULL | **Encrypted** | | `content` | TEXT NOT NULL | **Encrypted** | | `created_at`, `updated_at` | TIMESTAMPTZ | | @@ -1030,7 +1031,7 @@ guardrail. **Retention.** None — explicit. These tables grow forever. Disk should be sized accordingly. A future migration is on the roadmap. -### `audio_backups` — failed-transcription retry store +### `audio_backups` — 24-hour transcription recovery store | Column | Type | Notes | | ------ | ---- | ----- | @@ -1043,9 +1044,9 @@ should be sized accordingly. A future migration is on the roadmap. | `created_at`, `expires_at` | TIMESTAMPTZ | 24h default | **Who writes.** `routes/audioBackups.js` from the frontend -`audioBackup.js` lifecycle when a transcription call fails — the -client uploads the gzipped audio so the user can retry without -re-recording. +`audioBackup.js` lifecycle when a transcription call fails. The client +uploads encrypted gzipped audio so the user can retry without re-recording; +expired rows are deleted by the database cleanup job. **Retention.** 24 hours via hourly cleanup. Audio is the most sensitive PHI in the system; short retention is intentional. diff --git a/docs/logic/clinical-notes.md b/docs/logic/clinical-notes.md index 122eed0..3e66c9b 100644 --- a/docs/logic/clinical-notes.md +++ b/docs/logic/clinical-notes.md @@ -1404,8 +1404,8 @@ reference shape. router.post('/', authMiddleware, async function(req, res) { try { var { ..., physicianMemories, model } = req.body; - // Validate inputs, build context with wrapUserText() per field. - // Append style hints if physicianMemories. + // Validate inputs, build context with wrapUserText() per field. + // Append template preferences if physicianMemories. var result = await callAI([ { role: 'system', content: PROMPTS. + INJECTION_GUARD }, { role: 'user', content: context }