# HealthProbe – Claude Code Instructions

## Project Context

**HealthProbe** is an iOS app that audits Apple HealthKit data integrity.  
It detects anomalies: data loss, historical insertions, duplicates, divergence trends.  
Full specification: `HealthProbe/Doc/HealthProbe – Complete Specification & Motivations.md`

**Current state:** Xcode scaffold only. `ContentView.swift` and `Item.swift` are default templates — replace them entirely.

---

## Claude Code Scope: UI Layer

Claude Code is responsible for:
- All **SwiftUI Views** (`Views/` directory)
- All **ViewModels** (`ViewModels/` directory)
- **Navigation structure** and tab/split layout
- **Design system** (colors, typography, spacing)
- **Preview providers** for all views
- **Accessibility** (VoiceOver, Dynamic Type)

Claude Code does NOT own:
- `Services/` — HealthKit queries, anomaly detection, sync monitoring (see AGENTS.md)
- `Models/` — SwiftData models (see AGENTS.md)
- Entitlements, Info.plist, project configuration

When services are not yet implemented, **consume their protocols and use mock implementations** for UI development.

---

## Target Screen Structure

```
App (TabView)
├── Tab 1: Dashboard          → DashboardView
├── Tab 2: Anomalies          → AnomalyListView → AnomalyDetailView
├── Tab 3: Audit Trail        → AuditTrailView
├── Tab 4: Sync Status        → SyncStatusView
└── Tab 5: Settings           → SettingsView
```

### DashboardView
- Large status indicator: ✅ Healthy / ⚠️ Check / 🚨 Critical
- Last check timestamp
- Summary cards: samples tracked, anomalies found (all-time)
- Up to 3 recent active alerts (tappable → AnomalyDetailView)
- "Check Now" button (calls monitoring service)

### AnomalyListView
- List of `DetectedAnomaly` sorted by date (most recent first)
- Filter: All / Critical / Warning / Info
- Filter: by type (deletion, insertion, duplicate, divergence)
- Each row: severity badge, type, sample type, date
- Swipe to mark resolved

### AnomalyDetailView
- Full anomaly details
- Evidence dictionary displayed as key-value rows
- Severity badge
- Share button → exports as Markdown (for bug reports)
- "Mark Resolved" action

### AuditTrailView
- Chronological list of `AuditTrailEntry`
- Each row: timestamp, event type chip, message
- Search/filter by event type
- Export button → JSON

### SyncStatusView
- Current iCloud sync state (chip: enabled / local-only)
- Last sync timestamp
- List of `SyncStateChange` events (most recent first)
- Visual indicator when sync is stalled (no event in > 48h)

### SettingsView
- Check frequency: 2h / 6h / 12h / 24h (Picker)
- Sample types to monitor (MultiSelect toggle list)
- Alert thresholds (severity level for push notifications)
- CloudKit sync toggle (off by default, with privacy disclaimer)
- Export all data (JSON)
- Delete all audit data (destructive, confirm alert)

---

## Design Guidelines

**Tone:** Professional, calm, medical-adjacent. Not alarming unless critical.

**Color System:**
```swift
// Status colors
.healthyGreen   // SF: green  — all clear
.warningAmber   // SF: yellow — attention needed  
.criticalRed    // SF: red    — action required
.neutralGray    // SF: gray   — informational / resolved
```

**Typography:** SF Pro (system font). No custom fonts.

**Spacing:** 8pt grid. Use `VStack(spacing: 12)` as baseline.

**Icons:** SF Symbols only. No third-party icon sets.

**Key SF Symbols:**
- `checkmark.shield.fill` — healthy status
- `exclamationmark.triangle.fill` — warning
- `xmark.shield.fill` — critical
- `clock.arrow.circlepath` — audit trail
- `antenna.radiowaves.left.and.right` — sync
- `waveform.path.ecg` — health data
- `doc.text.magnifyingglass` — anomaly detail

**Dark mode:** Required. Test in both modes.

**Privacy-first UI:**
- Health metric values are **never shown in plain text** in list rows
- Values visible only in `AnomalyDetailView` after tap
- Evidence dictionary values shown as monospace text, not highlighted

---

## SwiftData Integration

Models are defined in `Models/`. Reference them read-only from views:

```swift
// In views, use @Query — never write directly from a View
@Query(sort: \DetectedAnomaly.detectedAt, order: .reverse)
private var anomalies: [DetectedAnomaly]

// Mutations go through ViewModels or services only
```

Until `Models/` are implemented, use mock data via `PreviewProvider`.

---

## ViewModel Pattern

```swift
// Pattern for all ViewModels
@MainActor
@Observable
final class DashboardViewModel {
    private let monitor: HealthMonitorProtocol  // protocol, not concrete type
    
    var status: HealthStatus = .unknown
    var recentAnomalies: [DetectedAnomaly] = []
    var lastChecked: Date?
    
    init(monitor: HealthMonitorProtocol = HealthMonitorService.shared) {
        self.monitor = monitor
    }
    
    func refresh() async {
        await monitor.runCheck()
    }
}
```

Always inject dependencies via protocols — makes previews and tests possible without real HealthKit.

---

## Mock Data Protocol

Until services are ready, define preview mocks in `Utilities/Mocks.swift`:

```swift
struct MockHealthMonitor: HealthMonitorProtocol {
    func runCheck() async { }
    var status: HealthStatus { .warning }
}

extension DetectedAnomaly {
    static var preview: DetectedAnomaly {
        DetectedAnomaly(
            detectedAt: .now,
            type: "silent_deletion",
            severity: "warning",
            sampleType: "Steps",
            summary: "72 samples missing without deletion event",
            evidence: ["loss_count": "72", "loss_percent": "23.4"]
        )
    }
}
```

---

## File Organization

```
HealthProbe/
├── Views/
│   ├── Dashboard/
│   │   ├── DashboardView.swift
│   │   └── StatusCardView.swift
│   ├── Anomalies/
│   │   ├── AnomalyListView.swift
│   │   └── AnomalyDetailView.swift
│   ├── AuditTrail/
│   │   └── AuditTrailView.swift
│   ├── Sync/
│   │   └── SyncStatusView.swift
│   └── Settings/
│       └── SettingsView.swift
├── ViewModels/
│   ├── DashboardViewModel.swift
│   ├── AnomalyListViewModel.swift
│   └── SyncViewModel.swift
├── Models/           ← NOT owned by Claude Code
├── Services/         ← NOT owned by Claude Code
└── Utilities/
    ├── Mocks.swift
    ├── DateFormatters.swift
    └── DesignSystem.swift
```

---

## Privacy Directives

**Mandatory — no exceptions:**
- No credentials, tokens, or API keys in any file
- No personal data, device identifiers, or account identifiers
- No real health values in code, comments, previews, or tests
- Synthetic preview data only (see Mocks.swift above)

---

## Before Marking a Task Complete

- [ ] View renders in both Light and Dark mode (use Preview)
- [ ] VoiceOver labels set on interactive elements
- [ ] Dynamic Type tested (at least xSmall and AX3)
- [ ] Works with mock data (no real HealthKit dependency in View layer)
- [ ] No health values displayed without explicit user tap
- [ ] Compiles without warnings
