HealthProbe / HealthProbe / Doc / 04-project / IMPLEMENTATION_STATUS.md
1 contributor
81 lines | 10.265kb

HealthProbe - Implementation Status

Last Updated: 2026-05-31

Current Reality

The app currently contains a working SwiftUI + SwiftData prototype with HealthKit capture, snapshot/delta screens, and an initial SQLite archive store.

The product direction has changed. The target architecture is now: - iOS 15-era compatible; - direct SQLite archive/analysis database as source of truth; - differential observation storage; - Core Data UI/report cache; - Time Machine UI and scoped exports; - recovery-compatible archive/export format; - no in-app restore, backup patching, or HealthKit re-publication.

Current SwiftData models and anomaly-oriented naming are legacy/prototype implementation details.

There are no real deployments, only test installations. Existing prototype databases are disposable: the archive v2 refactor should reset, ignore, or reinitialize old SwiftData/prototype SQLite stores instead of preserving backward compatibility with them.

Status By Area

Area Current Status Target / Next Work
Product docs Updated Keep HealthProbe/Doc/README.md as canonical index
HealthKit capture Capture now opens one archive observation per user-visible snapshot, attaches HealthKit pages, deleted-object evidence, and type verification to that observation id before finishing it, no longer aborts initial full-history imports after a fixed 30-minute wall-clock cap while page-level HealthKit timeouts remain in place, defers grouped observation summary/daily aggregate rebuilds until per-type verification instead of rebuilding after every imported page, and persists large HealthKit pages in smaller archive chunks while using type-specific import strategies: conservative paging for the heaviest metrics, more aggressive pages/chunks for ordinary metrics, adaptive write chunk sizing, batched deleted-object persistence, explicit task yields, and lower-allocation streaming loops to avoid long monolithic SQLite stalls Continue moving UI/cache reads to archive-backed observation ids and revisit full checkpoint/resume and background collection separately
SQLite archive Archive v2 schema, snapshot-level observation grouping, differential write path, v2 verification/delete bookkeeping, daily aggregate rebuilds, integrity report, v2 record reads, SQL diff/count/aggregate/provenance/consolidation-evidence APIs, large synthetic diff pagination coverage, formal timing/memory metrics, and XCTest coverage are in place; the legacy archive_samples mirror has been removed, the hot write path now reuses prepared SQLite statements within grouped page writes instead of reparsing the same SQL for every sample, processes sample rows in a lower-allocation streaming loop, batches same-page deleted-object evidence in one transaction, adds composite indexes for visibility-range and sample-uuid hot lookups, and opens SQLite connections with import-friendly busy timeout / synchronous / temp-store pragmas Continue moving capture/Dashboard actions to archive/cache DTOs
Core Data cache Initial programmatic Core Data model, full-cache rebuild service, read DTOs for observation/type/diff/health rows, and Dashboard archive-cache status wiring are in place Move remaining export/report paths to cache DTOs and add targeted partial invalidation
SwiftData cache Exists; test builds now reset legacy prototype UI/archive/cache stores once for archive v2 so old SwiftData-only snapshots are not treated as backed-up observations. Metric timeout calibration, local device profile settings, operation logging, ContentView preview, Settings data maintenance, legacy detail/PDF views, unused legacy repair/observer services, Dashboard view/view-model access, and legacy anomaly/count-drop review have moved outside SwiftData or been removed. Remaining SwiftData imports are inventoried in SwiftData-Retirement-Inventory.md Treat as disposable prototype data; stop returning/storing HealthSnapshot bridge handles before removing ModelContainer
UI Prototype exists; Dashboard status reads archive/cache observation rows and shows cache health, and Dashboard view/view-model code no longer imports SwiftData or reads ModelContext; capture/review actions now route through DTOs and snapshot ids, with the remaining legacy bridge isolated in HealthKitService. Snapshots and Data Types tab roots no longer import SwiftData, load Core Data cached observation rows, and open archive/cache-backed detail rows; SnapshotArchiveDetailView and DataTypeArchiveDetailView read Core Data type/diff summaries and page record drill-down through SQLite; unused legacy SwiftData snapshot/type detail and PDF views have been deleted; record-change evolution and temporal distribution screens now receive DTO rows/cache input instead of querying SwiftData directly; export preview reads the archive export API before showing/exporting JSON; simplified detail mode replaces heavy charts with summary rows on small/accessibility layouts or when enabled in Settings; visible change labels now use neutral new/missing/change-review language; Settings can now schedule a full test-database reset for the next app launch Stop writing prototype HealthSnapshot bridge rows during capture/review
Diff/change explanation SQL diff summaries, paged diff records, aggregate comparisons, and consolidation-evidence labels exist; legacy anomaly/count-drop review has been removed from active flows; the old direct HealthSnapshot.typeCounts diff helper has been retired Keep active diff/count views on archive/cache DTOs
Export SQLite export preview, paged JSON writing, SHA256 manifest hashing, and export_manifests rows are in place for selected records and observation diffs Fill remaining recovery-compatible envelope metadata, CSV export, relationship preservation, and reproducibility checks
Legacy device support Simplified detail UI mode is implemented for small/accessibility layouts and as a Settings toggle Remove SwiftData dependency and validate lower deployment targets
Recovery workflows Not supported Preserve export/archive structure for external recovery tools only

Refactoring Priorities

Detailed checkable milestones live in Refactoring-Plan.md.

  1. Stop writing prototype HealthSnapshot bridge rows during capture/review.
  2. Add targeted cache invalidation for affected observation/type ranges.
  3. Finish remaining UI language cleanup from anomaly/status to observation/diff/export where legacy model names still leak into active flows.
  4. Complete recovery-compatible export metadata, CSV output, and reproducibility checks.
  5. Remove SwiftData dependency and validate lower deployment targets.

Known Prototype Mismatches

  • SwiftData currently blocks iOS 15-era device support.
  • Some screens still imply snapshot-count monitoring rather than Time Machine inspection.
  • Current UI/cache layers still depend on 4 SwiftData-backed files for launch container, capture bridge writes, and remaining model definitions.
  • Snapshots timeline/detail rows, Data Types list/detail rows, and record drill-down are archive/cache-backed for new archive v2 observations when cache rows exist.
  • Legacy SwiftData-only snapshots are reset for archive v2 test installs rather than migrated.
  • Capture strategy and some legacy SwiftData transition paths may still decode or cache too much data for low-end devices.
  • Very large first-run HealthKit imports may still require adaptive paging, retryable partial progress, and background-friendly collection beyond the current smaller pages, chunked persistence, and prepared-statement reuse. Diagnostic import reports now also expose explicit per-metric and aggregate fetch / processing / insert / finalize timings so large import runs can be compared without inferring phases from progress counters.
  • Old prototype database compatibility is no longer required.
  • Initial SQLite archive tests cover open/init/reset/idempotency, snapshot-level observation grouping, legacy mirror removal, small observation diffs, large synthetic diff pagination, formal timing/memory metrics, materialized aggregate comparison, source/provenance breakdowns, consolidation-evidence labels, export preview, paged JSON output, and manifest row persistence.
  • Initial Core Data cache tests cover full rebuild from SQLite and delete-cache-then-rebuild without losing archive data.

Verification Checklist

  • [x] SQLite archive v2 can reconstruct records visible at observation T.
  • [ ] No recurring complete snapshot copies are written for high-volume types.
  • [x] SQL diff between two observations runs without loading full datasets into Swift arrays.
  • [x] Snapshots timeline rows use Core Data cached observation counts/change summaries when cache rows are available.
  • [x] Snapshot tab navigation/detail rows use Core Data cached summaries plus SQLite diff summaries when archive observation ids are available.
  • [x] Data Types list rows use Core Data cached counts plus SQLite diff summaries when archive observation ids are available.
  • [x] Data type new/missing drill-down pages records from SQLite diff queries when archive observation ids are available.
  • [x] Data type diff detail and evolution summaries prefer Core Data cache rows when archive observation ids are available.
  • [x] Expensive counts used by reports/UI are cached and rebuildable.
  • [x] Deleting Core Data cache and rebuilding from SQLite restores UI/report summaries.
  • [x] Dashboard surfaces SQLite/Core Data cache health, cache schema, cache errors, and latest archive observation counts.
  • [x] Export can stream/page selected record sets without materializing the full record list.
  • [x] Export manifests include hashes and diff observation metadata when applicable.
  • [ ] iOS app remains read-only with respect to HealthKit.
  • [ ] Docs and UI do not claim in-app restore/re-publication support.
  • [x] Legacy/small-device UI mode preserves capture/report/export.

Historical Notes

Older status docs described a completed snapshot/anomaly/SwiftData system. That was true for the prototype direction, but it is no longer the target architecture.