Add an admin page, and move the behaviour settings into the database #15
Reference in New Issue
Block a user
Delete Branch "admin-settings"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #5. Fourth of the six sub-issues in #1.
Three tunables were environment variables, so changing how long an incident waits before being paged again meant editing a chart, merging it, and waiting for a reconcile.
The split is by who owns the value
Stays in the environment — where the server is plugged in: listen address, DSN, ntfy URL and token, public URL. Needed before the database is open, and two are credentials. The settings endpoint reports that ntfy is configured and that a token is set, never what either is.
Moves to the database — how it behaves: notify repeat, stale window, archive window. The environment variable becomes the seed rather than the setting: written once on first start, never overwritten, so a redeploy can't put a chart default back over an administrator's edit — the rule the per-team dead-man switches already follow. The loops read the current value per tick, so a change at 02:00 is obeyed at 02:00.
Key/value rather than a column per knob, because #6 and #7 will both add settings. Unknown keys are refused rather than stored — a typo writing
notify_repeat_secondwould otherwise sit in the table looking like configuration and doing nothing — and each value has bounds loose enough to catch a slipped decimal point without having an opinion about anybody's rota.Disabling an account is not deleting one
Deleting a user nulls
acknowledged_byandassigned_to, quietly rewriting who did what during an incident months later. A disabled user can't authenticate by either credential, loses their sessions immediately, and stays the name on every acknowledgement they made.The check is part of the lookup in
serveAs, not a test afterwards, so there's no path where the row loads and the flag is then forgotten.The page
A fourth tab, shown only to an administrator — as a courtesy, not a gate: every endpoint under it is refused with 403 regardless, so typing
/admingets an explanation rather than a blank screen. Teams with size and open-incident counts, users with their flags, settings with their bounds, plus the environment half read-only so somebody hunting the ntfy URL learns where it lives.Delete is disabled rather than offered-and-refused for a team with open incidents, and neither admin action appears on your own account, since the server refuses both.
Verified
make fmt lint test helm-lintgreen with-raceagainst Postgres 17, plus nine new tests — including the one that matters most: a setting changed through the API takes effect on the very next sweep, with an alert that survives one pass under the seeded six-hour window and expires on the next after the window is shortened to an hour. Also checked that no credential appears in the settings response, and that disabling an account kills its key while the incident it acknowledged still names it.Driven against a live server too: seeded from that server's own env (
TERDUT_STALE_AFTER=26h→ 93600s), changed through the API, read back.https://claude.ai/code/session_01RHPj4ggeFdEjKKfm4SHbD7