feat(iace): sync IACE frontend, API routes, and scope engine updates from breakpilot-pwa
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 35s
CI / test-python-backend-compliance (push) Successful in 29s
CI / test-python-document-crawler (push) Successful in 24s
CI / test-python-dsms-gateway (push) Successful in 21s

- Add IACE project pages (classification, evidence, hazards, mitigations, monitoring, tech-file, verification)
- Add IACE API catch-all route
- Update compliance-scope-engine with IACE AI Act product triggers
- Update compliance-scope-types, navigation, roles, and sidebar for IACE
- Update company-profile page
This commit is contained in:
Benjamin Boenisch
2026-02-25 23:03:03 +01:00
parent 5314db49e2
commit 03708d9e5b
18 changed files with 5565 additions and 110 deletions

View File

@@ -13,6 +13,7 @@ import type {
ScopeDocumentType,
DocumentScopeRequirement,
} from './compliance-scope-types'
import type { CompanyProfile, MachineBuilderProfile } from './types'
import {
getDepthLevelNumeric,
depthLevelFromNumeric,
@@ -786,6 +787,176 @@ export const HARD_TRIGGER_RULES: HardTriggerRule[] = [
legalReference: 'Art. 39 Abs. 1 lit. b DSGVO',
description: 'Fehlende Schulungen zum Datenschutz',
},
// ========== J: IACE — AI Act Produkt-Triggers (3 rules) ==========
{
id: 'HT-J01',
category: 'iace_ai_act_product',
questionId: 'machineBuilder.containsAI',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L3',
requiresDSFA: false,
mandatoryDocuments: ['VVT', 'TOM'],
legalReference: 'EU AI Act Annex I + EU Maschinenverordnung 2023/1230',
description: 'KI mit Sicherheitsfunktion in Maschine → AI Act High-Risk',
combineWithMachineBuilder: { field: 'hasSafetyFunction', value: true },
riskWeight: 9,
},
{
id: 'HT-J02',
category: 'iace_ai_act_product',
questionId: 'machineBuilder.containsAI',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L3',
requiresDSFA: false,
mandatoryDocuments: ['VVT', 'TOM'],
legalReference: 'EU AI Act + EU Maschinenverordnung 2023/1230',
description: 'Autonome KI in Maschine → AI Act + Maschinenverordnung',
combineWithMachineBuilder: { field: 'autonomousBehavior', value: true },
riskWeight: 8,
},
{
id: 'HT-J03',
category: 'iace_ai_act_product',
questionId: 'machineBuilder.hasSafetyFunction',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L3',
requiresDSFA: false,
mandatoryDocuments: ['VVT', 'TOM'],
legalReference: 'EU AI Act Annex III',
description: 'KI-Bildverarbeitung mit Sicherheitsbezug',
combineWithMachineBuilder: { field: 'aiIntegrationType', includes: 'vision' },
riskWeight: 8,
},
// ========== K: IACE — CRA Triggers (3 rules) ==========
{
id: 'HT-K01',
category: 'iace_cra',
questionId: 'machineBuilder.isNetworked',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L2',
requiresDSFA: false,
mandatoryDocuments: ['TOM'],
legalReference: 'EU Cyber Resilience Act (CRA)',
description: 'Vernetztes Produkt → Cyber Resilience Act',
riskWeight: 6,
},
{
id: 'HT-K02',
category: 'iace_cra',
questionId: 'machineBuilder.hasRemoteAccess',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L2',
requiresDSFA: false,
mandatoryDocuments: ['TOM'],
legalReference: 'CRA + NIS2 Art. 21',
description: 'Remote-Zugriff → CRA + NIS2 Supply Chain',
riskWeight: 7,
},
{
id: 'HT-K03',
category: 'iace_cra',
questionId: 'machineBuilder.hasOTAUpdates',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L2',
requiresDSFA: false,
mandatoryDocuments: ['TOM'],
legalReference: 'CRA Art. 10 - Patch Management',
description: 'OTA-Updates → CRA Patch Management Pflicht',
riskWeight: 7,
},
// ========== L: IACE — NIS2 indirekt (2 rules) ==========
{
id: 'HT-L01',
category: 'iace_nis2_indirect',
questionId: 'machineBuilder.criticalSectorClients',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L2',
requiresDSFA: false,
mandatoryDocuments: ['TOM'],
legalReference: 'NIS2 Art. 21 - Supply Chain',
description: 'Lieferant an KRITIS → NIS2 Supply Chain Anforderungen',
riskWeight: 7,
},
{
id: 'HT-L02',
category: 'iace_nis2_indirect',
questionId: 'machineBuilder.oemClients',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L2',
requiresDSFA: false,
mandatoryDocuments: [],
legalReference: 'NIS2 + EU Maschinenverordnung',
description: 'OEM-Zulieferer → Compliance-Nachweispflicht',
riskWeight: 5,
},
// ========== M: IACE — Maschinenverordnung Triggers (4 rules) ==========
{
id: 'HT-M01',
category: 'iace_machinery_regulation',
questionId: 'machineBuilder.containsSoftware',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L3',
requiresDSFA: false,
mandatoryDocuments: ['TOM'],
legalReference: 'EU Maschinenverordnung 2023/1230 Anhang III',
description: 'Software als Sicherheitskomponente → Maschinenverordnung',
combineWithMachineBuilder: { field: 'hasSafetyFunction', value: true },
riskWeight: 9,
},
{
id: 'HT-M02',
category: 'iace_machinery_regulation',
questionId: 'machineBuilder.ceMarkingRequired',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L2',
requiresDSFA: false,
mandatoryDocuments: [],
legalReference: 'EU Maschinenverordnung 2023/1230',
description: 'CE-Kennzeichnung erforderlich',
riskWeight: 6,
},
{
id: 'HT-M03',
category: 'iace_machinery_regulation',
questionId: 'machineBuilder.ceMarkingRequired',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L3',
requiresDSFA: false,
mandatoryDocuments: [],
legalReference: 'EU Maschinenverordnung 2023/1230 Art. 10',
description: 'CE ohne bestehende Risikobeurteilung → Dringend!',
combineWithMachineBuilder: { field: 'hasRiskAssessment', value: false },
riskWeight: 9,
},
{
id: 'HT-M04',
category: 'iace_machinery_regulation',
questionId: 'machineBuilder.containsFirmware',
condition: 'EQUALS',
conditionValue: true,
minimumLevel: 'L2',
requiresDSFA: false,
mandatoryDocuments: ['TOM'],
legalReference: 'EU Maschinenverordnung + CRA',
description: 'Firmware mit Remote-Update → Change Management Pflicht',
combineWithMachineBuilder: { field: 'hasOTAUpdates', value: true },
riskWeight: 7,
},
]
// ============================================================================
@@ -795,15 +966,16 @@ export const HARD_TRIGGER_RULES: HardTriggerRule[] = [
export class ComplianceScopeEngine {
/**
* Haupteinstiegspunkt: Evaluiert alle Profiling-Antworten und produziert eine ScopeDecision
* Optional: companyProfile fuer machineBuilder-basierte IACE Triggers
*/
evaluate(answers: ScopeProfilingAnswer[]): ScopeDecision {
evaluate(answers: ScopeProfilingAnswer[], companyProfile?: CompanyProfile | null): ScopeDecision {
const decision = createEmptyScopeDecision()
// 1. Scores berechnen
decision.scores = this.calculateScores(answers)
// 2. Hard Triggers prüfen
decision.triggeredHardTriggers = this.evaluateHardTriggers(answers)
// 2. Hard Triggers prüfen (inkl. IACE machineBuilder Triggers)
decision.triggeredHardTriggers = this.evaluateHardTriggers(answers, companyProfile)
// 3. Finales Level bestimmen
decision.determinedLevel = this.determineLevel(
@@ -934,13 +1106,14 @@ export class ComplianceScopeEngine {
/**
* Evaluiert Hard Trigger Rules
* Optional: companyProfile fuer machineBuilder-basierte IACE Triggers
*/
evaluateHardTriggers(answers: ScopeProfilingAnswer[]): TriggeredHardTrigger[] {
evaluateHardTriggers(answers: ScopeProfilingAnswer[], companyProfile?: CompanyProfile | null): TriggeredHardTrigger[] {
const triggered: TriggeredHardTrigger[] = []
const answerMap = new Map(answers.map((a) => [a.questionId, a.answerValue]))
for (const rule of HARD_TRIGGER_RULES) {
const isTriggered = this.checkTriggerCondition(rule, answerMap, answers)
const isTriggered = this.checkTriggerCondition(rule, answerMap, answers, companyProfile)
if (isTriggered) {
triggered.push({
@@ -958,14 +1131,61 @@ export class ComplianceScopeEngine {
return triggered
}
/**
* Liest einen Wert aus dem MachineBuilderProfile anhand eines Feldnamens
*/
private getMachineBuilderValue(mb: MachineBuilderProfile, field: string): unknown {
return (mb as Record<string, unknown>)[field]
}
/**
* Prüft, ob eine Trigger-Regel erfüllt ist
*/
private checkTriggerCondition(
rule: HardTriggerRule,
answerMap: Map<string, any>,
answers: ScopeProfilingAnswer[]
answers: ScopeProfilingAnswer[],
companyProfile?: CompanyProfile | null,
): boolean {
// IACE machineBuilder-basierte Triggers
if (rule.questionId.startsWith('machineBuilder.')) {
const mb = companyProfile?.machineBuilder
if (!mb) return false
const fieldName = rule.questionId.replace('machineBuilder.', '')
const fieldValue = this.getMachineBuilderValue(mb, fieldName)
if (fieldValue === undefined) return false
let baseCondition = false
switch (rule.condition) {
case 'EQUALS':
baseCondition = fieldValue === rule.conditionValue
break
case 'CONTAINS':
if (Array.isArray(fieldValue)) {
baseCondition = fieldValue.includes(rule.conditionValue)
}
break
default:
baseCondition = fieldValue === rule.conditionValue
}
if (!baseCondition) return false
// combineWithMachineBuilder: additional AND condition on another MB field
const combine = (rule as any).combineWithMachineBuilder
if (combine) {
const combineVal = this.getMachineBuilderValue(mb, combine.field)
if (combine.value !== undefined && combineVal !== combine.value) return false
if (combine.includes !== undefined) {
if (!Array.isArray(combineVal) || !combineVal.includes(combine.includes)) return false
}
}
return true
}
// Standard answer-based triggers
const answerValue = answerMap.get(rule.questionId)
if (answerValue === undefined) return false

View File

@@ -183,7 +183,8 @@ export type ScopeDocumentType =
| 'risikoanalyse' // Risikoanalyse
| 'notfallplan' // Notfall- & Krisenplan
| 'zertifizierung' // Zertifizierungsvorbereitung
| 'datenschutzmanagement'; // Datenschutzmanagement-System (DSMS)
| 'datenschutzmanagement' // Datenschutzmanagement-System (DSMS)
| 'iace_ce_assessment'; // CE-Risikobeurteilung SW/FW/KI (IACE)
// ============================================================================
// Decision & Output Types
@@ -412,6 +413,7 @@ export const DOCUMENT_TYPE_LABELS: Record<ScopeDocumentType, string> = {
notfallplan: 'Notfall- & Krisenplan',
zertifizierung: 'Zertifizierungsvorbereitung',
datenschutzmanagement: 'Datenschutzmanagement-System (DSMS)',
iace_ce_assessment: 'CE-Risikobeurteilung SW/FW/KI (IACE)',
};
/**
@@ -1246,6 +1248,54 @@ export const DOCUMENT_SCOPE_MATRIX: Record<ScopeDocumentType, DocumentScopeRequi
estimatedEffort: '24-40 Stunden',
},
},
iace_ce_assessment: {
L1: {
required: false,
depth: 'Minimal',
detailItems: [
'Regulatorischer Quick-Check fuer SW/FW/KI',
'Grundlegende Identifikation relevanter Vorschriften',
],
estimatedEffort: '2 Stunden',
},
L2: {
required: true,
depth: 'Standard',
detailItems: [
'CE-Risikobeurteilung fuer SW/FW-Komponenten',
'Hazard Log mit S×E×P Bewertung',
'CRA-Konformitaetspruefung',
'Grundlegende Massnahmendokumentation',
],
estimatedEffort: '8 Stunden',
},
L3: {
required: true,
depth: 'Detailliert',
detailItems: [
'Alle L2-Anforderungen',
'Vollstaendige CE-Akte inkl. KI-Dossier',
'AI Act High-Risk Konformitaetsbewertung',
'Maschinenverordnung Anhang III Nachweis',
'Verifikationsplan mit Akzeptanzkriterien',
'Evidence-Management fuer Testnachweise',
],
estimatedEffort: '16 Stunden',
},
L4: {
required: true,
depth: 'Audit-Ready',
detailItems: [
'Alle L3-Anforderungen',
'Zertifizierungsfertige CE-Dokumentation',
'Benannte-Stelle-tauglicher Nachweis',
'Revisionssichere Audit Trails',
'Post-Market Monitoring Plan',
'Continuous Compliance Framework',
],
estimatedEffort: '24 Stunden',
},
},
};
// ============================================================================
@@ -1273,6 +1323,7 @@ export const DOCUMENT_SDK_STEP_MAP: Partial<Record<ScopeDocumentType, string>> =
notfallplan: '/sdk/notfallplan',
zertifizierung: '/sdk/zertifizierung',
datenschutzmanagement: '/sdk/dsms',
iace_ce_assessment: '/sdk/iace',
};
// ============================================================================