mirror of
https://github.com/Luchexx/wacrm.git
synced 2026-11-02 09:19:51 +00:00
119 lines
4.0 KiB
PL/PgSQL
119 lines
4.0 KiB
PL/PgSQL
- ============================================================
|
|
-- NOTIFICATIONS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS notifications (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
account_id UUID NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
|
|
-- Recipient — the agent this notification is for.
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
type TEXT NOT NULL DEFAULT 'conversation_assigned'
|
|
CHECK (type IN ('conversation_assigned')),
|
|
conversation_id UUID REFERENCES conversations(id) ON DELETE CASCADE,
|
|
contact_id UUID REFERENCES contacts(id) ON DELETE SET NULL,
|
|
-- Who triggered the notification. NULL means an automation / the
|
|
-- system did it rather than a signed-in teammate.
|
|
actor_user_id UUID REFERENCES auth.users(id) ON DELETE SET NULL,
|
|
title TEXT NOT NULL,
|
|
body TEXT,
|
|
read_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_notifications_user_created
|
|
ON notifications(user_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_notifications_user_unread
|
|
ON notifications(user_id)
|
|
WHERE read_at IS NULL;
|
|
|
|
ALTER TABLE notifications ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Recipients can read and mark their own notifications as read.
|
|
-- No client INSERT/DELETE policy — rows are created exclusively by
|
|
-- the SECURITY DEFINER trigger function below.
|
|
DROP POLICY IF EXISTS notifications_select ON notifications;
|
|
DROP POLICY IF EXISTS notifications_update ON notifications;
|
|
CREATE POLICY notifications_select ON notifications FOR SELECT
|
|
USING (auth.uid() = user_id);
|
|
CREATE POLICY notifications_update ON notifications FOR UPDATE
|
|
USING (auth.uid() = user_id)
|
|
WITH CHECK (auth.uid() = user_id);
|
|
|
|
-- ============================================================
|
|
-- TRIGGER — notify on conversation assignment
|
|
-- ============================================================
|
|
CREATE OR REPLACE FUNCTION notify_conversation_assigned()
|
|
RETURNS TRIGGER
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
SET search_path = public
|
|
AS $$
|
|
DECLARE
|
|
v_contact_name TEXT;
|
|
v_actor_name TEXT;
|
|
BEGIN
|
|
IF TG_OP = 'INSERT' THEN
|
|
IF NEW.assigned_agent_id IS NULL THEN
|
|
RETURN NEW;
|
|
END IF;
|
|
ELSE
|
|
IF NEW.assigned_agent_id IS NULL
|
|
OR NEW.assigned_agent_id IS NOT DISTINCT FROM OLD.assigned_agent_id THEN
|
|
RETURN NEW;
|
|
END IF;
|
|
END IF;
|
|
|
|
-- Skip self-assignment — nothing to notify the agent about.
|
|
IF auth.uid() IS NOT NULL AND auth.uid() = NEW.assigned_agent_id THEN
|
|
RETURN NEW;
|
|
END IF;
|
|
|
|
SELECT COALESCE(NULLIF(name, ''), phone) INTO v_contact_name
|
|
FROM contacts WHERE id = NEW.contact_id;
|
|
|
|
IF auth.uid() IS NOT NULL THEN
|
|
SELECT full_name INTO v_actor_name
|
|
FROM profiles WHERE user_id = auth.uid();
|
|
END IF;
|
|
|
|
INSERT INTO notifications (
|
|
account_id, user_id, type, conversation_id, contact_id,
|
|
actor_user_id, title, body
|
|
) VALUES (
|
|
NEW.account_id,
|
|
NEW.assigned_agent_id,
|
|
'conversation_assigned',
|
|
NEW.id,
|
|
NEW.contact_id,
|
|
auth.uid(),
|
|
'New conversation assigned',
|
|
COALESCE(v_actor_name, 'Someone') || ' assigned you a conversation with '
|
|
|| COALESCE(v_contact_name, 'a contact')
|
|
);
|
|
|
|
RETURN NEW;
|
|
EXCEPTION WHEN OTHERS THEN
|
|
-- Never let a notification failure block the assignment itself.
|
|
RAISE WARNING 'Failed to create assignment notification for conversation %: %', NEW.id, SQLERRM;
|
|
RETURN NEW;
|
|
END;
|
|
$$;
|
|
|
|
ALTER FUNCTION notify_conversation_assigned() OWNER TO postgres;
|
|
|
|
DROP TRIGGER IF EXISTS on_conversation_assigned ON conversations;
|
|
CREATE TRIGGER on_conversation_assigned
|
|
AFTER INSERT OR UPDATE OF assigned_agent_id ON conversations
|
|
FOR EACH ROW EXECUTE FUNCTION notify_conversation_assigned();
|
|
|
|
-- ============================================================
|
|
-- ENABLE REALTIME
|
|
-- ============================================================
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM pg_publication_tables
|
|
WHERE pubname = 'supabase_realtime' AND tablename = 'notifications'
|
|
) THEN
|
|
ALTER PUBLICATION supabase_realtime ADD TABLE notifications;
|
|
END IF;
|
|
END $$; |