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
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:
@@ -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
|
||||
|
||||
|
||||
@@ -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',
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user