// // LibraryModels.swift // Prisme // // Author: Simon-Pierre Boucher // import Foundation import SwiftData /// A saved passage — most of the time you don't want the page, you want /// the paragraph (CLAUDE.md §5, "L'extrait", P0). Stored with its source, /// date and section context; the DOM path anchors it back in the page. @Model final class Excerpt { var text: String var sourceURLString: String var sourceTitle: String var sourceHost: String var sectionTitle: String? var domPath: String? var containerID: UUID var savedAt: Date init( text: String, sourceURLString: String, sourceTitle: String, sourceHost: String, sectionTitle: String?, domPath: String?, containerID: UUID ) { self.text = text self.sourceURLString = sourceURLString self.sourceTitle = sourceTitle self.sourceHost = sourceHost self.sectionTitle = sectionTitle self.domPath = domPath self.containerID = containerID self.savedAt = Date() } } /// A page saved as native data, freed from its layout ("Le favori /// structuré", P0). Enriched by the digest when the model delivered one; /// deterministic (title, lead sentence, headings) otherwise. Not a rotting /// URL pointer: the structure is the favourite. @Model final class StructuredFavorite { @Attribute(.unique) var urlString: String var host: String var title: String var gist: String /// PageKind raw value when a digest classified the page. var kindRaw: String? var outlineTitles: [String] /// True when gist/outline came from the local model — drives the /// distinct "generated" treatment (§7). var isGenerated: Bool var containerID: UUID var savedAt: Date init( urlString: String, host: String, title: String, gist: String, kindRaw: String?, outlineTitles: [String], isGenerated: Bool, containerID: UUID ) { self.urlString = urlString self.host = host self.title = title self.gist = gist self.kindRaw = kindRaw self.outlineTitles = outlineTitles self.isGenerated = isGenerated self.containerID = containerID self.savedAt = Date() } }