[refactor](alarm): end alerts by disarm or expiry, not a ring timer
An alert now rings from trigger until the owner disarms it; a subscriber silences only its own device. The owner instead sets a persistence cap (default 24h, hard cap 14 days) and the sweeper destroys expired alerts. Disarm ends an armed alert too, and every ending (delivered, expired, disarmed, deleted) converges on the one destruction path so their event-log reasons cannot drift.
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
\c dcntrlized;
|
||||
|
||||
-- 006_alert_expiry.sql — a hard persistence cap chosen by the owner.
|
||||
--
|
||||
-- Contract decision (2026-10-18, user ruling): the creator sets a maximum
|
||||
-- persistence time, at most 14 days, after which devices that never came back
|
||||
-- are ignored and the alert "along with everything about it" is destroyed. This
|
||||
-- is what stops a phone that never returns from pinning an alert (and its
|
||||
-- delivery debt) forever once auto-stop is gone.
|
||||
--
|
||||
-- The application computes the absolute timestamp from the requested duration,
|
||||
-- rejects anything above the cap (API.md: ERR_VALIDATION, not a silent clamp) and
|
||||
-- inserts it explicitly. The DEFAULT is a safety net only: 24 hours, the
|
||||
-- documented default duration, so a row inserted by an older binary or by hand
|
||||
-- still expires instead of living forever.
|
||||
--
|
||||
-- Existing rows are backfilled to `created + 14 days` (the maximum): they were
|
||||
-- created under a contract with no cap, so they get the most generous value the
|
||||
-- new contract allows, not an instant expiry.
|
||||
--
|
||||
-- Read paths also filter `expires_at > now()` (db.GetAlert, transition, …) so an
|
||||
-- alert is invisible the moment it expires, even before the sweeper reaches it.
|
||||
--
|
||||
-- Idempotent (same guard pattern as 002–005): a re-apply of the whole sequence
|
||||
-- is a clean no-op.
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'alarm') THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
ALTER TABLE alarm.alerts ADD COLUMN IF NOT EXISTS expires_at TIMESTAMPTZ;
|
||||
|
||||
UPDATE alarm.alerts
|
||||
SET expires_at = created + interval '14 days'
|
||||
WHERE expires_at IS NULL;
|
||||
|
||||
ALTER TABLE alarm.alerts ALTER COLUMN expires_at SET NOT NULL;
|
||||
ALTER TABLE alarm.alerts ALTER COLUMN expires_at SET DEFAULT (now() + interval '24 hours');
|
||||
|
||||
CREATE INDEX IF NOT EXISTS alerts_expires_at_idx ON alarm.alerts (expires_at);
|
||||
END
|
||||
$$;
|
||||
Reference in New Issue
Block a user