56 lines
1.7 KiB
Swift
56 lines
1.7 KiB
Swift
import Foundation
|
|
|
|
/// A real-world encounter between two present users.
|
|
///
|
|
/// An encounter is deliberately **anonymous** until both parties mutually
|
|
/// consent to reveal. Until then it is a "silhouette" — a proof that two
|
|
/// humans were physically near each other, with no identity attached.
|
|
struct Encounter: Identifiable, Codable, Hashable {
|
|
let id: UUID
|
|
let remoteAnonToken: String
|
|
let timestamp: Date
|
|
let tier: DistanceTier
|
|
let engine: ProximityEngine
|
|
|
|
/// Coarse geohash (optional). Never precise location.
|
|
var geohash: String?
|
|
|
|
/// The relationship state of this encounter.
|
|
var status: EncounterStatus
|
|
|
|
/// A human-readable hint, e.g. "Cafe on 5th Ave" if the user tagged it.
|
|
var placeHint: String?
|
|
|
|
init(
|
|
id: UUID = UUID(),
|
|
remoteAnonToken: String,
|
|
timestamp: Date = Date(),
|
|
tier: DistanceTier,
|
|
engine: ProximityEngine,
|
|
geohash: String? = nil,
|
|
status: EncounterStatus = .silhouette,
|
|
placeHint: String? = nil
|
|
) {
|
|
self.id = id
|
|
self.remoteAnonToken = remoteAnonToken
|
|
self.timestamp = timestamp
|
|
self.tier = tier
|
|
self.engine = engine
|
|
self.geohash = geohash
|
|
self.status = status
|
|
self.placeHint = placeHint
|
|
}
|
|
}
|
|
|
|
/// Relationship lifecycle of an encounter.
|
|
enum EncounterStatus: String, Codable, Hashable {
|
|
/// Seen but not yet acknowledged. A silhouette.
|
|
case silhouette
|
|
/// This user has sent a "wave" (interest) but the other hasn't replied.
|
|
case waved
|
|
/// Both parties waved — identities revealed, chat unlocked.
|
|
case mutual
|
|
/// One party declined or blocked. Permanently removed from the graph.
|
|
case declined
|
|
}
|