feat: notification enhancement

This commit is contained in:
Krispire Admin
2026-06-11 00:31:35 +05:30
parent cb62adf2de
commit 187bcd1442
11 changed files with 441 additions and 79 deletions
@@ -0,0 +1,3 @@
-- The legacy users columns were dual-written the whole time, so dropping the
-- table loses no opt-out state that the old code paths read.
DROP TABLE IF EXISTS notification_prefs;
+41
View File
@@ -0,0 +1,41 @@
-- Per-event × per-channel notification preferences.
--
-- One row per (user, kind, channel) the user has turned OFF. Absence of a row
-- means enabled — the table stores opt-outs only, so new kinds/channels are
-- enabled for everyone with no backfill, and existing users keep receiving
-- everything they receive today.
--
-- `kind` is the notifications.kind machine string (follow_request, post_like,
-- chant_reminder, …); the Settings UI groups kinds into coarser categories
-- but storage stays kind-level so backfilled opt-outs map exactly.
CREATE TABLE IF NOT EXISTS notification_prefs (
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
kind TEXT NOT NULL,
channel TEXT NOT NULL CHECK (channel IN ('in_app', 'email', 'push')),
enabled BOOLEAN NOT NULL DEFAULT FALSE,
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (user_id, kind, channel)
);
-- Backfill the existing like-email opt-out at exactly its old granularity:
-- post_like × email only (NOT the whole post-interactions category, so these
-- users don't accidentally lose anything else).
INSERT INTO notification_prefs (user_id, kind, channel, enabled)
SELECT id, 'post_like', 'email', FALSE
FROM users WHERE like_emails_enabled = FALSE
ON CONFLICT DO NOTHING;
-- Backfill the reminder opt-out: the old toggle silenced all channels at
-- once, so it maps to every reminder kind × every channel.
INSERT INTO notification_prefs (user_id, kind, channel, enabled)
SELECT u.id, k.kind, c.channel, FALSE
FROM users u
CROSS JOIN (VALUES ('chant_reminder'), ('quote_reminder'), ('chant_incomplete_reminder')) AS k(kind)
CROSS JOIN (VALUES ('in_app'), ('email'), ('push')) AS c(channel)
WHERE u.sadhna_reminders_enabled = FALSE
ON CONFLICT DO NOTHING;
-- users.like_emails_enabled and users.sadhna_reminders_enabled stay for now:
-- the prefs endpoints dual-write them so an old frontend (or a rollback)
-- keeps working. They get dropped in a later migration once the new
-- endpoints are fully rolled out.