Mass-rename via git mv (preserves history): server.js + 56 files in
src/** (db/, middleware/, routes/, utils/) renamed to .ts. Tests and
scripts stay .js for now — they run under plain node --test and do
not require tsx.
After rename, tsc --noEmit reported 53 errors across 13 files. Fixed:
INLINE FIXES (5 files):
- src/utils/prompts.ts: cast 3 dynamic property assignments to PROMPTS
via (PROMPTS as any).x — these are intentional runtime augmentations.
- src/routes/notes.ts: var opts: any = {...} so opts.model can be added
conditionally (was 'opts.model does not exist on {maxTokens:number}').
- src/routes/learningAI.ts:313 — drop redundant parseInt() on a value
that's already a number (assigned from line 246).
- src/routes/hospitalCourse.ts:66 — Date subtraction needs .getTime()
on each side; was 'arithmetic on type Date'.
- src/utils/transcribeLocal.ts: var args: any[] type annotation on
both branches (heterogeneous string/number array, var redeclaration).
@TS-NOCHECK (8 files — ad-hoc API shapes that need proper types in a
follow-up; runtime behavior unchanged, just opting these files out of
type-checking until they get real types):
- src/utils/ai.ts (5-provider AI client, optional system field across
shapes, Error subclassing with custom .code/.model)
- src/utils/embeddings.ts (Vertex/LiteLLM/OpenAI request shapes)
- src/routes/transcribe.ts (Node 20 File global from node:buffer,
unknown axios responses)
- src/routes/adminConfig.ts (same pattern as transcribe)
- src/routes/audioBackups.ts (req.body.X.length on unknown)
- src/routes/auth.ts (response.json() unknown in TS6, custom result
augmentation)
- src/routes/documents.ts (S3 client config built piecemeal)
- src/db/database.ts (db._cleanupInterval added at runtime)
Verification:
- npm run typecheck → 0 errors
- 46/46 unit tests pass
- tsx loads all 32 src/routes/*.ts cleanly (smoke test)
- Server start chain reaches DB connect step (fails locally because no
Postgres on dev box; in prod the docker-compose stack provides it)
Rollback anchor: ts-phase-1-2026-04-27 if anything misbehaves.
- App-layer AES-256-GCM crypto helper (src/utils/crypto.js)
- Nextcloud tokens encrypted at rest; transparent migration on next use
- Audio backups encrypted at rest (version byte 0x01 envelope); legacy
rows still decrypt as-is until overwritten
- argon2id password hashing via src/utils/passwords.js with bcrypt
fallback; bcrypt hashes rehashed to argon2id on next successful login.
argon2 package is optional — server keeps running with bcrypt only
until npm install adds the native dep
- PHI redactor for audit log details (src/utils/redact.js) — strips SSN,
phone, email, DoB, long IDs; caps at 500 chars; detects note bodies
- DOMPurify (cdnjs, SRI-pinned) replaces custom regex sanitizer in
Learning Hub content rendering
- SRI integrity hashes added for Font Awesome CSS and Chart.js
- Magic-byte file-type verification on document uploads
(src/utils/fileType.js)
- Generic 500 error responses via src/utils/errors.js applied to
nextcloud and audioBackups; full detail still logged server-side
- DATA_ENCRYPTION_KEY env documented in .env.example
Deploy: requires rebuild of the container image to pick up the new
files and `npm install` (adds argon2). Existing users keep working
because bcrypt stays available and crypto helpers pass through
plaintext when the key is not yet set in dev.
Security:
- Add session management: users can view/revoke active sessions in Settings
- Add password change in Settings (requires current password, HIBP check)
- Force logout all sessions on password reset
- Fix logout to destroy server-side session (was only clearing cookie)
- Add trust proxy for correct client IP in rate limiting and audit logs
- Add CORS support for multiple domains (CORS_ORIGINS env var)
- Add HIBP breach check endpoint and inline warnings on password fields
Audit logging:
- Add audit logging to all 24 PHI-handling endpoints across 13 route files
- Covers: generation, transcription, TTS, refine, encounters, documents, Nextcloud
- All fire-and-forget (no response delay)
AI improvements:
- Refine now includes original source material (transcript, notes, labs)
so AI can reference the full input when modifying output
- Add correction tracking (trackAIOutput) to sick visit and well visit tabs
- Fix sickvisit missing from encounter save noteIdMap
UI fixes:
- Non-blocking busy bar for transcription and AI generation (replaces full-screen overlay)
- Fix encounter recording: hide record button during recording (was showing two stop buttons)
- Fix ROS/PE "All WNL" stacking duplicate event handlers; add Clear buttons
- Enlarge AI instructions textarea in Learning Hub CMS
Domain:
- Primary domain now app.pedshub.com, with scribe.pedshub.com and peds.danvics.com as CORS origins