Add notifications system, fix button href, admin settings and welcome email
All checks were successful
Build and Push Docker Image / build (push) Successful in 1m55s

- Fix admin settings 502 error by adding INSERT/UPDATE/DELETE grants
- Fix Button component to render <a> when href prop is provided
- Add welcome email for admin created during initial setup
- Add in-app notifications system with NotificationCenter component
- Add notifications table with RLS policies and welcome trigger
- Add API endpoints for fetching and marking notifications as read

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-26 16:04:27 +01:00
parent 2451582dc6
commit 274b13fe1e
8 changed files with 462 additions and 22 deletions

View File

@@ -660,8 +660,8 @@ GRANT SELECT, INSERT, UPDATE, DELETE ON public.documents TO authenticated;
GRANT SELECT ON public.document_categories TO authenticated;
GRANT SELECT, INSERT, UPDATE, DELETE ON public.document_folders TO authenticated;
-- Settings (public settings viewable)
GRANT SELECT ON public.app_settings TO authenticated;
-- Settings (admin can manage, all authenticated can read)
GRANT SELECT, INSERT, UPDATE, DELETE ON public.app_settings TO authenticated;
-- Email (admin can manage templates, users can view own logs)
GRANT SELECT, UPDATE ON public.email_templates TO authenticated;
@@ -1409,6 +1409,73 @@ ALTER TABLE public.members ADD COLUMN IF NOT EXISTS onboarding_completed_at TIME
CREATE INDEX IF NOT EXISTS idx_members_payment_deadline ON public.members(payment_deadline)
WHERE payment_deadline IS NOT NULL;
-- ============================================
-- MIGRATION 017: In-App Notifications
-- ============================================
-- In-app notifications table
CREATE TABLE public.notifications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
member_id UUID NOT NULL REFERENCES public.members(id) ON DELETE CASCADE,
type TEXT NOT NULL CHECK (type IN ('welcome', 'event', 'payment', 'membership', 'system', 'announcement')),
title TEXT NOT NULL,
message TEXT NOT NULL,
link TEXT,
read_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_notifications_member ON public.notifications(member_id);
CREATE INDEX idx_notifications_unread ON public.notifications(member_id) WHERE read_at IS NULL;
CREATE INDEX idx_notifications_created ON public.notifications(created_at DESC);
ALTER TABLE public.notifications ENABLE ROW LEVEL SECURITY;
-- Members can view their own notifications
CREATE POLICY "Members can view own notifications"
ON public.notifications FOR SELECT
TO authenticated
USING (member_id = auth.uid());
-- Members can update their own notifications (mark as read)
CREATE POLICY "Members can update own notifications"
ON public.notifications FOR UPDATE
TO authenticated
USING (member_id = auth.uid());
-- Admin can manage all notifications
CREATE POLICY "Admin can manage all notifications"
ON public.notifications FOR ALL
TO authenticated
USING (
EXISTS (SELECT 1 FROM public.members WHERE id = auth.uid() AND role = 'admin')
);
-- Grant permissions
GRANT SELECT, UPDATE ON public.notifications TO authenticated;
GRANT ALL ON public.notifications TO service_role;
-- Trigger to create welcome notification for new members
CREATE OR REPLACE FUNCTION create_welcome_notification()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO public.notifications (member_id, type, title, message, link)
VALUES (
NEW.id,
'welcome',
'Welcome to Monaco USA!',
'Thank you for joining our community. Complete your profile and explore upcoming events.',
'/profile'
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
CREATE TRIGGER on_member_created_notification
AFTER INSERT ON public.members
FOR EACH ROW
EXECUTE FUNCTION create_welcome_notification();
-- ============================================
-- GRANT SERVICE_ROLE ACCESS TO ALL TABLES
-- ============================================