Skip to content

Backups: one "Turn on backups" path with health alarms; short breaks are always paid - #652

Merged
techmore merged 1 commit into
mainfrom
feature/simple-backups
Nov 11, 2026
Merged

techmore merged 1 commit into
mainfrom
feature/simple-backups

Conversation

@techmore

Copy link
Copy Markdown
Owner

Why

Production's scheduled encrypted backups have been refused since late October ("no active backup key") and nothing told the owner. Separately, a punched "meal" of a few minutes came off paid hours, which federal law does not allow.

Backups

  • BackupHealth: one plain answer (off / starting / working / needs attention) built from the active backup key and the per-layer reports the backup scripts already write. Nothing new is stored and no second backup system is added. After a key is turned on, each layer gets one interval of its own schedule to make its first encrypted backup before an older "refused: no key" report counts as a failure.
  • Settings → Backups: status first (last good backup, weekly check, key fingerprint), then a two-step Turn on backups path. The recovery kit PDF downloads, the page moves on to the check code by itself (it used to sit unchanged until a manual refresh), and after the code it refreshes when the first backup lands (the rolling snapshot runs every 5 minutes). Plain language on what the kit is, where to keep it and what happens if it is lost.
  • Alarms: while backups are off, failed, or quiet past their schedule, super admins see a red alert on the bell on every page, a banner on the dashboard and a red status-bar entry (that entry used to track the never-connected Drive backup, so it was permanently red and ignored). BackupHealthAlertJob (hourly) leaves one notification a day until it is fixed.
  • Unchanged: age encryption, the one-time kit, the check code, the fresh sign-in rule, the scripts and the weekly verify. The private key is still never stored, logged or shown again (the existing test that scans every table and the log still passes).

Time & pay

A punched break of 20 minutes or less is paid time even when punched as a meal or where the store marks that kind unpaid (FLSA, 29 CFR 785.18-785.19). One predicate, ClockBreak#unpaid?, feeds ClockShift#unpaid_break_seconds and paid_hours_between, so the clock, the Pay page, the timesheet import and the payroll export agree. A break is judged by its whole length when a day boundary clips it. Checked that nothing deducts a break automatically: only punched breaks come off (scheduled-shift break minutes are a planning figure, and Square timecards keep Square's own paid flag). Approved sheets are not rewritten.

Tests

bin/rails test (4,059 runs, 0 failures) and bin/rubocop clean locally. New: backup_health_test.rb, backup_health_alerts_test.rb, three break tests in foundation_test.rb, and a timesheet import → pay run test.

No migration.

🤖 Generated with Claude Code

…; short breaks are always paid

Backups (production's encrypted backups were refused for 10+ days with no key and nobody was told):
- BackupHealth: one answer (off / starting / working / needs attention) from the active key and the
  layer reports the scripts already write. After a key is turned on each layer gets one interval of
  its schedule before an older "refused: no key" report counts as a failure.
- Settings → Backups: status first (last good backup, weekly check, key), then a two-step "Turn on
  backups" path: the kit downloads, the page moves to the check code by itself, and after the code it
  refreshes when the first backup lands. Plain words on what the kit is and what losing it means.
  Encryption, the one-time kit, the check code and the reauth rule are unchanged.
- While backups are off or failing, super admins see a red alert on the bell, a dashboard banner
  and a red status bar entry (which used to show the unused Drive backup); BackupHealthAlertJob
  leaves one notification a day.

Time & pay: a punched break of 20 minutes or less is paid time even as a "meal" or where the store
marks the kind unpaid (FLSA, 29 CFR 785.18-785.19). One predicate (ClockBreak#unpaid?) feeds the
clock, Pay page, timesheet import and so the payroll export. No automatic break deductions exist.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@techmore
techmore merged commit 8fefc13 into main Nov 11, 2026
8 checks passed
@techmore
techmore deleted the feature/simple-backups branch November 11, 2026 18:11
techmore added a commit that referenced this pull request Nov 11, 2026
* Backups: deploy receipt for #652

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

* Deploy receipt: name the pre-existing warnings

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.2 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant