64 lines
2.3 KiB
Swift
64 lines
2.3 KiB
Swift
// 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
|
|
}
|
|
}
|