* fix(sandbox): loop small cleanup batches (8s cap is real), clear last FK blockers
Draining the prod backlog exposed two final issues:
- The function-level statement_timeout shipped in 20260807150000 does NOT
lift authenticator's 8s cap: the timer arms when the top-level statement
starts (verified empirically on prod: SET LOCAL 2s canceled the RPC
despite its 290s proconfig; matches the 2026-08-04 SIE-import finding).
The route now loops batches of 10 (~220ms/user with the account_id
index, so ~2.2s per batch), each rpc() call being its own statement with
its own 8s window. The loop stops when a batch makes no progress or the
240s time budget nears; capacity is 250 users/night.
- processing_history.company_id and invoice_deliveries.company_id are
plain NO ACTION FKs, so sandboxes whose visitor produced AI telemetry or
sent a demo invoice could never be deleted (7 of ~510 backlog users). A
data-driven sweep of every NO ACTION FK into companies confirms these
two plus the already-handled audit_log are the only such tables with
sandbox rows. cleanup_sandbox_user (migration 20260807160000) deletes
them explicitly; the pg fixture now seeds a processing_history row.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(test): use valid processing_history aggregate_type/event_type in sandbox fixture
aggregate_type is CHECK-constrained and event_type is an FK to the seeded processing_event_types lookup; the guessed values failed all five fixture-dependent pg tests in CI. Validated against staging: Document/DocumentIngested inserts and tears down cleanly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(sandbox): bypass invoice-delivery delete guard in teardown, cover both blocker tables in pg fixture
CodeRabbit's fixture ask exposed a real gap: enforce_invoice_delivery_immutability silently swallows DELETEs (RETURN NULL plus a SECURITY_EVENT audit row) for terminal rows, so the explicit invoice_deliveries delete was a no-op and the companies FK still blocked teardown for sandboxes that sent a demo invoice. The trigger's DELETE branch now honors the gnubok.sandbox_cleanup flag with the same per-row sandbox re-verification as every other guard; base definition 20260803224000, all other branches untouched. The pg fixture seeds an invoice plus a marked_sent manual delivery, and a new test pins the zero-settings refusal path the Swedish review asked about. Validated on staging end-to-end.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>