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
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...');
const { data: recentUsage, error: recentError } = await supabase
const { data: recentUsageRaw, error: recentError } = await supabase
.from('api_usage')
.select(`
*,
profiles:user_id (
username
)
`)
.select('*')
.order('created_at', { ascending: false })
.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
const { data: userStats } = await supabase
const { data: userStatsRaw } = await supabase
.from('api_usage')
.select('user_id, api_type')
.order('created_at', { ascending: false });
.select('user_id, api_type');
// Group by user
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 };
if (item.api_type === 'google_search') current.googleSearch++;
if (item.api_type === 'gemini_ai') current.geminiAi++;
@@ -66,10 +74,9 @@ export default async function AdminPage() {
.slice(0, 10)
.map(([userId]) => userId);
const { data: topUsers } = await supabase
.from('profiles')
.select('id, username')
.in('id', topUserIds);
const { data: topUsers } = topUserIds.length > 0
? await supabase.from('profiles').select('id, username').in('id', topUserIds)
: { data: [] };
const topUsersWithStats = topUsers?.map(user => ({
...user,
@@ -222,8 +229,8 @@ export default async function AdminPage() {
</td>
<td className="py-3 px-4">
<span className={`px-2 py-1 rounded-full text-xs font-bold ${call.api_type === 'google_search'
? 'bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-400'
: 'bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-400'
? 'bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-400'
: 'bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-400'
}`}>
{call.api_type === 'google_search' ? 'Google Search' : 'Gemini AI'}
</span>