Commit Graph

14 Commits

Author SHA1 Message Date
link2026
39edc25dc1 refactor(profile,monitor): move height/weight from MonitorMetric to UserProfile
身高/体重对成人变化慢,作为 Profile 静态字段比每次录入 Indicator 更合适。

- MonitorMetric:6 case(从 8 减),删 .height / .weight
- UserProfile:加 weightKG: Double?(支持小数),加 bmi computed
- summaryLine 加体重段:'175cm · 68.5kg'(整数省小数)
- ProfileEditView basics 加 weight 行 + footer 显示 BMI + 分类(偏瘦/正常/超重/肥胖)
- IndicatorQuickSheet:删 .height 回写 Profile 的特殊逻辑
- UserProfileTests:+5 个(weight 字段、summaryLine 含 weight、BMI 计算)

兼容性:老 Indicator 里的 seriesKey 'weight' / 'height' 数据保留(SwiftData String?
不变),只是新录入路径走 Profile 不走 Indicator;Trends 仍能用 String seriesKey
查询历史(如果将来要展示老数据)。

测试:60 case pass / 0 fail / 0 warning。
2026-05-26 07:58:47 +08:00
link2026
37b47b2076 docs(claude): sync §5/§7/§10 with Monitor+Profile; fix SeriesBucket SwiftData import
- §5 schema 重写为 7 @Model 完整列表(含 UserProfile + Indicator.seriesKey)
- §7 IA 改成 5 槽 TabBar(2 内容 + 中间 + + 2 设置),记录入口 5 个 kind
- §10.6 红线例外清单加 Monitor + Profile(Symptom 也补上)
- SeriesBucket.swift 缺 import SwiftData(persistentModelID 报错)

全套测试 50 case pass / 0 fail / 0 warning。
2026-05-26 07:53:16 +08:00
link2026
e2fb631b96 feat(timeline): merge bp.systolic + bp.diastolic into single entry
- TimelineEntry.from(indicators:) 批处理:找 bp.systolic 配对同 capturedAt
  (±5s)的 bp.diastolic,合并成 '血压 120/80 mmHg' 一行
- 未配对的 systolic 单独退回 from(indicator:)
- 非 bp.* series 不动
- ArchiveListView + HomeView 改用 from(indicators:) 批处理
- 6 个新测试覆盖配对/未配对/异常标记/非 bp 不动/不同时间不合并
2026-05-26 07:50:00 +08:00
link2026
3dcb792131 feat(profile,monitor): ProfileEditView + MeView 卡片 + IndicatorQuickSheet 改造
- ProfileEditView Form 风格,即改即存,onDisappear 触发 ctx.save
  - basics(出生年 / 性别 / 身高 / 血型)
  - 慢病 chips(8 预设 + 自定义)
  - allergies / familyHistory / medications 通用 list section
  - FlowLayout(Layout 协议自实现)用于 chip 流式换行

- MeView 改造:NavigationStack + ProfileCard 显示 summaryLine,
  3 个 settings 卡片(模型 / Face ID / 关于)stub,DEBUG 块仍在底部

- IndicatorQuickSheet 整合 MonitorMetric:
  - 顶部 LazyVGrid 2 列展示 8 个 MonitorMetric(进趋势)
  - 下方 horizontal scroll 化验项快捷(不进趋势)
  - 选血压切到 2 字段 UI(收缩/舒张),保存写 2 条 Indicator(同 capturedAt)
  - 选单字段 monitor:自动算 status,锁 name/unit/range
  - 选 lab preset:辅助填 name/unit/range,status 手动
  - 自由输入路径不变
  - 身高 monitor 保存时回写 UserProfile.heightCM
  - Profile-aware range hint:'按 67 岁调整' 仅在 effectiveRange 不同于 baseRange 时显示
2026-05-26 07:47:20 +08:00
link2026
9a6d21100b feat(monitor): add UserProfile + MonitorMetric catalog + Indicator.seriesKey
数据层(spec 2026-05-26):
- UserProfile @Model:核心 4 项 + 健康背景 + 用药,SwiftData 单例(loadOrCreate)
- Indicator 加 seriesKey: String?,标识长期指标分组('bp.systolic' 等)
- MonitorMetric enum 8 case:血压(2 field 拆 2 Indicator)/ 空腹+餐后血糖 /
  体重 / 体温 / 心率 / SpO2 / 身高
- effectiveRange(for:profile:) 实现 1 条 Profile-aware 规则:
  age >= 65 时 bp.systolic 上限 140→150
- KangkangApp schema 加 UserProfile.self

测试 17 个全绿(UserProfile 6 + MonitorMetric 11);schema 烟测扩 2(seriesKey roundtrip + UserProfile persist)。
UI 层 + Timeline 合并下个 commit。
2026-05-26 07:40:42 +08:00
link2026
22cf4bcefe fix(concurrency): make DateSection nonisolated to silence #expect warnings
5 个 Swift Testing macro 展开的 warning:DateSection 的 Equatable 协议被默认
推到 MainActor,但 #expect 在 nonisolated context 比较 — Swift 6 严格模式会报错。
2026-05-25 23:39:52 +08:00
link2026
bb08243aa9 chore(preview): add #Preview to RecordSheet + DebugAIRunner
之前 HomeView/MeView/TrendsView/ArchiveListView/RootView/SymptomStartSheet
都有 #Preview,只剩这两个。补完后所有主屏 View 都能在 Xcode Canvas 直接
预览,改 UI 不用 build & run。
2026-05-25 23:37:55 +08:00
link2026
b63b26bce5 feat(timeline): TimelineRow + DateSection + grouping tests + Diary sheet
- TimelineRow: 时间线条目单行视图
- DateSection + TimelineGrouping: 今日/昨日/本周/更早分组
- DiaryQuickSheet: 文字日记快速记录入口
- TimelineGroupingTests: 分组逻辑烟测
- SymptomEndSheet / RootView: 配套微调
2026-05-25 23:23:21 +08:00
link2026
b1b8d0a8c7 fix(timeline): add missing SwiftData import + @MainActor on caller props
- TimelineEntry.swift: 缺 import SwiftData,4 处 persistentModelID 报错
- ArchiveListView.allEntries / HomeView.recentEntries: 显式 @MainActor,
  否则 default-isolation=MainActor 下被推断为 nonisolated,调用 MainActor
  方法 TimelineEntry.from(...) 触发 4+4 个 isolation 警告
2026-05-25 23:22:35 +08:00
link2026
2e728dcd24 chore(assets): add Kangkang AppIcon (light/dark/tinted, 16-1024) + SVG source
9 PNG sizes for iOS/macOS + dark + tinted variants. SVG design source under
docs/design/. Updates Contents.json to reference them.

Scheme reference 编码统一为 康康(Xcode 写入格式)。
2026-05-25 23:18:29 +08:00
link2026
46b69cf8e1 feat(symptom): add Symptom @Model + start/end sheets + ongoing card
- Symptom @Model with severity 1-5 clamp, isOngoing, duration helpers
- SymptomStartSheet / SymptomEndSheet / OngoingSymptomsCard
- RecordSheet 加 .symptom kind 入口
- RootView 增加 'records' tab + ArchiveListView placeholder
- HomeView 顶部加 OngoingSymptomsCard
- ModelsSchemaTests: 2 个 Symptom 烟测(ongoing predicate + severity clamp)

Note: Symptom 是 CLAUDE.md §10 清单外的新功能,由产品负责人决定加入。
ArchiveListView 仍是 placeholder,真实 C1 实现按计划在 W4。
2026-05-25 23:18:21 +08:00
link2026
e4a68a1bdd fix(concurrency): clear 4 Swift 6 warnings under default MainActor isolation
- ModelStore/FileVault: drop nonisolated(unsafe) on shared, mark all instance
  methods nonisolated (they only read filesystem); ModelKind enum also nonisolated
- AIRuntime ↔ ModelStore cross-actor call resolved by the above
- LLMSession: replace deprecated Device.setDefault(device:) with task-scoped
  Device.withDefaultDevice(.cpu, body:); wrap both load and generate so the
  TaskLocal propagates through ModelContainer.perform
2026-05-25 23:18:08 +08:00
link2026
53da442424 chore: rename Tiji→Kangkang test imports + scheme + sync docs
Rename @testable imports across all test/UI test files after the Tiji→Kangkang
project rename in 44ed01a. Add shared scheme. Sync CLAUDE.md / W2 plan / spec
v1.0 to current scope (Symptom feature noted, C1/C2 flow lockdown).
2026-05-25 23:18:00 +08:00
link2026
44ed01acf4 ```
refactor: 重命名项目名称从"体己"到"康康"

将整个项目的目录结构从"体己"重命名为"康康",包括所有源代码文件、
资源文件、测试文件以及Xcode项目配置文件。此更改涉及项目中所有的
文件路径和应用入口点(App/TijiApp.swift → App/KangkangApp.swift)。
```
2026-05-25 19:01:16 +08:00