Codex + CodeRabbit review fixes, all verified against current behavior: - Web Push: single-writer VAPID provisioning via a new conditional SetIfAbsent settings write (no split-brain identity across nodes), and read/decode failures now surface instead of silently rotating the keypair; the eager-provisioning goroutine joins the shutdown WaitGroup - Web Push: endpoint reassignment purges the previous owner's pending attempts inside the upsert transaction, with an ownership re-check at send time - Webhooks: per-profile cap enforced atomically (advisory-locked count+insert), typed pgconn unique-violation mapping, create-time type/URL mismatch rejection, send-time HTTPS re-check, and Retry-After HTTP-date support (shared, clamped parser also used by web push) - Delivery workers: transient delivery-row lookup errors leave the claim to lease expiry instead of permanently failing the attempt - Interest: history-only imports now feed the index (userstore history hooks + completed-history folding in recompute/rebuild), rebuild also recomputes existing interest rows so removed sources get cleaned up, and failed flush mutations requeue (bounded) instead of dropping - Retention: read notifications age from read_at, not created_at - Startup: scan queue workers start only after the availability detector is wired, so resumed scans cannot skip availability recording - mail: settings-store read failures propagate instead of reading as "not configured" - DB: new migration adds episode ordinal/key CHECK constraints - Web: service worker restricts notification clicks to same-origin URLs, preferences popover gets an error+retry state, and the realtime profile-rebind backoff grows to 5 minutes to keep shared channels stable through notifications-only outages Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
34 lines
1.3 KiB
SQL
34 lines
1.3 KiB
SQL
-- +goose Up
|
|
-- +goose StatementBegin
|
|
-- Enforce the episode-key invariants (episode_key.go: EpisodeKey /
|
|
-- ValidEpisodeOrdinals) at the database layer too, so direct SQL or future
|
|
-- backfill paths cannot insert rows that break the collision-free ordering
|
|
-- contract the fanout and suppression logic depend on. Bounds mirror the Go
|
|
-- constants: season <= 2146 keeps season * 1,000,000 + episode inside int4.
|
|
ALTER TABLE public.episode_availability
|
|
ADD CONSTRAINT episode_availability_ordinals_check CHECK (
|
|
season_number >= 0
|
|
AND season_number <= 2146
|
|
AND episode_number >= 0
|
|
AND episode_number < 1000000
|
|
AND episode_key = season_number * 1000000 + episode_number
|
|
);
|
|
|
|
ALTER TABLE public.release_events
|
|
ADD CONSTRAINT release_events_ordinals_check CHECK (
|
|
season_number >= 0
|
|
AND season_number <= 2146
|
|
AND episode_number >= 0
|
|
AND episode_number < 1000000
|
|
AND episode_key = season_number * 1000000 + episode_number
|
|
);
|
|
-- +goose StatementEnd
|
|
|
|
-- +goose Down
|
|
-- +goose StatementBegin
|
|
ALTER TABLE public.episode_availability
|
|
DROP CONSTRAINT IF EXISTS episode_availability_ordinals_check;
|
|
ALTER TABLE public.release_events
|
|
DROP CONSTRAINT IF EXISTS release_events_ordinals_check;
|
|
-- +goose StatementEnd
|