优化备份和日记同步#122
Open
qmday wants to merge 3 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces an experimental WebDAV-based incremental backup format and an incremental diary sync mechanism, including background auto-sync scheduling and local sync metadata tables to track applied batches, tombstones, and conflicts.
Changes:
- Add sync metadata models (state/tombstone/conflict) and wire them into SqlSugar initialization and diary delete flows (tombstones).
- Add WebDAV diary sync service + scheduler (manual sync + background loop) and start scheduler from the main layout.
- Replace legacy “upload/pull zip” backup UX with an incremental backup manifest flow (content-addressed uploads by hash), plus new sync/auto-sync UI controls.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/SwashbucklerDiary.Shared/Models/SyncTombstoneModel.cs | New tombstone model for propagating deletions during sync |
| src/SwashbucklerDiary.Shared/Models/SyncStateModel.cs | New model for tracking applied remote sync batches |
| src/SwashbucklerDiary.Shared/Models/SyncConflictModel.cs | New model for storing sync conflict records |
| src/SwashbucklerDiary.Rcl/Services/Sync/NoopWebDavDiarySyncScheduler.cs | No-op scheduler implementation for platforms without sync |
| src/SwashbucklerDiary.Rcl/Services/Sync/IWebDavDiarySyncScheduler.cs | Scheduler contract for starting/running sync |
| src/SwashbucklerDiary.Rcl/Services/Sync/IDiarySyncService.cs | Sync service contract (sync + local-change detection) |
| src/SwashbucklerDiary.Rcl/Services/Sync/DiarySyncResult.cs | Result DTO for sync statistics |
| src/SwashbucklerDiary.Rcl/Services/SettingService/Setting.cs | Add device/sync settings (device id, last push/sync, auto/interval) |
| src/SwashbucklerDiary.Rcl/Services/DiaryFileManager/DiaryFileManager.cs | Add deterministic “database snapshot” export + snapshot import alias |
| src/SwashbucklerDiary.Rcl/Services/Data/DiaryService/DiaryService.cs | Record tombstones on delete; add delete path intended for sync deletes |
| src/SwashbucklerDiary.Rcl/Layout/MainLayoutBase.cs | Start the diary sync scheduler during app initialization |
| src/SwashbucklerDiary.Rcl/Extensions/ServiceCollectionExtensions/AddSqlsugar.cs | Ensure new sync tables are included in CodeFirst init |
| src/SwashbucklerDiary.Rcl/Extensions/ServiceCollectionExtensions/AddRclDependencyInjection.cs | Register scheduler default (noop) in shared RCL DI |
| src/SwashbucklerDiary.Rcl.Hybird/Services/WebDAVSync/WebDavDiarySyncService.cs | New incremental diary sync implementation over WebDAV |
| src/SwashbucklerDiary.Rcl.Hybird/Services/WebDAVSync/WebDavDiarySyncScheduler.cs | Background auto-sync worker + RunOnce entrypoint |
| src/SwashbucklerDiary.Rcl.Hybird/Services/WebDAVSync/SyncBatch.cs | Sync batch wire format (diary changes + snapshots) |
| src/SwashbucklerDiary.Rcl.Hybird/Services/WebDAVBackups/WebDavIncrementalBackupService.cs | New incremental backup/restore using manifests + hash-addressed files |
| src/SwashbucklerDiary.Rcl.Hybird/Services/WebDAVBackups/WebDavIncrementalBackupManifest.cs | Manifest DTOs for incremental backups |
| src/SwashbucklerDiary.Rcl.Hybird/Services/WebDAVBackups/IWebDavIncrementalBackupService.cs | Incremental backup service contract |
| src/SwashbucklerDiary.Rcl.Hybird/Pages/Backups/WebDAVBackups/WebDAVBackupsPage.razor.cs | UI logic updated for incremental backups + manual sync/auto-sync settings |
| src/SwashbucklerDiary.Rcl.Hybird/Pages/Backups/WebDAVBackups/WebDAVBackupsPage.razor | UI updated to show manifests and new sync controls |
| src/SwashbucklerDiary.Maui/Extensions/ServiceCollectionExtensions/AddDependencyInjection.cs | Register sync + scheduler + incremental backup services for MAUI |
| src/SwashbucklerDiary.Gtk/Extensions/ServiceCollectionExtensions/AddDependencyInjection.cs | Register sync + scheduler + incremental backup services for GTK |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| public string DeviceId { get; set; } = string.Empty; | ||
|
|
||
| public DateTime DeletedAt { get; set; } = DateTime.UtcNow; |
|
|
||
| public string RemotePath { get; set; } = string.Empty; | ||
|
|
||
| public DateTime AppliedAt { get; set; } = DateTime.UtcNow; |
| AppVersion = _platformIntegration.AppVersionString | ||
| }; | ||
|
|
||
| string dbBackupPath = await _diaryFileManager.ExportDatabaseSnapshotAsync().ConfigureAwait(false); |
|
|
||
| await using (var stream = await _webDAV.DownloadAsync(database.RemotePath).ConfigureAwait(false)) | ||
| { | ||
| await _diaryFileManager.ImportDatabaseSnapshotAsync(stream).ConfigureAwait(false); |
Comment on lines
+49
to
+53
| EnsureSyncTables(); | ||
|
|
||
| await _webDAV.EnsureFolderAsync(SyncRoot).ConfigureAwait(false); | ||
| await _webDAV.EnsureFolderAsync(ChangesFolder).ConfigureAwait(false); | ||
| await _webDAV.EnsureFolderAsync(GetDeviceChangesFolder(deviceId)).ConfigureAwait(false); |
Comment on lines
+232
to
+237
| { | ||
| var local = await _diaryService.FindAsync(change.Id).ConfigureAwait(false); | ||
| if (local is not null && change.UpdatedAt >= local.UpdateTime) | ||
| { | ||
| await _diaryService.DeleteFromSyncAsync(local).ConfigureAwait(false); | ||
| result.Deleted++; |
Comment on lines
+180
to
+187
| private async Task EnsureFoldersAsync() | ||
| { | ||
| await _webDAV.EnsureFolderAsync(BackupRoot).ConfigureAwait(false); | ||
| await _webDAV.EnsureFolderAsync(FilesRoot).ConfigureAwait(false); | ||
| await _webDAV.EnsureFolderAsync($"{FilesRoot}/database").ConfigureAwait(false); | ||
| await _webDAV.EnsureFolderAsync($"{FilesRoot}/media").ConfigureAwait(false); | ||
| await _webDAV.EnsureFolderAsync(ManifestsRoot).ConfigureAwait(false); | ||
| } |
| return; | ||
| } | ||
|
|
||
| var result = await DiarySyncScheduler.RunOnceAsync(true) ?? await DiarySyncService.SyncAsync(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.