chore: post-merge cleanup for backup feature
This commit is contained in:
@@ -1,26 +0,0 @@
|
|||||||
# Feature Context: Backup Management
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
- **Development mode:** Automated
|
|
||||||
- **Execution mode:** Direct
|
|
||||||
- **Strategy:** Big Bang
|
|
||||||
- **Build (Go):** `go build ./cmd/server`
|
|
||||||
- **Build (Frontend):** `cd web && npm run build`
|
|
||||||
- **Check (Frontend):** `cd web && npm run check`
|
|
||||||
- **Dev server:** `./scripts/dev-server.sh` (port 8090)
|
|
||||||
|
|
||||||
## Current State
|
|
||||||
Starting fresh — no implementation yet.
|
|
||||||
|
|
||||||
## Key Architecture Decisions
|
|
||||||
- Backup via `VACUUM INTO` — creates a clean standalone DB copy, safe with WAL mode
|
|
||||||
- Backups stored in `DATA_DIR/backups/` as timestamped `.db` files
|
|
||||||
- Backup metadata tracked in a `backups` table in the main DB
|
|
||||||
- Autobackup uses existing robfig/cron scheduler pattern
|
|
||||||
- Restore replaces the DB file and triggers a graceful server restart
|
|
||||||
- ENCRYPTION_KEY is NOT backed up — user must have the same key on restore
|
|
||||||
|
|
||||||
## Cross-Phase Dependencies
|
|
||||||
- Phase 2 depends on Phase 1 (backup.Engine)
|
|
||||||
- Phase 3 depends on Phase 2 (API endpoints)
|
|
||||||
- Phase 4 depends on Phase 1 (Engine.Prune method)
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
# Feature: Backup Management
|
|
||||||
|
|
||||||
**Branch:** `feature/backup-management`
|
|
||||||
**Base branch:** `main`
|
|
||||||
**Created:** 2026-04-02
|
|
||||||
**Status:** 🟡 In Progress
|
|
||||||
**Strategy:** Big Bang
|
|
||||||
**Mode:** Automated
|
|
||||||
**Execution:** Direct
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
Add manual and automatic backup/restore functionality for the SQLite database.
|
|
||||||
Users can trigger backups on demand, configure autobackup on an interval with
|
|
||||||
retention policies, list/download/delete backups, and restore from a backup.
|
|
||||||
|
|
||||||
## Build & Test Commands
|
|
||||||
- **Build (Go):** `go build ./cmd/server`
|
|
||||||
- **Build (Frontend):** `cd web && npm run build`
|
|
||||||
- **Check (Frontend):** `cd web && npm run check`
|
|
||||||
- **Dev server:** `./scripts/dev-server.sh`
|
|
||||||
|
|
||||||
## Phases
|
|
||||||
|
|
||||||
- [ ] Phase 1: Backup engine & settings [domain: backend] → [subplan](./phase-1-backup-engine.md)
|
|
||||||
- [ ] Phase 2: Backup API endpoints [domain: backend] → [subplan](./phase-2-backup-api.md)
|
|
||||||
- [ ] Phase 3: Backup settings & management UI [domain: frontend] → [subplan](./phase-3-backup-ui.md)
|
|
||||||
- [ ] Phase 4: Retention & cleanup [domain: backend] → [subplan](./phase-4-retention.md)
|
|
||||||
|
|
||||||
## Phase Progress Log
|
|
||||||
|
|
||||||
| Phase | Domain | Status | Review | Build | Committed |
|
|
||||||
|-------|--------|--------|--------|-------|-----------|
|
|
||||||
| Phase 1: Backup engine & settings | backend | ⬜ Not Started | ⬜ | ⬜ | ⬜ |
|
|
||||||
| Phase 2: Backup API endpoints | backend | ⬜ Not Started | ⬜ | ⬜ | ⬜ |
|
|
||||||
| Phase 3: Backup UI | frontend | ⬜ Not Started | ⬜ | ⬜ | ⬜ |
|
|
||||||
| Phase 4: Retention & cleanup | backend | ⬜ Not Started | ⬜ | ⬜ | ⬜ |
|
|
||||||
|
|
||||||
## Final Review
|
|
||||||
- [ ] Comprehensive code review
|
|
||||||
- [ ] Full build passes
|
|
||||||
- [ ] Full test suite passes
|
|
||||||
- [ ] Merged to `main`
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# Phase 1: Backup Engine & Settings
|
|
||||||
|
|
||||||
**Status:** ⬜ Not Started
|
|
||||||
**Parent plan:** [PLAN.md](./PLAN.md)
|
|
||||||
**Domain:** backend
|
|
||||||
|
|
||||||
## Objective
|
|
||||||
Create the core backup engine and extend settings to support backup configuration.
|
|
||||||
|
|
||||||
## Tasks
|
|
||||||
|
|
||||||
- [ ] Task 1: Add backup settings fields to Settings model
|
|
||||||
- `BackupEnabled` bool (default false)
|
|
||||||
- `BackupIntervalHours` int (default 24)
|
|
||||||
- `BackupRetentionCount` int (default 10)
|
|
||||||
- [ ] Task 2: Add migration columns in store.go
|
|
||||||
- [ ] Task 3: Update GetSettings/UpdateSettings queries
|
|
||||||
- [ ] Task 4: Create `backups` metadata table
|
|
||||||
- id, filename, size_bytes, backup_type (manual/auto), created_at
|
|
||||||
- [ ] Task 5: Create `internal/backup/engine.go`
|
|
||||||
- Engine struct with db path, backup dir
|
|
||||||
- `CreateBackup(backupType string) (Backup, error)` — VACUUM INTO timestamped file
|
|
||||||
- `ListBackups() ([]Backup, error)` — read from metadata table
|
|
||||||
- `GetBackup(id string) (Backup, error)`
|
|
||||||
- `DeleteBackup(id string) error` — delete file + metadata
|
|
||||||
- `RestoreBackup(id string) error` — copy backup over main DB
|
|
||||||
- `DownloadPath(id string) (string, error)` — return file path for download
|
|
||||||
- [ ] Task 6: Create `internal/store/backups.go` — CRUD for backup metadata
|
|
||||||
- [ ] Task 7: Create backup directory on engine init (`DATA_DIR/backups/`)
|
|
||||||
|
|
||||||
## Files to Modify/Create
|
|
||||||
- `internal/store/models.go` — add Backup struct, extend Settings
|
|
||||||
- `internal/store/store.go` — add migration + backups table
|
|
||||||
- `internal/store/settings.go` — update queries
|
|
||||||
- `internal/store/backups.go` — backup metadata CRUD
|
|
||||||
- `internal/backup/engine.go` — core backup logic
|
|
||||||
|
|
||||||
## Acceptance Criteria
|
|
||||||
- Backup engine can create a backup file via VACUUM INTO
|
|
||||||
- Backup metadata stored in DB
|
|
||||||
- Backup files stored in DATA_DIR/backups/
|
|
||||||
- Settings include backup configuration fields
|
|
||||||
- Delete removes both file and metadata
|
|
||||||
|
|
||||||
## Handoff to Next Phase
|
|
||||||
<!-- Filled in after completion -->
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
# Phase 2: Backup API Endpoints
|
|
||||||
|
|
||||||
**Status:** ⬜ Not Started
|
|
||||||
**Parent plan:** [PLAN.md](./PLAN.md)
|
|
||||||
**Domain:** backend
|
|
||||||
|
|
||||||
## Objective
|
|
||||||
Expose backup operations via REST API and wire autobackup scheduling.
|
|
||||||
|
|
||||||
## Tasks
|
|
||||||
|
|
||||||
- [ ] Task 1: Create `internal/api/backups.go` with handlers
|
|
||||||
- `POST /api/backups` — trigger manual backup
|
|
||||||
- `GET /api/backups` — list all backups
|
|
||||||
- `GET /api/backups/{id}/download` — download backup file
|
|
||||||
- `DELETE /api/backups/{id}` — delete backup
|
|
||||||
- `POST /api/backups/{id}/restore` — restore from backup
|
|
||||||
- [ ] Task 2: Register routes in router.go (admin-only)
|
|
||||||
- [ ] Task 3: Add backup engine to Server struct
|
|
||||||
- SetBackupEngine method (same pattern as SetProxyManager)
|
|
||||||
- [ ] Task 4: Wire autobackup cron in main.go
|
|
||||||
- Create backup engine on startup
|
|
||||||
- If backup_enabled, schedule cron job
|
|
||||||
- Graceful shutdown: stop cron
|
|
||||||
- [ ] Task 5: Update settings handler to restart autobackup cron on settings change
|
|
||||||
- [ ] Task 6: Add GET /api/settings response fields for backup settings
|
|
||||||
|
|
||||||
## Files to Modify/Create
|
|
||||||
- `internal/api/backups.go` — new handler file
|
|
||||||
- `internal/api/router.go` — register routes, add engine field
|
|
||||||
- `cmd/server/main.go` — wire engine, schedule cron
|
|
||||||
- `internal/api/settings.go` — include backup fields in GET/PUT
|
|
||||||
|
|
||||||
## Acceptance Criteria
|
|
||||||
- All CRUD endpoints work for backups
|
|
||||||
- Manual backup creates file and returns metadata
|
|
||||||
- Download streams the backup file
|
|
||||||
- Restore replaces DB (may require restart)
|
|
||||||
- Autobackup runs on configured interval
|
|
||||||
- Settings change updates cron schedule
|
|
||||||
|
|
||||||
## Handoff to Next Phase
|
|
||||||
<!-- Filled in after completion -->
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
# Phase 3: Backup Settings & Management UI
|
|
||||||
|
|
||||||
**Status:** ⬜ Not Started
|
|
||||||
**Parent plan:** [PLAN.md](./PLAN.md)
|
|
||||||
**Domain:** frontend
|
|
||||||
|
|
||||||
## Objective
|
|
||||||
Create a backup management page under settings with autobackup configuration,
|
|
||||||
manual backup trigger, and backup list with download/delete/restore actions.
|
|
||||||
|
|
||||||
## Tasks
|
|
||||||
|
|
||||||
- [ ] Task 1: Add API functions in api.ts
|
|
||||||
- triggerBackup, listBackups, downloadBackup, deleteBackup, restoreBackup
|
|
||||||
- [ ] Task 2: Add types in types.ts (BackupInfo interface)
|
|
||||||
- [ ] Task 3: Add i18n keys for backup page (en.json, ru.json)
|
|
||||||
- [ ] Task 4: Create backup settings page at `/settings/backup/+page.svelte`
|
|
||||||
- Autobackup toggle + interval selector + retention count
|
|
||||||
- "Backup Now" button with loading state
|
|
||||||
- Backup list table: filename, date, size, type, actions
|
|
||||||
- Download button (direct file download)
|
|
||||||
- Delete button with confirmation
|
|
||||||
- Restore button with strong warning dialog
|
|
||||||
- [ ] Task 5: Add navigation link in settings layout
|
|
||||||
- [ ] Task 6: Create IconBackup component (or reuse IconHardDrive/IconDatabase)
|
|
||||||
|
|
||||||
## Files to Modify/Create
|
|
||||||
- `web/src/lib/api.ts` — add backup API functions
|
|
||||||
- `web/src/lib/types.ts` — add BackupInfo type
|
|
||||||
- `web/src/lib/i18n/en.json` — add backup i18n keys
|
|
||||||
- `web/src/lib/i18n/ru.json` — add backup i18n keys
|
|
||||||
- `web/src/routes/settings/backup/+page.svelte` — new page
|
|
||||||
- `web/src/routes/settings/+layout.svelte` — add nav item
|
|
||||||
|
|
||||||
## Acceptance Criteria
|
|
||||||
- Backup page accessible at /settings/backup
|
|
||||||
- Autobackup settings save correctly
|
|
||||||
- Manual backup triggers and shows result
|
|
||||||
- Backup list shows all backups with correct metadata
|
|
||||||
- Download streams file to browser
|
|
||||||
- Delete removes backup with confirmation
|
|
||||||
- Restore shows warning and triggers restore
|
|
||||||
|
|
||||||
## Handoff to Next Phase
|
|
||||||
<!-- Filled in after completion -->
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# Phase 4: Retention & Cleanup
|
|
||||||
|
|
||||||
**Status:** ⬜ Not Started
|
|
||||||
**Parent plan:** [PLAN.md](./PLAN.md)
|
|
||||||
**Domain:** backend
|
|
||||||
|
|
||||||
## Objective
|
|
||||||
Implement automatic retention enforcement — prune old backups after each backup
|
|
||||||
operation and on server startup.
|
|
||||||
|
|
||||||
## Tasks
|
|
||||||
|
|
||||||
- [ ] Task 1: Add `Prune()` method to backup engine
|
|
||||||
- Delete backups exceeding retention count (keep N most recent)
|
|
||||||
- Return count of pruned backups
|
|
||||||
- [ ] Task 2: Call Prune after every CreateBackup (both manual and auto)
|
|
||||||
- [ ] Task 3: Call Prune on server startup
|
|
||||||
- [ ] Task 4: Clean up orphaned files (files in backup dir not in metadata)
|
|
||||||
- [ ] Task 5: Log pruning results
|
|
||||||
|
|
||||||
## Files to Modify/Create
|
|
||||||
- `internal/backup/engine.go` — add Prune method
|
|
||||||
- `cmd/server/main.go` — call prune on startup
|
|
||||||
|
|
||||||
## Acceptance Criteria
|
|
||||||
- Backups exceeding retention count are automatically deleted
|
|
||||||
- Both file and metadata are removed during pruning
|
|
||||||
- Orphaned files (no metadata) are cleaned up
|
|
||||||
- Pruning runs after each backup and on startup
|
|
||||||
- Pruning results logged
|
|
||||||
|
|
||||||
## Handoff to Next Phase
|
|
||||||
<!-- Filled in after completion -->
|
|
||||||
Reference in New Issue
Block a user