import Foundation import SwiftData @Model final class SyncJob { var id: UUID var name: String var sourcePath: String var destinationPath: String var isRemote: Bool var remoteHost: String var remoteUser: String var remotePort: Int var sshKeyPath: String var archive: Bool var compress: Bool var deleteExtraneous: Bool var preservePermissions: Bool var preserveExtendedAttributes: Bool var showProgress: Bool var exclusionsText: String var additionalArguments: String var isEnabled: Bool var createdAt: Date var updatedAt: Date var lastRunAt: Date? var lastExitCode: Int? var scheduleEnabled: Bool = false var scheduleKindRaw: String = SyncScheduleKind.manual.rawValue var scheduleStartAt: Date = Date().addingTimeInterval(3600) var scheduleIntervalMinutes: Int = 30 var nextRunAt: Date? = nil var watchEnabled: Bool = false var watchPath: String = "" var watchDebounceSeconds: Int = 3 var lastWatchEventAt: Date? = nil var allowUnattendedDelete: Bool = false var retryCount: Int = 2 var retryDelaySeconds: Int = 10 var notifyOnFailure: Bool = true var notifyOnSuccess: Bool = false var requireExpectedVolume: Bool = false var expectedVolumeIdentifier: String = "" var minimumFreeSpaceMB: Int = 512 init( name: String = "New Sync Job", sourcePath: String = "", destinationPath: String = "" ) { self.id = UUID() self.name = name self.sourcePath = sourcePath self.destinationPath = destinationPath self.isRemote = false self.remoteHost = "" self.remoteUser = "" self.remotePort = 22 self.sshKeyPath = "" self.archive = true self.compress = false self.deleteExtraneous = false self.preservePermissions = true self.preserveExtendedAttributes = true self.showProgress = true self.exclusionsText = "" self.additionalArguments = "" self.isEnabled = true self.createdAt = Date() self.updatedAt = Date() self.lastRunAt = nil self.lastExitCode = nil self.scheduleEnabled = false self.scheduleKindRaw = SyncScheduleKind.manual.rawValue self.scheduleStartAt = Date().addingTimeInterval(3600) self.scheduleIntervalMinutes = 30 self.nextRunAt = nil self.watchEnabled = false self.watchPath = "" self.watchDebounceSeconds = 3 self.lastWatchEventAt = nil self.allowUnattendedDelete = false self.retryCount = 2 self.retryDelaySeconds = 10 self.notifyOnFailure = true self.notifyOnSuccess = false self.requireExpectedVolume = false self.expectedVolumeIdentifier = "" self.minimumFreeSpaceMB = 512 } var exclusions: [String] { exclusionsText .split(whereSeparator: \.isNewline) .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } .filter { !$0.isEmpty } } var expectedVolumeDisplay: String { expectedVolumeIdentifier.isEmpty ? "Not pinned" : expectedVolumeIdentifier } var destinationDisplay: String { if isRemote { let userPrefix = remoteUser.isEmpty ? "" : "\(remoteUser)@" return "\(userPrefix)\(remoteHost):\(destinationPath)" } return destinationPath } }