From cf20fa85db11e3258f74488c554836d4908ac13c Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Tue, 16 Jun 2026 23:36:49 +0200 Subject: [PATCH] =?UTF-8?q?feat(cra):=20'Projekt=20anlegen'=20aus=20Datenb?= =?UTF-8?q?latt=20=E2=86=92=20IACE=20mit=20editierbaren=20Grenzen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DatasheetExtract: Button legt ein IACE-Projekt an (POST /iace/projects) und speichert die extrahierten Grenzen + Rückfrage-Antworten als metadata.limits_form (PUT), dann Navigation ins Interview. Das Interview-Formular bleibt voll editierbar (jedes vorbefuellte Feld aenderbar, Auto-Save). Manuelles Anlegen ueber /sdk/iace bleibt unveraendert. Co-Authored-By: Claude Opus 4.7 --- .../sdk/cra/_components/DatasheetExtract.tsx | 52 +++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/admin-compliance/app/sdk/cra/_components/DatasheetExtract.tsx b/admin-compliance/app/sdk/cra/_components/DatasheetExtract.tsx index 2519456d..dae0adbb 100644 --- a/admin-compliance/app/sdk/cra/_components/DatasheetExtract.tsx +++ b/admin-compliance/app/sdk/cra/_components/DatasheetExtract.tsx @@ -1,6 +1,7 @@ 'use client' import { useState } from 'react' +import { useRouter } from 'next/navigation' import { DATASHEET_EXAMPLES } from './readiness-presets' interface Followup { key: string; label: string; question: string } @@ -27,9 +28,11 @@ const FIELD_LABEL: Record = { } export function DatasheetExtract() { + const router = useRouter() const [text, setText] = useState('') const [res, setRes] = useState(null) const [loading, setLoading] = useState(false) + const [creating, setCreating] = useState(false) const [answers, setAnswers] = useState>({}) const run = async () => { @@ -44,6 +47,39 @@ export function DatasheetExtract() { } finally { setLoading(false) } } + // Create an IACE project from the extracted limits + follow-up answers. The + // limits land as the project's editable limits_form; the interview form stays + // fully editable (every prefilled field can be changed). Manual creation via + // /sdk/iace remains unchanged. + const createProject = async () => { + if (!res) return + setCreating(true) + try { + const nonEmptyAnswers = Object.fromEntries( + Object.entries(answers).filter(([, v]) => (v || '').trim()), + ) + const limits = { ...res.limits, ...nonEmptyAnswers } + const machineName = limits.machine_designation || limits.machine_type || 'Neues Produkt' + const cr = await fetch('/api/sdk/v1/iace/projects', { + method: 'POST', headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + machine_name: machineName, + machine_type: limits.machine_type || '', + manufacturer: limits.manufacturer || '', + }), + }) + if (!cr.ok) return + const proj = await cr.json() + const pid = proj.id || proj.project_id + if (!pid) return + await fetch(`/api/sdk/v1/iace/projects/${pid}`, { + method: 'PUT', headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ metadata: { limits_form: limits } }), + }) + router.push(`/sdk/iace/${pid}/interview`) + } finally { setCreating(false) } + } + return (

Datenblatt-Analyse → Maschinengrenzen

@@ -129,9 +165,19 @@ export function DatasheetExtract() {
)} -

- Nächster Schritt: „Projekt anlegen" überträgt diese Grenzen + Antworten in das IACE-Modul; daraus - werden Gefährdungen und Maßnahmen abgeleitet (Entwurf — Bestätigung mit Sicherheitsingenieur). +

+ + + Übernimmt Grenzen + Antworten als editierbaren Entwurf ins + IACE-Interview — jedes Feld bleibt änderbar. Manuelles Anlegen weiterhin über{' '} + iACE. + +
+

+ Aus den Grenzen leitet IACE anschließend Gefährdungen und Maßnahmen ab (Entwurf — Bestätigung mit Sicherheitsingenieur).

)}