mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:31:12 -05:00
Refactor: Enhance submission notification payload
This commit is contained in:
@@ -11,6 +11,11 @@ interface NotificationPayload {
|
|||||||
submission_type: string;
|
submission_type: string;
|
||||||
submitter_name: string;
|
submitter_name: string;
|
||||||
action: string;
|
action: string;
|
||||||
|
content_preview: string;
|
||||||
|
submitted_at: string;
|
||||||
|
has_photos: boolean;
|
||||||
|
item_count: number;
|
||||||
|
is_escalated: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
serve(async (req) => {
|
serve(async (req) => {
|
||||||
@@ -25,9 +30,44 @@ serve(async (req) => {
|
|||||||
const supabase = createClient(supabaseUrl, supabaseServiceKey);
|
const supabase = createClient(supabaseUrl, supabaseServiceKey);
|
||||||
|
|
||||||
const payload: NotificationPayload = await req.json();
|
const payload: NotificationPayload = await req.json();
|
||||||
const { submission_id, submission_type, submitter_name, action } = payload;
|
const {
|
||||||
|
submission_id,
|
||||||
|
submission_type,
|
||||||
|
submitter_name,
|
||||||
|
action,
|
||||||
|
content_preview,
|
||||||
|
submitted_at,
|
||||||
|
has_photos,
|
||||||
|
item_count,
|
||||||
|
is_escalated
|
||||||
|
} = payload;
|
||||||
|
|
||||||
console.log('Notifying moderators about submission via topic:', { submission_id, submission_type });
|
console.log('Notifying moderators about submission via topic:', {
|
||||||
|
submission_id,
|
||||||
|
submission_type,
|
||||||
|
content_preview
|
||||||
|
});
|
||||||
|
|
||||||
|
// Calculate relative time and priority
|
||||||
|
const submittedDate = new Date(submitted_at);
|
||||||
|
const now = new Date();
|
||||||
|
const waitTimeMs = now.getTime() - submittedDate.getTime();
|
||||||
|
const waitTimeHours = waitTimeMs / (1000 * 60 * 60);
|
||||||
|
|
||||||
|
// Format relative time
|
||||||
|
const relativeTime = (() => {
|
||||||
|
const minutes = Math.floor(waitTimeMs / (1000 * 60));
|
||||||
|
const hours = Math.floor(waitTimeMs / (1000 * 60 * 60));
|
||||||
|
const days = Math.floor(waitTimeMs / (1000 * 60 * 60 * 24));
|
||||||
|
|
||||||
|
if (minutes < 1) return 'just now';
|
||||||
|
if (minutes < 60) return `${minutes} minute${minutes !== 1 ? 's' : ''} ago`;
|
||||||
|
if (hours < 24) return `${hours} hour${hours !== 1 ? 's' : ''} ago`;
|
||||||
|
return `${days} day${days !== 1 ? 's' : ''} ago`;
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Determine priority based on wait time
|
||||||
|
const priority = waitTimeHours >= 24 ? 'urgent' : 'normal';
|
||||||
|
|
||||||
// Get the moderation-alert workflow
|
// Get the moderation-alert workflow
|
||||||
const { data: workflow, error: workflowError } = await supabase
|
const { data: workflow, error: workflowError } = await supabase
|
||||||
@@ -51,13 +91,27 @@ serve(async (req) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare notification payload
|
// Prepare enhanced notification payload
|
||||||
const notificationPayload = {
|
const notificationPayload = {
|
||||||
|
// Basic info
|
||||||
itemType: submission_type,
|
itemType: submission_type,
|
||||||
submitterName: submitter_name,
|
submitterName: submitter_name,
|
||||||
submissionId: submission_id,
|
submissionId: submission_id,
|
||||||
action: action || 'create',
|
action: action || 'create',
|
||||||
moderationUrl: `https://ydvtmnrszybqnbcqbdcy.supabase.co/admin/moderation`,
|
moderationUrl: `https://ydvtmnrszybqnbcqbdcy.supabase.co/admin/moderation`,
|
||||||
|
|
||||||
|
// Enhanced content
|
||||||
|
contentPreview: content_preview,
|
||||||
|
|
||||||
|
// Timing information
|
||||||
|
submittedAt: submitted_at,
|
||||||
|
relativeTime: relativeTime,
|
||||||
|
priority: priority,
|
||||||
|
|
||||||
|
// Additional metadata
|
||||||
|
hasPhotos: has_photos,
|
||||||
|
itemCount: item_count,
|
||||||
|
isEscalated: is_escalated,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send ONE notification to the moderation-submissions topic
|
// Send ONE notification to the moderation-submissions topic
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
-- Update trigger function to include enhanced notification data
|
||||||
|
CREATE OR REPLACE FUNCTION public.notify_moderators_on_new_submission()
|
||||||
|
RETURNS TRIGGER
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
SECURITY DEFINER
|
||||||
|
SET search_path = public
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
submitter_profile record;
|
||||||
|
function_url text;
|
||||||
|
anon_key text;
|
||||||
|
content_preview text;
|
||||||
|
has_photos boolean := false;
|
||||||
|
item_count integer := 0;
|
||||||
|
BEGIN
|
||||||
|
-- Get submitter's username or display name
|
||||||
|
SELECT username, display_name INTO submitter_profile
|
||||||
|
FROM public.profiles
|
||||||
|
WHERE user_id = NEW.user_id;
|
||||||
|
|
||||||
|
-- Build content preview based on submission type
|
||||||
|
content_preview := CASE NEW.submission_type
|
||||||
|
WHEN 'park' THEN
|
||||||
|
COALESCE(NEW.content->>'name', 'Unnamed') || ' - ' ||
|
||||||
|
COALESCE(NEW.content->>'park_type', 'Park') ||
|
||||||
|
CASE
|
||||||
|
WHEN NEW.content->>'location' IS NOT NULL
|
||||||
|
THEN ' in ' || (NEW.content->>'location')
|
||||||
|
ELSE ''
|
||||||
|
END
|
||||||
|
WHEN 'ride' THEN
|
||||||
|
COALESCE(NEW.content->>'name', 'Unnamed') || ' - ' ||
|
||||||
|
COALESCE(NEW.content->>'category', 'Ride') ||
|
||||||
|
CASE
|
||||||
|
WHEN NEW.content->>'park_name' IS NOT NULL
|
||||||
|
THEN ' at ' || (NEW.content->>'park_name')
|
||||||
|
ELSE ''
|
||||||
|
END
|
||||||
|
WHEN 'company' THEN
|
||||||
|
COALESCE(NEW.content->>'name', 'Unnamed') || ' - ' ||
|
||||||
|
COALESCE(NEW.content->>'company_type', 'Company')
|
||||||
|
WHEN 'ride_model' THEN
|
||||||
|
COALESCE(NEW.content->>'name', 'Unnamed') || ' - ' ||
|
||||||
|
'Ride Model' ||
|
||||||
|
CASE
|
||||||
|
WHEN NEW.content->>'manufacturer_name' IS NOT NULL
|
||||||
|
THEN ' by ' || (NEW.content->>'manufacturer_name')
|
||||||
|
ELSE ''
|
||||||
|
END
|
||||||
|
WHEN 'photo' THEN
|
||||||
|
'Photo submission for ' || COALESCE(NEW.content->>'entity_type', 'entity')
|
||||||
|
ELSE
|
||||||
|
'Submission'
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- Truncate preview to 200 characters
|
||||||
|
content_preview := LEFT(content_preview, 200);
|
||||||
|
|
||||||
|
-- Check if this submission has photos
|
||||||
|
has_photos := EXISTS (
|
||||||
|
SELECT 1 FROM photo_submissions ps
|
||||||
|
WHERE ps.submission_id = NEW.id
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Count submission items
|
||||||
|
SELECT COUNT(*) INTO item_count
|
||||||
|
FROM submission_items
|
||||||
|
WHERE submission_id = NEW.id;
|
||||||
|
|
||||||
|
-- Build the function URL
|
||||||
|
function_url := 'https://ydvtmnrszybqnbcqbdcy.supabase.co/functions/v1/notify-moderators-submission';
|
||||||
|
|
||||||
|
-- Use the public anon key
|
||||||
|
anon_key := 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InlkdnRtbnJzenlicW5iY3FiZGN5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTgzMjYzNTYsImV4cCI6MjA3MzkwMjM1Nn0.DM3oyapd_omP5ZzIlrT0H9qBsiQBxBRgw2tYuqgXKX4';
|
||||||
|
|
||||||
|
-- Call edge function asynchronously with enhanced data
|
||||||
|
PERFORM net.http_post(
|
||||||
|
url := function_url,
|
||||||
|
headers := jsonb_build_object(
|
||||||
|
'Content-Type', 'application/json',
|
||||||
|
'Authorization', 'Bearer ' || anon_key,
|
||||||
|
'apikey', anon_key
|
||||||
|
),
|
||||||
|
body := jsonb_build_object(
|
||||||
|
'submission_id', NEW.id,
|
||||||
|
'submission_type', NEW.submission_type,
|
||||||
|
'submitter_name', COALESCE(submitter_profile.display_name, submitter_profile.username, 'Anonymous'),
|
||||||
|
'action', COALESCE((NEW.content->>'action')::text, 'create'),
|
||||||
|
'content_preview', content_preview,
|
||||||
|
'submitted_at', NEW.submitted_at,
|
||||||
|
'has_photos', has_photos,
|
||||||
|
'item_count', item_count,
|
||||||
|
'is_escalated', COALESCE(NEW.escalated, false)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
-- Log error but don't fail the submission
|
||||||
|
RAISE WARNING 'Failed to notify moderators: %', SQLERRM;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION public.notify_moderators_on_new_submission() IS
|
||||||
|
'Sends enhanced notifications to moderators via Novu topics when new submissions are created, including content preview, timing, and metadata';
|
||||||
Reference in New Issue
Block a user