import Dependencies import DependenciesMacros import Fluent import Vapor public extension DependencyValues { var vendorBranches: VendorBranchDB { get { self[VendorBranchDB.self] } set { self[VendorBranchDB.self] = newValue } } } @DependencyClient public struct VendorBranchDB: Sendable { var create: @Sendable (VendorBranch.Create, Vendor.IDValue) async throws -> VendorBranch.DTO var delete: @Sendable (VendorBranch.IDValue) async throws -> Void var fetchAll: @Sendable (Bool) async throws -> [VendorBranch.DTO] var fetchForVendor: @Sendable (Vendor.IDValue) async throws -> [VendorBranch.DTO] var get: @Sendable (VendorBranch.IDValue) async throws -> VendorBranch.DTO? var update: @Sendable (VendorBranch.IDValue, VendorBranch.Update) async throws -> VendorBranch.DTO func fetchAll() async throws -> [VendorBranch.DTO] { try await fetchAll(false) } } extension VendorBranchDB: TestDependencyKey { public static let testValue: VendorBranchDB = Self() static func live(database db: any Database) -> Self { .init( create: { model, vendorID in let branch = model.toModel() guard let vendor = try await Vendor.find(vendorID, on: db) else { throw Abort(.badRequest, reason: "Vendor does not exist.") } try await vendor.$branches.create(branch, on: db) return branch.toDTO() }, delete: { id in guard let branch = try await VendorBranch.find(id, on: db) else { throw Abort(.notFound) } try await branch.delete(on: db) }, fetchAll: { withVendor in var query = VendorBranch.query(on: db) if withVendor == true { query = query.with(\.$vendor) } return try await query.all().map { $0.toDTO() } }, fetchForVendor: { vendorID in guard let vendor = try await Vendor.query(on: db) .filter(\.$id == vendorID) .with(\.$branches) .first() else { throw Abort(.notFound) } return vendor.branches.map { $0.toDTO() } }, get: { id in try await VendorBranch.find(id, on: db).map { $0.toDTO() } }, update: { id, updates in guard let branch = try await VendorBranch.find(id, on: db) else { throw Abort(.notFound) } branch.applyUpdates(updates) try await branch.save(on: db) return branch.toDTO() } ) } }