/** * Central Supabase Client Export with Automatic Breadcrumb Tracking * * All application code should import from this file instead of the base client. * This wrapper automatically tracks all database operations as breadcrumbs for error debugging. */ import { supabase as baseClient } from '@/integrations/supabase/client'; import { breadcrumb } from './errorBreadcrumbs'; type SupabaseClient = typeof baseClient; /** * Wrap Supabase client to automatically track API calls as breadcrumbs */ function wrapSupabaseClient(client: SupabaseClient): SupabaseClient { return new Proxy(client, { get(target, prop: string | symbol) { const value = target[prop as keyof typeof target]; // Only wrap 'from' and 'rpc' methods for database operations if ((prop === 'from' || prop === 'rpc') && typeof value === 'function') { return (...args: any[]) => { const result = (value as any).apply(target, args); const endpoint = prop === 'from' ? `/table/${args[0]}` : `/rpc/${args[0]}`; // Return a proxy for chained query methods return new Proxy(result, { get(queryTarget: any, queryProp: string | symbol) { const queryValue = queryTarget[queryProp]; // If it's a function, wrap it to track the call if (typeof queryValue === 'function') { return async (...queryArgs: any[]) => { try { const response = await queryValue.apply(queryTarget, queryArgs); // Log breadcrumb after response breadcrumb.apiCall( endpoint, String(queryProp).toUpperCase(), response.error ? 400 : 200 ); return response; } catch (error) { // Log breadcrumb for exceptions breadcrumb.apiCall(endpoint, String(queryProp).toUpperCase(), 500); throw error; } }; } return queryValue; } }); }; } return value; } }) as SupabaseClient; } export const supabase = wrapSupabaseClient(baseClient);