import Foundation import SwiftData /// Lokales Cache-Model für Decks. Spiegelt das Server-DTO + zwei /// computed Werte (cardCount, dueCount), die Web pro Deck als zusätzliche /// API-Calls holt. /// /// Offline-Read: Liste sichtbar ohne Netz. Server bleibt Wahrheit — /// alle Edits laufen über die API, der Cache wird nur beim Re-Fetch /// aktualisiert. @Model final class CachedDeck { @Attribute(.unique) var id: String var userId: String var name: String var deckDescription: String? var color: String? var categoryRaw: String? var visibilityRaw: String var contentHash: String? var forkedFromMarketplaceDeckId: String? var forkedFromMarketplaceVersionId: String? var archivedAt: Date? var createdAt: Date var updatedAt: Date /// Anzahl Karten im Deck (über `/api/v1/cards?deck_id=...`). var cardCount: Int = 0 /// Anzahl fälliger Reviews (über `/api/v1/reviews/due?deck_id=...`). var dueCount: Int = 0 /// Zeitpunkt des letzten erfolgreichen Server-Pulls für dieses Deck. var lastFetchedAt: Date init(deck: Deck, cardCount: Int = 0, dueCount: Int = 0) { id = deck.id userId = deck.userId name = deck.name deckDescription = deck.description color = deck.color categoryRaw = deck.category?.rawValue visibilityRaw = deck.visibility.rawValue contentHash = deck.contentHash forkedFromMarketplaceDeckId = deck.forkedFromMarketplaceDeckId forkedFromMarketplaceVersionId = deck.forkedFromMarketplaceVersionId archivedAt = deck.archivedAt createdAt = deck.createdAt updatedAt = deck.updatedAt self.cardCount = cardCount self.dueCount = dueCount lastFetchedAt = .now } /// Übernimmt aktualisierte Felder vom Server-DTO. func update(from deck: Deck, cardCount: Int, dueCount: Int) { name = deck.name deckDescription = deck.description color = deck.color categoryRaw = deck.category?.rawValue visibilityRaw = deck.visibility.rawValue contentHash = deck.contentHash forkedFromMarketplaceDeckId = deck.forkedFromMarketplaceDeckId forkedFromMarketplaceVersionId = deck.forkedFromMarketplaceVersionId archivedAt = deck.archivedAt updatedAt = deck.updatedAt self.cardCount = cardCount self.dueCount = dueCount lastFetchedAt = .now } var category: DeckCategory? { categoryRaw.flatMap(DeckCategory.init(rawValue:)) } var isFromMarketplace: Bool { forkedFromMarketplaceDeckId != nil } }