feat(rust): Admin → Rust servers page and the next wipe on the web (phase 16)
All checks were successful
PR Checks / client-build (pull_request) Successful in 26s
PR Checks / frozen-manifest (pull_request) Successful in 49s
PR Checks / server-tests (pull_request) Successful in 7m49s

The module had no page for its own server rows: they were written only
through PUT /admin/rust/servers/:id, and the README described an
"Admin → Rust" server form that did not exist. D133 (org lead) builds it:
add, edit, test and delete a server, with the D130 wipe schedule in the
same form. The token stays write-only and an edit sends the stored
protocol back rather than re-stamping the row.

The next wipe shows on the server list and in the server page's header,
in the reader's own clock, marked "rescheduled" for a one-off date.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-09-25 13:26:10 -05:00
parent 0670341198
commit cddba957d3
8 changed files with 450 additions and 11 deletions

View File

@@ -11,7 +11,7 @@
import test from 'node:test'
import assert from 'node:assert/strict'
import { ago, clock, count, day, duration, prefab, shortId } from '../src/lib/format.js'
import { ago, clock, count, day, duration, nextWipe, prefab, shortId } from '../src/lib/format.js'
const NOW = Date.parse('2026-09-16T12:00:00Z')
@@ -94,3 +94,16 @@ test("a feed row from another day carries its date, not just a time", () => {
const earlyToday = Date.parse('2026-09-16T00:20:00')
assert.ok(clock(lateLastNight, earlyToday).length > time(lateLastNight).length)
})
test('the next wipe: the reader’s own clock, how far away, and whether it moved', () => {
const now = Date.parse('2026-09-25T12:00:00Z')
const forced = nextWipe({ at: '2026-10-01T18:00:00.000Z', source: 'forced' }, now)
assert.match(forced, /\(in 6 days\)$/)
assert.ok(!forced.includes('rescheduled'))
assert.match(nextWipe({ at: '2026-09-27T17:00:00.000Z', source: 'once' }, now), /\(in 2 days\) — rescheduled$/)
// No schedule is no line, not "unknown": the page leaves the part out.
assert.equal(nextWipe(null, now), null)
assert.equal(nextWipe({ at: 'soon', source: 'rule' }, now), null)
})