Files
breakpilot-compliance/admin-compliance/app/(sdk)/sdk/document-generator/searchTemplates.ts
Benjamin Admin 7e5047290c
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 36s
CI / test-python-backend-compliance (push) Successful in 31s
CI / test-python-document-crawler (push) Successful in 23s
CI / test-python-dsms-gateway (push) Successful in 18s
feat: Dokumentengenerator — Vollständige Vorlage-Bibliothek + Frontend-Redesign
- Migration 020: Typ-Renames (data_processing_agreement→dpa, withdrawal_policy→widerruf) + 11 neue MIT-Templates (NDA DE/EN, SLA, AUP, Community Guidelines, Copyright Policy, Cloud Service Agreement, Data Usage Clause, Cookie Banner, AGB, Liability Clause)
- Backend: VALID_DOCUMENT_TYPES auf 16 Typen erweitert; /legal-templates/status nutzt jetzt dynamisches GROUP BY statt Hard-coded Felder
- searchTemplates.ts: loadAllTemplates() für Library-First UX
- page.tsx: Vollständig-Rewrite — Template-Bibliothek (immer sichtbar) mit Kategorie-Pills, Sprache-Toggle, optionaler Suche, Inline-Preview-Expand und Kachel-Grid; Generator-Section erscheint per Scroll wenn Vorlage gewählt
- Tests: 52/52 bestanden, TestLegalTemplateNewTypes (19 neue Tests) + aktualisierte Typ-Checks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 10:47:38 +01:00

172 lines
5.3 KiB
TypeScript

/**
* Template search helpers for document-generator.
*
* Two-tier search:
* 1. Primary: own backend (compliance_legal_templates DB) — MIT-licensed, curated
* 2. Fallback: RAG proxy (ai-compliance-sdk regulation search — law texts)
*/
import type { LegalTemplateResult } from '@/lib/sdk/types'
export const TEMPLATES_API = '/api/sdk/v1/compliance/legal-templates'
export const RAG_PROXY = '/api/sdk/v1/rag'
export interface TemplateSearchParams {
query: string
templateType?: string
licenseTypes?: string[]
language?: 'de' | 'en'
jurisdiction?: string
limit?: number
}
/**
* Search for legal templates.
*
* Tries own backend DB first (5 s timeout). Falls back to RAG proxy
* (regulation texts — useful as reference, but not ready-made templates).
* Returns an empty array if both services are down.
*/
export async function searchTemplates(
params: TemplateSearchParams
): Promise<LegalTemplateResult[]> {
// 1. Primary: own backend — compliance_legal_templates table
try {
const url = new URL(TEMPLATES_API, window.location.origin)
if (params.query) url.searchParams.set('query', params.query)
if (params.templateType) url.searchParams.set('document_type', params.templateType)
if (params.language) url.searchParams.set('language', params.language)
url.searchParams.set('limit', String(params.limit || 20))
url.searchParams.set('status', 'published')
const res = await fetch(url.toString(), { signal: AbortSignal.timeout(5000) })
if (res.ok) {
const data = await res.json()
return (data.templates || []).map(mapTemplateToResult)
}
} catch {
// Backend not reachable — fall through to RAG
}
// 2. Fallback: RAG proxy (Gesetzestexte — Referenz, kein fertiges Template)
try {
const res = await fetch(`${RAG_PROXY}/search`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: params.query || '', limit: params.limit || 10 }),
})
if (res.ok) {
const data = await res.json()
return (data.results || []).map((r: any, i: number) => ({
id: r.regulation_code || `rag-${i}`,
score: r.score ?? 0.5,
text: r.text || '',
documentTitle: r.regulation_name || r.regulation_short || 'Dokument',
templateType: 'regulation',
clauseCategory: null,
language: 'de',
jurisdiction: 'eu',
licenseId: null,
licenseName: null,
licenseUrl: null,
attributionRequired: false,
attributionText: null,
sourceName: 'RAG',
sourceUrl: null,
sourceRepo: null,
placeholders: [],
isCompleteDocument: false,
isModular: true,
requiresCustomization: true,
outputAllowed: true,
modificationAllowed: true,
distortionProhibited: false,
source: 'rag' as const,
}))
}
} catch {
// both services failed
}
return []
}
function mapTemplateToResult(r: any): LegalTemplateResult {
return {
id: r.id,
score: 1.0,
text: r.content || '',
documentTitle: r.title,
templateType: r.document_type,
clauseCategory: null,
language: r.language,
jurisdiction: r.jurisdiction,
licenseId: r.license_id as any,
licenseName: r.license_name,
licenseUrl: null,
attributionRequired: r.attribution_required ?? false,
attributionText: null,
sourceName: r.source_name,
sourceUrl: null,
sourceRepo: null,
placeholders: r.placeholders || [],
isCompleteDocument: r.is_complete_document ?? true,
isModular: false,
requiresCustomization: (r.placeholders || []).length > 0,
outputAllowed: true,
modificationAllowed: true,
distortionProhibited: false,
source: 'db' as const,
}
}
/**
* Load all published templates without requiring a search query.
* Used for the library-first UX (show all cards on initial load).
*/
export async function loadAllTemplates(limit = 200): Promise<LegalTemplateResult[]> {
try {
const url = new URL(TEMPLATES_API, window.location.origin)
url.searchParams.set('limit', String(limit))
url.searchParams.set('status', 'published')
const res = await fetch(url.toString(), { signal: AbortSignal.timeout(5000) })
if (res.ok) {
const data = await res.json()
return (data.templates || []).map(mapTemplateToResult)
}
} catch { /* ignore */ }
return []
}
export async function getTemplatesStatus(): Promise<any> {
try {
const res = await fetch(`${TEMPLATES_API}/status`, { signal: AbortSignal.timeout(5000) })
if (!res.ok) return null
return res.json()
} catch {
return null
}
}
export async function getSources(): Promise<any[]> {
try {
// Fetch status to get type counts for building source objects
const res = await fetch(`${TEMPLATES_API}/status`, { signal: AbortSignal.timeout(5000) })
if (!res.ok) return []
const data = await res.json()
const byType: Record<string, number> = data.by_type || {}
const activeTypes = Object.keys(byType).filter(k => byType[k] > 0)
return [
{
name: 'BreakPilot Compliance',
enabled: true,
license_type: 'mit' as const,
description: `${data.total || 0} selbst erstellte Vorlagen (MIT-Lizenz) — DE & EN`,
template_types: activeTypes,
},
]
} catch {
return []
}
}