// ============================================================ // SHARED TYPES — consumed by both server (src/routes/*.ts) and // client (client/src/*). A response-shape change here breaks the // build on both sides until they agree. // // This is the single most important file in the TypeScript // migration. Three of the bugs we hit before this point were // response-shape mismatches (refine returned `content` vs // `refined`, sick-visit endpoint path mismatch, hospital-course // key mismatch). Typing the wire protocol makes them compile-time // errors. // // Keep this file strictly about wire protocol — no DB row shapes, // no server-internal helpers. Anything that crosses the network. // ============================================================ // ── Envelope ───────────────────────────────────────────────── // Every route returns either `{success: true, ...extraFields}` or // `{success: false, error: string}`. The generic `T` is the shape // of the extra fields on success. Client code does: // const r: ApiResponse = await fetch(...).then(r => r.json()); // if (r.success) console.log(r.hpi); // else showToast(r.error); export interface ApiErr { success: false; error: string; } export type ApiResponse = ({ success: true } & T) | ApiErr; // Model tag accompanies every AI response — LiteLLM pass-through. export interface WithModel { model: string; } // ── AI generation responses ────────────────────────────────── // Keys match exactly what each route returns today. Do not rename // without updating the server-side res.json() call in the same commit. // /api/generate-hpi-encounter // /api/generate-hpi-dictation export interface HpiOk extends WithModel { hpi: string; } // /api/generate-soap export interface SoapOk extends WithModel { soap: string; } // /api/sick-visit/note (NOT /api/generate-sick-visit — that path does not exist) // /api/well-visit/note export interface VisitNoteOk extends WithModel { note: string; } // /api/generate-hospital-course export interface HospitalCourseOk extends WithModel { hospitalCourse: string; format?: string; } // /api/generate-chart-review export interface ChartReviewOk extends WithModel { review: string; } // /api/generate-pe-narrative export interface PeNarrativeOk extends WithModel { narrative: string; summary: { normal: number; abnormal: number; notAssessed: number; }; } // /api/generate-milestone-narrative export interface MilestoneNarrativeOk extends WithModel { narrative: string; summary: { achieved: number; notAchieved: number; notAssessed: number; }; } // /api/generate-milestone-summary export interface MilestoneSummaryOk extends WithModel { summary: string; } // /api/well-visit/shadess export interface ShadessOk extends WithModel { assessment: string; } // /api/refine export interface RefineOk extends WithModel { refined: string; } // /api/shorten (via refine.js router) export interface ShortenOk extends WithModel { shortened: string; } // /api/clarify and /hospital-course/clarify export interface ClarifyOk extends WithModel { questions: string; } // /api/suggest-billing-codes export interface BillingCodesOk extends WithModel { icd10: Array<{ code: string; description: string; reason?: string }>; cpt: Array<{ code: string; description: string; reason?: string }>; } // /api/transcribe export interface TranscribeOk { text: string; provider: string; duration: number; } // /api/tts export interface TtsOk { audioBase64: string; } // /api/models export interface ModelsOk { models: Array<{ id: string; label?: string }>; } // ── Auth ───────────────────────────────────────────────────── export interface AuthUser { id: number; email: string; name: string; role?: string; isVerified?: boolean; has2FA?: boolean; } // /api/auth/login (two-phase: may also return requires2FA / needsVerification) export interface LoginOk { token: string; user: AuthUser; sessionId?: string; } export interface LoginRequires2FA { success: true; requires2FA: true; } export interface LoginNeedsVerification { success: true; needsVerification: true; } // /api/auth/me export interface MeOk { user: AuthUser; } // ── Sessions ───────────────────────────────────────────────── export interface SessionRow { id: string; userAgent?: string; ipAddress?: string; createdAt: string; lastUsedAt?: string; } export interface SessionsOk { sessions: SessionRow[]; currentSessionId: string | null; } // ── Extensions (pagers/directory) ──────────────────────────── export interface Extension { id: number; location: string; name: string; number: string; type: 'extension' | 'pager'; notes?: string; deletedAt?: string | null; } export interface ExtensionsListOk { items: Extension[]; } // ── Memories (saved templates / style hints) ───────────────── export interface Memory { id: number; category: string; name: string; content: string; } export interface MemoriesListOk { items: Memory[]; } // ── Learning hub ───────────────────────────────────────────── export interface LearningContentItem { id: number | string; slug?: string; title: string; category?: string; excerpt?: string; body?: string; } export interface LearningFeedOk { content: LearningContentItem[]; total?: number; } // ── Encounters (saved drafts) ──────────────────────────────── export interface EncounterSummary { id: number; label: string; type: 'encounter' | 'dictation' | 'hospital' | 'chart' | 'wellvisit' | 'sickvisit' | 'soap'; createdAt: string; updatedAt: string; } export interface EncountersListOk { items: EncounterSummary[]; } // ── Health ─────────────────────────────────────────────────── export interface HealthOk { ok: boolean; }