Coverage for src/local_deep_research/web/warning_checks/backup.py: 100%
30 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-22 21:20 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-22 21:20 +0000
1"""Backup status warning checks.
3Pure functions that take primitive values and return warning dicts (or None).
4"""
6from typing import Optional
8from ...config.paths import MODE_NOT_KEPT, OWNED_BY_ANOTHER_ACCOUNT
10_REPORT_BACKUP_CAUSES = {
11 OWNED_BY_ANOTHER_ACCOUNT: (
12 "another OS account owns the server's research_outputs folder, as "
13 "with Docker Desktop bind mounts of Windows folders or after the app "
14 "ran as a different user"
15 ),
16 MODE_NOT_KEPT: (
17 "the filesystem holding the server's research_outputs folder does not "
18 "keep owner-only permissions, as on WSL drives such as /mnt/c, "
19 "CIFS/SMB shares and exFAT"
20 ),
21}
24def check_report_backup_unavailable(
25 backup_enabled: bool, problem: Optional[str]
26) -> Optional[dict]:
27 """Warn that report file backups are refused although they are enabled.
29 ``problem`` is None when the folder is private, a
30 ``DirectoryNotPrivateError.reason``, or any other string when the folder
31 could not be prepared at all. Not dismissible: it shows while the
32 setting is on and FileReportStorage would refuse the folder.
33 """
34 if not backup_enabled or problem is None:
35 return None
36 cause = _REPORT_BACKUP_CAUSES.get(
37 problem,
38 "the server could not make its research_outputs folder private "
39 "(the server log names the cause when a report is saved)",
40 )
41 return {
42 "type": "report_backup_unavailable",
43 "icon": "⚠️",
44 "title": "Report File Backups Disabled",
45 "message": (
46 "Report file backup is on, but no report files are being "
47 f"written because {cause}. Reports are still saved in the "
48 "database. Keep the data directory (LDR_DATA_DIR) on a Linux "
49 "filesystem path or a Docker named volume owned by the account "
50 "that runs the app, or turn off report file backup."
51 ),
52 "dismissKey": None,
53 "actionUrl": "/settings#setting-report-enable_file_backup",
54 "actionLabel": "Open report backup setting",
55 }
58def check_backup_disabled(
59 backup_enabled: bool, dismissed: bool
60) -> Optional[dict]:
61 """Warn if automatic backups are disabled."""
62 if backup_enabled:
63 return None
64 if dismissed:
65 return None
67 return {
68 "type": "backup_disabled",
69 "icon": "💾",
70 "title": "Database Backups Disabled",
71 "message": (
72 "Automatic database backups are disabled. Without backups, "
73 "data cannot be recovered if the database is corrupted. "
74 "Enable backups in Settings \u203a Backup."
75 ),
76 "dismissKey": "app.warnings.dismiss_backup_disabled",
77 }
80def check_no_backups_exist(
81 backup_enabled: bool, backup_count: int, dismissed: bool
82) -> Optional[dict]:
83 """Warn if backups are enabled but none exist yet."""
84 if not backup_enabled:
85 return None
86 if backup_count > 0:
87 return None
88 if dismissed:
89 return None
91 return {
92 "type": "no_backups",
93 "icon": "📁",
94 "title": "No Backups Found",
95 "message": (
96 "No database backups have been created yet. A backup will "
97 "be created automatically on your next login. You can "
98 "configure backup settings in Settings \u203a Backup."
99 ),
100 "dismissKey": "app.warnings.dismiss_no_backups",
101 }
104def check_backup_healthy(
105 backup_enabled: bool,
106 backup_count: int,
107 total_size_human: str,
108 dismissed: bool,
109) -> Optional[dict]:
110 """Show positive backup status info (dismissable)."""
111 if not backup_enabled:
112 return None
113 if backup_count == 0:
114 return None
115 if dismissed:
116 return None
118 return {
119 "type": "backup_info",
120 "icon": "✅",
121 "title": "Database Backup Active",
122 "message": (
123 f"{backup_count} backup{'s' if backup_count > 1 else ''} "
124 f"({total_size_human}) on disk. Encrypted backups cannot be "
125 "compressed, so each backup equals your database size "
126 "(which can be large if PDFs are stored in the database). "
127 "Backups are created once per day on login. Manage backups "
128 "in Settings \u203a Backup."
129 ),
130 "dismissKey": "app.warnings.dismiss_backup_info",
131 }