Skip to content

优化备份和日记同步#122

Open
qmday wants to merge 3 commits into
Yu-Core:masterfrom
qmday:feature/webdav-sync-backup
Open

优化备份和日记同步#122
qmday wants to merge 3 commits into
Yu-Core:masterfrom
qmday:feature/webdav-sync-backup

Conversation

@qmday

@qmday qmday commented May 27, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants