mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 11:51:14 -05:00
Refactor: Update Supabase client
This commit is contained in:
141
src/lib/requestTracking.ts
Normal file
141
src/lib/requestTracking.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Request Tracking Service
|
||||
* Tracks API requests with correlation IDs and stores metadata for monitoring
|
||||
*/
|
||||
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { requestContext, type RequestContext } from './requestContext';
|
||||
|
||||
export interface RequestTrackingOptions {
|
||||
endpoint: string;
|
||||
method: string;
|
||||
userId?: string;
|
||||
parentRequestId?: string;
|
||||
traceId?: string;
|
||||
}
|
||||
|
||||
export interface RequestResult {
|
||||
requestId: string;
|
||||
statusCode: number;
|
||||
duration: number;
|
||||
error?: {
|
||||
type: string;
|
||||
message: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Track a request and store metadata
|
||||
* Returns requestId for correlation and support
|
||||
*/
|
||||
export async function trackRequest<T>(
|
||||
options: RequestTrackingOptions,
|
||||
fn: (context: RequestContext) => Promise<T>
|
||||
): Promise<{ result: T; requestId: string; duration: number }> {
|
||||
const context = requestContext.create(options.userId, options.traceId);
|
||||
const start = Date.now();
|
||||
|
||||
try {
|
||||
const result = await fn(context);
|
||||
const duration = Date.now() - start;
|
||||
|
||||
// Log to database (fire and forget - don't block response)
|
||||
logRequestMetadata({
|
||||
requestId: context.requestId,
|
||||
userId: options.userId,
|
||||
endpoint: options.endpoint,
|
||||
method: options.method,
|
||||
statusCode: 200,
|
||||
duration,
|
||||
userAgent: context.userAgent,
|
||||
clientVersion: context.clientVersion,
|
||||
parentRequestId: options.parentRequestId,
|
||||
traceId: context.traceId,
|
||||
}).catch(err => {
|
||||
console.error('[RequestTracking] Failed to log metadata:', err);
|
||||
});
|
||||
|
||||
// Cleanup context
|
||||
requestContext.cleanup(context.requestId);
|
||||
|
||||
return { result, requestId: context.requestId, duration };
|
||||
|
||||
} catch (error) {
|
||||
const duration = Date.now() - start;
|
||||
const errorInfo = error instanceof Error
|
||||
? { type: error.name, message: error.message }
|
||||
: { type: 'UnknownError', message: String(error) };
|
||||
|
||||
// Log error to database (fire and forget)
|
||||
logRequestMetadata({
|
||||
requestId: context.requestId,
|
||||
userId: options.userId,
|
||||
endpoint: options.endpoint,
|
||||
method: options.method,
|
||||
statusCode: 500,
|
||||
duration,
|
||||
errorType: errorInfo.type,
|
||||
errorMessage: errorInfo.message,
|
||||
userAgent: context.userAgent,
|
||||
clientVersion: context.clientVersion,
|
||||
parentRequestId: options.parentRequestId,
|
||||
traceId: context.traceId,
|
||||
}).catch(err => {
|
||||
console.error('[RequestTracking] Failed to log error metadata:', err);
|
||||
});
|
||||
|
||||
// Cleanup context
|
||||
requestContext.cleanup(context.requestId);
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
interface RequestMetadata {
|
||||
requestId: string;
|
||||
userId?: string;
|
||||
endpoint: string;
|
||||
method: string;
|
||||
statusCode: number;
|
||||
duration: number;
|
||||
errorType?: string;
|
||||
errorMessage?: string;
|
||||
userAgent?: string;
|
||||
clientVersion?: string;
|
||||
parentRequestId?: string;
|
||||
traceId?: string;
|
||||
}
|
||||
|
||||
async function logRequestMetadata(metadata: RequestMetadata): Promise<void> {
|
||||
await supabase.from('request_metadata').insert({
|
||||
request_id: metadata.requestId,
|
||||
user_id: metadata.userId || null,
|
||||
endpoint: metadata.endpoint,
|
||||
method: metadata.method,
|
||||
status_code: metadata.statusCode,
|
||||
duration_ms: metadata.duration,
|
||||
error_type: metadata.errorType || null,
|
||||
error_message: metadata.errorMessage || null,
|
||||
user_agent: metadata.userAgent || null,
|
||||
client_version: metadata.clientVersion || null,
|
||||
parent_request_id: metadata.parentRequestId || null,
|
||||
trace_id: metadata.traceId || null,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple wrapper for tracking without async operations
|
||||
*/
|
||||
export function createRequestContext(
|
||||
userId?: string,
|
||||
traceId?: string
|
||||
): RequestContext {
|
||||
return requestContext.create(userId, traceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request context for current operation
|
||||
*/
|
||||
export function getCurrentRequestContext(): RequestContext | undefined {
|
||||
return requestContext.getCurrentContext();
|
||||
}
|
||||
Reference in New Issue
Block a user