feat: Add Compliance Wiki as internal admin knowledge base
Migration 040 with wiki_categories + wiki_articles tables, 10 seed articles across 8 categories (DSGVO, Art. 9, AVV, HinSchG etc.). Read-only FastAPI API, Next.js proxy, and two-column frontend with full-text search. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* retry logic, and optimistic locking support.
|
||||
*/
|
||||
|
||||
import { SDKState, CheckpointStatus, ProjectInfo } from './types'
|
||||
import { SDKState, CheckpointStatus, ProjectInfo, WikiCategory, WikiArticle, WikiSearchResult } from './types'
|
||||
|
||||
// =============================================================================
|
||||
// TYPES
|
||||
@@ -730,6 +730,110 @@ export class SDKApiClient {
|
||||
)
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// WIKI (read-only knowledge base)
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* List all wiki categories with article counts
|
||||
*/
|
||||
async listWikiCategories(): Promise<WikiCategory[]> {
|
||||
const data = await this.fetchWithRetry<{ categories: Array<{
|
||||
id: string; name: string; description: string; icon: string;
|
||||
sort_order: number; article_count: number
|
||||
}> }>(
|
||||
`${this.baseUrl}/wiki?endpoint=categories`,
|
||||
{ method: 'GET' }
|
||||
)
|
||||
return (data.categories || []).map(c => ({
|
||||
id: c.id,
|
||||
name: c.name,
|
||||
description: c.description,
|
||||
icon: c.icon,
|
||||
sortOrder: c.sort_order,
|
||||
articleCount: c.article_count,
|
||||
}))
|
||||
}
|
||||
|
||||
/**
|
||||
* List wiki articles, optionally filtered by category
|
||||
*/
|
||||
async listWikiArticles(categoryId?: string): Promise<WikiArticle[]> {
|
||||
const params = new URLSearchParams({ endpoint: 'articles' })
|
||||
if (categoryId) params.set('category_id', categoryId)
|
||||
const data = await this.fetchWithRetry<{ articles: Array<{
|
||||
id: string; category_id: string; category_name: string; title: string;
|
||||
summary: string; content: string; legal_refs: string[]; tags: string[];
|
||||
relevance: string; source_urls: string[]; version: number; updated_at: string
|
||||
}> }>(
|
||||
`${this.baseUrl}/wiki?${params.toString()}`,
|
||||
{ method: 'GET' }
|
||||
)
|
||||
return (data.articles || []).map(a => ({
|
||||
id: a.id,
|
||||
categoryId: a.category_id,
|
||||
categoryName: a.category_name,
|
||||
title: a.title,
|
||||
summary: a.summary,
|
||||
content: a.content,
|
||||
legalRefs: a.legal_refs || [],
|
||||
tags: a.tags || [],
|
||||
relevance: a.relevance as WikiArticle['relevance'],
|
||||
sourceUrls: a.source_urls || [],
|
||||
version: a.version,
|
||||
updatedAt: a.updated_at,
|
||||
}))
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single wiki article by ID
|
||||
*/
|
||||
async getWikiArticle(id: string): Promise<WikiArticle> {
|
||||
const data = await this.fetchWithRetry<{
|
||||
id: string; category_id: string; category_name: string; title: string;
|
||||
summary: string; content: string; legal_refs: string[]; tags: string[];
|
||||
relevance: string; source_urls: string[]; version: number; updated_at: string
|
||||
}>(
|
||||
`${this.baseUrl}/wiki?endpoint=article&id=${encodeURIComponent(id)}`,
|
||||
{ method: 'GET' }
|
||||
)
|
||||
return {
|
||||
id: data.id,
|
||||
categoryId: data.category_id,
|
||||
categoryName: data.category_name,
|
||||
title: data.title,
|
||||
summary: data.summary,
|
||||
content: data.content,
|
||||
legalRefs: data.legal_refs || [],
|
||||
tags: data.tags || [],
|
||||
relevance: data.relevance as WikiArticle['relevance'],
|
||||
sourceUrls: data.source_urls || [],
|
||||
version: data.version,
|
||||
updatedAt: data.updated_at,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Full-text search across wiki articles
|
||||
*/
|
||||
async searchWiki(query: string): Promise<WikiSearchResult[]> {
|
||||
const data = await this.fetchWithRetry<{ results: Array<{
|
||||
id: string; title: string; summary: string; category_name: string;
|
||||
relevance: string; highlight: string
|
||||
}> }>(
|
||||
`${this.baseUrl}/wiki?endpoint=search&q=${encodeURIComponent(query)}`,
|
||||
{ method: 'GET' }
|
||||
)
|
||||
return (data.results || []).map(r => ({
|
||||
id: r.id,
|
||||
title: r.title,
|
||||
summary: r.summary,
|
||||
categoryName: r.category_name,
|
||||
relevance: r.relevance,
|
||||
highlight: r.highlight,
|
||||
}))
|
||||
}
|
||||
|
||||
/**
|
||||
* Health check
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user