// Models/PendingPhoto.swift // ------------------------- // SwiftData model for photos waiting to be uploaded to the server. // Photos are saved locally first, uploaded during sync, then the // local path reference is replaced with the server path. import Foundation import SwiftData @Model final class PendingPhoto { @Attribute(.unique) var localId: String /// Absolute path in app's Documents/JQC/Photos/ directory var localFilePath: String /// "inspection" | "issue" var entityType: String /// References LocalInspection.localId or LocalIssue.localId var entityLocalId: String /// For inspection form image fields — the field's id string var fieldId: String? /// Populated after successful upload var serverPath: String? /// "pending" | "uploaded" | "failed" var uploadStatus: String var createdAt: Date // ── Capture metadata (sent to the server, burned into the photo) ─────── // Recorded when the shutter fires, NOT when the upload runs — the app is // offline-first, so a photo taken at 09:14 may not sync until 16:00 and // the stamp must show 09:14. EXIF cannot serve as a fallback here: the // photo is re-encoded via jpegData() on save, which strips every tag. // Optional so existing SwiftData stores migrate without a schema step. var capturedAt: Date? var captureLatitude: Double? var captureLongitude: Double? var inspection: LocalInspection? init( localFilePath: String, entityType: String, entityLocalId: String, fieldId: String? = nil, capturedAt: Date? = nil, captureLatitude: Double? = nil, captureLongitude: Double? = nil ) { self.localId = UUID().uuidString self.localFilePath = localFilePath self.entityType = entityType self.entityLocalId = entityLocalId self.fieldId = fieldId self.serverPath = nil self.uploadStatus = "pending" self.createdAt = Date() // Fall back to now when the caller has no recorded capture moment — // still far better than the server's upload-time default. self.capturedAt = capturedAt ?? Date() self.captureLatitude = captureLatitude self.captureLongitude = captureLongitude } }