mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 15:31:12 -05:00
Migrate Admin Admin Functions to wrapEdgeFunction
Migrate Phase 3 administrative functions to use the wrapEdgeFunction wrapper: - cancel-account-deletion - cancel-email-change - create-novu-subscriber - update-novu-subscriber - trigger-notification - remove-novu-subscriber - manage-moderator-topic - migrate-novu-users - sync-all-moderators-to-topic - update-novu-preferences - notify-system-announcement This update standardizes error handling, tracing, auth, and logging across admin endpoints, removes manual serve/CORS boilerplate, and prepares for consistent monitoring and testing.
This commit is contained in:
@@ -1,17 +1,15 @@
|
||||
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
|
||||
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
||||
import { corsHeaders } from '../_shared/cors.ts';
|
||||
import { edgeLogger, startRequest, endRequest } from '../_shared/logger.ts';
|
||||
import { formatEdgeError } from '../_shared/errorFormatter.ts';
|
||||
import { edgeLogger } from '../_shared/logger.ts';
|
||||
import { createEdgeFunction } from '../_shared/edgeFunctionWrapper.ts';
|
||||
|
||||
serve(async (req) => {
|
||||
const tracking = startRequest();
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response(null, { headers: corsHeaders });
|
||||
}
|
||||
|
||||
try {
|
||||
export default createEdgeFunction(
|
||||
{
|
||||
name: 'cancel-account-deletion',
|
||||
requireAuth: true,
|
||||
corsHeaders: corsHeaders
|
||||
},
|
||||
async (req, context) => {
|
||||
const { cancellation_reason } = await req.json();
|
||||
|
||||
const supabaseClient = createClient(
|
||||
@@ -24,23 +22,14 @@ serve(async (req) => {
|
||||
}
|
||||
);
|
||||
|
||||
// Get authenticated user
|
||||
const {
|
||||
data: { user },
|
||||
error: userError,
|
||||
} = await supabaseClient.auth.getUser();
|
||||
|
||||
if (userError || !user) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
edgeLogger.info('Cancelling deletion request', { action: 'cancel_deletion', userId: user.id, requestId: tracking.requestId });
|
||||
context.span.setAttribute('action', 'cancel_deletion');
|
||||
edgeLogger.info('Cancelling deletion request', { action: 'cancel_deletion', userId: context.userId, requestId: context.requestId });
|
||||
|
||||
// Find pending or confirmed deletion request
|
||||
const { data: deletionRequest, error: requestError } = await supabaseClient
|
||||
.from('account_deletion_requests')
|
||||
.select('*')
|
||||
.eq('user_id', user.id)
|
||||
.eq('user_id', context.userId)
|
||||
.in('status', ['pending', 'confirmed'])
|
||||
.maybeSingle();
|
||||
|
||||
@@ -81,7 +70,7 @@ serve(async (req) => {
|
||||
deactivated_at: null,
|
||||
deactivation_reason: null,
|
||||
})
|
||||
.eq('user_id', user.id);
|
||||
.eq('user_id', context.userId);
|
||||
|
||||
if (profileError) {
|
||||
throw profileError;
|
||||
@@ -90,8 +79,9 @@ serve(async (req) => {
|
||||
// Send cancellation email
|
||||
const forwardEmailKey = Deno.env.get('FORWARDEMAIL_API_KEY');
|
||||
const fromEmail = Deno.env.get('FROM_EMAIL_ADDRESS') || 'noreply@thrillwiki.com';
|
||||
const userEmail = (await supabaseClient.auth.getUser()).data.user?.email;
|
||||
|
||||
if (forwardEmailKey) {
|
||||
if (forwardEmailKey && userEmail) {
|
||||
try {
|
||||
await fetch('https://api.forwardemail.net/v1/emails', {
|
||||
method: 'POST',
|
||||
@@ -101,7 +91,7 @@ serve(async (req) => {
|
||||
},
|
||||
body: JSON.stringify({
|
||||
from: fromEmail,
|
||||
to: user.email,
|
||||
to: userEmail,
|
||||
subject: 'Account Deletion Cancelled',
|
||||
html: `
|
||||
<h2>Account Deletion Cancelled</h2>
|
||||
@@ -112,35 +102,23 @@ serve(async (req) => {
|
||||
`,
|
||||
}),
|
||||
});
|
||||
edgeLogger.info('Cancellation confirmation email sent', { action: 'cancel_deletion_email', userId: user.id, requestId: tracking.requestId });
|
||||
edgeLogger.info('Cancellation confirmation email sent', { action: 'cancel_deletion_email', userId: context.userId, requestId: context.requestId });
|
||||
} catch (emailError) {
|
||||
edgeLogger.error('Failed to send email', { action: 'cancel_deletion_email', userId: user.id, requestId: tracking.requestId });
|
||||
edgeLogger.error('Failed to send email', { action: 'cancel_deletion_email', userId: context.userId, requestId: context.requestId });
|
||||
}
|
||||
}
|
||||
|
||||
const duration = endRequest(tracking);
|
||||
edgeLogger.info('Deletion cancelled successfully', { action: 'cancel_deletion_success', userId: user.id, requestId: tracking.requestId, duration });
|
||||
edgeLogger.info('Deletion cancelled successfully', { action: 'cancel_deletion_success', userId: context.userId, requestId: context.requestId });
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
success: true,
|
||||
message: 'Account deletion cancelled successfully',
|
||||
requestId: tracking.requestId
|
||||
}),
|
||||
{
|
||||
status: 200,
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json', 'X-Request-ID': tracking.requestId },
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
const duration = endRequest(tracking);
|
||||
edgeLogger.error('Error cancelling deletion', { action: 'cancel_deletion_error', error: formatEdgeError(error), requestId: tracking.requestId, duration });
|
||||
return new Response(
|
||||
JSON.stringify({ error: error.message, requestId: tracking.requestId }),
|
||||
{
|
||||
status: 400,
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json', 'X-Request-ID': tracking.requestId },
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user