Point-of-care TEE case logger. Collapses a ~5-minute logging workflow into a ~40-second capture and tracks progress against ACGME / NBE (Advanced PTEeXAM, Basic PTE) case-minimum requirements.
- Native iOS only. No web components (no WKWebView, no HTML/JS, no React Native/Flutter), no backend, no cloud sync, no URLSession networking, no third-party packages. Everything is Apple system frameworks.
- De-identified by design: no name / MRN / DOB / hospital is ever stored (age / sex / BSA only).
Package.swift # SwiftPM: ACTATEEAssistantCore (pure Swift, Linux-testable) + tests
project.yml # XcodeGen project definition (do NOT hand-edit .xcodeproj)
ACTATEEAssistant/ # iOS app target
Models/ # SwiftData @Model entities (CaseLog, ValveFinding, QuizCard)
Engine/ # Apple-only engine glue (SpeechController, PDF renderers,
# QuizCardEnqueuer) — pure core engines compile into ACTATEEAssistantCore
Intents/ # App Intents (F1): LogTEE / ShowProgress / QuickFindings
Shared/ # ModelContainerFactory — app-group store shared with widget
ViewModels/ # @Observable view models (MVVM)
Views/ # SwiftUI screens + shared components (incl. Quiz/, Insights/)
Info.plist # usage strings (§10) — generated by XcodeGen from project.yml
ACTATEEAssistant.entitlements # app group (F1) — no network, no iCloud
ACTATEEWidget/ # WidgetKit extension (F1): total/totalMinimum complication
Tests/ACTATEEAssistantCoreTests/ # table-driven unit tests (run with `swift test`)
Core/tests are NOT Apple-only. ACTATEEAssistant/Models + Engine (enums, tracks,
requirements engine, auto-categorizer, dictation mapper, CSV writer) imports
only Foundation, so the engine logic is unit-testable on Linux with
swift test — no Xcode required:
$ swift test
On this Silverblue host (no system toolchain), tests run via rootless podman with the swift.org tarball mounted in:
$ podman build -t teelog-swift -f ~/swift/Dockerfile ~/swift # once
$ podman run --rm -v ~/swift:/swift:ro,Z -v "$PWD":/work:Z -w /work \
teelog-swift /swift/usr/bin/swift test
Result: 114 tests green (AutoCategorizer ×18, DictationMapper ×32, RequirementsEngine ×16, SpacedRepetition ×11, QuizCardGenerator ×17, InsightsEngine ×20).
- Install XcodeGen (
brew install xcodegen). xcodegen generatein this directory → producesACTATEEAssistant.xcodeproj.- Open
ACTATEEAssistant.xcodeproj, select the ACTATEEAssistant scheme, run on an iPhone simulator/device (iOS 17+). - Unit tests:
xcodebuild test -scheme ACTATEEAssistant -destination 'platform=iOS Simulator,name=iPhone 15'or justswift testfor the core engine.
The .xcodeproj is generated and git-ignored — project.yml is the source
of truth.
- P1 Skeleton — done (models, enums, tab shell, project definition)
- P2 Capture — done (Quick Log 3-step flow, Findings, auto-categorize, Dashboard + Library read views)
- P3 Requirements — done (engine, Progress screen, gap alerts)
- P4 Dictation — done (engine + mapper + SpeechController; DictationSheet with live chip fill while listening, confirmation diff, field-level mics on Procedure / Indication / Views / LV EF / RV / Valve lesions / Notes, speech-not-authorized + on-device-unavailable states with manual fallback)
- P5 Export — done (CSV writer; ACGME / NBE / PDF content builders; multi-page UIGraphicsPDFRenderer with wrapping + page breaks + footers; academic-year range; native preview; share sheet + Save PDF to Files)
- P6 Hardening — done (Face ID / passcode lock with settings toggle and background re-lock; VoiceOver labels incl. severity steppers and progress bars; Dynamic Type safe; ≥44 pt targets; Reduce Motion respected; system colors only; empty states on Dashboard, Library, Progress, Export, Findings)
- F3 Spaced-repetition quiz — done (SM-2 scheduler + question generator in ACTATEEAssistantCore; QuizCard model; Review · N cards due entry on the Library header; ReviewSessionView with Again/Good/Easy; cards auto-enqueued on case save, deduped per case)
- F1 Siri Shortcuts / hands-free capture — done (LogTEECaseIntent, ShowProgressIntent, QuickFindingsIntent + AppShortcuts provider; WidgetKit extension showing total/totalMinimum with actatee://quicklog tap-through to Quick Log; reload on every case save; shared app-group store + preferences)
- F2 Personal pattern insights — done (InsightsEngine aggregations + InsightsEngineTests; Insights screen from the Progress header with Swift Charts cards, one-line takeaways, tap-through to the filtered Library)
See IMPLEMENTATION.md (§12–§15) for phase details and open product
questions (track minima placeholders marked in Tracks.swift).