mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
refactor(admin): read the off-host card from evidence, sort the worst row first
Four smaller things around the same card. The configured flag came from the environment of whichever process serves the request. A hand-rolled split that gives BACKUP_S3_* to the worker and not to the web process would have shown an operator "nothing leaves this host" over a ledger full of fresh rows. The ledger is queried either way now, and a row in it outranks an environment read: a row is proof an upload happened. Rows sorted by username put the one account that needs attention wherever the alphabet leaves it, which on a hundred-account cohort is the crowd problem the card exists to end, moved from a count into a list. Worst verdict first, alphabetical within a verdict, decided server-side so the tests and the accessibility fixture see the order the operator does. The card's docblock claimed the worker holds PutObject and GetObject. The runbook is right and the multipart path needs AbortMultipartUpload too, so the prose no longer documents a grant that would break the uploader. And the byte formatter moved to lib. The off-host card was importing it out of a thousand-line client component, which costs nothing while both cards render on one route and becomes a cost the moment either moves.
This commit is contained in:
1 parent
9d18b8fd25
commit
a7faae8ded
6 files changed
+120
-54
No files matched your search
@@ -47,6 +47,7 @@ import { SettingsCard } from "@/components/settings/settings-card";
|
||||
import { SettingsCardHeader } from "@/components/settings/_card-header";
|
||||
import { ListRow } from "@/components/ui/list-row";
|
||||
import { useFormatters, useTranslations } from "@/lib/i18n/context";
|
||||
import { formatBytes } from "@/lib/format/bytes";
|
||||
import { queryKeys } from "@/lib/query-keys";
|
||||
import { randomId } from "@/lib/random-id";
|
||||
import type { BackupRow, BackupsList } from "@/types/backups";
|
||||
@@ -322,21 +323,6 @@ function RestoreRowDialog({
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exported for the off-host card, which reads the same sizes out of the same
|
||||
* response and must not spell "1.25 MB" a second way two cards apart.
|
||||
*/
|
||||
export function formatBytes(
|
||||
bytes: number,
|
||||
fmt: ReturnType<typeof useFormatters>,
|
||||
) {
|
||||
if (bytes < 1024) return `${bytes} B`;
|
||||
if (bytes < 1024 * 1024) {
|
||||
return `${fmt.integer(Math.round(bytes / 1024))} KB`;
|
||||
}
|
||||
return `${fmt.number(bytes / 1024 / 1024, 2)} MB`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the `DataBackup.type` enum (`WEEKLY_AUTO` / `MANUAL`) as a
|
||||
* human label. Unknown values fall through to the raw enum so a future
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
* been refusing the worker's signature since March.
|
||||
*
|
||||
* Every verdict is computed server-side from the ledger the worker writes. The
|
||||
* page never lists the bucket: the worker's grant is deliberately PutObject +
|
||||
* GetObject, and putting a credentialed listing call on the render path of an
|
||||
* admin page would be a poor trade for a number the database already holds.
|
||||
* page never lists the bucket: the worker's grant is deliberately PutObject,
|
||||
* GetObject and AbortMultipartUpload — the three the runbook documents, the
|
||||
* abort being what the multipart path needs — and putting a credentialed
|
||||
* listing call on the render path of an admin page would be a poor trade for
|
||||
* a number the database already holds.
|
||||
*/
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
@@ -31,7 +33,7 @@ import { useFormatters, useTranslations } from "@/lib/i18n/context";
|
||||
import { queryKeys } from "@/lib/query-keys";
|
||||
import type { OffhostBackupFreshness } from "@/lib/jobs/offhost-backup-freshness";
|
||||
import type { BackupsList, OffhostAccountRow } from "@/types/backups";
|
||||
import { formatBytes } from "./backups-section";
|
||||
import { formatBytes } from "@/lib/format/bytes";
|
||||
|
||||
/**
|
||||
* Status wash per verdict. `never` and `unknown` are deliberately neutral
|
||||
|
||||
Reference in new issue
Block a user