import Foundation /// App-spezifische Konfiguration für ManaCore. Wird von der konsumierenden /// App beim Erzeugen eines `AuthClient` injiziert. /// /// ManaCore hardcoded nichts App-Spezifisches. Bundle-ID, Auth-Server-URL /// und Keychain-Adressierung kommen ausschließlich hierüber. public protocol ManaAppConfig: Sendable { /// Basis-URL des mana-auth-Servers, z.B. `https://auth.mana.how`. var authBaseURL: URL { get } /// Keychain-Service-Identifier, üblich `ev.mana.`. Trennt /// Token-Einträge verschiedener Apps voneinander, falls keine /// shared Access-Group benutzt wird. var keychainService: String { get } /// Optional: Shared-Keychain-Access-Group für Cross-App-SSO. /// `nil` bedeutet: nur App-eigener Keychain-Zugriff. /// /// Wenn gesetzt, müssen alle teilnehmenden Apps unter derselben /// Apple-Developer-Team-ID provisioniert sein und das Entitlement /// `keychain-access-groups` mit demselben Wert tragen. var keychainAccessGroup: String? { get } /// App-Group für Daten-Sharing zwischen App ↔ Widget ↔ ShareExt. /// Üblich `group.ev.mana.`. `nil` für Apps ohne Extensions. /// /// Single-Source für den App-Group-String, der heute in jeder App /// 3-4× hardcoded steht (AppConfig + App-Entitlement + Widget- /// Entitlement + ShareExt-Entitlement). Die Entitlements bleiben /// hardcoded (das verlangt iOS), aber im Swift-Code ist der Wert /// damit single-source. var appGroup: String? { get } /// OSLog-Subsystem für App-Logger, üblich `ev.mana.`. Default /// ist `keychainService` (der schon der Konvention folgt). var logSubsystem: String { get } } // MARK: - Default-Implementationen public extension ManaAppConfig { /// Default `nil` — Apps ohne Widget/ShareExt müssen nichts setzen. var appGroup: String? { nil } /// Default = `keychainService`. Beide folgen heute in allen Apps /// derselben Konvention `ev.mana.`. var logSubsystem: String { keychainService } } /// Standard-Implementierung von ``ManaAppConfig``. Apps können diese /// nutzen oder ein eigenes Type adoptieren. public struct DefaultManaAppConfig: ManaAppConfig { public let authBaseURL: URL public let keychainService: String public let keychainAccessGroup: String? public let appGroup: String? public let logSubsystem: String public init( authBaseURL: URL, keychainService: String, keychainAccessGroup: String? = nil, appGroup: String? = nil, logSubsystem: String? = nil ) { self.authBaseURL = authBaseURL self.keychainService = keychainService self.keychainAccessGroup = keychainAccessGroup self.appGroup = appGroup // Konvention: log-Subsystem = keychainService, falls nicht // explizit anders gewünscht. self.logSubsystem = logSubsystem ?? keychainService } }