zitare-native/Sources/Core/Submit/PendingSubmissionModel.swift
Till JS f5a26b2392 chore(format): disable redundantSelf + redundantSendable in swiftformat
Default `--self remove` strippt `self.` aus @autoclosure-Calls (Logger.info)
und Closure-Captures, was Swift-6-strict-concurrency dann als "implicit
use of self in closure" rejected. Default `redundantSendable` strippt
`Sendable` von Codable-DTOs, die über actor-Grenzen wandern müssen.

Beide Regeln aus. Zusätzlich Lauf über alle Files: harmlose Whitespace-/
Trailing-Comma-/Optional-Init-Normalisierung in 5 Files. `self.` und
`Sendable` bleiben überall erhalten. Build grün.

Hintergrund: η-0-Lauf hat das aktiv gemacht und Submit-DTOs zerschossen,
die ich dann von Hand revertieren musste. Dieser Commit verhindert die
Wiederholung in η-1+.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:37:46 +02:00

84 lines
2.9 KiB
Swift

import Foundation
import SwiftData
/// Pending Quote-Submission, die wegen Network-Fehler nicht durchging.
/// Wird beim nächsten Foreground/Reconnect via `SubmissionQueue.tryFlush`
/// nachgereicht.
///
/// Eigener Store (`submissions.store`) im App-Group-Container, damit
/// Snapshot-Sync und Pending-Submissions sich nicht in den Quere kommen.
@Model
final class PendingSubmission {
@Attribute(.unique) var id: UUID
var createdAt: Date
var lastTriedAt: Date?
var retryCount: Int
var lastError: String?
// QuoteDraft-Felder, flach gespeichert für SwiftData-Kompatibilität.
var text: String
var language: String
var authorName: String?
var authorSlug: String?
var sourceTitle: String?
var sourceKindRaw: String?
var sourceYear: Int?
var editReason: String?
var acceptedTos: Bool
init(draft: QuoteDraft, id: UUID = UUID(), createdAt: Date = Date()) {
self.id = id
self.createdAt = createdAt
self.retryCount = 0
self.text = draft.text
self.language = draft.language
self.authorName = draft.authorName
self.authorSlug = draft.authorSlug
self.sourceTitle = draft.sourceTitle
self.sourceKindRaw = draft.sourceKind?.rawValue
self.sourceYear = draft.sourceYear
self.editReason = draft.editReason
self.acceptedTos = draft.acceptedTos
}
func toDraft() -> QuoteDraft {
QuoteDraft(
text: text,
language: language,
authorName: authorName,
authorSlug: authorSlug,
sourceTitle: sourceTitle,
sourceKind: sourceKindRaw.flatMap(QuoteDraft.SourceKind.init(rawValue:)),
sourceYear: sourceYear,
editReason: editReason,
acceptedTos: acceptedTos
)
}
}
/// Helper für den ModelContainer. Eigener Store, damit das
/// Snapshot-Schema nicht mit-migriert wird, wenn wir Submission-
/// Felder ändern.
enum PendingSubmissionContainer {
static let appGroup = "group.ev.mana.zitare"
static func defaultStoreURL() -> URL {
let fm = FileManager.default
if let groupURL = fm.containerURL(forSecurityApplicationGroupIdentifier: appGroup) {
return groupURL.appendingPathComponent("submissions.store")
}
let docs = fm.urls(for: .documentDirectory, in: .userDomainMask).first
?? URL(fileURLWithPath: NSTemporaryDirectory())
return docs.appendingPathComponent("submissions.store")
}
static func make(inMemory: Bool = false) throws -> ModelContainer {
let schema = Schema([PendingSubmission.self])
let config = if inMemory {
ModelConfiguration(schema: schema, isStoredInMemoryOnly: true)
} else {
ModelConfiguration("submissions", schema: schema, url: defaultStoreURL())
}
return try ModelContainer(for: schema, configurations: [config])
}
}