feat(backup): add automatic weekly encrypted backups
A silent safety net against in-app data loss or DB corruption, with zero friction. Driven off the app lifecycle (startup + when hidden), it writes a sealed .tanemaki copy into the app's private storage once a week, keeping the newest 3 (rotating). Reuses the manual backup's encryption via the extracted ExportImportService.buildSealedBackup(); never throws, so a failed copy can't crash startup or backgrounding. Not registered on web (no file storage). Settings shows a quiet reassurance line with the date of the last automatic copy (localised via intl), hidden where no automatic backup exists.
This commit is contained in:
parent
cf6975b748
commit
9c449964fd
19 changed files with 559 additions and 29 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:commons_core/commons_core.dart';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:flutter/services.dart' show rootBundle;
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
|
@ -15,6 +16,8 @@ import '../db/encrypted_executor.dart';
|
|||
import '../i18n/strings.g.dart';
|
||||
import '../security/secret_store.dart';
|
||||
import '../security/secure_key_store.dart';
|
||||
import '../services/auto_backup_service.dart';
|
||||
import '../services/auto_backup_store.dart';
|
||||
import '../services/export_import_service.dart';
|
||||
import '../services/file_picker_file_service.dart';
|
||||
import '../services/file_service.dart';
|
||||
|
|
@ -98,6 +101,23 @@ Future<void> configureDependencies() async {
|
|||
..registerSingleton<RecoverySheetService>(
|
||||
RecoverySheetService(files: fileService),
|
||||
);
|
||||
|
||||
// Automatic silent backups need real file storage; the web build has none, so
|
||||
// it simply goes without (the manual "save a copy" still works there).
|
||||
if (!kIsWeb) {
|
||||
getIt.registerSingleton<AutoBackupService>(
|
||||
AutoBackupService(
|
||||
exporter: getIt<ExportImportService>(),
|
||||
store: AutoBackupStore(secretStore),
|
||||
directory: _backupsDir,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Directory> _backupsDir() async {
|
||||
final dir = await getApplicationSupportDirectory();
|
||||
return Directory(p.join(dir.path, 'backups'));
|
||||
}
|
||||
|
||||
Future<File> _databaseFile() async {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue