// // Project.swift // GasTankAR // // Created by Dennis Nemec on 25.08.26. // import Foundation import SwiftData import ARKit @Model final class Project { /// Identifier given by the user for the project. In DOCUframe terms /// it is the LeadID. var leadID: String /// Customer name to link the project to. var customerName: String var creationDate: Date /// Der für das Projekt ausgewählte Tank. Jedes Projekt hat genau einen Tank. /// `Tank` ist `Codable`, daher persistiert SwiftData das direkt als Attribut. var tank: Tank /// Archivierte `ARWorldMap` (via `NSKeyedArchiver`). Wegen der Größe extern gespeichert. @Attribute(.externalStorage) var worldMapData: Data? /// Welt-Transform des platzierten Tanks (Position, Rotation, Skalierung) als /// 16 Floats (spaltenweise). Zusammen mit der WorldMap wird der Tank so wiederhergestellt. var tankTransform: [Float]? /// Im AR-Modus aufgenommene Fotos. Werden beim Löschen des Projekts mitentfernt. @Relationship(deleteRule: .cascade, inverse: \ProjectPhoto.project) var photos: [ProjectPhoto] = [] init( leadID: String, customerName: String, creationDate: Date, tank: Tank = Tank(), worldMapData: Data? = nil, tankTransform: [Float]? = nil ) { self.leadID = leadID self.customerName = customerName self.creationDate = creationDate self.tank = tank self.worldMapData = worldMapData self.tankTransform = tankTransform } /// Human-readable title combining the lead identifier and customer name. var title: String { "\(leadID) – \(customerName)" } /// Up to two uppercased initials derived from the customer name, for use as an avatar. var initials: String { let letters = customerName .split(whereSeparator: { $0 == " " || $0 == "&" }) .prefix(2) .compactMap { $0.first } return String(letters).uppercased() } /// Gespeicherte Session der getrackten Welt. (De-)serialisiert `worldMapData`. /// Berechnete Property – wird von SwiftData nicht persistiert. var worldMap: ARWorldMap? { get { guard let worldMapData else { return nil } return try? NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self, from: worldMapData) } set { worldMapData = newValue.flatMap { try? NSKeyedArchiver.archivedData(withRootObject: $0, requiringSecureCoding: true) } } } }