HealthProbe / CLAUDE.md
Newer Older
240 lines | 7.209kb
Bogdan Timofte authored a month ago
1
# HealthProbe – Claude Code Instructions
2

            
3
## Project Context
4

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

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

            
11
---
12

            
13
## Claude Code Scope: UI Layer
14

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

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

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

            
30
---
31

            
32
## Target Screen Structure
33

            
34
```
35
App (TabView)
36
├── Tab 1: Dashboard          → DashboardView
37
├── Tab 2: Anomalies          → AnomalyListView → AnomalyDetailView
38
├── Tab 3: Audit Trail        → AuditTrailView
39
├── Tab 4: Sync Status        → SyncStatusView
40
└── Tab 5: Settings           → SettingsView
41
```
42

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

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

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

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

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

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

            
84
---
85

            
86
## Design Guidelines
87

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

            
90
**Color System:**
91
```swift
92
// Status colors
93
.healthyGreen   // SF: green  — all clear
94
.warningAmber   // SF: yellow — attention needed
95
.criticalRed    // SF: red    — action required
96
.neutralGray    // SF: gray   — informational / resolved
97
```
98

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

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

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

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

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

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

            
121
---
122

            
123
## SwiftData Integration
124

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

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

            
132
// Mutations go through ViewModels or services only
133
```
134

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

            
137
---
138

            
139
## ViewModel Pattern
140

            
141
```swift
142
// Pattern for all ViewModels
143
@MainActor
144
@Observable
145
final class DashboardViewModel {
146
    private let monitor: HealthMonitorProtocol  // protocol, not concrete type
147

            
148
    var status: HealthStatus = .unknown
149
    var recentAnomalies: [DetectedAnomaly] = []
150
    var lastChecked: Date?
151

            
152
    init(monitor: HealthMonitorProtocol = HealthMonitorService.shared) {
153
        self.monitor = monitor
154
    }
155

            
156
    func refresh() async {
157
        await monitor.runCheck()
158
    }
159
}
160
```
161

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

            
164
---
165

            
166
## Mock Data Protocol
167

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

            
170
```swift
171
struct MockHealthMonitor: HealthMonitorProtocol {
172
    func runCheck() async { }
173
    var status: HealthStatus { .warning }
174
}
175

            
176
extension DetectedAnomaly {
177
    static var preview: DetectedAnomaly {
178
        DetectedAnomaly(
179
            detectedAt: .now,
180
            type: "silent_deletion",
181
            severity: "warning",
182
            sampleType: "Steps",
183
            summary: "72 samples missing without deletion event",
184
            evidence: ["loss_count": "72", "loss_percent": "23.4"]
185
        )
186
    }
187
}
188
```
189

            
190
---
191

            
192
## File Organization
193

            
194
```
195
HealthProbe/
196
├── Views/
197
│   ├── Dashboard/
198
│   │   ├── DashboardView.swift
199
│   │   └── StatusCardView.swift
200
│   ├── Anomalies/
201
│   │   ├── AnomalyListView.swift
202
│   │   └── AnomalyDetailView.swift
203
│   ├── AuditTrail/
204
│   │   └── AuditTrailView.swift
205
│   ├── Sync/
206
│   │   └── SyncStatusView.swift
207
│   └── Settings/
208
│       └── SettingsView.swift
209
├── ViewModels/
210
│   ├── DashboardViewModel.swift
211
│   ├── AnomalyListViewModel.swift
212
│   └── SyncViewModel.swift
213
├── Models/           ← NOT owned by Claude Code
214
├── Services/         ← NOT owned by Claude Code
215
└── Utilities/
216
    ├── Mocks.swift
217
    ├── DateFormatters.swift
218
    └── DesignSystem.swift
219
```
220

            
221
---
222

            
223
## Privacy Directives
224

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

            
231
---
232

            
233
## Before Marking a Task Complete
234

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