feat(models): add Asset/ChatTurn, indicator-report relationship, pinned flag

按 W2 plan Task 2 落地数据模型:
- Indicator 加 report / asset / pinned 字段
- Report 加 indicators / assets @Relationship(cascade)
- DiaryEntry 加 tags
- 新增 @Model Asset (原图元数据)
- 新增 @Model ChatTurn (问答历史 + 引用)
- TijiApp Schema 加入新 model

注:Schema 破坏性变更,用户需在 Xcode 里 Erase Simulator
后重启 App。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
link2026
2026-05-25 14:55:26 +08:00
parent c050865db5
commit 2b6c4b9726
2 changed files with 64 additions and 2 deletions

View File

@@ -8,6 +8,8 @@ struct TijiApp: App {
Indicator.self, Indicator.self,
Report.self, Report.self,
DiaryEntry.self, DiaryEntry.self,
Asset.self,
ChatTurn.self,
]) ])
let config = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) let config = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
do { do {

View File

@@ -29,13 +29,20 @@ final class Indicator {
var note: String? var note: String?
var capturedAt: Date var capturedAt: Date
var report: Report?
var asset: Asset?
var pinned: Bool = false
init(name: String, init(name: String,
value: String, value: String,
unit: String, unit: String,
range: String, range: String,
status: IndicatorStatus, status: IndicatorStatus,
note: String? = nil, note: String? = nil,
capturedAt: Date = .now) { capturedAt: Date = .now,
report: Report? = nil,
asset: Asset? = nil,
pinned: Bool = false) {
self.name = name self.name = name
self.value = value self.value = value
self.unit = unit self.unit = unit
@@ -43,6 +50,9 @@ final class Indicator {
self.statusRaw = status.rawValue self.statusRaw = status.rawValue
self.note = note self.note = note
self.capturedAt = capturedAt self.capturedAt = capturedAt
self.report = report
self.asset = asset
self.pinned = pinned
} }
var status: IndicatorStatus { var status: IndicatorStatus {
@@ -61,6 +71,12 @@ final class Report {
var pageCount: Int var pageCount: Int
var createdAt: Date var createdAt: Date
@Relationship(deleteRule: .cascade, inverse: \Indicator.report)
var indicators: [Indicator] = []
@Relationship(deleteRule: .cascade)
var assets: [Asset] = []
init(title: String, init(title: String,
type: ReportType, type: ReportType,
reportDate: Date, reportDate: Date,
@@ -88,9 +104,53 @@ final class Report {
final class DiaryEntry { final class DiaryEntry {
var content: String var content: String
var createdAt: Date var createdAt: Date
var tags: [String]
init(content: String, createdAt: Date = .now) { init(content: String, createdAt: Date = .now, tags: [String] = []) {
self.content = content self.content = content
self.createdAt = createdAt self.createdAt = createdAt
self.tags = tags
}
}
@Model
final class Asset {
var relativePath: String
var mimeType: String
var bytes: Int
var createdAt: Date
init(relativePath: String,
mimeType: String = "image/jpeg",
bytes: Int = 0,
createdAt: Date = .now) {
self.relativePath = relativePath
self.mimeType = mimeType
self.bytes = bytes
self.createdAt = createdAt
}
}
@Model
final class ChatTurn {
var question: String
var answer: String
var referencedIndicatorIDs: [String]
var referencedReportIDs: [String]
var createdAt: Date
var decodeRate: Double
init(question: String,
answer: String,
referencedIndicatorIDs: [String] = [],
referencedReportIDs: [String] = [],
createdAt: Date = .now,
decodeRate: Double = 0) {
self.question = question
self.answer = answer
self.referencedIndicatorIDs = referencedIndicatorIDs
self.referencedReportIDs = referencedReportIDs
self.createdAt = createdAt
self.decodeRate = decodeRate
} }
} }