import { serve } from "https://deno.land/std@0.190.0/http/server.ts"; import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4"; import { Novu } from "npm:@novu/api@1.6.0"; import { edgeLogger, startRequest, endRequest } from "../_shared/logger.ts"; const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type, x-request-id', }; const TOPICS = { MODERATION_SUBMISSIONS: 'moderation-submissions', MODERATION_REPORTS: 'moderation-reports', } as const; serve(async (req) => { if (req.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders }); } const tracking = startRequest('manage-moderator-topic'); try { const novuApiKey = Deno.env.get('NOVU_API_KEY'); if (!novuApiKey) { throw new Error('NOVU_API_KEY is not configured'); } const novu = new Novu({ secretKey: novuApiKey }); const { userId, action } = await req.json(); if (!userId || !action) { throw new Error('Missing required fields: userId, action'); } if (action !== 'add' && action !== 'remove') { throw new Error('Action must be either "add" or "remove"'); } edgeLogger.info(`${action === 'add' ? 'Adding' : 'Removing'} user ${userId} ${action === 'add' ? 'to' : 'from'} moderator topics`, { action: 'manage_moderator_topic', requestId: tracking.requestId, userId, operation: action }); const topics = [TOPICS.MODERATION_SUBMISSIONS, TOPICS.MODERATION_REPORTS]; const results = []; for (const topicKey of topics) { try { if (action === 'add') { // Add subscriber to topic await novu.topics.addSubscribers(topicKey, { subscribers: [userId], }); edgeLogger.info('Added user to topic', { action: 'manage_moderator_topic', requestId: tracking.requestId, userId, topicKey }); results.push({ topic: topicKey, action: 'added', success: true }); } else { // Remove subscriber from topic await novu.topics.removeSubscribers(topicKey, { subscribers: [userId], }); edgeLogger.info('Removed user from topic', { action: 'manage_moderator_topic', requestId: tracking.requestId, userId, topicKey }); results.push({ topic: topicKey, action: 'removed', success: true }); } } catch (error: any) { edgeLogger.error(`Error ${action}ing user ${userId} ${action === 'add' ? 'to' : 'from'} topic ${topicKey}`, { action: 'manage_moderator_topic', requestId: tracking.requestId, userId, topicKey, error: error.message }); results.push({ topic: topicKey, action: action === 'add' ? 'added' : 'removed', success: false, error: error.message }); } } const allSuccess = results.every(r => r.success); endRequest(tracking, allSuccess ? 200 : 207); return new Response( JSON.stringify({ success: allSuccess, userId, action, results, requestId: tracking.requestId }), { headers: { ...corsHeaders, 'Content-Type': 'application/json', 'X-Request-ID': tracking.requestId }, status: allSuccess ? 200 : 207, // 207 = Multi-Status (partial success) } ); } catch (error: any) { edgeLogger.error('Error managing moderator topic', { action: 'manage_moderator_topic', requestId: tracking.requestId, error: error.message }); endRequest(tracking, 500, error.message); return new Response( JSON.stringify({ success: false, error: error.message, requestId: tracking.requestId }), { headers: { ...corsHeaders, 'Content-Type': 'application/json', 'X-Request-ID': tracking.requestId }, status: 500, } ); } });