Some checks failed
Forgejo Android APK / Root app tests (push) Successful in 47s
Forgejo Docker Build / Root app tests (push) Successful in 48s
Forgejo Android APK / Build signed APK (push) Successful in 2m38s
Forgejo Docker Build / Build Docker image (push) Successful in 12s
Forgejo Docker Build / Deploy to the host (push) Failing after 2s
Three pairs of docs described the same thing twice, and the copies had drifted
apart. Merged each into one file, keeping the unique content from both:
- ARCHITECTURE.md -> architecture.md (its operational map: ownership, request
flow, runtime boundaries, source of truth, deployment shape)
- DEVELOPMENT.md -> developer-guide.md (change workflow, Clinical Assistant
high-risk areas, frontend rendering rules, deployment checks)
- transcription-options.md -> speech.md (the clinic setup table, and the list
of browser-Whisper paths that must stay removed)
Then audited what remained against the code and the live database rather than
against the previous docs. Corrected:
- Google Vertex was still documented as a provider across nine files. The SDK
is gone; AI_PROVIDER=vertex now logs an advisory and falls back to
OpenRouter, and Gemini is reached through LiteLLM. Fixed the provider
selection order to match src/utils/ai.js, which starts from LITELLM_API_BASE.
- promptSafe was documented on 8 routes; it is on 13.
- Node 20 -> 24, "24 vanilla JS modules" -> no fixed count, and
transcribe.js/tts.js -> sttProvider.js/ttsProvider.js, which is what exists.
- STT/TTS are LiteLLM-only; README listed direct Google, AWS Transcribe and
ElevenLabs paths that are not in the runtime.
- Learning Hub PPTX export was documented as pptxgenjs, which is not a
dependency. It is pandoc against a reference deck.
- POST /api/admin/milestones/seed does not exist; it is /bulk-import.
- NEXTCLOUD_URL and NTFY_TOPIC are not read anywhere. Nextcloud is per-user in
the users table, and the ntfy topic is derived as pedscribe-{userId}.
- A prose paragraph sat inside the Clinical Assistant settings table, so half
the rows rendered as text.
Filled the gaps the audit exposed:
- database.md was missing 12 of 29 tables, including user_resources,
personal_notes, login_codes, registration_invites and generated_image_jobs.
- developer-guide.md was missing 11 routers and 10 frontend modules.
- api-reference.md detailed 121 of 244 endpoints and said so, but whole
features were absent. Added an endpoint index covering Clinical Assistant,
My Resources, Notes, Diagrams, ED Encounters, invites and sign-in codes.
- configuration.md was missing METRICS_TOKEN, REDIS_URL, API_RATE_LIMIT_MAX,
the LITELLM_* model variables, the DB_* ones maintenance.js reads, and the
per-purpose S3 resolution scheme.
- clinical-assistant.md documented 2 of its 17 environment variables.
- features-explained.md had no entry for My Resources or Clinical Assistant.
Renamed the three remaining SHOUTING filenames to kebab-case, which is what the
docs viewer's prettyName() was working around, and rewrote README's index,
which listed architecture.md twice and omitted nine files.
Noted but not changed: the Turnstile site key is hardcoded in index.html rather
than read from TURNSTILE_SITE_KEY, and /api/health/detailed can report
tts: 'elevenlabs' though no ElevenLabs path exists.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
93 lines
4.1 KiB
Markdown
93 lines
4.1 KiB
Markdown
# Application Architecture Logic
|
|
|
|
This is the long-form companion to [`../architecture.md`](../architecture.md).
|
|
Older versions of this file tried to document every source line and frontend
|
|
wrapper pattern; that became stale as Ped-AI moved selected areas to ES modules,
|
|
added cookie-based web auth, migrations, Redis, metrics, patient education, and
|
|
mobile support.
|
|
|
|
## Current Shape
|
|
|
|
- Runtime: Node.js 24 + Express 4 in Docker.
|
|
- Data: PostgreSQL 16 with pgvector, plus Redis for operational cache/prompt
|
|
suggestion groundwork.
|
|
- Schema: idempotent baseline init in `src/db/database.js` plus versioned
|
|
migrations in `migrations/` through `node-pg-migrate`.
|
|
- Frontend: vanilla JS SPA. Many files are still classic deferred scripts;
|
|
isolated newer areas use ES modules. There is no frontend bundler.
|
|
- Auth: web uses the `ped_auth` httpOnly cookie; mobile uses secure token
|
|
storage and `Authorization: Bearer` headers. `user_sessions` is authoritative.
|
|
- AI: `src/utils/ai.js` routes to LiteLLM, OpenRouter, Bedrock, or Azure
|
|
based on startup configuration and server-side model allowlists.
|
|
- Speech: server-side STT through LiteLLM plus explicit opt-in browser Web Speech
|
|
preview. Browser Whisper/browser-local model downloads are not part of the
|
|
runtime.
|
|
- Observability: `/metrics`, structured JSONL logs, Postgres audit/API/access
|
|
logs, and optional direct Loki push.
|
|
|
|
## Composition Root
|
|
|
|
`server.js` owns the boot and routing order:
|
|
|
|
1. Load environment and core middleware.
|
|
2. Apply Helmet/CSP, CORS, cookie parsing, metrics, JSON limits, rate limiters,
|
|
static file serving, and logging.
|
|
3. Mount auth, admin, Learning Hub, clinical workflow, storage, user data,
|
|
metrics, and utility routers.
|
|
4. Serve the SPA fallback for non-API paths.
|
|
5. Drain audit queues and close Postgres on shutdown.
|
|
|
|
For exact current route mounts, read `server.js` and `src/routes/*.js`.
|
|
|
|
## Frontend Pattern
|
|
|
|
- `public/index.html` is the SPA shell.
|
|
- `public/components/*.html` contains lazy-loaded tab fragments.
|
|
- `public/js/app.js` handles tab activation and dispatches
|
|
`CustomEvent('tabChanged', { detail: { tab } })`.
|
|
- Feature scripts initialize their DOM only when the relevant tab is active.
|
|
- Shared browser helpers are still exposed through `window.*` where needed.
|
|
- New isolated frontend work should prefer small ES modules where the existing
|
|
page load order supports it, but do not rewrite unrelated clinical flows just
|
|
for style.
|
|
|
|
## Data And PHI
|
|
|
|
- Sensitive fields use `src/utils/crypto.js` AES-256-GCM helpers.
|
|
- `user_memories.name` and `user_memories.content` are encrypted for new rows.
|
|
- `audio_backups.audio_data` is gzipped and encrypted, then deleted after its
|
|
short expiry window.
|
|
- `saved_encounters` expire by `site.auto_delete_days`.
|
|
- Audit details are PHI-redacted before database insert.
|
|
|
|
## Operational Boundaries
|
|
|
|
- Ped-AI owns the clinical UI, prompts, provider selection, note helpers,
|
|
patient education, and local user data.
|
|
- External MCP/Nextcloud services own retrieval/indexing when used by clinical
|
|
assistant features.
|
|
- Clinical answer response caching is intentionally avoided; Redis is for
|
|
operational metadata and prompt suggestions, not answer reuse.
|
|
|
|
## High-Risk Areas
|
|
|
|
Treat these as small-diff zones unless you are deliberately testing a broader
|
|
refactor:
|
|
|
|
- Auth/session/crypto: `src/middleware/auth.js`, `src/routes/auth.js`,
|
|
`src/routes/oidc.js`, `src/utils/crypto.js`, `src/utils/sessions.js`.
|
|
- Recording/STT plumbing: `AudioRecorder` in `public/js/app.js`,
|
|
`public/js/audioBackup.js`, `public/js/speechRecognition.js`,
|
|
`src/routes/transcribe.js`.
|
|
- Encounter persistence: `src/routes/encounters.js` and
|
|
`public/js/encounters.js`.
|
|
- Validated calculators/reference data: `public/js/calc-math.js`,
|
|
`public/js/calculators.js`, `public/data/**`, bedside calculator modules,
|
|
and tests under `test/`.
|
|
- ED MDM/finalization prompts and billing-related helpers.
|
|
|
|
## Keep Current
|
|
|
|
Do not add file-line citations here unless a test locks them down. Prefer
|
|
describing responsibilities and pointing to file paths. If implementation moves,
|
|
update this doc in the same commit.
|