From 5531376edf5e027554183a7c0242383ee44d92ee Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 04:57:54 +0000 Subject: [PATCH] Fix span duplicates and metrics Implements complete plan to resolve duplicate span_id issues and metric collection errors: - Ensure edge handlers return proper Response objects to prevent double logging - Update collect-metrics to use valid metric categories, fix system_alerts query, and adjust returns - Apply detect-anomalies adjustments if needed and add defensive handling in wrapper - Prepare ground for end-to-end verification of location-related fixes --- .../functions/_shared/edgeFunctionWrapper.ts | 10 +++++- supabase/functions/collect-metrics/index.ts | 32 +++++++++++-------- supabase/functions/detect-anomalies/index.ts | 16 +++++++--- 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/supabase/functions/_shared/edgeFunctionWrapper.ts b/supabase/functions/_shared/edgeFunctionWrapper.ts index f67a8098..6d20e6cb 100644 --- a/supabase/functions/_shared/edgeFunctionWrapper.ts +++ b/supabase/functions/_shared/edgeFunctionWrapper.ts @@ -266,7 +266,15 @@ export function wrapEdgeFunction( logSpanToDatabase(span, requestId); // Clone response to add tracking headers - const responseBody = await response.text(); + // Defensive check: ensure handler returned a Response object + let responseBody: string; + if (response instanceof Response) { + responseBody = await response.text(); + } else { + // Handler returned non-Response (shouldn't happen, but handle it) + addSpanEvent(span, 'warning_non_response_object'); + responseBody = JSON.stringify(response); + } const enhancedResponse = new Response(responseBody, { status: response.status, statusText: response.statusText, diff --git a/supabase/functions/collect-metrics/index.ts b/supabase/functions/collect-metrics/index.ts index 8dc12288..9c3a1606 100644 --- a/supabase/functions/collect-metrics/index.ts +++ b/supabase/functions/collect-metrics/index.ts @@ -28,7 +28,7 @@ const handler = async (req: Request, { supabase, span, requestId }: EdgeFunction metrics.push({ metric_name: 'api_error_count', metric_value: errorCount as number, - metric_category: 'performance', + metric_category: 'api', timestamp, }); } @@ -45,7 +45,7 @@ const handler = async (req: Request, { supabase, span, requestId }: EdgeFunction metrics.push({ metric_name: 'rate_limit_violations', metric_value: violationCount as number, - metric_category: 'security', + metric_category: 'rate_limit', timestamp, }); } @@ -61,7 +61,7 @@ const handler = async (req: Request, { supabase, span, requestId }: EdgeFunction metrics.push({ metric_name: 'pending_submissions', metric_value: pendingCount as number, - metric_category: 'workflow', + metric_category: 'moderation', timestamp, }); } @@ -77,7 +77,7 @@ const handler = async (req: Request, { supabase, span, requestId }: EdgeFunction metrics.push({ metric_name: 'active_incidents', metric_value: incidentCount as number, - metric_category: 'monitoring', + metric_category: 'system', timestamp, }); } @@ -86,14 +86,14 @@ const handler = async (req: Request, { supabase, span, requestId }: EdgeFunction const { data: unresolvedAlerts, error: alertsError } = await supabase .from('system_alerts') .select('id', { count: 'exact', head: true }) - .eq('resolved', false); + .is('resolved_at', null); if (!alertsError) { const alertCount = unresolvedAlerts || 0; metrics.push({ metric_name: 'unresolved_alerts', metric_value: alertCount as number, - metric_category: 'monitoring', + metric_category: 'system', timestamp, }); } @@ -112,7 +112,7 @@ const handler = async (req: Request, { supabase, span, requestId }: EdgeFunction metrics.push({ metric_name: 'submission_approval_rate', metric_value: approvalRate, - metric_category: 'workflow', + metric_category: 'moderation', timestamp, }); } @@ -136,7 +136,7 @@ const handler = async (req: Request, { supabase, span, requestId }: EdgeFunction metrics.push({ metric_name: 'avg_moderation_time', metric_value: avgTimeMinutes, - metric_category: 'workflow', + metric_category: 'moderation', timestamp, }); } @@ -155,11 +155,17 @@ const handler = async (req: Request, { supabase, span, requestId }: EdgeFunction addSpanEvent(span, 'metrics_recorded', { count: metrics.length }); } - return { - success: true, - metrics_collected: metrics.length, - metrics: metrics.map(m => ({ name: m.metric_name, value: m.metric_value })), - }; + return new Response( + JSON.stringify({ + success: true, + metrics_collected: metrics.length, + metrics: metrics.map(m => ({ name: m.metric_name, value: m.metric_value })), + }), + { + status: 200, + headers: { 'Content-Type': 'application/json' }, + } + ); }; serve(createEdgeFunction({ diff --git a/supabase/functions/detect-anomalies/index.ts b/supabase/functions/detect-anomalies/index.ts index 17ccaf59..a0966fc7 100644 --- a/supabase/functions/detect-anomalies/index.ts +++ b/supabase/functions/detect-anomalies/index.ts @@ -474,11 +474,17 @@ const handler = async (req: Request, { supabase, span, requestId }: EdgeFunction addSpanEvent(span, 'anomaly_detection_complete', { detected: anomaliesDetected.length }); - return { - success: true, - anomalies_detected: anomaliesDetected.length, - anomalies: anomaliesDetected, - }; + return new Response( + JSON.stringify({ + success: true, + anomalies_detected: anomaliesDetected.length, + anomalies: anomaliesDetected, + }), + { + status: 200, + headers: { 'Content-Type': 'application/json' }, + } + ); }; serve(createEdgeFunction({