fix: code review cleanup

- Added missing API functions: fetchKnowledgeStats, fetchEntryGraph
- Exported StatsDashboard and EntryGraphViewer components
- Replaced 'any' types with proper TypeScript types:
  * AuthUser for @CurrentUser parameters
  * Prisma.KnowledgeEntryWhereInput for where clauses
  * Prisma.KnowledgeEntryUpdateInput for update data
  * Prisma.TransactionClient for transaction parameters
- All TypeScript checks passing
- XSS protection verified in WikiLinkRenderer (escapeHtml function)
- Wiki-link parsing properly handles code blocks and escaping
This commit is contained in:
Jason Woltje
2026-01-30 00:12:13 -06:00
parent ee9663a1f6
commit 8a24c2f5fd
4 changed files with 99 additions and 8 deletions

View File

@@ -7,3 +7,5 @@ export { EntryViewer } from "./EntryViewer";
export { EntryEditor } from "./EntryEditor";
export { EntryMetadata } from "./EntryMetadata";
export { VersionHistory } from "./VersionHistory";
export { StatsDashboard } from "./StatsDashboard";
export { EntryGraphViewer } from "./EntryGraphViewer";

View File

@@ -230,6 +230,94 @@ export async function fetchBacklinks(slug: string): Promise<{
}>(`/api/knowledge/entries/${slug}/backlinks`);
}
/**
* Fetch knowledge base statistics
*/
export async function fetchKnowledgeStats(): Promise<{
overview: {
totalEntries: number;
totalTags: number;
totalLinks: number;
publishedEntries: number;
draftEntries: number;
archivedEntries: number;
};
mostConnected: Array<{
id: string;
slug: string;
title: string;
incomingLinks: number;
outgoingLinks: number;
totalConnections: number;
}>;
recentActivity: Array<{
id: string;
slug: string;
title: string;
updatedAt: string;
status: string;
}>;
tagDistribution: Array<{
id: string;
name: string;
slug: string;
color: string | null;
entryCount: number;
}>;
}> {
return apiGet(`/api/knowledge/stats`);
}
/**
* Fetch entry graph (network of connected entries)
*/
export async function fetchEntryGraph(
slug: string,
depth: number = 1
): Promise<{
centerNode: {
id: string;
slug: string;
title: string;
summary: string | null;
tags: Array<{
id: string;
name: string;
slug: string;
color: string | null;
}>;
depth: number;
};
nodes: Array<{
id: string;
slug: string;
title: string;
summary: string | null;
tags: Array<{
id: string;
name: string;
slug: string;
color: string | null;
}>;
depth: number;
}>;
edges: Array<{
id: string;
sourceId: string;
targetId: string;
linkText: string;
}>;
stats: {
totalNodes: number;
totalEdges: number;
maxDepth: number;
};
}> {
const params = new URLSearchParams();
params.append("depth", depth.toString());
return apiGet(`/api/knowledge/entries/${slug}/graph?${params.toString()}`);
}
/**
* Mock entries for development (until backend endpoints are ready)
*/