Files
hyungi_document_server/Sources/DSKit/DSClient.swift
T
Hyungi 0becf7829e feat(s3): SwiftPM scaffold + DSKit data layer + 14-fixture acceptance
- Package.swift: AI (S2-owned) + DSKit (models/client/fixtures) + DSKitTests, tools 6.2, .swiftLanguageMode(.v6), .macOS(.v26)
- JSONValue (Sendable AnyCodable), DSDate (value-type ISO8601FormatStyle cascade, date-only UTC), explicit-CodingKeys decoder
- Models: Auth/Document(+Detail flat-compose, MD-first)/Catalog/Search+Ask/Memo/Digest; non-optional limited to id/file_type/created+updated_at/total
- DSClient protocol + FixtureDSClient (Bundle.module, zero backend) + DSError + DSConfig + DownloadURL (?token= query)
- Tests: 14-fixture contract acceptance (value asserts) + JSONValue number trap + Ask round-trip + AI router fallback/explicit-unavailable

swift build + swift test green (19 tests). Sources/AI untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 17:16:55 +09:00

44 lines
2.2 KiB
Swift

import Foundation
/// The single networking seam the whole app codes against. The app builds entirely on
/// `FixtureDSClient` (zero backend); `LiveDSClient` (FU-A) drops in later unchanged.
///
/// `ask(backend:)` keeps `backend` as `String?` (raw AI-ROUTING §4 values) S2 maps AIProviderID
/// to that string. This shape is locked by AI-ROUTING.md §4 (a documented contract), verified at
/// integration by the FU-B call-shape regression.
public protocol DSClient: Sendable {
// Auth
func login(username: String, password: String, totpCode: String?) async throws -> AccessTokenResponse
func me() async throws -> UserResponse
func refresh() async throws -> AccessTokenResponse
func logout() async throws
// Documents
func documents(_ query: DocumentListQuery) async throws -> DocumentListResponse
func document(id: Int) async throws -> DocumentDetailResponse
func documentContent(id: Int) async throws -> DocumentContentResponse
func documentTree() async throws -> [DomainTreeNode]
func categoryCounts() async throws -> CategoryCounts
func duplicates() async throws -> DuplicatesResponse
func patchDocument(id: Int, _ update: DocumentUpdate) async throws -> DocumentResponse
func putContent(id: Int, content: String) async throws
func deleteDocument(id: Int) async throws
// Search / Ask
func search(q: String, mode: SearchMode?, page: Int?, debug: Bool?) async throws -> SearchResponse
func ask(q: String, limit: Int?, backend: String?, debug: Bool?) async throws -> AskResponse
// Memos
func memos(_ query: MemoListQuery) async throws -> MemoListResponse
func memo(id: Int) async throws -> MemoResponse
func createMemo(_ create: MemoCreate) async throws -> MemoResponse
func patchMemo(id: Int, _ update: MemoUpdate) async throws -> MemoResponse
func pinMemo(id: Int, pinned: Bool) async throws -> MemoResponse
func archiveMemo(id: Int, archived: Bool) async throws -> MemoResponse
func toggleMemoTask(id: Int, taskIndex: Int, checked: Bool) async throws -> MemoResponse
func deleteMemo(id: Int) async throws
// Digest
func digest(date: String?, country: String?) async throws -> DigestResponse
}