From 65b4857be5fda17a59e5bc103810926e78622154 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Tue, 12 May 2026 10:07:10 +0200 Subject: [PATCH] feat(iace): KI-Vorschlag Button im FMEA-Tab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Dropdown: Komponente waehlen → "KI-Vorschlag" klicken - Ruft POST /projects/:id/components/:cid/suggest-fms auf - Zeigt LLM-generierte oder Bibliotheks-FMs als Overlay - Jeder Vorschlag mit Name, Auswirkung, S/O/D, RPZ Co-Authored-By: Claude Opus 4.6 (1M context) --- .../iace/[projectId]/fmea/_hooks/useFMEA.ts | 28 ++++++++- .../app/sdk/iace/[projectId]/fmea/page.tsx | 63 ++++++++++++++++++- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/admin-compliance/app/sdk/iace/[projectId]/fmea/_hooks/useFMEA.ts b/admin-compliance/app/sdk/iace/[projectId]/fmea/_hooks/useFMEA.ts index f34d4d2..b95be21 100644 --- a/admin-compliance/app/sdk/iace/[projectId]/fmea/_hooks/useFMEA.ts +++ b/admin-compliance/app/sdk/iace/[projectId]/fmea/_hooks/useFMEA.ts @@ -130,5 +130,31 @@ export function useFMEA(projectId: string) { acceptable: rows.filter((r) => r.rpz <= 100).length, } - return { rows, loading, stats } + const [suggesting, setSuggesting] = useState(false) + const [suggestions, setSuggestions] = useState([]) + const [suggestSource, setSuggestSource] = useState('') + + async function suggestFMs(componentId: string) { + setSuggesting(true) + setSuggestions([]) + try { + const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}/components/${componentId}/suggest-fms`, { + method: 'POST', + }) + if (res.ok) { + const json = await res.json() + setSuggestions(json.suggestions || []) + setSuggestSource(json.source || 'unknown') + } + } catch (err) { + console.error('FM suggest failed:', err) + } finally { + setSuggesting(false) + } + } + + // Get unique components for the suggest button + const components = [...new Map(rows.map((r) => [r.component.id, r.component])).values()] + + return { rows, loading, stats, components, suggestFMs, suggesting, suggestions, suggestSource, setSuggestions } } diff --git a/admin-compliance/app/sdk/iace/[projectId]/fmea/page.tsx b/admin-compliance/app/sdk/iace/[projectId]/fmea/page.tsx index f70961c..44cb731 100644 --- a/admin-compliance/app/sdk/iace/[projectId]/fmea/page.tsx +++ b/admin-compliance/app/sdk/iace/[projectId]/fmea/page.tsx @@ -27,7 +27,8 @@ function rpzLabel(rpz: number): string { export default function FMEAPage() { const { projectId } = useParams<{ projectId: string }>() - const { rows, loading, stats } = useFMEA(projectId) + const { rows, loading, stats, components, suggestFMs, suggesting, suggestions, suggestSource, setSuggestions } = useFMEA(projectId) + const [suggestComp, setSuggestComp] = useState(null) if (loading) { return ( @@ -50,8 +51,35 @@ export default function FMEAPage() { {/* Info Box */} - {/* Export Button */} -
+ {/* KI-Vorschlag + Export */} +
+
+ + +
+
+ {/* Suggest Results */} + {suggestions.length > 0 && ( +
+
+

+ KI-Vorschlaege ({suggestions.length}) — {suggestSource === 'llm' ? 'LLM-generiert' : 'Bibliothek'} +

+ +
+
+ {suggestions.map((fm, i) => ( +
+
+
{fm.name_de}
+
{fm.effect}
+
+ S={fm.default_severity} + O={fm.default_occurrence} + D={fm.default_detection} + RPZ={fm.default_severity * fm.default_occurrence * fm.default_detection} +
+
+
+ ))} +
+
+ )} + {/* Stats */}