feat(backup): daily server and user backups, restore by section (backend)

Admins switch automatic backups on, pick the time and the retention
(default 03:00, 3 days). Each run writes a gzip snapshot of the whole
database (VACUUM INTO, consistent while others write) and one MindSift
backup ZIP per active user below $DATA_DIR/backups, then deletes files
past the retention. A restart after the time catches up on that day.
Admins list, download and trigger runs; users list, download and restore
their own backups.

Import and restore can be limited to sections (notes, tasks, lists,
inbox, themes): restore only empties the chosen sections. Export and
import now carry custom themes. File names are checked against a fixed
pattern, so no other file can be fetched through the API.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-10-29 15:10:06 +01:00
1 parent cab5a79f6d
commit c97765e08e
9 files changed
+632 -68

No files matched your search

+5
View File
@@ -292,6 +292,10 @@ type SystemSettings struct {
// metadata stay blocked
AllowPrivateWebhooks bool `json:"allowPrivateWebhooks"`
SMTPConfiguredViaEnv bool `json:"smtpConfiguredViaEnv,omitempty"`
// Automatic backups: on/off, daily time (HH:MM, server time zone) and how many days to keep them
BackupEnabled bool `json:"backupEnabled"`
BackupTime string `json:"backupTime"`
BackupRetentionDays int `json:"backupRetentionDays"`
}
// UnmarshalJSON accepts smtpPort as text or number: older clients sent a number, which made the whole
@@ -532,6 +536,7 @@ type FullExport struct {
Documents []Document `json:"documents"`
Lists []SharedList `json:"lists"`
TaskLists []TaskList `json:"taskLists,omitempty"`
Themes []UserTheme `json:"themes,omitempty"`
}
type SharedFolder struct {