mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 09:31:13 -05:00
Refactor Phase 3 Batch 2–4 Novu-related functions to use the createEdgeFunction wrapper, replacing explicit HTTP servers with edge wrapper, adding standardized logging, tracing, and error handling across subscriber management, topic/notification, and migration/sync functions.
135 lines
4.4 KiB
TypeScript
135 lines
4.4 KiB
TypeScript
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4";
|
|
import { corsHeadersWithTracing as corsHeaders } from '../_shared/cors.ts';
|
|
import { edgeLogger } from "../_shared/logger.ts";
|
|
import { createEdgeFunction } from '../_shared/edgeFunctionWrapper.ts';
|
|
|
|
interface AnnouncementPayload {
|
|
title: string;
|
|
message: string;
|
|
severity: 'info' | 'warning' | 'critical';
|
|
actionUrl?: string;
|
|
}
|
|
|
|
export default createEdgeFunction(
|
|
{
|
|
name: 'notify-system-announcement',
|
|
requireAuth: true,
|
|
corsHeaders: corsHeaders
|
|
},
|
|
async (req, context) => {
|
|
const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
|
|
const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
|
|
|
|
const supabase = createClient(supabaseUrl, supabaseServiceKey);
|
|
|
|
context.span.setAttribute('action', 'notify_system_announcement');
|
|
|
|
// Check user role
|
|
const { data: roles, error: roleError } = await supabase
|
|
.from('user_roles')
|
|
.select('role')
|
|
.eq('user_id', context.userId)
|
|
.in('role', ['admin', 'superuser']);
|
|
|
|
if (roleError || !roles || roles.length === 0) {
|
|
throw new Error('Unauthorized: Admin or superuser role required');
|
|
}
|
|
|
|
// Get user profile for logging
|
|
const { data: profile } = await supabase
|
|
.from('profiles')
|
|
.select('username, display_name')
|
|
.eq('user_id', context.userId)
|
|
.single();
|
|
|
|
const payload: AnnouncementPayload = await req.json();
|
|
|
|
// Validate required fields
|
|
if (!payload.title || !payload.message || !payload.severity) {
|
|
throw new Error('Missing required fields: title, message, or severity');
|
|
}
|
|
|
|
if (!['info', 'warning', 'critical'].includes(payload.severity)) {
|
|
throw new Error('Invalid severity level. Must be: info, warning, or critical');
|
|
}
|
|
|
|
edgeLogger.info('Processing system announcement', {
|
|
action: 'notify_system_announcement',
|
|
title: payload.title,
|
|
severity: payload.severity,
|
|
publishedBy: profile?.username || 'unknown',
|
|
requestId: context.requestId
|
|
});
|
|
|
|
// Fetch the workflow ID for system announcements
|
|
const { data: template, error: templateError } = await supabase
|
|
.from('notification_templates')
|
|
.select('workflow_id')
|
|
.eq('workflow_id', 'system-announcement')
|
|
.eq('is_active', true)
|
|
.maybeSingle();
|
|
|
|
if (templateError) {
|
|
edgeLogger.error('Error fetching workflow', { action: 'notify_system_announcement', requestId: context.requestId, error: templateError });
|
|
throw new Error(`Failed to fetch workflow: ${templateError.message}`);
|
|
}
|
|
|
|
if (!template) {
|
|
edgeLogger.warn('No active system-announcement workflow found', { action: 'notify_system_announcement', requestId: context.requestId });
|
|
throw new Error('No active system-announcement workflow configured');
|
|
}
|
|
|
|
const announcementId = crypto.randomUUID();
|
|
const publishedAt = new Date().toISOString();
|
|
const publishedBy = profile?.display_name || profile?.username || 'System Admin';
|
|
|
|
// Build notification payload for all users
|
|
const notificationPayload = {
|
|
baseUrl: 'https://www.thrillwiki.com',
|
|
announcementId,
|
|
title: payload.title,
|
|
message: payload.message,
|
|
severity: payload.severity,
|
|
actionUrl: payload.actionUrl || '',
|
|
publishedAt,
|
|
publishedBy,
|
|
};
|
|
|
|
edgeLogger.info('Triggering announcement to all users via "users" topic', { action: 'notify_system_announcement', requestId: context.requestId });
|
|
|
|
// Invoke the trigger-notification function with users topic
|
|
const { data: result, error: notifyError } = await supabase.functions.invoke(
|
|
'trigger-notification',
|
|
{
|
|
body: {
|
|
workflowId: template.workflow_id,
|
|
topicKey: 'users',
|
|
payload: notificationPayload,
|
|
},
|
|
}
|
|
);
|
|
|
|
if (notifyError) {
|
|
edgeLogger.error('Error triggering notification', { action: 'notify_system_announcement', requestId: context.requestId, error: notifyError });
|
|
throw notifyError;
|
|
}
|
|
|
|
edgeLogger.info('System announcement triggered successfully', { action: 'notify_system_announcement', requestId: context.requestId, result });
|
|
|
|
return new Response(
|
|
JSON.stringify({
|
|
success: true,
|
|
transactionId: result?.transactionId,
|
|
announcementId,
|
|
payload: notificationPayload,
|
|
}),
|
|
{
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
status: 200,
|
|
}
|
|
);
|
|
}
|
|
);
|