Files
stack/apps/api/src/knowledge/stats.controller.ts
Jason Woltje 26a334c677 feat: add knowledge graph views and stats (closes #73, closes #74)
Issue #73 - Entry-Centered Graph View:
- Added GET /api/knowledge/entries/:id/graph endpoint with depth parameter
- Returns entry + connected nodes with link relationships
- Created GraphService for graph traversal using BFS
- Added EntryGraphViewer component for frontend
- Integrated graph view tab into entry detail page

Issue #74 - Graph Statistics Dashboard:
- Added GET /api/knowledge/stats endpoint
- Returns overview stats (entries, tags, links by status)
- Includes most connected entries, recent activity, tag distribution
- Created StatsDashboard component with visual stats
- Added route at /knowledge/stats

Backend:
- GraphService: BFS-based graph traversal with configurable depth
- StatsService: Parallel queries for comprehensive statistics
- GraphQueryDto: Validation for depth parameter (1-5)
- Entity types for graph nodes/edges and statistics
- Unit tests for both services

Frontend:
- EntryGraphViewer: Entry-centered graph visualization
- StatsDashboard: Statistics overview with charts
- Graph view tab on entry detail page
- API client functions for new endpoints
- TypeScript strict typing throughout
2026-01-29 23:25:29 -06:00

26 lines
835 B
TypeScript

import { Controller, Get, UseGuards } from "@nestjs/common";
import { AuthGuard } from "../auth/guards/auth.guard";
import { WorkspaceGuard, PermissionGuard } from "../common/guards";
import { Workspace, RequirePermission, Permission } from "../common/decorators";
import { StatsService } from "./services";
/**
* Controller for knowledge statistics endpoints
*/
@Controller("knowledge/stats")
@UseGuards(AuthGuard, WorkspaceGuard, PermissionGuard)
export class KnowledgeStatsController {
constructor(private readonly statsService: StatsService) {}
/**
* GET /api/knowledge/stats
* Get knowledge base statistics
* Requires: Any workspace member
*/
@Get()
@RequirePermission(Permission.WORKSPACE_ANY)
async getStats(@Workspace() workspaceId: string) {
return this.statsService.getStats(workspaceId);
}
}