Skip to content

Commit 95113e8

Browse files
committed
feat(notifications): add full notification system (DB migration, hooks, UI, generators)
- Add DB migration script to create notifications and notification_preferences tables with RLS, indexes, triggers and cleanup function - Implement React Query hooks: fetch notifications, unread count, mark as read, mark all read, delete, fetch/update preferences - Add notification generation utilities: createNotification, checkBudgetAlerts, checkSavingsGoalMilestones, generateSpendingInsights, generateDailyTip - Add UI components: NotificationPanel, NotificationItem, ScrollArea (Radix wrapper) and integrate panel into TopBar - Add developer docs: implementation guide and status summary - Install @radix-ui/react-scroll-area and bump package version to 1.0.0
1 parent 675d24d commit 95113e8

11 files changed

Lines changed: 1769 additions & 13 deletions
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
-- Add notifications table
2+
CREATE TABLE IF NOT EXISTS notifications (
3+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4 (),
4+
user_id UUID NOT NULL REFERENCES auth.users (id) ON DELETE CASCADE,
5+
type VARCHAR(50) NOT NULL,
6+
title VARCHAR(255) NOT NULL,
7+
message TEXT NOT NULL,
8+
icon VARCHAR(50),
9+
priority VARCHAR(20) DEFAULT 'normal' CHECK (
10+
priority IN (
11+
'low',
12+
'normal',
13+
'high',
14+
'urgent'
15+
)
16+
),
17+
is_read BOOLEAN DEFAULT false,
18+
action_url VARCHAR(255),
19+
metadata JSONB,
20+
created_at TIMESTAMP
21+
WITH
22+
TIME ZONE DEFAULT NOW(),
23+
read_at TIMESTAMP
24+
WITH
25+
TIME ZONE,
26+
expires_at TIMESTAMP
27+
WITH
28+
TIME ZONE
29+
);
30+
31+
-- Add indexes for better performance
32+
CREATE INDEX IF NOT EXISTS idx_notifications_user_read ON notifications (user_id, is_read);
33+
34+
CREATE INDEX IF NOT EXISTS idx_notifications_created ON notifications (created_at DESC);
35+
36+
CREATE INDEX IF NOT EXISTS idx_notifications_type ON notifications(type);
37+
38+
-- Row Level Security for notifications
39+
ALTER TABLE notifications ENABLE ROW LEVEL SECURITY;
40+
41+
DROP POLICY IF EXISTS "Users can view own notifications" ON notifications;
42+
43+
CREATE POLICY "Users can view own notifications" ON notifications FOR
44+
SELECT USING (auth.uid () = user_id);
45+
46+
DROP POLICY IF EXISTS "Users can insert own notifications" ON notifications;
47+
48+
CREATE POLICY "Users can insert own notifications" ON notifications FOR
49+
INSERT
50+
WITH
51+
CHECK (auth.uid () = user_id);
52+
53+
DROP POLICY IF EXISTS "Users can update own notifications" ON notifications;
54+
55+
CREATE POLICY "Users can update own notifications" ON notifications FOR
56+
UPDATE USING (auth.uid () = user_id);
57+
58+
DROP POLICY IF EXISTS "Users can delete own notifications" ON notifications;
59+
60+
CREATE POLICY "Users can delete own notifications" ON notifications FOR DELETE USING (auth.uid () = user_id);
61+
62+
-- Add notification_preferences table
63+
CREATE TABLE IF NOT EXISTS notification_preferences (
64+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4 (),
65+
user_id UUID NOT NULL UNIQUE REFERENCES auth.users (id) ON DELETE CASCADE,
66+
budget_alerts BOOLEAN DEFAULT true,
67+
goal_milestones BOOLEAN DEFAULT true,
68+
spending_insights BOOLEAN DEFAULT true,
69+
daily_tips BOOLEAN DEFAULT false,
70+
weekly_summary BOOLEAN DEFAULT true,
71+
created_at TIMESTAMP
72+
WITH
73+
TIME ZONE DEFAULT NOW(),
74+
updated_at TIMESTAMP
75+
WITH
76+
TIME ZONE DEFAULT NOW()
77+
);
78+
79+
-- Row Level Security for notification_preferences
80+
ALTER TABLE notification_preferences ENABLE ROW LEVEL SECURITY;
81+
82+
DROP POLICY IF EXISTS "Users can view own preferences" ON notification_preferences;
83+
84+
CREATE POLICY "Users can view own preferences" ON notification_preferences FOR
85+
SELECT USING (auth.uid () = user_id);
86+
87+
DROP POLICY IF EXISTS "Users can insert own preferences" ON notification_preferences;
88+
89+
CREATE POLICY "Users can insert own preferences" ON notification_preferences FOR
90+
INSERT
91+
WITH
92+
CHECK (auth.uid () = user_id);
93+
94+
DROP POLICY IF EXISTS "Users can update own preferences" ON notification_preferences;
95+
96+
CREATE POLICY "Users can update own preferences" ON notification_preferences FOR
97+
UPDATE USING (auth.uid () = user_id);
98+
99+
-- Function to create default notification preferences for new users
100+
CREATE OR REPLACE FUNCTION create_default_notification_preferences()
101+
RETURNS TRIGGER AS $$
102+
BEGIN
103+
INSERT INTO notification_preferences (user_id)
104+
VALUES (NEW.id)
105+
ON CONFLICT (user_id) DO NOTHING;
106+
RETURN NEW;
107+
END;
108+
$$ LANGUAGE plpgsql SECURITY DEFINER;
109+
110+
-- Trigger to automatically create notification preferences for new users
111+
DROP TRIGGER IF EXISTS on_auth_user_created_notification_prefs ON auth.users;
112+
113+
CREATE TRIGGER on_auth_user_created_notification_prefs
114+
AFTER INSERT ON auth.users
115+
FOR EACH ROW
116+
EXECUTE FUNCTION create_default_notification_preferences();
117+
118+
-- Function to clean up expired notifications
119+
CREATE OR REPLACE FUNCTION cleanup_expired_notifications()
120+
RETURNS void AS $$
121+
BEGIN
122+
DELETE FROM notifications
123+
WHERE expires_at IS NOT NULL
124+
AND expires_at < NOW();
125+
END;
126+
$$ LANGUAGE plpgsql SECURITY DEFINER;
127+
128+
-- Optional: Create a scheduled job to clean up expired notifications
129+
-- This requires pg_cron extension (comment out if not available)
130+
-- SELECT cron.schedule(
131+
-- 'cleanup-expired-notifications',
132+
-- '0 0 * * *', -- Run daily at midnight
133+
-- $$SELECT cleanup_expired_notifications()$$
134+
-- );

0 commit comments

Comments
 (0)