import Foundation public enum RepositoryError: Error, Equatable, Sendable { case invalidOrigin case duplicateOrigin case revisionConflict case notFound case databaseFailed } public struct Instance: Codable, Equatable, Identifiable, Sendable { public let id: UUID public var name: String public var origin: URL public var tags: [String] public var credentialConfigured: Bool public var configRevision: Int public let createdAt: Date public var updatedAt: Date public init( id: UUID, name: String, origin: URL, tags: [String] = [], credentialConfigured: Bool = false, configRevision: Int = 1, createdAt: Date, updatedAt: Date ) { self.id = id self.name = name self.origin = origin self.tags = tags self.credentialConfigured = credentialConfigured self.configRevision = configRevision self.createdAt = createdAt self.updatedAt = updatedAt } } public struct InstanceInput: Sendable { public var name: String public var origin: URL public var tags: [String] public var password: String? public init( name: String, origin: URL, tags: [String] = [], password: String? = nil ) { self.name = name self.origin = origin self.tags = tags self.password = password } } public struct InstancePatch: Sendable { public var name: String? public var origin: URL? public var tags: [String]? public var password: String? public init( name: String? = nil, origin: URL? = nil, tags: [String]? = nil, password: String? = nil ) { self.name = name self.origin = origin self.tags = tags self.password = password } } public struct InstanceQuery: Sendable { public var search: String? public var tags: [String]? public init(search: String? = nil, tags: [String]? = nil) { self.search = search self.tags = tags } } public protocol InstanceRepository: Sendable { func list(_ query: InstanceQuery) async throws -> [Instance] func get(_ id: UUID) async throws -> Instance? func create(_ input: InstanceInput) async throws -> Instance func update(_ id: UUID, expectedRevision: Int, _ patch: InstancePatch) async throws -> Instance func delete(_ id: UUID, expectedRevision: Int) async throws }