// // ProjectService.swift // Snail // import Foundation nonisolated struct Project: Codable, Identifiable, Hashable, Sendable { let id: String let key: String let name: String let ownerId: String let createdAt: Date let updatedAt: Date } nonisolated struct PaginationMeta: Decodable, Sendable { let totalCount: Int let page: Int let totalPages: Int } nonisolated struct ProjectPage: Decodable, Sendable { let list: [Project] let meta: PaginationMeta } nonisolated struct ProjectService: Sendable { private let client: APIClient init(client: APIClient = APIClient()) { self.client = client } /// Проекты, в которых участвует текущий пользователь. Страницы нумеруются с 1. func list(page: Int, limit: Int) async throws -> ProjectPage { let response: Envelope = try await client.send( "GET", "projects/list", query: [ URLQueryItem(name: "page", value: String(page)), URLQueryItem(name: "limit", value: String(limit)), ] ) return response.data } func create(key: String, name: String) async throws -> Project { let response: Envelope = try await client.send( "POST", "projects", body: ["key": key, "name": name] ) return response.data } /// Менять можно только название — ключ участвует в номерах задач. func update(id: String, name: String) async throws -> Project { let response: Envelope = try await client.send( "PATCH", "projects/\(id)", body: ["name": name] ) return response.data } }