Migrate check-transaction-status to wrapper

Migrate the remaining administrative function check-transaction-status to use the wrapEdgeFunction wrapper, aligning with admin-delete-user. Updated to remove manual Deno.serve handling, integrate edge wrapper, standardized logging with edgeLogger, and utilize context for auth and tracing. admin-delete-user already migrated.
This commit is contained in:
gpt-engineer-app[bot]
2025-11-11 03:56:44 +00:00
parent a1280ddd05
commit 08926610b9

View File

@@ -9,7 +9,9 @@
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.57.4'; import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.57.4';
import { corsHeaders } from '../_shared/cors.ts'; import { corsHeaders } from '../_shared/cors.ts';
import { edgeLogger, startRequest, endRequest } from '../_shared/logger.ts'; import { edgeLogger } from '../_shared/logger.ts';
import { createEdgeFunction } from '../_shared/edgeFunctionWrapper.ts';
import { validateString } from '../_shared/typeValidation.ts';
interface StatusRequest { interface StatusRequest {
idempotencyKey: string; idempotencyKey: string;
@@ -27,53 +29,29 @@ interface StatusResponse {
submissionId?: string; submissionId?: string;
} }
const handler = async (req: Request): Promise<Response> => { export default createEdgeFunction(
if (req.method === 'OPTIONS') { {
return new Response(null, { headers: corsHeaders }); name: 'check-transaction-status',
} requireAuth: true,
corsHeaders: corsHeaders
const tracking = startRequest(); },
async (req, context) => {
try {
// Verify authentication
const authHeader = req.headers.get('Authorization');
if (!authHeader) {
edgeLogger.warn('Missing authorization header', { requestId: tracking.requestId });
return new Response(
JSON.stringify({ error: 'Unauthorized', status: 'not_found' }),
{ status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
);
}
const supabase = createClient( const supabase = createClient(
Deno.env.get('SUPABASE_URL')!, Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_ANON_KEY')!, Deno.env.get('SUPABASE_ANON_KEY')!,
{ global: { headers: { Authorization: authHeader } } } { global: { headers: { Authorization: req.headers.get('Authorization')! } } }
); );
// Verify user
const { data: { user }, error: authError } = await supabase.auth.getUser();
if (authError || !user) {
edgeLogger.warn('Invalid auth token', { requestId: tracking.requestId, error: authError });
return new Response(
JSON.stringify({ error: 'Unauthorized', status: 'not_found' }),
{ status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
);
}
// Parse request // Parse request
const { idempotencyKey }: StatusRequest = await req.json(); const { idempotencyKey }: StatusRequest = await req.json();
validateString(idempotencyKey, 'idempotencyKey', { userId: context.userId, requestId: context.requestId });
if (!idempotencyKey) { context.span.setAttribute('action', 'check_transaction_status');
return new Response( context.span.setAttribute('idempotency_key', idempotencyKey);
JSON.stringify({ error: 'Missing idempotencyKey', status: 'not_found' }),
{ status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
);
}
edgeLogger.info('Checking transaction status', { edgeLogger.info('Checking transaction status', {
requestId: tracking.requestId, requestId: context.requestId,
userId: user.id, userId: context.userId,
idempotencyKey, idempotencyKey,
}); });
@@ -86,7 +64,7 @@ const handler = async (req: Request): Promise<Response> => {
if (queryError || !keyRecord) { if (queryError || !keyRecord) {
edgeLogger.info('Idempotency key not found', { edgeLogger.info('Idempotency key not found', {
requestId: tracking.requestId, requestId: context.requestId,
idempotencyKey, idempotencyKey,
error: queryError, error: queryError,
}); });
@@ -98,22 +76,22 @@ const handler = async (req: Request): Promise<Response> => {
} as StatusResponse), } as StatusResponse),
{ {
status: 404, status: 404,
headers: { ...corsHeaders, 'Content-Type': 'application/json' } headers: { 'Content-Type': 'application/json' }
} }
); );
} }
// Verify user owns this key // Verify user owns this key
if (keyRecord.user_id !== user.id) { if (keyRecord.user_id !== context.userId) {
edgeLogger.warn('User does not own idempotency key', { edgeLogger.warn('User does not own idempotency key', {
requestId: tracking.requestId, requestId: context.requestId,
userId: user.id, userId: context.userId,
keyUserId: keyRecord.user_id, keyUserId: keyRecord.user_id,
}); });
return new Response( return new Response(
JSON.stringify({ error: 'Unauthorized', status: 'not_found' }), JSON.stringify({ error: 'Unauthorized', status: 'not_found' }),
{ status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } } { status: 403, headers: { 'Content-Type': 'application/json' } }
); );
} }
@@ -138,10 +116,8 @@ const handler = async (req: Request): Promise<Response> => {
response.completedAt = keyRecord.completed_at; response.completedAt = keyRecord.completed_at;
} }
const duration = endRequest(tracking);
edgeLogger.info('Transaction status retrieved', { edgeLogger.info('Transaction status retrieved', {
requestId: tracking.requestId, requestId: context.requestId,
duration,
status: response.status, status: response.status,
}); });
@@ -149,31 +125,8 @@ const handler = async (req: Request): Promise<Response> => {
JSON.stringify(response), JSON.stringify(response),
{ {
status: 200, status: 200,
headers: { ...corsHeaders, 'Content-Type': 'application/json' } headers: { 'Content-Type': 'application/json' }
}
);
} catch (error) {
const duration = endRequest(tracking);
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
edgeLogger.error('Error checking transaction status', {
requestId: tracking.requestId,
duration,
error: errorMessage,
});
return new Response(
JSON.stringify({
error: 'Internal server error',
status: 'not_found'
}),
{
status: 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
} }
); );
} }
}; );
Deno.serve(handler);