Epic: Welcome Screen (#139)
Task ID: T-0 · Wave: 0 (prerequisite) · Complexity: L
Описание
Реализовать персистентное хранение серверов. Сейчас серверы хранятся только в памяти (ServerListFeature.State.servers) и теряются при перезапуске.
SwiftData (ServerModel): метаданные — serverID (UUID, unique), host, port, displayName, serverType, baseURL, certificateFingerprint, defaultImage, createdAt, lastConnectedAt.
Keychain (ServerKeychainStore): секреты — token, clientCertificatePEM, clientKeyPEM, caCertificatePEM. Ключ: serverID.uuidString.
TCA Dependency (ServerRepositoryClient): методы loadAll, save, delete, updateLastConnected. Live: CRUD в SwiftData + sync секретов в Keychain.
Обновить ServerListFeature: _loadServers загружает из SwiftData+Keychain, save/delete пишет через dependency. Убрать TODO Phase 4b.
Module: MacApp/Relay/Persistence + MacApp/Relay/ServerManagement
Acceptance Criteria
Dependencies
Нет — параллельно с T-1, T-2.
Epic: Welcome Screen (#139)
Task ID: T-0 · Wave: 0 (prerequisite) · Complexity: L
Описание
Реализовать персистентное хранение серверов. Сейчас серверы хранятся только в памяти (
ServerListFeature.State.servers) и теряются при перезапуске.SwiftData (
ServerModel): метаданные — serverID (UUID, unique), host, port, displayName, serverType, baseURL, certificateFingerprint, defaultImage, createdAt, lastConnectedAt.Keychain (
ServerKeychainStore): секреты — token, clientCertificatePEM, clientKeyPEM, caCertificatePEM. Ключ:serverID.uuidString.TCA Dependency (
ServerRepositoryClient): методы loadAll, save, delete, updateLastConnected. Live: CRUD в SwiftData + sync секретов в Keychain.Обновить
ServerListFeature:_loadServersзагружает из SwiftData+Keychain, save/delete пишет через dependency. Убрать TODO Phase 4b.Module:
MacApp/Relay/Persistence+MacApp/Relay/ServerManagementAcceptance Criteria
ServerModel(@model) с метаданными сервера в SwiftDataServerKeychainStore: CRUD для секретов по serverIDServerRepositoryClientкак TCA DependencyKey (live + testValue)ServerListFeature._loadServersзагружает из persistenceDependencies
Нет — параллельно с T-1, T-2.