fix: resolve relationship error in admin dashboard

- Fetched api_usage and profiles separately to avoid Supabase join errors when relationships are not explicitly defined in the schema cache.
- Updated Gemini AI tracking integration to ensure all calls are recorded correctly.
- Improved error handling in admin dashboard.
This commit is contained in:
2025-12-18 15:43:40 +01:00
parent f25aad401e
commit 960fa89fc1

View File

@@ -29,30 +29,38 @@ export default async function AdminPage() {
// Fetch global API stats // Fetch global API stats
const stats = await getGlobalApiStats(); const stats = await getGlobalApiStats();
// Fetch recent API usage // Fetch recent API usage without join to avoid relationship errors
console.log('[Admin Page] Fetching recent API usage...'); console.log('[Admin Page] Fetching recent API usage...');
const { data: recentUsage, error: recentError } = await supabase const { data: recentUsageRaw, error: recentError } = await supabase
.from('api_usage') .from('api_usage')
.select(` .select('*')
*,
profiles:user_id (
username
)
`)
.order('created_at', { ascending: false }) .order('created_at', { ascending: false })
.limit(50); .limit(50);
console.log('[Admin Page] Recent usage - count:', recentUsage?.length, 'error:', recentError); console.log('[Admin Page] Recent usage raw - count:', recentUsageRaw?.length, 'error:', recentError);
// Get unique user IDs from recent usage
const recentUserIds = Array.from(new Set(recentUsageRaw?.map(u => u.user_id) || []));
// Fetch profiles for these users
const { data: recentProfiles } = recentUserIds.length > 0
? await supabase.from('profiles').select('id, username').in('id', recentUserIds)
: { data: [] };
// Combine usage with profiles
const recentUsage = recentUsageRaw?.map(usage => ({
...usage,
profiles: recentProfiles?.find(p => p.id === usage.user_id) || { username: 'Unknown' }
})) || [];
// Fetch per-user statistics // Fetch per-user statistics
const { data: userStats } = await supabase const { data: userStatsRaw } = await supabase
.from('api_usage') .from('api_usage')
.select('user_id, api_type') .select('user_id, api_type');
.order('created_at', { ascending: false });
// Group by user // Group by user
const userStatsMap = new Map<string, { googleSearch: number; geminiAi: number; total: number }>(); const userStatsMap = new Map<string, { googleSearch: number; geminiAi: number; total: number }>();
userStats?.forEach(item => { userStatsRaw?.forEach(item => {
const current = userStatsMap.get(item.user_id) || { googleSearch: 0, geminiAi: 0, total: 0 }; const current = userStatsMap.get(item.user_id) || { googleSearch: 0, geminiAi: 0, total: 0 };
if (item.api_type === 'google_search') current.googleSearch++; if (item.api_type === 'google_search') current.googleSearch++;
if (item.api_type === 'gemini_ai') current.geminiAi++; if (item.api_type === 'gemini_ai') current.geminiAi++;
@@ -66,10 +74,9 @@ export default async function AdminPage() {
.slice(0, 10) .slice(0, 10)
.map(([userId]) => userId); .map(([userId]) => userId);
const { data: topUsers } = await supabase const { data: topUsers } = topUserIds.length > 0
.from('profiles') ? await supabase.from('profiles').select('id, username').in('id', topUserIds)
.select('id, username') : { data: [] };
.in('id', topUserIds);
const topUsersWithStats = topUsers?.map(user => ({ const topUsersWithStats = topUsers?.map(user => ({
...user, ...user,