Aug 19 - Fixed photo-loss issue

This commit is contained in:
Nguyen Ngo
2026-08-19 10:31:20 -04:00
parent 7cbc514c39
commit e31cd7e1ff
13 changed files with 856 additions and 149 deletions
+53
View File
@@ -59,6 +59,59 @@ nonisolated enum ServerConfig {
}
}
// MARK: - Session scope
/// The (server, user) pair the local database is currently scoped to.
///
/// Almost every local id is meaningful only within one such pair. `serverId`
/// values differ between jqc and jqc1; facility/template ids and inspector
/// facility scope differ per user. So when either half changes, the cached data
/// is not merely stale it is *wrong*, and silently belongs to someone else.
///
/// Two concrete failures this exists to close:
/// A different inspector signing in on the same iPad inherited the previous
/// one's issues. `pullAssignedIssues`' reconciliation only deletes rows with
/// `inspectionLocalId == ""`, so device-authored synced issues survived
/// indefinitely and were simply visible to whoever logged in next.
/// A server switch cleared `LocalIssue` alone, leaving `LocalInspection`
/// rows carrying facility/template ids from the other server, ready to be
/// submitted against it.
///
/// Deliberately in UserDefaults, NOT the Keychain: `KeychainHelper.clearAll()`
/// runs on logout, and this marker has to OUTLIVE a logout to be able to notice
/// that the next login is a different person. It is not a secret.
nonisolated enum SessionScope {
struct Scope: Equatable, Sendable {
let server: String
let userId: Int
}
private static let userKey = "com.jqc.sessionScope.userId"
private static let serverKey = "com.jqc.sessionScope.server"
/// The recorded scope, or nil when none has ever been written.
static var stored: Scope? {
let d = UserDefaults.standard
guard let server = d.string(forKey: serverKey),
d.object(forKey: userKey) != nil
else { return nil }
return Scope(server: server, userId: d.integer(forKey: userKey))
}
static func record(userId: Int, server: String = ServerConfig.current) {
UserDefaults.standard.set(userId, forKey: userKey)
UserDefaults.standard.set(server, forKey: serverKey)
}
/// Forget the scope entirely used on a server switch, where the next
/// login is guaranteed to be against a different data set.
static func clear() {
UserDefaults.standard.removeObject(forKey: userKey)
UserDefaults.standard.removeObject(forKey: serverKey)
}
}
// MARK: - App-wide constants
// Explicitly not @MainActor these constants must be readable from