Bump the package version to 1.2.0 and document the operations-focused release
with updater, readonly access, notifications, bandwidth controls, live progress,
and more robust retention cleanup.
Make the CLI version test assert against the package version so future release
bumps do not require changing a hardcoded expected value.
Add a Django updater view for checking configured Gitea releases, inspecting
the installed git checkout, fetching tags, pulling the current branch, and
running the configured native systemd update command.
Document the updater environment settings and keep the page staff-only so
readonly status users cannot trigger deployment actions.
Introduce a central access policy that lets authenticated non-staff users view
backup status pages while keeping credentials, logs, configs, and mutating
actions staff-only.
Hide sensitive navigation and host controls for read-only users, expose only
the status API to authenticated viewers, and document the two access levels.
Default queued and management-command backups to verbose rsync output so live
run views show progress for long-running real backups, matching dry-run
visibility.
Add a quiet-rsync escape hatch for operators who intentionally want less noisy
real-run logs.
Use filesystem usage for incomplete snapshots instead of trusting potentially
stale metadata, and expose unique non-hardlinked data totals for completed
snapshots.
Update dashboard and host storage summaries so incomplete data is visible and
complete snapshot totals distinguish allocated and unique data.
Add email and webhook notification targets with delivery tracking, and send
notifications when backup runs reach a terminal status.
Expose notification target management in the Django UI and keep delivery
failures recorded without failing the backup worker.
Require incomplete snapshots to be marked reviewed before the cleanup action
can delete them, and show review state in the retention plan UI.
Keep cleanup confirmation counts scoped to reviewed incomplete snapshots and
add coverage for blocked, reviewed, and deletion flows.
Repair user permissions inside snapshot trees before deleting them so
retention prune and incomplete cleanup can remove directories copied with
restrictive rsync archive modes.
Add path validation for scheduled/manual snapshot deletes and cover
non-traversable nested directories in retention tests.
- Fall back to filesystem measurement when snapshot storage metadata is missing.
- Prefer `data/` inside snapshot directories so incomplete snapshot metadata/log files are not counted as backup data.
- Add stats and dashboard rendering coverage for incomplete snapshots without recorded storage metadata.
## Tests
- .venv/bin/python manage.py test src.pobsync_backend.tests.test_stats_summary src.pobsync_backend.tests.test_views.ViewTests.test_dashboard_host_cards_measure_incomplete_data_without_snapshot_metadata --verbosity 2
- .venv/bin/python manage.py check
- git diff --check
- .venv/bin/python manage.py test src.pobsync_backend --verbosity 2
Closes#62
Aggregate snapshot storage metadata by snapshot kind so operators can see
scheduled, manual, incomplete, and total backup data.
Surface the totals per host and across all hosts on the dashboard, using
allocated snapshot size from recorded backup metadata without rescanning
backup storage.
- Add a dedicated `/hosts/` page with host cards and enabled/disabled filtering.
- Link the dashboard Hosts metric and top navigation to the new page.
- Add host enable/disable plus schedule and scheduled-retention pause/resume actions.
## Tests
- `.venv/bin/python manage.py test src.pobsync_backend.tests.test_views.ViewTests.test_base_navigation_groups_primary_and_system_links src.pobsync_backend.tests.test_views.ViewTests.test_dashboard_renders_hosts_and_latest_runs src.pobsync_backend.tests.test_views.ViewTests.test_dashboard_hosts_live_returns_hosts_partial src.pobsync_backend.tests.test_views.ViewTests.test_hosts_list_renders_host_cards_and_controls src.pobsync_backend.tests.test_views.ViewTests.test_hosts_list_filters_by_enabled_state src.pobsync_backend.tests.test_views.ViewTests.test_update_host_state_toggles_host_schedule_and_retention --verbosity 2`
- `.venv/bin/python manage.py check`
- `.venv/bin/python manage.py test src.pobsync_backend --verbosity 2`
Closes#48Closes#49
Use a shared Run Progress presentation for dry-runs and normal backup
runs so live run feedback is consistent across run types.
Keep mode-specific metrics while aligning status, mode, log, and warning
layout.
Refs #52
Only pass the process_started hook when live run state tracking is active,
so existing rsync call sites and tests without that hook remain compatible.
Refs #54
Record rsync process pid and execution phase while normal backup runs are
active so the worker can reconcile stale running rows when rsync has
already disappeared.
Keep finalizing runs out of the missing-process path to avoid marking
slow post-rsync stats collection as a failed transfer.
Closes#54
Record live rsync log paths for normal backup runs so the worker can
recover stale running state after terminal rsync errors.
Treat rsync vanished-file exit code 24 as a warning and keep the
completed snapshot instead of failing the run into incomplete state.
Closes#54
Pass remote rsync and source-root preflight checks as a single quoted
shell command to SSH so the remote shell evaluates command -v and test
expressions reliably.
Refs #45
Bump the package and runtime version to 1.1.0, add release notes for
the UI-focused control panel update, and refresh version assertions for
the CLI entrypoint.
Refs 1.1
Split dashboard priority and host status sections into server-rendered
partials and wire them into the shared refresh hook so operational state
updates without a full page reload.
Refs #36
Add a server-rendered run detail partial and a small vanilla JavaScript
refresh hook so active backup runs update status, controls, timing, and
rsync log output without a full page reload.
Document the Django-template-first refresh pattern for future control
panel work.
Refs #36
Mark the active primary or system navigation link with aria-current and a
subtle visual state so staff users can see where they are in the control
panel without making Admin a primary app route.
Refs #37
Move operator routes into a primary navigation group and demote admin,
self-check, changelog, and status API links into a secondary system group
so the header reflects the control panel workflow more clearly.
Refs #37
Let dashboard-specific panels size naturally instead of inheriting generic
panel overflow behavior, and tighten activity and host card sizing so long
content wraps without creating internal scrollbars.
Refs #38
Give dashboard summary, trends, and host sections dedicated layout hooks
and tighten their responsive behavior so metrics and host cards remain
readable on narrower screens.
Refs #38
Rework the dashboard priority grid to avoid cramped four-column layouts,
prevent stretched empty panels, and make long host and snapshot text wrap
safely across dashboard cards.
Refs #38
Move run cancellation and review actions out of the page header into
dedicated action panels with clearer operator copy and consistent form
button styling.
Refs #25
Make retention apply, incomplete cleanup, and SSH key deletion visibly
destructive with warning copy, danger styling, and consistent cancel actions
while keeping the existing confirmation requirements intact.
Refs #25
Add shared form action styling and consistent Cancel links across config,
schedule, and SSH key forms so create/edit flows behave predictably.
Refs #25
Replace the raw host check table with diagnostic cards and group effective
runtime config into operator-focused sections for backup target, connection,
and selection/retention details.
Refs #26
Replace the database-style Latest Runs and Snapshots tables on the host
detail page with scannable record cards and host-filtered View all links.
Refs #26
Move host-level actions out of the page header and into the panels where
operators expect them: configuration, connection preflight, and snapshot
storage. This keeps the host control page calmer while preserving the same
actions.
Refs #26
Add a first-screen host control workspace with status, backup actions,
schedule state, and current activity so the host detail page behaves as the
primary operator page instead of starting with raw configuration blocks.
Refs #26
Move backup root usage, runway, daily new data, and available capacity into
the top dashboard priority area so storage risk is visible before deeper trend
details.
Refs #27
Move required actions, upcoming scheduled work, and recent run activity to the
top of the dashboard so the first screen answers what needs attention next.
Keep summary metrics, trends, and host cards as supporting drill-down content.
Refs #27
Add inline Mark reviewed actions for failed and warning runs on the run list,
preserving active filters after review so Operational Status drill-downs can
be cleared without opening every run detail page.
Refs #22
Add a staff-only schedules page with filters for host, enabled state, and
prune state, including next run and last scheduler state.
Wire the dashboard Schedules metric to the new overview so all primary
dashboard count cards have useful destinations.
Refs #23
Turn the dashboard operational status rows into direct links to filtered run
lists, so failed, warning, running, and queued states can be investigated from
the first screen.
Also move the hosts anchor back to the actual Hosts section.
Refs #23
Add staff-only list pages for backup runs and snapshots with practical
filters, then wire the dashboard summary cards and latest-runs panel to
those overviews.
This gives the dashboard real drill-down paths for run and snapshot counts
instead of leaving the data only partially visible on the first screen.
Refs #23
Apply the shared page-header pattern to configuration, access,
operations, retention, log, and changelog pages so the control panel
uses one consistent title, context, and action structure.
Add representative view assertions for the new page context on utility
pages.
Refs #28
Introduce a shared page-header pattern with kicker, title, subtitle, and
actions, then apply it to the dashboard, host detail, run detail, snapshot
detail, and retention plan pages.
Scope the global app header styles to avoid leaking sticky navigation styles
onto page-level headers, and add view assertions for the new page context.
Refs #28
Refresh the shared base styling so the Django control panel has a calmer,
more polished production-tool feel across all pages. Update typography,
navigation, panels, metrics, host cards, tables, forms, buttons, messages,
focus states, and responsive behavior through reusable CSS variables and
component styles.
Refs #28
Replace refactor-era wording such as Source, Source root, SQL records,
database, runtime, and Django generation labels with operator-facing copy
around backup source, tracking records, changelog files, active config, and
pobsync-managed SSH keys.
Add view assertions so the old source/SQL labels do not quietly return.
Refs #24
Record snapshot purge history whenever retention or incomplete cleanup removes
snapshot directories and SQL records. Store the purge reason, original kind,
path, action source, and triggering operator so manual, scheduled, CLI, and
incomplete cleanup actions remain auditable after the original snapshot record
is deleted.
Add a staff-only Purged Snapshots page with host/action filters and register
the audit model in Django admin.
Refs #16
Refs #8
Make SSH credential management more explicit by adding an edit action in the
key overview and requiring name confirmation before deletion. Keep deletion
blocked while a key is still selected by hosts or global config, and cover
rename, delete confirmation, and in-use protection in view tests.
Refs #20
Refs #8
Add reviewed state for failed/warning runs and incomplete snapshot records,
then use it to clear dashboard and host “need review” tasks after an operator
has acknowledged them.
Expose Mark reviewed actions on run detail and host retention warnings, keep
reviewed records available for audit/debug, and exclude reviewed problem runs
from operational counts and latest issue summaries.
Refs #19
Refs #8
Add a dedicated cleanup path for incomplete snapshots instead of letting
retention prune them implicitly. The retention plan now exposes a guarded
form that requires host and delete-count confirmation before removing
.incomplete snapshot directories and their SQL records.
Keep scheduled/manual retention behavior unchanged, add path safety checks,
and cover cleanup success, confirmation failures, max-delete limits, and
unexpected paths in tests.
Refs #10
Record worker pid, host, claim time, and heartbeat metadata on running
backup jobs so operators can see which worker owns a run.
Refresh the heartbeat while rsync is active and reconcile stale running
runs when the worker heartbeat stops. Add a worker option to tune or
disable stale-run reconciliation.
Refs #11
Expose the repository CHANGELOG.md through a staff-only Django view and
link it from the main navigation.
Render a small safe subset of Markdown without adding a runtime dependency,
copy the changelog into the Docker image, and cover the page with view tests.