Skip to content

Add Prep for Doctor Appointment tab; merge Health + Documents - #40

Merged
bisonbet merged 3 commits into
mainfrom
feat/appointment-prep
Jun 19, 2026
Merged

Add Prep for Doctor Appointment tab; merge Health + Documents#40
bisonbet merged 3 commits into
mainfrom
feat/appointment-prep

Conversation

@bisonbet

Copy link
Copy Markdown
Owner

Summary

Adds a Prep for Doctor Appointment primary tab and merges the Health Data + Documents tabs into one Health tab.

The Prep feature is ported from the Python medical-appt-prep tool and enhanced to pull the user's existing health record into the LLM context. The user enters this visit's symptoms/notes; the app auto-fills medications and feeds labs, conditions, and relevant documents to the model, then runs a three-call workflow producing a Timeline, Questions for the doctor, and Relevant Info. Reports are saved, editable, and exportable (share / print / copy).

What's included

  • Model + persistenceAppointmentPrep stored as an encrypted blob; DB migration v7 → v8 adds the appointment_preps table (create paths + migration case + index).
  • Generation engine — prompts ported verbatim (AppointmentPrepPrompts); validation + output cleaning ported from processor.py (AppointmentPrepProcessor). AppointmentPrepManager runs the 3 calls through the existing AIProviderInterface (Bedrock / OpenAI-compatible / on-device MLX) with progressive section updates, medication prefill, and JSON health-context assembly (same builder AI Chat uses).
  • UIAppointmentPrepView (saved list), AppointmentPrepEditorView (inputs + live generation), AppointmentPrepDetailView (view/edit + export).
  • Tab merge — new HealthTabView hosts Records/Documents behind a themed segmented scope switch in the navigation title; HealthDataView/DocumentsView gained an embedInNavigation flag (default true, so standalone behavior is unchanged).
  • Tests — unit tests for the ported processor logic.
  • DocsCLAUDE.md updated (DB version 8 + components).

Notes

  • Tabs are now: Health · Prep · AI Chat · Settings.
  • Within the merged tab, iPad document detail opens as a sheet (the split view can't coexist with a single shared title bar); DocumentsView's split code is preserved behind the default flag.
  • The segmented scope switch is a custom themed control because the native .segmented style renders the selected label unreadably against the dark theme.

Testing

  • xcodebuild ... -destination 'generic/platform=iOS Simulator' buildBUILD SUCCEEDED (no warnings from new code, including Swift 6 concurrency).
  • Added AppointmentPrepProcessorTests.

🤖 Generated with Claude Code

Adds a "Prep" primary tab that turns this visit's symptoms/notes plus the
user's existing health record into an organized report (timeline, questions
for the doctor, relevant info), ported from the medical-appt-prep tool and
enhanced to auto-pull meds, labs, conditions, and relevant documents into
the LLM context. Reports are saved, editable, and exportable (share/print/copy).

- Model + encrypted persistence (DB migration v7 -> v8, appointment_preps table)
- Prompts ported verbatim; output cleaning/validation ported from processor.py
- AppointmentPrepManager runs the 3-call workflow via the existing AI provider
  interface with progressive section updates
- Prep tab UI: list, editor with live generation, detail with export
- Merge Health Data + Documents into one "Health" tab with a themed segmented
  scope switch in the navigation title (child views gain embedInNavigation)
- Unit tests for the ported processor logic
- Docs updated (CLAUDE.md DB version + components)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ba2bea796

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

} else if !selectedTypes.isEmpty {
categoriesToFilter = []
} else {
categoriesToFilter = nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Respect an empty appointment context selection

When the user turns off every “Include From My Record” toggle, selectedTypes is empty and this branch passes nil to fetchDocumentsForAIContext, which that API treats as “fetch all AI-context documents”; HealthContextJSON then includes those medical_documents even though selected_types is empty. In that opt-out scenario, generating a prep report can still send all included documents/PHI to the AI provider, so this should use an explicit empty filter or skip document fetching when no types are selected.

Useful? React with 👍 / 👎.

Persist partial appointment prep output when generation fails after producing sections.

Include appointment prep records in the encrypted Health Data iCloud backup payload and restore them when present.

Co-authored-by: OpenAI Codex <codex@openai.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fff8174338

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +111 to +112
if !lastLine.isEmpty && firstMatch(lastLine, pattern: "[.!?*_)]\\s*$") == nil {
lines.removeLast()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve complete bullets that omit punctuation

When a model returns a multi-line section whose final bullet is complete but does not end with punctuation, this cleanup drops that last item before the report is shown or saved. That is common for concise timeline/relevant-info bullets such as - Track whether symptoms worsen after meals, so users can lose one of the generated doctor-prep points even though the response was otherwise valid.

Useful? React with 👍 / 👎.

@bisonbet
bisonbet merged commit 9203ad8 into main Jun 19, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9904210115

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

errorMessage = nil
generationStage = .idle

var prep = input

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear stale report sections before regenerating

When an existing report is regenerated after the user edits symptoms or notes, var prep = input keeps the previous timeline, questions, and relevantInfo. If any provider call fails before all sections are overwritten, the catch path sees hasGeneratedContent from those stale sections and saves a “complete” prep with old doctor-prep content attached to the new inputs; clear the generated fields at the start of a run or distinguish content produced by this run.

Useful? React with 👍 / 👎.

@bisonbet
bisonbet deleted the feat/appointment-prep branch June 19, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant