| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { getDb } from './db'; |
| import { getUserSettings } from './user-settings'; |
| import { decodeHealthPayload } from './health-data-repo'; |
|
|
| export function buildPatientContextForUser(userId: string | null | undefined): string { |
| if (!userId) return ''; |
|
|
| const settings = getUserSettings(userId); |
| const ehr = (settings.ehr || {}) as Record<string, any>; |
|
|
| const db = getDb(); |
| const medRows = db |
| .prepare( |
| `SELECT data FROM health_data |
| WHERE user_id = ? AND type = 'medication' |
| ORDER BY updated_at DESC`, |
| ) |
| .all(userId) as Array<{ data: string }>; |
|
|
| const meds = medRows |
| .map((r) => { |
| try { |
| return decodeHealthPayload<Record<string, any>>(r.data); |
| } catch { |
| return null; |
| } |
| }) |
| .filter((m) => m && typeof m === 'object' && (m as any).active !== false); |
|
|
| const lines: string[] = []; |
|
|
| |
| const demo: string[] = []; |
| if (ehr.dateOfBirth) { |
| const t = new Date(ehr.dateOfBirth).getTime(); |
| if (Number.isFinite(t)) { |
| const age = Math.floor((Date.now() - t) / (365.25 * 86400000)); |
| if (age >= 0 && age < 130) demo.push(`age=${age}`); |
| } |
| } |
| if (ehr.gender && ehr.gender !== 'prefer-not-to-say') { |
| demo.push(`sex=${String(ehr.gender)[0].toUpperCase()}`); |
| } |
| if (demo.length) lines.push(demo.join(' ')); |
|
|
| if (Array.isArray(ehr.chronicConditions) && ehr.chronicConditions.length) { |
| lines.push(`conditions=${ehr.chronicConditions.join(', ')}`); |
| } |
|
|
| if ( |
| Array.isArray(ehr.allergies) && |
| ehr.allergies.length && |
| !ehr.allergies.includes('None known') |
| ) { |
| lines.push(`allergies=${ehr.allergies.join(', ')}`); |
| } |
|
|
| if (meds.length > 0) { |
| lines.push( |
| `medications=${meds |
| .map((m: any) => `${m.name || '?'} ${m.dose || ''}`.trim()) |
| .join(', ')}`, |
| ); |
| } |
|
|
| const life: string[] = []; |
| if (ehr.smokingStatus === 'current') life.push('smoker'); |
| else if (ehr.smokingStatus === 'former') life.push('ex-smoker'); |
| if (ehr.alcoholUse === 'heavy') life.push('heavy alcohol'); |
| if (life.length) lines.push(`lifestyle=${life.join(', ')}`); |
|
|
| if (lines.length === 0) return ''; |
| return `\n<patient_context>\n${lines.join('\n')}\n</patient_context>`; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function stripInjectedPatientContext(content: string): string { |
| if (!content) return ''; |
| return content |
| .replace(/\n?<patient_context>[\s\S]*?<\/patient_context>\s*/gi, '') |
| .replace(/(^|\n)\s*\[Patient:[^\]\n]*\](?=\n|$)/g, '') |
| .replace(/^\n+/, ''); |
| } |
|
|