import DatabaseClient import Dependencies import SharedModels import Vapor struct EmployeeApiController: RouteCollection { @Dependency(\.database.employees) var employees func boot(routes: any RoutesBuilder) throws { let protected = routes.apiProtected(route: "employees") protected.get(use: index(req:)) protected.post(use: create(req:)) protected.group(":id") { $0.get(use: get(req:)) $0.put(use: update(req:)) $0.delete(use: delete(req:)) } } @Sendable func index(req: Request) async throws -> [Employee] { let params = try req.query.decode(EmployeesIndexQuery.self) return try await employees.fetchAll(params.request) } @Sendable func create(req: Request) async throws -> Employee { try await employees.create( req.content.decode(Employee.Create.self) ) } @Sendable func get(req: Request) async throws -> Employee { guard let employee = try await employees.get(req.ensureIDPathComponent()) else { throw Abort(.notFound) } return employee } @Sendable func update(req: Request) async throws -> Employee { return try await employees.update( req.ensureIDPathComponent(), req.content.decode(Employee.Update.self) ) } @Sendable func delete(req: Request) async throws -> HTTPStatus { try await employees.delete(req.ensureIDPathComponent()) return .ok } } struct EmployeesIndexQuery: Content { let active: Bool? var request: DatabaseClient.Employees.FetchRequest { switch active { case .none: return .all case .some(true): return .active case .some(false): return .inactive } } }