feat(hub): v0.69.0 — customer DELETE is the guided full-teardown cascade (R-25b)
POST /configs/{id}/delete now runs hosts -> RESET -> purge behind three
acknowledgements, a typed customer-id, a stale-preview check and the
ONLINE-host refusal (every gate before any write, so a refusal has zero
side effects). The shallow handleConfigDelete is gone.
Two invariants are asserted, not just commented: ruling 3 is preserved by
construction (leg 2 never sees a host row) and retained escrow custody is
purged exactly once, in leg 3 (leg 2 runs with purgeEscrow=false).
handleCustomerReset's committed half was extracted as commitCustomerReset;
the standalone RESET path is byte-identical to v0.68.1 and its suite is
untouched. Five red-proofs run.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J55BQE1gE2V4ffud5jweGS
This commit is contained in:
@@ -263,8 +263,11 @@ func TestCustomerActions_RedirectAnchors(t *testing.T) {
|
||||
{"regen-password lands on Setup (its card lives there)", func(t *testing.T, s *Server, rr *httptest.ResponseRecorder) {
|
||||
s.handleConfigRegenPassword(rr, postForm("/configs/c1/regen-password", ""), "c1")
|
||||
}, false, "/customers/c1?flash=password_regenerated#tab=setup"},
|
||||
// v0.69.0 (R-25b): the shallow delete became the guided cascade — same route, same
|
||||
// anchor-free landing, but the three acks + typed id + host-count are now required.
|
||||
{"delete stays anchor-free (leaves the page)", func(t *testing.T, s *Server, rr *httptest.ResponseRecorder) {
|
||||
s.handleConfigDelete(rr, postForm("/configs/c1/delete", ""), "c1")
|
||||
s.handleCustomerDelete(rr, postForm("/configs/c1/delete",
|
||||
"ack_hosts=1&ack_reset=1&ack_purge=1&confirm_id=c1&expect_hosts=0"), "c1")
|
||||
}, false, "/configs?flash=deleted"},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user