import Foundation public enum UpstreamRoute: Equatable, Sendable { case health case device case sim case network case signalStrength case connectivity case smsList(limit: Int, offset: Int, direction: String?) case smsSend(phoneNumber: String, content: String) case smsBatchDelete(ids: [Int]) case authLogin(password: String) case authLogout public var method: String { switch self { case .health, .device, .sim, .network, .signalStrength, .connectivity, .smsList: return "GET" case .smsSend, .smsBatchDelete, .authLogin, .authLogout: return "POST" } } public var path: String { switch self { case .health: return "/api/health" case .device: return "/api/device" case .sim: return "/api/sim" case .network: return "/api/network" case .signalStrength: return "/api/network/signal-strength" case .connectivity: return "/api/connectivity" case .smsList(let limit, let offset, let direction): var items = ["limit=\(limit)", "offset=\(offset)"] if let direction { items.append("direction=\(direction)") } return "/api/sms/list?\(items.joined(separator: "&"))" case .smsSend: return "/api/sms/send" case .smsBatchDelete: return "/api/sms/batch-delete" case .authLogin: return "/api/auth/login" case .authLogout: return "/api/auth/logout" } } public var body: Data? { switch self { case .smsSend(let phoneNumber, let content): return try? JSONSerialization.data( withJSONObject: ["phone_number": phoneNumber, "content": content] ) case .smsBatchDelete(let ids): return try? JSONSerialization.data(withJSONObject: ["ids": ids]) case .authLogin(let password): return try? JSONSerialization.data(withJSONObject: ["password": password]) default: return nil } } } public enum UpstreamError: Error, Equatable { case invalidRequest case unauthorized case forbidden case notSupported case timeout case transportFailed case invalidResponse }