Skip to content

Add HealthKit integration, FHIR normalization, dashboard redesign, and clinical records#8

Merged
chehanw merged 12 commits intomainfrom
Chehan-branch
Feb 11, 2026
Merged

Add HealthKit integration, FHIR normalization, dashboard redesign, and clinical records#8
chehanw merged 12 commits intomainfrom
Chehan-branch

Conversation

@chehanw
Copy link
Collaborator

@chehanw chehanw commented Feb 11, 2026

HealthKit Integration, FHIR Normalization, Dashboard Redesign & Clinical Records

♻️ Current situation & Problem

This PR represents the cumulative development work on Chehan-branch since the last merge (#5). The app previously had a basic onboarding flow with chatbot-based medical history collection, but lacked:

  • HealthKit data collection: No activity, sleep, or vitals queries from Apple Health.
  • Clinical records support: No ability to import medications, labs, conditions, or procedures from Apple Health clinical records (FHIR).
  • Medical history prefill: The chatbot asked ALL questions manually regardless of available health data.
  • Home dashboard: The main app experience was a placeholder with no useful summary views.
  • Daily check-in companion: The Health tab had no meaningful patient-facing view.

⚙️ Release Notes

HealthKit Integration

  • Implement comprehensive HealthKit client for activity (steps, exercise, sedentary time), sleep (stages, efficiency), and vitals (HR, HRV, SpO2, respiratory rate)
  • Add getBiologicalSex(), getDateOfBirth(), and getDemographics() for patient demographics
  • Add health data test screen in onboarding for verifying HealthKit connectivity

Clinical Records Module

  • Add expo-clinical-records native module wrapping Apple Health clinical records (HKClinicalRecord)
  • Implement ClinicalRecordsClient with typed helpers for medications, lab results, conditions, and procedures
  • Add clinical records permission card to onboarding permissions screen

FHIR Normalization Layer (lib/services/fhir/)

  • Parser: Parse raw FHIR JSON into normalized resources, handling Bundles and DSTU2/R4 formats
  • Medication classifier: Classify medications into BPH drug classes (alpha blockers, 5-ARIs, anticholinergics, beta-3 agonists) via LOINC/RxNorm code matching with text fallback
  • Lab extractor: Extract PSA, HbA1c, urinalysis from Observation resources using LOINC codes
  • Condition mapper: Map conditions to diabetes/hypertension/BPH/other using SNOMED CT and ICD-10 codes
  • Procedure mapper: Separate BPH procedures (TURP, HoLEP, UroLift, Rezum, etc.) from general surgical history
  • Prefill builder: Orchestrate all classifiers to build MedicalHistoryPrefill with confidence scores and provenance
  • Prompt modifier: Generate modified chatbot system prompt that skips known fields and focuses on gaps

Medical History Prefill Integration

  • Medical history screen now shows loading spinner while fetching clinical records + demographics
  • If health records provide data, chatbot receives a modified prompt that skips known fields
  • If fully prefilled, shows summary screen with option to proceed to gap-filling chatbot
  • Structured data (medications, conditions, procedures) persisted to onboarding service on continue

Dashboard & Navigation Redesign

  • Redesign Home tab as a study dashboard with surgery countdown, daily task cards, and health summary
  • Redesign Health tab as a Daily Check-In companion view
  • Restructure tab navigation (Home, Health, Chat, Contacts, Profile)
  • Add concierge chat tab for ongoing patient support

Bug Fixes

  • Fix reset onboarding button not redirecting immediately
  • Fix missing MEDICAL_HISTORY route in DevToolBar
  • Fix chatbot and enrollment flow ordering (medical records after consent)
  • Add clinicalRecords to OnboardingData.permissions type (was causing TS error)
  • Fix stale onboarding service tests (isComplete and reset out of sync with ONBOARDING_FINISHED flag)

Infrastructure

  • Add native iOS and Android build configurations
  • Add HealthKit entitlements and Info.plist usage descriptions
  • Configure metro bundler for monorepo workspace resolution

📚 Documentation

  • All new FHIR service files include JSDoc comments explaining matching strategies (code-based vs text fallback), confidence scoring, and data flow
  • PrefillEntry<T> pattern documented with confidence levels (high = code match, medium = text match, none = no data)
  • Medical history screen comments updated to reflect the new loading → prefill → chatbot flow
  • HealthKit client functions documented with Apple privacy caveats (read permissions always return "not determined")

✅ Testing

  • All 291 tests pass (npm test — services + workspaces)
  • Zero TypeScript errors (npx tsc --noEmit)
  • Fixed 2 pre-existing test failures in onboarding-service.test.ts:
    • isComplete test now correctly mocks ONBOARDING_FINISHED storage key
    • reset test now includes ONBOARDING_FINISHED in expected multiRemove array
  • FHIR normalization layer is deterministic and testable (pure functions, no side effects)
  • HealthKit and clinical records queries are guarded with .catch(() => null) fallbacks so the app degrades gracefully on simulators or devices without health data

📝 Code of Conduct & Contributing Guidelines

By submitting this pull request, I agree to follow the Code of Conduct and Contributing Guidelines:

chehanw and others added 12 commits January 29, 2026 01:20
The MEDICAL_HISTORY step was added to OnboardingStep enum and ONBOARDING_FLOW
but never added to the DevToolBar path map, causing a crash when navigating
back from BASELINE_SURVEY.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…leep, and vitals

This is a major feature commit that adds full HealthKit data querying capabilities
for the HomeFlow BPH study, including daily activity tracking, sleep stage analysis,
and Apple Watch vitals collection.

New Features:
- Daily activity queries: steps, exercise/move/stand minutes, sedentary time estimation
- Sleep queries with iOS 16+ stage support (Awake/Core/Deep/REM) and legacy fallback
- Vitals queries: heart rate stats, resting HR, HRV (SDNN), respiratory rate
- Date range utilities for bucketing health samples by day
- Debug panel UI for testing 7/30 day data fetches
- Detailed permission status tracking

New Types:
- DailyActivityDay, SleepNight, SleepStage enum, VitalsDay
- PermissionResult with granted/denied/notDetermined arrays
- Query result types (DailyActivityResult, SleepResult, VitalsResult)

API Additions:
- getDailyActivity(range), getSleep(range), getVitals(range)
- getDateRange(days), date bucketing utilities
- HealthKitService.querySleepSamples() for category type queries
- HealthKitService.requestAuthorizationWithStatus() for detailed permissions

Testing:
- 75 tests covering date utilities, sleep stage mapping, sedentary calculation

Note: Sedentary time is approximated as (16h waking - exercise - stand) since
HealthKit doesn't track sedentary time directly. This is documented as a limitation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Delete old packages/healthkit/ workspace and rebuild as a clean service
layer under lib/services/healthkit/ using @kingstinct/react-native-healthkit
directly with correct Nitro module API signatures.

New service layer:
- types.ts: DailyActivity, SleepNight, VitalsDay, HealthPermissionResult
- mappers.ts: Date helpers, sample bucketing, sleep stage mapping
- HealthKitClient.ts: requestHealthPermissions(), getDailyActivity(),
  getSleep(), getVitals() with correct filter/limit/unit query options
- index.ts: Barrel exports

Data pulled:
- Activity: steps, exercise/move/stand minutes, sedentary (estimated),
  active energy, distance
- Sleep: stages (Core/Deep/REM/Awake) on iOS 16+, fallback to
  asleep/inBed on older iOS
- Vitals: heart rate (min/avg/max), resting HR, HRV SDNN,
  respiratory rate, SpO2

Updated health.tsx debug panel and permissions.tsx to use new service.
Removed @spezivibe/healthkit workspace reference from package.json
and tsconfig.json.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add ios/, android/, and plugins/ directories for native builds
- Configure HealthKit with background delivery and deployment target 16.0
- Update onboarding flow and service
- Remove Swift 6.0.3 compiler crash workaround (now on Swift 6.2.1)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace raw debug panel with calm, section-based health summary
for BPH patients (age 50+). Add view-model layer that derives
plain-language insights from HealthKit data, with expandable
Sleep, Activity, and Vitals cards using subtle color-tinted
dark mode palette (indigo/teal/rose).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Notify the onboarding status hook after reset so the root layout
re-evaluates and declaratively redirects to the onboarding flow
without requiring an app restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace parallax Home screen with dashboard showing surgery countdown,
  watch reminders, daily tasks, and study progress cards
- Restructure tab bar: add Voiding, Profile tabs; hide old Explore,
  Contacts, Schedule tabs; update styling and icons
- Upgrade Chat tab to concierge chat helper with guided playbook
- Add new screens: profile, voiding log, consent viewer
- Add hooks for surgery date tracking and watch usage monitoring
- Add SurgeryCompleteModal component and consent document content
- Update permissions, DevToolBar, and icon-symbol for new flows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…est screen

Adds expo-clinical-records native module for FHIR clinical data access,
withClinicalRecords config plugin for entitlements, and health data test
screen in onboarding flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…records

Build a deterministic FHIR parsing layer that extracts medications, labs,
conditions, and procedures from Apple Health clinical records to pre-fill
medical history fields. The chatbot now only asks about gaps instead of
all fields. Also adds HealthKit demographics (age, biological sex),
clinical records permission to onboarding, and fixes stale tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move useEffect before early return in onboarding index (rules-of-hooks)
- Wrap strings with apostrophes in JSX expressions (react/no-unescaped-entities)
- Merge duplicate healthkit imports in health-data-test
- Remove unused error variable in permissions catch block
- Use T[] syntax instead of Array<T> in questionnaire

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@chehanw chehanw merged commit 6b61afe into main Feb 11, 2026
5 checks passed
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