mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 14:32:03 +00:00
feat(admin): say per account how fresh the off-host copy is
The nightly off-host job reports counts — uploaded, failed, total — and a count cannot name the account it is failing for. A cohort where one object has been refused every night for a month reads as "99 uploaded, 1 failed" each time, which looks like weather rather than like an account with no disaster-recovery copy at all. The worker now writes a ledger row when an object lands (account, instant, size), and Admin → Backups gains a second card that rates every account against the nightly schedule: fresh inside one run, due when one run produced nothing, stale when two did not, never when no object has ever landed. On a host without BACKUP_S3_* the card says off-host backup is not configured and stops there. The verdicts are computed from the ledger, never from a bucket listing: the worker's grant is deliberately PutObject + GetObject, and an admin page must not put the operator's credentials on its render path to state a number the database already holds.
This commit is contained in:
1 parent
348d9e0739
commit
1c10bbbde8
23 files changed
+797
-10
No files matched your search
@@ -215,6 +215,26 @@ A run where SOME account got a copy still succeeds, with the rest counted in
|
||||
`offhost_backup_failed`. Failing the whole queue over one account's object
|
||||
would re-upload everybody's on every retry.
|
||||
|
||||
### Which account has no copy
|
||||
|
||||
The counts above say how many accounts were uploaded, never which. An account
|
||||
whose object has failed every night for a month reads as `99 uploaded, 1
|
||||
failed` each time, which looks like weather.
|
||||
|
||||
**Admin console → Backups → Off-host copies** answers it per account: when this
|
||||
host last put that account's encrypted copy in the bucket, how big it was, and
|
||||
how that compares with the nightly schedule. **Fresh** is inside one run,
|
||||
**due** means one run produced nothing for that account, **stale** means two
|
||||
did not, and **never** means no object has ever landed. On a host without
|
||||
`BACKUP_S3_*` the card says off-host backup is not configured and stops there.
|
||||
|
||||
The verdicts come from a ledger the worker writes when the object lands
|
||||
(`offhost_backup_state`), not from a listing of the bucket. Keep the worker's
|
||||
grant as documented — PutObject, GetObject, AbortMultipartUpload — and the card
|
||||
still tells the truth. A row that goes stale while the run reports success is
|
||||
that account's object being refused, and the reason is in the run's
|
||||
`offhost_backup_failures` meta.
|
||||
|
||||
## The weekly in-database backup (`data-backup`)
|
||||
|
||||
Separate from the off-host job above, and easy to confuse with it. A second
|
||||
|
||||
Reference in new issue
Block a user