diff --git a/api/app/lib/backup_streaming.py b/api/app/lib/backup_streaming.py index 38be4cf74..dde8666ff 100644 --- a/api/app/lib/backup_streaming.py +++ b/api/app/lib/backup_streaming.py @@ -1,7 +1,7 @@ """ Backup Streaming Service -Implements ADR-015 Phase 2: Streaming backup download with chunked transfer encoding. +Implements ADR-015 Phase 1: Streaming backup download with chunked transfer encoding. Converts backup dictionaries into JSON or GEXF streams without loading entire backup into memory. Supports two formats: diff --git a/cli/src/api/client.ts b/cli/src/api/client.ts index 836485df5..7f1b7b8df 100644 --- a/cli/src/api/client.ts +++ b/cli/src/api/client.ts @@ -43,10 +43,7 @@ import { DissolveResponse, SystemStatusResponse, BackupRequest, - BackupResponse, ListBackupsResponse, - RestoreRequest, - RestoreResponse, ResourceCreate, ResourceRead, ResourceUpdate, diff --git a/cli/src/types/index.ts b/cli/src/types/index.ts index d5ff8d0e7..6e10cdef0 100644 --- a/cli/src/types/index.ts +++ b/cli/src/types/index.ts @@ -685,22 +685,9 @@ export interface BackupRequest { format?: 'archive' | 'json' | 'gexf'; // Export format: archive (tar.gz with documents, default), json (graph only), or gexf (Gephi visualization) } -export interface BackupIntegrityAssessment { - external_dependencies_count: number; - warnings_count: number; - issues_count: number; - has_external_deps: boolean; - details: Record; -} - -export interface BackupResponse { - success: boolean; - backup_file: string; - file_size_mb: number; - statistics: Record; - integrity_assessment?: BackupIntegrityAssessment; - message: string; -} +// BackupIntegrityAssessment / BackupResponse removed in ADR-102 P6: the backup route +// streams the file (createBackup returns {filename,path,size}); the Python-side +// BackupResponse/BackupIntegrityAssessment models were deleted in P6a. export interface BackupInfo { filename: string; @@ -715,23 +702,9 @@ export interface ListBackupsResponse { count: number; } -export interface RestoreRequest { - username: string; - password: string; - backup_file: string; - // ADR-102 P4: restore merge mode (replaces overwrite + handle_external_deps). - mode?: 'idempotent' | 'adjacent' | 'integration'; - // ADR-102 P5: epoch reconciliation. 'faithful' is clone-only (idempotent + empty target). - epoch?: 'simple' | 'faithful'; -} - -export interface RestoreResponse { - success: boolean; - restored_counts: Record; - warnings: string[]; - message: string; - // external_deps_handled removed in ADR-102 P6 (dead field; restore uses --mode/--epoch) -} +// RestoreRequest / RestoreResponse removed in ADR-102 P6: restoreBackup() uses +// positional args (backupFilePath, mode, onUploadProgress, epoch) + multipart +// FormData and returns an inline result type — these interfaces were never used. // ========== RBAC Types (ADR-028) ========== diff --git a/docs/architecture/infrastructure/ADR-015-backup-restore-streaming.md b/docs/architecture/infrastructure/ADR-015-backup-restore-streaming.md index cd11638de..5cc6df3e4 100644 --- a/docs/architecture/infrastructure/ADR-015-backup-restore-streaming.md +++ b/docs/architecture/infrastructure/ADR-015-backup-restore-streaming.md @@ -6,10 +6,21 @@ deciders: related: - ADR-012 - ADR-013 + - ADR-102 --- # ADR-015: Backup/Restore Streaming Architecture +> **Status update (ADR-102, 2026):** the client-controlled streaming model decided +> here is live. **Phase 1 (backup download)** ships as +> `api/app/lib/backup_streaming.py` + `backup_archive.py`. **Phase 2 (restore upload)**, +> tracked below as "🚧 IN PROGRESS", was *delivered* by +> [ADR-102](ADR-102-portable-backup-and-restore-with-clone-merge-semantics.md) — the +> portable `kg-backup/2` format with clone/merge/restamp restore semantics, epoch +> reconciliation, and the async `restore_worker`. ADR-102 builds **on** this ADR's +> streaming foundation rather than replacing it, so ADR-015 remains Accepted; the +> Phase-2 progress markers below are historical (read them as "done, see ADR-102"). + ## Overview Think about how you back up photos from your phone. The photos live on your device, not on some cloud server. You initiate the backup, your phone sends the files where you want them, and you can restore them whenever needed. Now imagine if instead, all your photos were "backed up" to a folder on Apple's servers that you couldn't even access - that would be pretty useless, right?