import DatabaseClientLive import Dependencies import Fluent import SharedModels import Vapor private let apiMiddleware: [any Middleware] = [ UserPasswordAuthenticator(), UserTokenAuthenticator(), User.guardMiddleware() ] extension ApiRoute { var middleware: [any Middleware]? { apiMiddleware } func handle(request: Request) async throws -> any AsyncResponseEncodable { switch self { case let .employee(route): return try await route.handleApiRequest(request: request) case let .purchaseOrder(route): return try await route.handleApiRequest(request: request) case let .user(route): return try await route.handleApiRequest(request: request) case let .vendor(route): return try await route.handleApiRequest(request: request) case let .vendorBranch(route): return try await route.handleApiRequest(request: request) } } } extension ApiRoute.EmployeeRoute { func handleApiRequest(request: Request) async throws -> any AsyncResponseEncodable { @Dependency(\.database) var database switch self { case let .delete(id: id): try await database.employees.delete(id) return HTTPStatus.ok case let .base(route): switch route { case let .create(employee): return try await database.employees.create(employee) case .index: return try await database.employees.fetchAll() case let .get(id: id): guard let employee = try await database.employees.get(id) else { throw Abort(.badRequest, reason: "Employee not found") } return employee case let .update(id: id, updates: updates): return try await database.employees.update(id, updates) } } } } extension BaseRoute.PurchaseOrderRoute { func handleApiRequest(request: Request) async throws -> any AsyncResponseEncodable { @Dependency(\.database.purchaseOrders) var purchaseOrders switch self { case .index: return try await purchaseOrders.fetchAll() case let .create(purchaseOrder): return try await purchaseOrders.create(purchaseOrder) case let .delete(id: id): try await purchaseOrders.delete(id) return HTTPStatus.ok case let .get(id: id): guard let output = try await purchaseOrders.get(id) else { throw Abort(.badRequest, reason: "Purchase order not found.") } return output case let .page(page: page, limit: limit): return try await purchaseOrders.fetchPage(.init(page: page, per: limit)) } } } // TODO: Add Login. extension BaseRoute.UserRoute { func handleApiRequest(request: Request) async throws -> any AsyncResponseEncodable { @Dependency(\.database.users) var users switch self { case let .create(user): return try await users.create(user) case let .delete(id: id): try await users.delete(id) return HTTPStatus.ok case .index: return try await users.fetchAll() case let .get(id: id): guard let user = try await users.get(id) else { throw Abort(.badRequest, reason: "Employee not found") } return user // case let .login(user): // return try await users.login(user) case let .update(id: id, updates: updates): return try await users.update(id, updates) } } } extension BaseRoute.VendorRoute { func handleApiRequest(request: Request) async throws -> any AsyncResponseEncodable { @Dependency(\.database.vendors) var vendors switch self { case let .create(vendor): return try await vendors.create(vendor) case let .delete(id: id): try await vendors.delete(id) return HTTPStatus.ok case let .get(id: id): guard let vendor = try await vendors.get(id) else { throw Abort(.badRequest, reason: "Employee not found") } return vendor case let .update(id: id, updates: updates): return try await vendors.update(id, with: updates) case let .index(withBranches: withBranches): guard withBranches == true else { return try await vendors.fetchAll() } return try await vendors.fetchAll(.withBranches) } } } extension BaseRoute.VendorBranchRoute { func handleApiRequest(request: Request) async throws -> any AsyncResponseEncodable { @Dependency(\.database.vendorBranches) var vendorBranches switch self { case let .create(branch): return try await vendorBranches.create(branch) case let .delete(id: id): try await vendorBranches.delete(id) return HTTPStatus.ok case let .index(for: optionalVendorID): guard let vendorID = optionalVendorID else { return try await vendorBranches.fetchAll() } return try await vendorBranches.fetchAll(.for(vendorID: vendorID)) case let .get(id: id): guard let branch = try await vendorBranches.get(id) else { throw Abort(.badRequest, reason: "Employee not found") } return branch case let .update(id: id, updates: updates): return try await vendorBranches.update(id, updates) } } }