diff --git a/src/modules/admin-learning/admin-learning.controller.ts b/src/modules/admin-learning/admin-learning.controller.ts index 9f4db09..d1b78c1 100644 --- a/src/modules/admin-learning/admin-learning.controller.ts +++ b/src/modules/admin-learning/admin-learning.controller.ts @@ -16,6 +16,10 @@ export class AdminLearningController { @Query('endDate') endDate?: string, ) { return this.service.getDashboard({ knowledgeBaseId, startDate, endDate }); } + // ── Knowledge Bases ── + @Get('knowledge-bases') + async getKnowledgeBases() { return this.service.getKnowledgeBases(); } + // ── ReadingEvents ── @Get('reading-events') async getReadingEvents(@Query() query: EventFilterQuery) { return this.service.getReadingEvents(query); } diff --git a/src/modules/admin-learning/admin-learning.service.ts b/src/modules/admin-learning/admin-learning.service.ts index f1c8563..7300d35 100644 --- a/src/modules/admin-learning/admin-learning.service.ts +++ b/src/modules/admin-learning/admin-learning.service.ts @@ -9,6 +9,28 @@ export class AdminLearningService { private readonly snapshotBuilder: SnapshotBuilderService, ) {} + // ══ Knowledge Bases (for filter dropdown) ══ + + async getKnowledgeBases() { + // Return knowledge bases that appear in reading_events, with real names from KB table + const ids = await this.prisma.readingEvent.findMany({ + where: { knowledgeBaseId: { not: null } }, + select: { knowledgeBaseId: true }, + distinct: ['knowledgeBaseId'], + take: 200, + }); + const kbIds = [...new Set(ids.map(r => r.knowledgeBaseId!).filter(Boolean))]; + + if (kbIds.length === 0) return []; + + const kbs = await this.prisma.knowledgeBase.findMany({ + where: { id: { in: kbIds } }, + select: { id: true, title: true }, + take: 200, + }); + return kbs.map(kb => ({ id: kb.id, name: kb.title })); + } + // ══ Dashboard ══ async getDashboard(filters?: { knowledgeBaseId?: string; startDate?: string; endDate?: string }) {