From 53a48ab6d55d139ad40817b36e894127a07b480a Mon Sep 17 00:00:00 2001 From: Jamie Brunton Date: Sat, 5 Sep 2026 17:02:07 +0100 Subject: [PATCH] fix(admin): use feature interest composite key --- apps/admin/src/lib/featureInterests.test.ts | 10 +++++++--- apps/admin/src/lib/featureInterests.ts | 6 ++++-- apps/admin/src/pages/DashboardPage.tsx | 5 +++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/apps/admin/src/lib/featureInterests.test.ts b/apps/admin/src/lib/featureInterests.test.ts index 9d4360e..f962c77 100644 --- a/apps/admin/src/lib/featureInterests.test.ts +++ b/apps/admin/src/lib/featureInterests.test.ts @@ -1,16 +1,20 @@ import { describe, expect, it } from 'vitest'; -import { formatFeatureName, toRecentFeatureInterest } from './featureInterests'; +import { featureInterestKey, formatFeatureName, toRecentFeatureInterest } from './featureInterests'; describe('toRecentFeatureInterest', () => { it('preserves the standalone API feature field for dashboard rendering', () => { const interest = toRecentFeatureInterest({ - id: 'interest-1', user_id: 'user-1', feature: 'better_chat', created_at: '2026-09-05T12:00:00.000Z', }); - expect(interest.feature).toBe('better_chat'); + expect(interest).toEqual({ + user_id: 'user-1', + feature: 'better_chat', + created_at: '2026-09-05T12:00:00.000Z', + }); expect(formatFeatureName(interest.feature)).toBe('Better Chat'); + expect(featureInterestKey(interest)).toBe('user-1:better_chat'); }); }); diff --git a/apps/admin/src/lib/featureInterests.ts b/apps/admin/src/lib/featureInterests.ts index 8193fee..4e73ecd 100644 --- a/apps/admin/src/lib/featureInterests.ts +++ b/apps/admin/src/lib/featureInterests.ts @@ -1,5 +1,4 @@ export interface FeatureInterestRow { - id: string; user_id: string; feature: string; created_at: string; @@ -16,13 +15,16 @@ export interface RecentFeatureInterest extends FeatureInterestRow { export function toRecentFeatureInterest(row: FeatureInterestRow): RecentFeatureInterest { return { - id: row.id, user_id: row.user_id, feature: row.feature, created_at: row.created_at, }; } +export function featureInterestKey(row: Pick): string { + return `${row.user_id}:${row.feature}`; +} + export function formatFeatureName(feature: string): string { return feature .split('_') diff --git a/apps/admin/src/pages/DashboardPage.tsx b/apps/admin/src/pages/DashboardPage.tsx index aecf042..28b2b41 100644 --- a/apps/admin/src/pages/DashboardPage.tsx +++ b/apps/admin/src/pages/DashboardPage.tsx @@ -12,6 +12,7 @@ import { useRealtimeSubscription } from '@/hooks/useRealtimeSubscription'; import { RealtimeStatusIndicator } from '@/components/RealtimeStatusIndicator'; import { formatFeatureName, + featureInterestKey, toRecentFeatureInterest, type FeatureInterestRow, type RecentFeatureInterest, @@ -80,7 +81,7 @@ export function DashboardPage() { ? adminData.from('feature_interests').select('created_at, user_id').gte('created_at', startDate.toISOString()).lte('created_at', endDate.toISOString()) : Promise.resolve({ data: [] }), canViewUsers - ? adminData.from('feature_interests').select('id, user_id, feature, created_at').order('created_at', { ascending: false }).limit(10) + ? adminData.from('feature_interests').select('user_id, feature, created_at').order('created_at', { ascending: false }).limit(10) : Promise.resolve({ data: [] }), ]); @@ -566,7 +567,7 @@ export function DashboardPage() { .toUpperCase(); return ( -
+