feat: IACE CE-Compliance Module — Normen, Risikobewertung, Production Lines
Major features: - 215 norms library with section references + Beuth URLs (A/B1/B2/C norms) - 173 hazard patterns with detail fields (scenario, trigger, harm, zone) - Deterministic pattern matching: Component × Lifecycle × Pattern cross-product - SIL/PL auto-calculation from S×E×P risk graph - Risk assessment table with editable S/E/P dropdowns - Production Line Dashboard with animated station flow (Running Dots) - IACE process flow + norms coverage on start page - Non-blocking cookie banner, ProcessFlow SSR fix - 104 Playwright E2E tests passing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,15 +30,15 @@ async function proxyRequest(
|
|||||||
headers['Authorization'] = authHeader
|
headers['Authorization'] = authHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default tenant/user for IACE (same pattern as training proxy)
|
||||||
|
const DEFAULT_TENANT = process.env.DEFAULT_TENANT_ID || '9282a473-5c95-4b3a-bf78-0ecc0ec71d3e'
|
||||||
|
const DEFAULT_USER = '00000000-0000-0000-0000-000000000001'
|
||||||
|
|
||||||
const tenantHeader = request.headers.get('x-tenant-id')
|
const tenantHeader = request.headers.get('x-tenant-id')
|
||||||
if (tenantHeader) {
|
headers['X-Tenant-Id'] = tenantHeader || DEFAULT_TENANT
|
||||||
headers['X-Tenant-Id'] = tenantHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
const userHeader = request.headers.get('x-user-id')
|
const userHeader = request.headers.get('x-user-id')
|
||||||
if (userHeader) {
|
headers['X-User-Id'] = userHeader || DEFAULT_USER
|
||||||
headers['X-User-Id'] = userHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchOptions: RequestInit = {
|
const fetchOptions: RequestInit = {
|
||||||
method,
|
method,
|
||||||
|
|||||||
@@ -0,0 +1,258 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, { useState, useEffect, useRef, useCallback } from 'react'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { usePathname, useParams } from 'next/navigation'
|
||||||
|
|
||||||
|
interface CEStep {
|
||||||
|
step: number
|
||||||
|
label: string
|
||||||
|
href: string | null
|
||||||
|
external?: boolean
|
||||||
|
sameAs?: number
|
||||||
|
note?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const CE_STEPS: CEStep[] = [
|
||||||
|
{ step: 3, label: 'Grenzen & Verwendung', href: '/interview' },
|
||||||
|
{ step: 4, label: 'Normenrecherche', href: null, external: true },
|
||||||
|
{ step: 5, label: 'Komponenten', href: '/components' },
|
||||||
|
{ step: 6, label: 'Gefaehrdungen', href: '/hazards' },
|
||||||
|
{ step: 7, label: 'Risikobewertung', href: '/hazards', sameAs: 6 },
|
||||||
|
{ step: 8, label: 'Massnahmen', href: '/mitigations' },
|
||||||
|
{ step: 9, label: 'Nachweise', href: '/evidence' },
|
||||||
|
{ step: 10, label: 'Restrisiko', href: '/hazards', note: 'Reassessment' },
|
||||||
|
{ step: 11, label: 'Verifikation', href: '/verification' },
|
||||||
|
{ step: 14, label: 'CE-Akte', href: '/tech-file' },
|
||||||
|
]
|
||||||
|
|
||||||
|
function getNavigableSteps(basePath: string): CEStep[] {
|
||||||
|
return CE_STEPS.filter((s) => s.href !== null && !s.external)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function IACEFlowFAB() {
|
||||||
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
|
const panelRef = useRef<HTMLDivElement>(null)
|
||||||
|
const fabRef = useRef<HTMLButtonElement>(null)
|
||||||
|
const pathname = usePathname()
|
||||||
|
const params = useParams()
|
||||||
|
const projectId = params?.projectId as string
|
||||||
|
|
||||||
|
const basePath = `/sdk/iace/${projectId}`
|
||||||
|
|
||||||
|
const activeStepIndex = CE_STEPS.findIndex((s) => {
|
||||||
|
if (!s.href) return false
|
||||||
|
return pathname.startsWith(`${basePath}${s.href}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
const navigableSteps = getNavigableSteps(basePath)
|
||||||
|
const currentNavIndex = navigableSteps.findIndex((s) => {
|
||||||
|
if (!s.href) return false
|
||||||
|
return pathname.startsWith(`${basePath}${s.href}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
const completedCount = CE_STEPS.filter((s) => s.href && !s.external).length
|
||||||
|
const totalSteps = CE_STEPS.length
|
||||||
|
|
||||||
|
const handleClose = useCallback(() => setIsOpen(false), [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function onKeyDown(e: KeyboardEvent) {
|
||||||
|
if (e.key === 'Escape') handleClose()
|
||||||
|
}
|
||||||
|
function onClickOutside(e: MouseEvent) {
|
||||||
|
if (
|
||||||
|
panelRef.current &&
|
||||||
|
!panelRef.current.contains(e.target as Node) &&
|
||||||
|
fabRef.current &&
|
||||||
|
!fabRef.current.contains(e.target as Node)
|
||||||
|
) {
|
||||||
|
handleClose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isOpen) {
|
||||||
|
document.addEventListener('keydown', onKeyDown)
|
||||||
|
document.addEventListener('mousedown', onClickOutside)
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('keydown', onKeyDown)
|
||||||
|
document.removeEventListener('mousedown', onClickOutside)
|
||||||
|
}
|
||||||
|
}, [isOpen, handleClose])
|
||||||
|
|
||||||
|
const goPrev = () => {
|
||||||
|
if (currentNavIndex > 0) {
|
||||||
|
const prev = navigableSteps[currentNavIndex - 1]
|
||||||
|
if (prev.href) window.location.href = `${basePath}${prev.href}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const goNext = () => {
|
||||||
|
if (currentNavIndex < navigableSteps.length - 1) {
|
||||||
|
const next = navigableSteps[currentNavIndex + 1]
|
||||||
|
if (next.href) window.location.href = `${basePath}${next.href}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fixed bottom-6 right-6 z-50 flex flex-col items-end">
|
||||||
|
{/* Expanded Panel */}
|
||||||
|
<div
|
||||||
|
ref={panelRef}
|
||||||
|
className={`mb-3 w-[300px] max-h-[70vh] overflow-y-auto bg-white dark:bg-gray-800 rounded-xl shadow-2xl border border-gray-200 dark:border-gray-700 transition-all duration-200 origin-bottom-right ${
|
||||||
|
isOpen
|
||||||
|
? 'opacity-100 scale-100 translate-y-0'
|
||||||
|
: 'opacity-0 scale-95 translate-y-2 pointer-events-none'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{/* Header */}
|
||||||
|
<div className="sticky top-0 bg-white dark:bg-gray-800 px-4 py-3 border-b border-gray-100 dark:border-gray-700">
|
||||||
|
<h3 className="text-sm font-semibold text-gray-900 dark:text-white">
|
||||||
|
CE-Prozessschritte
|
||||||
|
</h3>
|
||||||
|
<p className="text-xs text-gray-500 mt-0.5">
|
||||||
|
{completedCount}/{totalSteps} Schritte im Tool
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Steps */}
|
||||||
|
<div className="py-2 px-2">
|
||||||
|
{CE_STEPS.map((step, idx) => {
|
||||||
|
const isActive = idx === activeStepIndex
|
||||||
|
const isExternal = step.external || step.href === null
|
||||||
|
const fullHref = step.href ? `${basePath}${step.href}` : null
|
||||||
|
|
||||||
|
const rowContent = (
|
||||||
|
<div
|
||||||
|
className={`flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors ${
|
||||||
|
isActive
|
||||||
|
? 'bg-purple-50 dark:bg-purple-900/40'
|
||||||
|
: isExternal
|
||||||
|
? 'opacity-50 cursor-default'
|
||||||
|
: 'hover:bg-gray-50 dark:hover:bg-gray-700/50 cursor-pointer'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{/* Step number circle */}
|
||||||
|
<div
|
||||||
|
className={`w-6 h-6 rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0 ${
|
||||||
|
isActive
|
||||||
|
? 'bg-purple-600 text-white'
|
||||||
|
: isExternal
|
||||||
|
? 'bg-gray-200 dark:bg-gray-600 text-gray-400 dark:text-gray-500'
|
||||||
|
: 'bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{isActive ? (
|
||||||
|
<span className="w-2 h-2 rounded-full bg-white" />
|
||||||
|
) : !isExternal ? (
|
||||||
|
<svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
|
||||||
|
</svg>
|
||||||
|
) : (
|
||||||
|
step.step
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Label */}
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<span
|
||||||
|
className={`block truncate font-medium ${
|
||||||
|
isActive
|
||||||
|
? 'text-purple-700 dark:text-purple-300'
|
||||||
|
: isExternal
|
||||||
|
? 'text-gray-400 dark:text-gray-500'
|
||||||
|
: 'text-gray-700 dark:text-gray-200'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{step.label}
|
||||||
|
</span>
|
||||||
|
{(step.note || isExternal) && (
|
||||||
|
<span className="text-[10px] text-gray-400">
|
||||||
|
{step.note || '(extern)'}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Step badge */}
|
||||||
|
<span className="text-[10px] text-gray-400 flex-shrink-0">
|
||||||
|
#{step.step}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
if (fullHref && !isExternal) {
|
||||||
|
return (
|
||||||
|
<Link key={idx} href={fullHref} onClick={handleClose}>
|
||||||
|
{rowContent}
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return <div key={idx}>{rowContent}</div>
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Prev/Next navigation */}
|
||||||
|
<div className="sticky bottom-0 bg-white dark:bg-gray-800 border-t border-gray-100 dark:border-gray-700 px-4 py-2.5 flex items-center justify-between">
|
||||||
|
<button
|
||||||
|
onClick={goPrev}
|
||||||
|
disabled={currentNavIndex <= 0}
|
||||||
|
className="flex items-center gap-1 text-xs font-medium text-purple-600 hover:text-purple-700 disabled:text-gray-300 disabled:cursor-not-allowed transition-colors"
|
||||||
|
>
|
||||||
|
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||||
|
</svg>
|
||||||
|
Zurueck
|
||||||
|
</button>
|
||||||
|
<span className="text-[10px] text-gray-400">
|
||||||
|
{currentNavIndex >= 0 ? currentNavIndex + 1 : '-'}/{navigableSteps.length}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
onClick={goNext}
|
||||||
|
disabled={currentNavIndex >= navigableSteps.length - 1 || currentNavIndex < 0}
|
||||||
|
className="flex items-center gap-1 text-xs font-medium text-purple-600 hover:text-purple-700 disabled:text-gray-300 disabled:cursor-not-allowed transition-colors"
|
||||||
|
>
|
||||||
|
Weiter
|
||||||
|
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* FAB Button */}
|
||||||
|
<button
|
||||||
|
ref={fabRef}
|
||||||
|
onClick={() => setIsOpen((o) => !o)}
|
||||||
|
className="w-14 h-14 rounded-full bg-gradient-to-br from-purple-600 to-indigo-600 text-white shadow-lg hover:shadow-xl hover:scale-105 active:scale-95 transition-all flex items-center justify-center"
|
||||||
|
title="CE-Prozessschritte"
|
||||||
|
>
|
||||||
|
{/* Steps/flow icon */}
|
||||||
|
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" />
|
||||||
|
</svg>
|
||||||
|
{/* Progress ring */}
|
||||||
|
<svg className="absolute w-14 h-14" viewBox="0 0 56 56">
|
||||||
|
<circle
|
||||||
|
cx="28"
|
||||||
|
cy="28"
|
||||||
|
r="25"
|
||||||
|
fill="none"
|
||||||
|
stroke="rgba(255,255,255,0.2)"
|
||||||
|
strokeWidth="3"
|
||||||
|
/>
|
||||||
|
<circle
|
||||||
|
cx="28"
|
||||||
|
cy="28"
|
||||||
|
r="25"
|
||||||
|
fill="none"
|
||||||
|
stroke="white"
|
||||||
|
strokeWidth="3"
|
||||||
|
strokeDasharray={`${(completedCount / totalSteps) * 157} 157`}
|
||||||
|
strokeLinecap="round"
|
||||||
|
transform="rotate(-90 28 28)"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
interface NormRef {
|
||||||
|
id: string
|
||||||
|
number: string
|
||||||
|
title_de: string
|
||||||
|
norm_type: string
|
||||||
|
scope_de: string
|
||||||
|
mandatory: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NormSuggestion {
|
||||||
|
norm: NormRef
|
||||||
|
reason: string
|
||||||
|
confidence: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NormResult {
|
||||||
|
a_norms: NormSuggestion[]
|
||||||
|
b1_norms: NormSuggestion[]
|
||||||
|
b2_norms: NormSuggestion[]
|
||||||
|
c_norms: NormSuggestion[]
|
||||||
|
total: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const TYPE_CONFIG: Record<string, { label: string; color: string; desc: string }> = {
|
||||||
|
a_norms: { label: 'A-Normen', color: 'border-red-200 bg-red-50 text-red-800', desc: 'Grundnormen (immer anwendbar)' },
|
||||||
|
b1_norms: { label: 'B1-Normen', color: 'border-blue-200 bg-blue-50 text-blue-800', desc: 'Sicherheitsgrundnormen' },
|
||||||
|
b2_norms: { label: 'B2-Normen', color: 'border-green-200 bg-green-50 text-green-800', desc: 'Sicherheitsfachgrundnormen' },
|
||||||
|
c_norms: { label: 'C-Normen', color: 'border-purple-200 bg-purple-50 text-purple-800', desc: 'Maschinenspezifische Normen' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SuggestedNorms({ projectId }: { projectId: string }) {
|
||||||
|
const [data, setData] = useState<NormResult | null>(null)
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [collapsed, setCollapsed] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(`/api/sdk/v1/iace/projects/${projectId}/suggested-norms`)
|
||||||
|
.then((r) => r.ok ? r.json() : null)
|
||||||
|
.then((json) => {
|
||||||
|
if (json?.suggestions) setData(json.suggestions)
|
||||||
|
else if (json?.a_norms !== undefined) setData(json)
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => setLoading(false))
|
||||||
|
}, [projectId])
|
||||||
|
|
||||||
|
if (loading) return null
|
||||||
|
if (!data || data.total === 0) return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700">
|
||||||
|
<button
|
||||||
|
onClick={() => setCollapsed(!collapsed)}
|
||||||
|
className="w-full flex items-center justify-between p-6 text-left"
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="w-10 h-10 bg-amber-50 rounded-lg flex items-center justify-center">
|
||||||
|
<svg className="w-5 h-5 text-amber-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2 className="text-sm font-semibold text-gray-900 dark:text-white">
|
||||||
|
Normenrecherche — {data.total} relevante Normen
|
||||||
|
</h2>
|
||||||
|
<p className="text-xs text-gray-500">
|
||||||
|
Automatisch ermittelt aus Maschinentyp, Gefaehrdungen und Komponenten
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<svg className={`w-5 h-5 text-gray-400 transition-transform ${collapsed ? '' : 'rotate-180'}`} fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{!collapsed && (
|
||||||
|
<div className="px-6 pb-6 space-y-4">
|
||||||
|
{/* Legend */}
|
||||||
|
<div className="flex flex-wrap gap-2 text-xs">
|
||||||
|
{Object.entries(TYPE_CONFIG).map(([key, cfg]) => (
|
||||||
|
<span key={key} className={`px-2 py-0.5 rounded border ${cfg.color}`}>{cfg.label}: {cfg.desc}</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Norm groups */}
|
||||||
|
{(['a_norms', 'b1_norms', 'b2_norms', 'c_norms'] as const).map((type) => {
|
||||||
|
const norms = data[type]
|
||||||
|
if (!norms || norms.length === 0) return null
|
||||||
|
const cfg = TYPE_CONFIG[type]
|
||||||
|
return (
|
||||||
|
<div key={type}>
|
||||||
|
<h3 className={`text-xs font-semibold px-2 py-1 rounded inline-block mb-2 border ${cfg.color}`}>
|
||||||
|
{cfg.label} ({norms.length})
|
||||||
|
</h3>
|
||||||
|
<div className="space-y-2">
|
||||||
|
{norms.map((s) => (
|
||||||
|
<div key={s.norm.id} className="flex items-start gap-3 p-3 rounded-lg bg-gray-50 dark:bg-gray-700/50 border border-gray-100 dark:border-gray-600">
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-sm font-mono font-semibold text-gray-900 dark:text-white">
|
||||||
|
{s.norm.number}
|
||||||
|
</span>
|
||||||
|
{s.norm.mandatory && (
|
||||||
|
<span className="px-1.5 py-0.5 text-xs font-medium bg-red-100 text-red-700 rounded">
|
||||||
|
Pflicht
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<span className="px-1.5 py-0.5 text-xs bg-gray-200 text-gray-600 rounded">
|
||||||
|
{Math.round(s.confidence * 100)}%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs text-gray-700 dark:text-gray-300 mt-0.5">{s.norm.title_de}</p>
|
||||||
|
<p className="text-xs text-gray-500 mt-1">{s.norm.scope_de}</p>
|
||||||
|
<p className="text-xs text-amber-600 mt-1">
|
||||||
|
Grund: {s.reason}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
|
||||||
|
{/* Disclaimer */}
|
||||||
|
<div className="p-3 rounded-lg bg-amber-50 border border-amber-200 text-xs text-amber-800">
|
||||||
|
<strong>Hinweis:</strong> Diese Normenvorschlaege basieren auf dem Maschinentyp und den identifizierten
|
||||||
|
Gefaehrdungen. Der CE-Fachmann muss die Anwendbarkeit pruefen und ggf. weitere Normen ergaenzen.
|
||||||
|
Nur Normennummern und -titel werden angezeigt — der Normtext muss separat beschafft werden (z.B. ueber Beuth/DIN).
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -115,7 +115,7 @@ export default function ComponentsPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
!c.showForm && (
|
!showForm && (
|
||||||
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-12 text-center">
|
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-12 text-center">
|
||||||
<div className="w-16 h-16 mx-auto bg-purple-100 dark:bg-purple-900/30 rounded-full flex items-center justify-center mb-4">
|
<div className="w-16 h-16 mx-auto bg-purple-100 dark:bg-purple-900/30 rounded-full flex items-center justify-center mb-4">
|
||||||
<svg className="w-8 h-8 text-purple-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg className="w-8 h-8 text-purple-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
@@ -132,7 +132,7 @@ export default function ComponentsPage() {
|
|||||||
className="px-6 py-3 border border-purple-300 text-purple-700 rounded-lg hover:bg-purple-50 transition-colors">
|
className="px-6 py-3 border border-purple-300 text-purple-700 rounded-lg hover:bg-purple-50 transition-colors">
|
||||||
Aus Bibliothek waehlen
|
Aus Bibliothek waehlen
|
||||||
</button>
|
</button>
|
||||||
<button onClick={() => c.setShowForm(true)}
|
<button onClick={() => setShowForm(true)}
|
||||||
className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors">
|
className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors">
|
||||||
Manuell hinzufuegen
|
Manuell hinzufuegen
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ export function AutoSuggestPanel({ matchResult, applying, onApply, onClose }: {
|
|||||||
onClose: () => void
|
onClose: () => void
|
||||||
}) {
|
}) {
|
||||||
const [selectedHazards, setSelectedHazards] = useState<Set<string>>(
|
const [selectedHazards, setSelectedHazards] = useState<Set<string>>(
|
||||||
new Set(matchResult.suggested_hazards.map(h => h.category))
|
new Set((matchResult.suggested_hazards || []).map(h => h.category))
|
||||||
)
|
)
|
||||||
const [selectedMeasures, setSelectedMeasures] = useState<Set<string>>(
|
const [selectedMeasures, setSelectedMeasures] = useState<Set<string>>(
|
||||||
new Set(matchResult.suggested_measures.map(m => m.measure_id))
|
new Set((matchResult.suggested_measures || []).map(m => m.measure_id))
|
||||||
)
|
)
|
||||||
const [selectedEvidence, setSelectedEvidence] = useState<Set<string>>(
|
const [selectedEvidence, setSelectedEvidence] = useState<Set<string>>(
|
||||||
new Set(matchResult.suggested_evidence.map(e => e.evidence_id))
|
new Set((matchResult.suggested_evidence || []).map(e => e.evidence_id))
|
||||||
)
|
)
|
||||||
|
|
||||||
function toggle<T>(set: Set<T>, setSet: (s: Set<T>) => void, key: T) {
|
function toggle<T>(set: Set<T>, setSet: (s: Set<T>) => void, key: T) {
|
||||||
|
|||||||
+274
@@ -0,0 +1,274 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useState, useEffect, useCallback } from 'react'
|
||||||
|
import {
|
||||||
|
Hazard, CATEGORY_LABELS, getRiskColor, getRiskLevelLabel, getRiskLevelISO,
|
||||||
|
} from './types'
|
||||||
|
|
||||||
|
interface RiskAssessmentTableProps {
|
||||||
|
projectId: string
|
||||||
|
hazards: Hazard[]
|
||||||
|
onReassess?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Editable S/E/P/A state per hazard for the "after measures" column. */
|
||||||
|
interface EditState {
|
||||||
|
severity: number; exposure: number; probability: number; avoidance: number
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function rpz(s: number, e: number, p: number, a: number): number {
|
||||||
|
return a >= 1 ? s * e * p * a : s * e * p
|
||||||
|
}
|
||||||
|
|
||||||
|
function plFromRpz(r: number): string {
|
||||||
|
if (r > 300) return 'e'
|
||||||
|
if (r >= 151) return 'd'
|
||||||
|
if (r >= 61) return 'c'
|
||||||
|
if (r >= 21) return 'b'
|
||||||
|
return 'a'
|
||||||
|
}
|
||||||
|
|
||||||
|
function silFromRpz(r: number): number {
|
||||||
|
if (r > 300) return 3
|
||||||
|
if (r >= 151) return 2
|
||||||
|
if (r >= 61) return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const PL_COLORS: Record<string, string> = {
|
||||||
|
e: 'bg-red-100 text-red-800', d: 'bg-orange-100 text-orange-800',
|
||||||
|
c: 'bg-yellow-100 text-yellow-800', b: 'bg-green-100 text-green-800',
|
||||||
|
a: 'bg-gray-100 text-gray-600',
|
||||||
|
}
|
||||||
|
|
||||||
|
const SIL_COLORS: Record<number, string> = {
|
||||||
|
3: 'bg-red-100 text-red-800', 2: 'bg-orange-100 text-orange-800',
|
||||||
|
1: 'bg-yellow-100 text-yellow-800', 0: 'bg-gray-100 text-gray-600',
|
||||||
|
}
|
||||||
|
|
||||||
|
const VALUES = [1, 2, 3, 4, 5]
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Inline editable dropdown
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function InlineSelect({ value, onChange, label }: {
|
||||||
|
value: number; onChange: (v: number) => void; label: string
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<select value={value} onChange={e => onChange(Number(e.target.value))}
|
||||||
|
aria-label={label}
|
||||||
|
className="w-12 text-center text-xs border border-gray-300 rounded bg-white dark:bg-gray-700 dark:border-gray-600 dark:text-white py-0.5 focus:ring-1 focus:ring-purple-400 focus:border-purple-400">
|
||||||
|
{VALUES.map(v => <option key={v} value={v}>{v}</option>)}
|
||||||
|
</select>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Main component
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export function RiskAssessmentTable({ projectId, hazards, onReassess }: RiskAssessmentTableProps) {
|
||||||
|
const [mitCounts, setMitCounts] = useState<Record<string, number>>({})
|
||||||
|
const [edits, setEdits] = useState<Record<string, EditState>>({})
|
||||||
|
const [saving, setSaving] = useState<string | null>(null)
|
||||||
|
|
||||||
|
// Fetch mitigation counts per hazard
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}/mitigations`)
|
||||||
|
if (!res.ok) return
|
||||||
|
const json = await res.json()
|
||||||
|
const mits: { hazard_id: string }[] = json.mitigations || json || []
|
||||||
|
const counts: Record<string, number> = {}
|
||||||
|
for (const m of mits) {
|
||||||
|
counts[m.hazard_id] = (counts[m.hazard_id] || 0) + 1
|
||||||
|
}
|
||||||
|
setMitCounts(counts)
|
||||||
|
} catch { /* ignore */ }
|
||||||
|
})()
|
||||||
|
}, [projectId])
|
||||||
|
|
||||||
|
// Initialise edit state from hazard defaults
|
||||||
|
useEffect(() => {
|
||||||
|
const init: Record<string, EditState> = {}
|
||||||
|
for (const h of hazards) {
|
||||||
|
if (!edits[h.id]) {
|
||||||
|
// Read from risk_assessment if available (enriched response), fallback to hazard fields
|
||||||
|
const ra = (h as Record<string, unknown>).risk_assessment as Record<string, number> | null
|
||||||
|
init[h.id] = {
|
||||||
|
severity: ra?.severity || h.severity || 3,
|
||||||
|
exposure: ra?.exposure || h.exposure || 3,
|
||||||
|
probability: ra?.probability || h.probability || 3,
|
||||||
|
avoidance: h.avoidance || 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Object.keys(init).length > 0) setEdits(prev => ({ ...prev, ...init }))
|
||||||
|
}, [hazards]) // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
|
const updateEdit = useCallback((id: string, field: keyof EditState, value: number) => {
|
||||||
|
setEdits(prev => ({ ...prev, [id]: { ...prev[id], [field]: value } }))
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
async function handleReassess(hazardId: string) {
|
||||||
|
const e = edits[hazardId]
|
||||||
|
if (!e) return
|
||||||
|
setSaving(hazardId)
|
||||||
|
try {
|
||||||
|
const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}/hazards/${hazardId}/reassess`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
hazard_id: hazardId, severity: e.severity, exposure: e.exposure,
|
||||||
|
probability: e.probability, avoidance: e.avoidance,
|
||||||
|
control_maturity: 3, control_coverage: 0.5, test_evidence_strength: 0.5,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
if (res.ok) onReassess?.()
|
||||||
|
} catch (err) { console.error('Reassess failed:', err) }
|
||||||
|
finally { setSaving(null) }
|
||||||
|
}
|
||||||
|
|
||||||
|
const sorted = [...hazards].sort((a, b) => (b.r_inherent || 0) - (a.r_inherent || 0))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden">
|
||||||
|
<div className="px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
|
||||||
|
<h2 className="text-sm font-semibold text-gray-900 dark:text-white">Risikobewertungstabelle (ISO 12100)</h2>
|
||||||
|
<span className="text-xs text-gray-500">{hazards.length} Gefaehrdungen</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="overflow-x-auto">
|
||||||
|
<table className="w-full text-xs whitespace-nowrap">
|
||||||
|
<thead>
|
||||||
|
{/* Group header */}
|
||||||
|
<tr className="bg-gray-100 dark:bg-gray-750 border-b border-gray-200 dark:border-gray-700">
|
||||||
|
<th colSpan={2} className="px-3 py-1.5 text-left font-semibold text-gray-700 dark:text-gray-300 border-r border-gray-200 dark:border-gray-600">Gefaehrdung</th>
|
||||||
|
<th colSpan={5} className="px-3 py-1.5 text-center font-semibold text-gray-700 dark:text-gray-300 border-r border-gray-200 dark:border-gray-600">Erstbewertung</th>
|
||||||
|
<th colSpan={6} className="px-3 py-1.5 text-center font-semibold text-purple-700 dark:text-purple-400 border-r border-gray-200 dark:border-gray-600">Nach Massnahmen (editierbar)</th>
|
||||||
|
<th colSpan={2} className="px-3 py-1.5 text-center font-semibold text-gray-700 dark:text-gray-300 border-r border-gray-200 dark:border-gray-600">SIL / PL</th>
|
||||||
|
<th colSpan={2} className="px-3 py-1.5 text-center font-semibold text-gray-700 dark:text-gray-300">Status</th>
|
||||||
|
</tr>
|
||||||
|
{/* Column header */}
|
||||||
|
<tr className="bg-gray-50 dark:bg-gray-750 border-b border-gray-200 dark:border-gray-700">
|
||||||
|
<th className="px-3 py-2 text-left font-medium text-gray-500 uppercase tracking-wider">Bezeichnung</th>
|
||||||
|
<th className="px-3 py-2 text-left font-medium text-gray-500 uppercase tracking-wider border-r border-gray-200 dark:border-gray-600">Kategorie</th>
|
||||||
|
{/* Initial */}
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-gray-500">S</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-gray-500">E</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-gray-500">P</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-gray-500">RPZ</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-gray-500 border-r border-gray-200 dark:border-gray-600">Risiko</th>
|
||||||
|
{/* After */}
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-purple-600">S</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-purple-600">E</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-purple-600">P</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-purple-600">RPZ</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-purple-600">Risiko</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-purple-600 border-r border-gray-200 dark:border-gray-600"></th>
|
||||||
|
{/* SIL/PL */}
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-gray-500">SIL</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-gray-500 border-r border-gray-200 dark:border-gray-600">PL</th>
|
||||||
|
{/* Status */}
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-gray-500">Massn.</th>
|
||||||
|
<th className="px-2 py-2 text-center font-medium text-gray-500">Akzeptabel</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="divide-y divide-gray-100 dark:divide-gray-700">
|
||||||
|
{sorted.map(h => {
|
||||||
|
const e = edits[h.id]
|
||||||
|
const initRpz = h.r_inherent || rpz(h.severity, h.exposure, h.probability, h.avoidance)
|
||||||
|
const afterRpz = e ? rpz(e.severity, e.exposure, e.probability, e.avoidance) : initRpz
|
||||||
|
const afterLevel = getRiskLevelISO(afterRpz)
|
||||||
|
const sil = silFromRpz(afterRpz)
|
||||||
|
const pl = plFromRpz(afterRpz)
|
||||||
|
const mc = mitCounts[h.id] || 0
|
||||||
|
const changed = e && (e.severity !== h.severity || e.exposure !== h.exposure || e.probability !== h.probability || e.avoidance !== (h.avoidance || 3))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr key={h.id} className="hover:bg-gray-50 dark:hover:bg-gray-750 transition-colors">
|
||||||
|
{/* Hazard info */}
|
||||||
|
<td className="px-3 py-2 max-w-[200px]">
|
||||||
|
<div className="font-medium text-gray-900 dark:text-white truncate">{h.name}</div>
|
||||||
|
{h.component_name && <div className="text-[10px] text-gray-400 truncate">{h.component_name}</div>}
|
||||||
|
</td>
|
||||||
|
<td className="px-3 py-2 border-r border-gray-200 dark:border-gray-600">
|
||||||
|
<span className="inline-block px-1.5 py-0.5 rounded bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 text-[10px] font-medium">
|
||||||
|
{CATEGORY_LABELS[h.category] || h.category}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
{/* Initial S/E/P/RPZ/Risk */}
|
||||||
|
<td className="px-2 py-2 text-center text-gray-700 dark:text-gray-300">{h.severity}</td>
|
||||||
|
<td className="px-2 py-2 text-center text-gray-700 dark:text-gray-300">{h.exposure}</td>
|
||||||
|
<td className="px-2 py-2 text-center text-gray-700 dark:text-gray-300">{h.probability}</td>
|
||||||
|
<td className="px-2 py-2 text-center font-bold text-gray-900 dark:text-white">{initRpz}</td>
|
||||||
|
<td className="px-2 py-2 text-center border-r border-gray-200 dark:border-gray-600">
|
||||||
|
<span className={`inline-block px-1.5 py-0.5 rounded-full text-[10px] font-medium border ${getRiskColor(h.risk_level)}`}>
|
||||||
|
{getRiskLevelLabel(h.risk_level)}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
{/* After measures (editable) */}
|
||||||
|
<td className="px-1 py-2 text-center">{e && <InlineSelect value={e.severity} onChange={v => updateEdit(h.id, 'severity', v)} label="S nach" />}</td>
|
||||||
|
<td className="px-1 py-2 text-center">{e && <InlineSelect value={e.exposure} onChange={v => updateEdit(h.id, 'exposure', v)} label="E nach" />}</td>
|
||||||
|
<td className="px-1 py-2 text-center">{e && <InlineSelect value={e.probability} onChange={v => updateEdit(h.id, 'probability', v)} label="P nach" />}</td>
|
||||||
|
<td className="px-2 py-2 text-center font-bold text-purple-900 dark:text-purple-300">{afterRpz}</td>
|
||||||
|
<td className="px-2 py-2 text-center">
|
||||||
|
<span className={`inline-block px-1.5 py-0.5 rounded-full text-[10px] font-medium border ${getRiskColor(afterLevel)}`}>
|
||||||
|
{getRiskLevelLabel(afterLevel)}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className="px-1 py-2 text-center border-r border-gray-200 dark:border-gray-600">
|
||||||
|
{changed && (
|
||||||
|
<button onClick={() => handleReassess(h.id)} disabled={saving === h.id}
|
||||||
|
className="px-1.5 py-0.5 bg-purple-600 text-white rounded text-[10px] hover:bg-purple-700 disabled:opacity-50 transition-colors">
|
||||||
|
{saving === h.id ? '...' : 'Speichern'}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
{/* SIL / PL */}
|
||||||
|
<td className="px-2 py-2 text-center">
|
||||||
|
<span className={`inline-block px-1.5 py-0.5 rounded text-[10px] font-bold ${SIL_COLORS[sil]}`}>
|
||||||
|
{sil > 0 ? `SIL ${sil}` : '-'}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className="px-2 py-2 text-center border-r border-gray-200 dark:border-gray-600">
|
||||||
|
<span className={`inline-block px-1.5 py-0.5 rounded text-[10px] font-bold ${PL_COLORS[pl]}`}>
|
||||||
|
PL {pl}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
{/* Status */}
|
||||||
|
<td className="px-2 py-2 text-center">
|
||||||
|
<span className={`inline-block px-1.5 py-0.5 rounded text-[10px] font-medium ${mc > 0 ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 text-gray-500'}`}>
|
||||||
|
{mc}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className="px-2 py-2 text-center">
|
||||||
|
{afterRpz <= 20 ? (
|
||||||
|
<span className="inline-block w-4 h-4 rounded-full bg-green-500 text-white text-[10px] leading-4 text-center" title="Akzeptabel">✓</span>
|
||||||
|
) : afterRpz <= 60 ? (
|
||||||
|
<span className="inline-block w-4 h-4 rounded-full bg-yellow-400 text-yellow-900 text-[10px] leading-4 text-center" title="Bedingt">≈</span>
|
||||||
|
) : (
|
||||||
|
<span className="inline-block w-4 h-4 rounded-full bg-red-500 text-white text-[10px] leading-4 text-center" title="Nicht akzeptabel">✗</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{hazards.length === 0 && (
|
||||||
|
<div className="px-4 py-8 text-center text-sm text-gray-500">
|
||||||
|
Keine Gefaehrdungen vorhanden. Fuegen Sie zuerst Gefaehrdungen hinzu.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -169,5 +169,6 @@ export function useHazards(projectId: string) {
|
|||||||
suggestingAI, matchingPatterns, matchResult, setMatchResult, applyingPatterns,
|
suggestingAI, matchingPatterns, matchResult, setMatchResult, applyingPatterns,
|
||||||
fetchLibrary, handleAddFromLibrary, handleSubmit,
|
fetchLibrary, handleAddFromLibrary, handleSubmit,
|
||||||
handleAISuggestions, handlePatternMatching, handleApplyPatterns, handleDelete,
|
handleAISuggestions, handlePatternMatching, handleApplyPatterns, handleDelete,
|
||||||
|
refetch: fetchHazards,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import React from 'react'
|
import React, { useState } from 'react'
|
||||||
import { useParams } from 'next/navigation'
|
import { useParams } from 'next/navigation'
|
||||||
import { HazardForm } from './_components/HazardForm'
|
import { HazardForm } from './_components/HazardForm'
|
||||||
import { HazardTable } from './_components/HazardTable'
|
import { HazardTable } from './_components/HazardTable'
|
||||||
|
import { RiskAssessmentTable } from './_components/RiskAssessmentTable'
|
||||||
import { LibraryModal } from './_components/LibraryModal'
|
import { LibraryModal } from './_components/LibraryModal'
|
||||||
import { AutoSuggestPanel } from './_components/AutoSuggestPanel'
|
import { AutoSuggestPanel } from './_components/AutoSuggestPanel'
|
||||||
import { useHazards } from './_hooks/useHazards'
|
import { useHazards } from './_hooks/useHazards'
|
||||||
|
|
||||||
|
type ViewMode = 'list' | 'risk'
|
||||||
|
|
||||||
export default function HazardsPage() {
|
export default function HazardsPage() {
|
||||||
const params = useParams()
|
const params = useParams()
|
||||||
const projectId = params.projectId as string
|
const projectId = params.projectId as string
|
||||||
const h = useHazards(projectId)
|
const h = useHazards(projectId)
|
||||||
|
const [view, setView] = useState<ViewMode>('list')
|
||||||
|
|
||||||
if (h.loading) {
|
if (h.loading) {
|
||||||
return (
|
return (
|
||||||
@@ -29,6 +33,16 @@ export default function HazardsPage() {
|
|||||||
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
Gefaehrdungsanalyse mit 4-Faktor-Risikobewertung (S x F x P x A).
|
Gefaehrdungsanalyse mit 4-Faktor-Risikobewertung (S x F x P x A).
|
||||||
</p>
|
</p>
|
||||||
|
<div className="mt-2 flex rounded-lg border border-gray-200 dark:border-gray-600 overflow-hidden text-xs">
|
||||||
|
<button onClick={() => setView('list')}
|
||||||
|
className={`px-3 py-1.5 font-medium transition-colors ${view === 'list' ? 'bg-purple-600 text-white' : 'bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-50'}`}>
|
||||||
|
Hazard-Liste
|
||||||
|
</button>
|
||||||
|
<button onClick={() => setView('risk')}
|
||||||
|
className={`px-3 py-1.5 font-medium transition-colors border-l border-gray-200 dark:border-gray-600 ${view === 'risk' ? 'bg-purple-600 text-white' : 'bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-50'}`}>
|
||||||
|
Risikobewertung
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<button onClick={h.handlePatternMatching} disabled={h.matchingPatterns}
|
<button onClick={h.handlePatternMatching} disabled={h.matchingPatterns}
|
||||||
@@ -70,12 +84,12 @@ export default function HazardsPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{h.matchResult && h.matchResult.matched_patterns.length > 0 && (
|
{h.matchResult && h.matchResult.matched_patterns?.length > 0 && (
|
||||||
<AutoSuggestPanel projectId={projectId} matchResult={h.matchResult} applying={h.applyingPatterns}
|
<AutoSuggestPanel projectId={projectId} matchResult={h.matchResult} applying={h.applyingPatterns}
|
||||||
onApply={h.handleApplyPatterns} onClose={() => h.setMatchResult(null)} />
|
onApply={h.handleApplyPatterns} onClose={() => h.setMatchResult(null)} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{h.matchResult && h.matchResult.matched_patterns.length === 0 && (
|
{h.matchResult && (!h.matchResult.matched_patterns || h.matchResult.matched_patterns.length === 0) && (
|
||||||
<div className="bg-yellow-50 border border-yellow-200 rounded-xl p-4 flex items-start gap-3">
|
<div className="bg-yellow-50 border border-yellow-200 rounded-xl p-4 flex items-start gap-3">
|
||||||
<svg className="w-5 h-5 text-yellow-600 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg className="w-5 h-5 text-yellow-600 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
@@ -121,7 +135,11 @@ export default function HazardsPage() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{h.hazards.length > 0 ? (
|
{h.hazards.length > 0 ? (
|
||||||
|
view === 'risk' ? (
|
||||||
|
<RiskAssessmentTable projectId={projectId} hazards={h.hazards} onReassess={h.refetch} />
|
||||||
|
) : (
|
||||||
<HazardTable hazards={h.hazards} lifecyclePhases={h.lifecyclePhases} onDelete={h.handleDelete} />
|
<HazardTable hazards={h.hazards} lifecyclePhases={h.lifecyclePhases} onDelete={h.handleDelete} />
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
!h.showForm && (
|
!h.showForm && (
|
||||||
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-12 text-center">
|
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-12 text-center">
|
||||||
|
|||||||
+3
-3
@@ -16,8 +16,8 @@ export function MitigationCard({
|
|||||||
<div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4">
|
<div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4">
|
||||||
<div className="flex items-start justify-between mb-2">
|
<div className="flex items-start justify-between mb-2">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<h4 className="text-sm font-medium text-gray-900 dark:text-white">{mitigation.title}</h4>
|
<h4 className="text-sm font-medium text-gray-900 dark:text-white">{mitigation.title || ''}</h4>
|
||||||
{mitigation.title.startsWith('Auto:') && (
|
{(mitigation.title || '').startsWith('Auto:') && (
|
||||||
<span className="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-green-100 text-green-700">
|
<span className="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-green-100 text-green-700">
|
||||||
Auto
|
Auto
|
||||||
</span>
|
</span>
|
||||||
@@ -28,7 +28,7 @@ export function MitigationCard({
|
|||||||
{mitigation.description && (
|
{mitigation.description && (
|
||||||
<p className="text-xs text-gray-500 mb-3">{mitigation.description}</p>
|
<p className="text-xs text-gray-500 mb-3">{mitigation.description}</p>
|
||||||
)}
|
)}
|
||||||
{mitigation.linked_hazard_names.length > 0 && (
|
{(mitigation.linked_hazard_names || []).length > 0 && (
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<div className="flex flex-wrap gap-1">
|
<div className="flex flex-wrap gap-1">
|
||||||
{mitigation.linked_hazard_names.map((name, i) => (
|
{mitigation.linked_hazard_names.map((name, i) => (
|
||||||
|
|||||||
@@ -20,15 +20,33 @@ export function useMitigations(projectId: string) {
|
|||||||
fetch(`/api/sdk/v1/iace/projects/${projectId}/mitigations`),
|
fetch(`/api/sdk/v1/iace/projects/${projectId}/mitigations`),
|
||||||
fetch(`/api/sdk/v1/iace/projects/${projectId}/hazards`),
|
fetch(`/api/sdk/v1/iace/projects/${projectId}/hazards`),
|
||||||
])
|
])
|
||||||
if (mitRes.ok) {
|
let hazardList: Hazard[] = []
|
||||||
const json = await mitRes.json()
|
|
||||||
const mits = json.mitigations || json || []
|
|
||||||
setMitigations(mits)
|
|
||||||
validateHierarchy(mits)
|
|
||||||
}
|
|
||||||
if (hazRes.ok) {
|
if (hazRes.ok) {
|
||||||
const json = await hazRes.json()
|
const json = await hazRes.json()
|
||||||
setHazards((json.hazards || json || []).map((h: Hazard) => ({ id: h.id, name: h.name, risk_level: h.risk_level, category: h.category })))
|
hazardList = (json.hazards || json || []).map((h: Hazard) => ({ id: h.id, name: h.name, risk_level: h.risk_level, category: h.category }))
|
||||||
|
setHazards(hazardList)
|
||||||
|
}
|
||||||
|
if (mitRes.ok) {
|
||||||
|
const json = await mitRes.json()
|
||||||
|
const raw = json.mitigations || json || []
|
||||||
|
// Map API fields (name, hazard_id) to frontend fields (title, linked_hazard_ids/names)
|
||||||
|
const hazardMap = Object.fromEntries(hazardList.map((h) => [h.id, h.name]))
|
||||||
|
const mits: Mitigation[] = raw.map((m: Record<string, unknown>) => ({
|
||||||
|
id: m.id as string,
|
||||||
|
title: (m.title || m.name || '') as string,
|
||||||
|
description: (m.description || '') as string,
|
||||||
|
reduction_type: (m.reduction_type === 'protective' ? 'protection' : m.reduction_type || 'design') as Mitigation['reduction_type'],
|
||||||
|
status: (m.status || 'planned') as Mitigation['status'],
|
||||||
|
linked_hazard_ids: m.linked_hazard_ids ? (m.linked_hazard_ids as string[]) : m.hazard_id ? [m.hazard_id as string] : [],
|
||||||
|
linked_hazard_names: m.linked_hazard_ids
|
||||||
|
? (m.linked_hazard_ids as string[]).map((id) => hazardMap[id] || id)
|
||||||
|
: m.hazard_id ? [hazardMap[m.hazard_id as string] || (m.hazard_id as string)] : [],
|
||||||
|
created_at: (m.created_at || '') as string,
|
||||||
|
verified_at: (m.verified_at || null) as string | null,
|
||||||
|
verified_by: (m.verified_by || null) as string | null,
|
||||||
|
}))
|
||||||
|
setMitigations(mits)
|
||||||
|
validateHierarchy(mits)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to fetch data:', err)
|
console.error('Failed to fetch data:', err)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useParams } from 'next/navigation'
|
import { useParams } from 'next/navigation'
|
||||||
|
import { SuggestedNorms } from './_components/SuggestedNorms'
|
||||||
|
|
||||||
interface ProjectOverview {
|
interface ProjectOverview {
|
||||||
id: string
|
id: string
|
||||||
@@ -120,11 +121,72 @@ export default function ProjectOverviewPage() {
|
|||||||
|
|
||||||
async function fetchProject() {
|
async function fetchProject() {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}`)
|
// Fetch project detail + live risk summary + mitigations count in parallel
|
||||||
if (res.ok) {
|
const [projRes, riskRes, mitRes, hazRes] = await Promise.all([
|
||||||
const json = await res.json()
|
fetch(`/api/sdk/v1/iace/projects/${projectId}`),
|
||||||
setProject(json)
|
fetch(`/api/sdk/v1/iace/projects/${projectId}/risk-summary`),
|
||||||
|
fetch(`/api/sdk/v1/iace/projects/${projectId}/mitigations`),
|
||||||
|
fetch(`/api/sdk/v1/iace/projects/${projectId}/hazards`),
|
||||||
|
])
|
||||||
|
|
||||||
|
if (!projRes.ok) return
|
||||||
|
const json = await projRes.json()
|
||||||
|
|
||||||
|
// Live risk summary from dedicated endpoint
|
||||||
|
let rs = json.risk_summary || {}
|
||||||
|
if (riskRes.ok) {
|
||||||
|
const riskJson = await riskRes.json()
|
||||||
|
const live = riskJson.risk_summary || riskJson || {}
|
||||||
|
rs = {
|
||||||
|
critical: live.critical || 0,
|
||||||
|
high: live.high || 0,
|
||||||
|
medium: live.medium || 0,
|
||||||
|
low: live.low || 0,
|
||||||
|
negligible: live.negligible || 0,
|
||||||
|
total: live.total_hazards || live.total || 0,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Live counts
|
||||||
|
let mitCount = 0
|
||||||
|
if (mitRes.ok) {
|
||||||
|
const mitJson = await mitRes.json()
|
||||||
|
mitCount = mitJson.total || (mitJson.mitigations || []).length || 0
|
||||||
|
}
|
||||||
|
let hazCount = 0
|
||||||
|
if (hazRes.ok) {
|
||||||
|
const hazJson = await hazRes.json()
|
||||||
|
hazCount = hazJson.total || (hazJson.hazards || []).length || 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate dynamic completeness percentage
|
||||||
|
const compCount = json.components?.length || 0
|
||||||
|
const gates = (json.completeness_gates || json.gates || [])
|
||||||
|
const gatesPassed = gates.filter((g: Record<string, unknown>) => g.passed === true).length
|
||||||
|
const gatesTotal = gates.length || 1
|
||||||
|
const completeness = Math.round((gatesPassed / gatesTotal) * 100)
|
||||||
|
|
||||||
|
setProject({
|
||||||
|
...json,
|
||||||
|
completeness_pct: completeness,
|
||||||
|
component_count: compCount,
|
||||||
|
hazard_count: hazCount,
|
||||||
|
mitigation_count: mitCount,
|
||||||
|
risk_summary: {
|
||||||
|
critical: rs.critical || 0,
|
||||||
|
high: rs.high || 0,
|
||||||
|
medium: rs.medium || 0,
|
||||||
|
low: rs.low || 0,
|
||||||
|
total: rs.total || hazCount,
|
||||||
|
},
|
||||||
|
gates: gates.map((g: Record<string, unknown>) => ({
|
||||||
|
id: g.id,
|
||||||
|
name: g.name || g.label || '',
|
||||||
|
description: g.description || g.details || '',
|
||||||
|
passed: g.passed,
|
||||||
|
required: g.required,
|
||||||
|
})),
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to fetch project:', err)
|
console.error('Failed to fetch project:', err)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -229,15 +291,31 @@ export default function ProjectOverviewPage() {
|
|||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Risk Summary */}
|
{/* Risk Summary — live from /risk-summary endpoint */}
|
||||||
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-6">
|
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-6">
|
||||||
<h2 className="text-sm font-semibold text-gray-900 dark:text-white mb-4">Risikozusammenfassung</h2>
|
<h2 className="text-sm font-semibold text-gray-900 dark:text-white mb-4">Risikozusammenfassung</h2>
|
||||||
<div className="flex items-center justify-around">
|
{/* Risk level bars */}
|
||||||
<RiskGauge label="Kritisch" value={project.risk_summary?.critical || 0} max={project.risk_summary?.total || 1} color="#EF4444" />
|
<div className="space-y-2">
|
||||||
<RiskGauge label="Hoch" value={project.risk_summary?.high || 0} max={project.risk_summary?.total || 1} color="#F97316" />
|
{[
|
||||||
<RiskGauge label="Mittel" value={project.risk_summary?.medium || 0} max={project.risk_summary?.total || 1} color="#EAB308" />
|
{ label: 'Kritisch', value: project.risk_summary?.critical || 0, color: 'bg-red-500', text: 'text-red-700' },
|
||||||
<RiskGauge label="Niedrig" value={project.risk_summary?.low || 0} max={project.risk_summary?.total || 1} color="#22C55E" />
|
{ label: 'Hoch', value: project.risk_summary?.high || 0, color: 'bg-orange-500', text: 'text-orange-700' },
|
||||||
|
{ label: 'Mittel', value: project.risk_summary?.medium || 0, color: 'bg-yellow-500', text: 'text-yellow-700' },
|
||||||
|
{ label: 'Niedrig', value: project.risk_summary?.low || 0, color: 'bg-green-500', text: 'text-green-700' },
|
||||||
|
].map((level) => {
|
||||||
|
const total = project.risk_summary?.total || 1
|
||||||
|
const pct = Math.round((level.value / total) * 100)
|
||||||
|
return (
|
||||||
|
<div key={level.label} className="flex items-center gap-3">
|
||||||
|
<span className={`text-xs font-medium w-16 ${level.text}`}>{level.label}</span>
|
||||||
|
<div className="flex-1 bg-gray-100 rounded-full h-4 overflow-hidden">
|
||||||
|
<div className={`${level.color} h-4 rounded-full transition-all`} style={{ width: `${pct}%` }} />
|
||||||
</div>
|
</div>
|
||||||
|
<span className="text-sm font-bold text-gray-900 dark:text-white w-8 text-right">{level.value}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
{/* Counts */}
|
||||||
<div className="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700 grid grid-cols-3 gap-4 text-center">
|
<div className="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700 grid grid-cols-3 gap-4 text-center">
|
||||||
<div>
|
<div>
|
||||||
<div className="text-2xl font-bold text-gray-900 dark:text-white">{project.component_count}</div>
|
<div className="text-2xl font-bold text-gray-900 dark:text-white">{project.component_count}</div>
|
||||||
@@ -252,6 +330,10 @@ export default function ProjectOverviewPage() {
|
|||||||
<div className="text-xs text-gray-500">Massnahmen</div>
|
<div className="text-xs text-gray-500">Massnahmen</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/* RPZ threshold info */}
|
||||||
|
<div className="mt-3 pt-3 border-t border-gray-200 dark:border-gray-700 text-xs text-gray-500">
|
||||||
|
RPZ-Schwellen: Kritisch >100 | Hoch 60-100 | Mittel 20-60 | Niedrig <20
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Completeness Gates */}
|
{/* Completeness Gates */}
|
||||||
@@ -267,6 +349,9 @@ export default function ProjectOverviewPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Suggested Norms */}
|
||||||
|
<SuggestedNorms projectId={projectId} />
|
||||||
|
|
||||||
{/* Quick Actions */}
|
{/* Quick Actions */}
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-sm font-semibold text-gray-900 dark:text-white mb-4">Schnellzugriff</h2>
|
<h2 className="text-sm font-semibold text-gray-900 dark:text-white mb-4">Schnellzugriff</h2>
|
||||||
|
|||||||
@@ -0,0 +1,172 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
interface NormStats {
|
||||||
|
total: number
|
||||||
|
byType: Record<string, number>
|
||||||
|
categories: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const TYPE_INFO: Record<string, { label: string; color: string }> = {
|
||||||
|
A: { label: 'A-Normen (Grundnormen)', color: 'bg-red-50 text-red-800 border-red-200' },
|
||||||
|
B1: { label: 'B1-Normen (Sicherheitsgrundnormen)', color: 'bg-blue-50 text-blue-800 border-blue-200' },
|
||||||
|
B2: { label: 'B2-Normen (Sicherheitsfachgrundnormen)', color: 'bg-green-50 text-green-800 border-green-200' },
|
||||||
|
C: { label: 'C-Normen (Maschinenspezifisch)', color: 'bg-purple-50 text-purple-800 border-purple-200' },
|
||||||
|
}
|
||||||
|
|
||||||
|
const CATEGORY_DESCRIPTIONS: Record<string, string> = {
|
||||||
|
A: 'ISO 12100 (Grundnorm Risikobeurteilung)',
|
||||||
|
B1: 'ISO 13849-1/2, IEC 62061, IEC 61508 (SIL/PL, Funktionale Sicherheit)',
|
||||||
|
B2: 'Elektrik, Ergonomie, Vibration, Laerm, Brandschutz, Hydraulik/Pneumatik, Software-Safety, Emissionen, Schutzeinrichtungen, Zugaenge, Signale',
|
||||||
|
C: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function NormsCoverage() {
|
||||||
|
const [stats, setStats] = useState<NormStats | null>(null)
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [expanded, setExpanded] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch('/api/sdk/v1/iace/norms-library')
|
||||||
|
.then((r) => (r.ok ? r.json() : null))
|
||||||
|
.then((json) => {
|
||||||
|
if (!json?.norms) return
|
||||||
|
const norms = json.norms as Array<{ norm_type: string; machine_types?: string[] }>
|
||||||
|
const byType: Record<string, number> = {}
|
||||||
|
const machineTypes = new Set<string>()
|
||||||
|
for (const n of norms) {
|
||||||
|
byType[n.norm_type] = (byType[n.norm_type] || 0) + 1
|
||||||
|
if (n.machine_types) {
|
||||||
|
for (const mt of n.machine_types) machineTypes.add(mt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Group machine types into readable categories
|
||||||
|
const catMap: Record<string, string> = {
|
||||||
|
press: 'Pressen', hydraulic_press: 'Pressen', mechanical_press: 'Pressen', press_brake: 'Pressen',
|
||||||
|
robot: 'Roboter', industrial_robot: 'Roboter', robot_cell: 'Roboter',
|
||||||
|
collaborative_robot: 'Kollaborierende Roboter', cobot: 'Kollaborierende Roboter',
|
||||||
|
woodworking: 'Holzbearbeitung', saw: 'Holzbearbeitung', circular_saw: 'Holzbearbeitung',
|
||||||
|
panel_saw: 'Holzbearbeitung', table_saw: 'Holzbearbeitung', miter_saw: 'Holzbearbeitung',
|
||||||
|
log_saw: 'Holzbearbeitung', planer: 'Holzbearbeitung', router: 'Holzbearbeitung',
|
||||||
|
lathe: 'Metallbearbeitung', turning_machine: 'Metallbearbeitung', large_lathe: 'Metallbearbeitung',
|
||||||
|
small_lathe: 'Metallbearbeitung', milling_machine: 'Metallbearbeitung', drilling_machine: 'Metallbearbeitung',
|
||||||
|
grinding_machine: 'Metallbearbeitung', metal_saw: 'Metallbearbeitung', band_saw: 'Metallbearbeitung',
|
||||||
|
cold_saw: 'Metallbearbeitung', shearing_machine: 'Metallbearbeitung', bending_machine: 'Metallbearbeitung',
|
||||||
|
cnc: 'Metallbearbeitung', machining_center: 'Metallbearbeitung', transfer_machine: 'Metallbearbeitung',
|
||||||
|
injection_molding: 'Kunststoff/Gummi', plastics_machine: 'Kunststoff/Gummi',
|
||||||
|
compression_molding: 'Kunststoff/Gummi', blow_molding: 'Kunststoff/Gummi',
|
||||||
|
extruder: 'Kunststoff/Gummi', plastics_press: 'Kunststoff/Gummi',
|
||||||
|
rubber_machine: 'Kunststoff/Gummi', two_roll_mill: 'Kunststoff/Gummi',
|
||||||
|
reaction_molding: 'Kunststoff/Gummi', calender: 'Kunststoff/Gummi',
|
||||||
|
food_machine: 'Lebensmittel', meat_grinder: 'Lebensmittel', bread_slicer: 'Lebensmittel',
|
||||||
|
bakery: 'Lebensmittel', mixer: 'Lebensmittel', cooker: 'Lebensmittel',
|
||||||
|
cutter: 'Lebensmittel', food_cutter: 'Lebensmittel', filling_machine: 'Lebensmittel',
|
||||||
|
packaging_machine: 'Verpackung', palletizer: 'Verpackung', pallet_wrapper: 'Verpackung',
|
||||||
|
wrapping_machine: 'Verpackung', strapping_machine: 'Verpackung',
|
||||||
|
textile_machine: 'Textilmaschinen', spinning_machine: 'Textilmaschinen',
|
||||||
|
weaving_machine: 'Textilmaschinen', dyeing_machine: 'Textilmaschinen',
|
||||||
|
nonwoven_machine: 'Textilmaschinen',
|
||||||
|
agricultural_machine: 'Landmaschinen', combine_harvester: 'Landmaschinen',
|
||||||
|
mower: 'Landmaschinen', baler: 'Landmaschinen', sprayer: 'Landmaschinen', tiller: 'Landmaschinen',
|
||||||
|
crane: 'Krane/Hebezeuge', bridge_crane: 'Krane/Hebezeuge', gantry_crane: 'Krane/Hebezeuge',
|
||||||
|
tower_crane: 'Krane/Hebezeuge', mobile_crane: 'Krane/Hebezeuge', hoist: 'Krane/Hebezeuge',
|
||||||
|
winch: 'Krane/Hebezeuge', slewing_crane: 'Krane/Hebezeuge',
|
||||||
|
elevator: 'Aufzuege', lift: 'Aufzuege', construction_hoist: 'Aufzuege',
|
||||||
|
conveyor: 'Foerdertechnik', belt_conveyor: 'Foerdertechnik', screw_conveyor: 'Foerdertechnik',
|
||||||
|
transfer_system: 'Foerdertechnik', rotary_transfer_machine: 'Foerdertechnik',
|
||||||
|
forklift: 'Flurfoerderzeuge', industrial_truck: 'Flurfoerderzeuge',
|
||||||
|
earth_moving: 'Erdbaumaschinen', excavator: 'Erdbaumaschinen',
|
||||||
|
wheel_loader: 'Erdbaumaschinen', bulldozer: 'Erdbaumaschinen',
|
||||||
|
welding_machine: 'Schweissmaschinen', arc_welder: 'Schweissmaschinen',
|
||||||
|
printing_press: 'Druckmaschinen', coating_machine: 'Druckmaschinen',
|
||||||
|
pump: 'Pumpen/Kompressoren', compressor: 'Pumpen/Kompressoren', vacuum_pump: 'Pumpen/Kompressoren',
|
||||||
|
foundry_machine: 'Giesserei', casting_machine: 'Giesserei', die_casting: 'Giesserei',
|
||||||
|
industrial_furnace: 'Industrieoefen', heat_treatment: 'Industrieoefen',
|
||||||
|
dryer: 'Trockner/Oefen', oven: 'Trockner/Oefen', kiln: 'Trockner/Oefen',
|
||||||
|
paper_machine: 'Papiermaschinen', slitter_rewinder: 'Papiermaschinen', pulper: 'Papiermaschinen',
|
||||||
|
centrifuge: 'Zentrifugen',
|
||||||
|
aerial_platform: 'Hubarbeitsbuehnen', cherry_picker: 'Hubarbeitsbuehnen',
|
||||||
|
scissor_lift: 'Hubtische', lift_table: 'Hubtische',
|
||||||
|
powered_gate: 'Tore/Tueren', industrial_door: 'Tore/Tueren',
|
||||||
|
laser_machine: 'Lasermaschinen', laser_cutter: 'Lasermaschinen',
|
||||||
|
silo: 'Schuettgutanlagen', bunker: 'Schuettgutanlagen',
|
||||||
|
suspended_platform: 'Haengebuehnen', scaffold: 'Haengebuehnen',
|
||||||
|
storage_retrieval: 'Lagertechnik', automated_warehouse: 'Lagertechnik',
|
||||||
|
pressure_vessel: 'Druckbehaelter', hydraulic_accumulator: 'Druckbehaelter',
|
||||||
|
}
|
||||||
|
const cats = new Set<string>()
|
||||||
|
for (const mt of machineTypes) {
|
||||||
|
cats.add(catMap[mt] || mt)
|
||||||
|
}
|
||||||
|
const sortedCats = Array.from(cats).sort()
|
||||||
|
setStats({ total: norms.length, byType, categories: sortedCats })
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => setLoading(false))
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (loading || !stats) return null
|
||||||
|
|
||||||
|
const cDesc = stats.categories.join(', ')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-4 bg-purple-50 dark:bg-purple-900/10 border border-purple-200 dark:border-purple-800 rounded-lg">
|
||||||
|
<button onClick={() => setExpanded(!expanded)} className="w-full text-left">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<svg className="w-5 h-5 text-purple-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
|
||||||
|
</svg>
|
||||||
|
<span className="text-sm font-semibold text-purple-800 dark:text-purple-300">
|
||||||
|
Normen-Bibliothek: {stats.total} Normen in {stats.categories.length} Branchen
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<svg className={`w-4 h-4 text-purple-400 transition-transform ${expanded ? 'rotate-180' : ''}`} fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{expanded && (
|
||||||
|
<div className="mt-3 space-y-2">
|
||||||
|
<table className="w-full text-xs">
|
||||||
|
<thead>
|
||||||
|
<tr className="border-b border-purple-200 dark:border-purple-700">
|
||||||
|
<th className="text-left py-1.5 px-2 font-semibold text-purple-800 dark:text-purple-300 w-48">Typ</th>
|
||||||
|
<th className="text-center py-1.5 px-2 font-semibold text-purple-800 dark:text-purple-300 w-16">Anzahl</th>
|
||||||
|
<th className="text-left py-1.5 px-2 font-semibold text-purple-800 dark:text-purple-300">Abdeckung</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{(['A', 'B1', 'B2', 'C'] as const).map((type) => {
|
||||||
|
const info = TYPE_INFO[type]
|
||||||
|
const count = stats.byType[type] || 0
|
||||||
|
const desc = type === 'C' ? cDesc : CATEGORY_DESCRIPTIONS[type]
|
||||||
|
return (
|
||||||
|
<tr key={type} className="border-b border-purple-100 dark:border-purple-800/50">
|
||||||
|
<td className="py-2 px-2">
|
||||||
|
<span className={`inline-block px-2 py-0.5 rounded border text-xs font-medium ${info.color}`}>
|
||||||
|
{info.label}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className="py-2 px-2 text-center font-bold text-purple-900 dark:text-purple-200">{count}</td>
|
||||||
|
<td className="py-2 px-2 text-gray-700 dark:text-gray-300">{desc}</td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div className="pt-2 text-xs text-purple-600 dark:text-purple-400">
|
||||||
|
Alle Normen mit Abschnittsnummern und{' '}
|
||||||
|
<a href="https://www.beuth.de" target="_blank" rel="noopener noreferrer" className="underline font-medium hover:text-purple-800">
|
||||||
|
Beuth-Kauflinks
|
||||||
|
</a>{' '}
|
||||||
|
hinterlegt. Die vollstaendige Bibliothek ist unter "Normenrecherche" in jedem Projekt einsehbar.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,369 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import { NormsCoverage } from './NormsCoverage'
|
||||||
|
|
||||||
|
type ScopeStatus = 'in_scope' | 'partially' | 'not_in_scope' | 'planned'
|
||||||
|
|
||||||
|
interface ProcessStep {
|
||||||
|
number: number
|
||||||
|
title: string
|
||||||
|
description: string
|
||||||
|
actor: string
|
||||||
|
scope: ScopeStatus
|
||||||
|
toolNote?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const CE_PROCESS_STEPS: ProcessStep[] = [
|
||||||
|
{
|
||||||
|
number: 1,
|
||||||
|
title: 'Maschinenplanung',
|
||||||
|
description: 'Hersteller plant Maschine/Anlage',
|
||||||
|
actor: 'Hersteller',
|
||||||
|
scope: 'not_in_scope',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 2,
|
||||||
|
title: 'CE-Firma beauftragen',
|
||||||
|
description: 'Hersteller beauftragt CE-Beratungsfirma oder internes CE-Team',
|
||||||
|
actor: 'Hersteller',
|
||||||
|
scope: 'not_in_scope',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 3,
|
||||||
|
title: 'Grenzen definieren',
|
||||||
|
description:
|
||||||
|
'Bestimmungsgemasse Verwendung, vorhersehbare Fehlanwendung, Betriebsarten, raeumliche/zeitliche Grenzen',
|
||||||
|
actor: 'Gemeinsam',
|
||||||
|
scope: 'in_scope',
|
||||||
|
toolNote: 'Interview/Wizard tab',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 4,
|
||||||
|
title: 'Normenrecherche',
|
||||||
|
description:
|
||||||
|
'C-Normen (maschinenspezifisch), B-Normen (Sicherheitsfunktionen), A-Normen (ISO 12100). Harmonisierte Normen ermoeglichen Konformitaetsvermutung.',
|
||||||
|
actor: 'CE-Firma',
|
||||||
|
scope: 'in_scope',
|
||||||
|
toolNote: 'manueller Eintrag',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 5,
|
||||||
|
title: 'Maschinenbeschreibung',
|
||||||
|
description:
|
||||||
|
'Komponentenbaum, Energiequellen, technische Daten, Betriebsarten systematisch erfassen',
|
||||||
|
actor: 'CE-Firma',
|
||||||
|
scope: 'in_scope',
|
||||||
|
toolNote: 'Komponenten tab',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 6,
|
||||||
|
title: 'Gefaehrdungen identifizieren',
|
||||||
|
description:
|
||||||
|
'Systematisch pro Komponente x Lebenszyklus. Deterministisches Pattern-Matching generiert Vorschlaege.',
|
||||||
|
actor: 'CE-Firma + Tool',
|
||||||
|
scope: 'in_scope',
|
||||||
|
toolNote: 'Hazard Log',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 7,
|
||||||
|
title: 'Risiko bewerten',
|
||||||
|
description:
|
||||||
|
'Schwere x Exposition x Eintrittswahrscheinlichkeit. Automatische SIL/PL-Ableitung aus Risikograph.',
|
||||||
|
actor: 'CE-Firma + Tool',
|
||||||
|
scope: 'in_scope',
|
||||||
|
toolNote: 'Hazard Log',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 8,
|
||||||
|
title: 'Massnahmen definieren',
|
||||||
|
description:
|
||||||
|
'3-Stufen-Hierarchie (PFLICHT): 1. Design, 2. Schutzeinrichtung, 3. Information. Tool schlaegt kategorienspezifisch vor.',
|
||||||
|
actor: 'CE-Firma + Tool',
|
||||||
|
scope: 'in_scope',
|
||||||
|
toolNote: 'Massnahmen tab',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 9,
|
||||||
|
title: 'Massnahmen umsetzen',
|
||||||
|
description:
|
||||||
|
'Hersteller implementiert konstruktive Aenderungen, Schutzeinrichtungen, Beschilderung etc.',
|
||||||
|
actor: 'Hersteller',
|
||||||
|
scope: 'partially',
|
||||||
|
toolNote: 'Nachweis-Upload',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 10,
|
||||||
|
title: 'Restrisiko bewerten',
|
||||||
|
description:
|
||||||
|
'Iterativ: Nach Massnahmen-Umsetzung erneut bewerten. Akzeptabel? Wenn nein: zurueck zu Schritt 8.',
|
||||||
|
actor: 'CE-Firma',
|
||||||
|
scope: 'in_scope',
|
||||||
|
toolNote: 'Reassessment',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 11,
|
||||||
|
title: 'Verifikation',
|
||||||
|
description: 'Messungen, Berechnungen, Pruefungen. Nachweise den Massnahmen zuordnen.',
|
||||||
|
actor: 'CE-Firma',
|
||||||
|
scope: 'in_scope',
|
||||||
|
toolNote: 'Verifikation tab',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 12,
|
||||||
|
title: 'Benannte Stelle',
|
||||||
|
description:
|
||||||
|
'NUR fuer Annex-IV-Maschinen (Pressen, Holzbearbeitung, Hebezeuge): Formale Baumusterpruefung durch TUeV/DGUV Test o.ae.',
|
||||||
|
actor: 'Notified Body',
|
||||||
|
scope: 'not_in_scope',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 13,
|
||||||
|
title: 'Betriebsanleitung',
|
||||||
|
description:
|
||||||
|
'Restrisiken fuer Bediener dokumentieren, Sicherheitshinweise, bestimmungsgemasse Verwendung',
|
||||||
|
actor: 'CE-Firma',
|
||||||
|
scope: 'planned',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 14,
|
||||||
|
title: 'Technische Unterlagen',
|
||||||
|
description:
|
||||||
|
'Gesamtdossier: Plaene, Schaltbilder, Berechnungen, Risikobeurteilung, Normen, Pruefberichte, Betriebsanleitung',
|
||||||
|
actor: 'CE-Firma',
|
||||||
|
scope: 'in_scope',
|
||||||
|
toolNote: 'CE-Akte tab',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 15,
|
||||||
|
title: 'CE-Erklaerung',
|
||||||
|
description:
|
||||||
|
'Hersteller unterschreibt EU-Konformitaetserklaerung und bringt CE-Kennzeichnung an. Die CE-Firma gibt KEIN CE — der Hersteller traegt die Verantwortung.',
|
||||||
|
actor: 'Hersteller',
|
||||||
|
scope: 'not_in_scope',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const SCOPE_STYLES: Record<ScopeStatus, { border: string; bg: string; badge: string; badgeText: string }> = {
|
||||||
|
in_scope: {
|
||||||
|
border: 'border-l-purple-500',
|
||||||
|
bg: 'bg-purple-50 dark:bg-purple-900/10',
|
||||||
|
badge: 'bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-300',
|
||||||
|
badgeText: 'Im Tool',
|
||||||
|
},
|
||||||
|
partially: {
|
||||||
|
border: 'border-l-yellow-500',
|
||||||
|
bg: 'bg-yellow-50 dark:bg-yellow-900/10',
|
||||||
|
badge: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/40 dark:text-yellow-300',
|
||||||
|
badgeText: 'Teilweise',
|
||||||
|
},
|
||||||
|
not_in_scope: {
|
||||||
|
border: 'border-l-gray-300',
|
||||||
|
bg: 'bg-gray-50 dark:bg-gray-800/50',
|
||||||
|
badge: 'bg-gray-100 text-gray-500 dark:bg-gray-700 dark:text-gray-400',
|
||||||
|
badgeText: 'Nicht im Tool',
|
||||||
|
},
|
||||||
|
planned: {
|
||||||
|
border: 'border-l-gray-300 border-dashed',
|
||||||
|
bg: 'bg-gray-50 dark:bg-gray-800/50',
|
||||||
|
badge: 'bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300',
|
||||||
|
badgeText: 'Geplant',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'iace-process-flow-collapsed'
|
||||||
|
|
||||||
|
function StepCard({ step }: { step: ProcessStep }) {
|
||||||
|
const style = SCOPE_STYLES[step.scope]
|
||||||
|
const muted = step.scope === 'not_in_scope' || step.scope === 'planned'
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`relative flex gap-4 ${muted ? 'opacity-75' : ''}`}>
|
||||||
|
{/* Timeline connector */}
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
<div
|
||||||
|
className={`w-8 h-8 rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0 ${
|
||||||
|
step.scope === 'in_scope'
|
||||||
|
? 'bg-purple-600 text-white'
|
||||||
|
: step.scope === 'partially'
|
||||||
|
? 'bg-yellow-500 text-white'
|
||||||
|
: 'bg-gray-300 text-gray-600 dark:bg-gray-600 dark:text-gray-300'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{step.number}
|
||||||
|
</div>
|
||||||
|
{step.number < 15 && (
|
||||||
|
<div className="w-0.5 flex-1 bg-gray-200 dark:bg-gray-700 mt-1" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Card */}
|
||||||
|
<div
|
||||||
|
className={`flex-1 mb-3 p-4 rounded-lg border-l-4 ${style.border} ${style.bg} ${
|
||||||
|
step.scope === 'planned' ? 'border-dashed border border-gray-300 dark:border-gray-600' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="flex items-start justify-between gap-2 mb-1">
|
||||||
|
<h4 className={`font-semibold text-sm ${muted ? 'text-gray-600 dark:text-gray-400' : 'text-gray-900 dark:text-white'}`}>
|
||||||
|
{step.title}
|
||||||
|
</h4>
|
||||||
|
<div className="flex items-center gap-2 flex-shrink-0">
|
||||||
|
<span className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${style.badge}`}>
|
||||||
|
{style.badgeText}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className={`text-xs leading-relaxed ${muted ? 'text-gray-500 dark:text-gray-500' : 'text-gray-700 dark:text-gray-300'}`}>
|
||||||
|
{step.description}
|
||||||
|
</p>
|
||||||
|
<div className="mt-2 flex items-center gap-3">
|
||||||
|
<span className="inline-flex items-center gap-1 text-xs text-gray-500 dark:text-gray-400">
|
||||||
|
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
||||||
|
</svg>
|
||||||
|
{step.actor}
|
||||||
|
</span>
|
||||||
|
{step.toolNote && (
|
||||||
|
<span className="inline-flex items-center gap-1 text-xs text-purple-600 dark:text-purple-400">
|
||||||
|
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||||
|
</svg>
|
||||||
|
{step.toolNote}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProcessFlow() {
|
||||||
|
// Default to expanded (false) — avoids SSR hydration mismatch
|
||||||
|
const [collapsed, setCollapsed] = useState(false)
|
||||||
|
const [mounted, setMounted] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const stored = localStorage.getItem(STORAGE_KEY)
|
||||||
|
if (stored === 'true') {
|
||||||
|
setCollapsed(true)
|
||||||
|
}
|
||||||
|
setMounted(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
const next = !collapsed
|
||||||
|
setCollapsed(next)
|
||||||
|
localStorage.setItem(STORAGE_KEY, String(next))
|
||||||
|
}
|
||||||
|
|
||||||
|
const inScopeCount = CE_PROCESS_STEPS.filter((s) => s.scope === 'in_scope').length
|
||||||
|
const partialCount = CE_PROCESS_STEPS.filter((s) => s.scope === 'partially').length
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden">
|
||||||
|
{/* Header — always visible */}
|
||||||
|
<button
|
||||||
|
onClick={toggle}
|
||||||
|
className="w-full flex items-center justify-between px-6 py-4 text-left hover:bg-gray-50 dark:hover:bg-gray-750 transition-colors"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<h2 className="text-base font-semibold text-gray-900 dark:text-white">
|
||||||
|
CE-Prozess: 15 Schritte zur Konformitaet
|
||||||
|
</h2>
|
||||||
|
<p className="text-xs text-gray-500 dark:text-gray-400 mt-0.5">
|
||||||
|
{inScopeCount} Schritte im Tool abgedeckt, {partialCount} teilweise
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<svg
|
||||||
|
className={`w-5 h-5 text-gray-400 transition-transform ${collapsed ? '' : 'rotate-180'}`}
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Content — collapsible */}
|
||||||
|
{!collapsed && (
|
||||||
|
<div className="px-6 pb-6 border-t border-gray-100 dark:border-gray-700">
|
||||||
|
{/* Legend */}
|
||||||
|
<div className="flex flex-wrap items-center gap-4 py-3 mb-4">
|
||||||
|
<span className="flex items-center gap-1.5 text-xs text-gray-600 dark:text-gray-300">
|
||||||
|
<span className="w-3 h-3 rounded-sm bg-purple-500" />
|
||||||
|
Im Tool abgedeckt
|
||||||
|
</span>
|
||||||
|
<span className="flex items-center gap-1.5 text-xs text-gray-600 dark:text-gray-300">
|
||||||
|
<span className="w-3 h-3 rounded-sm bg-yellow-500" />
|
||||||
|
Teilweise abgedeckt
|
||||||
|
</span>
|
||||||
|
<span className="flex items-center gap-1.5 text-xs text-gray-600 dark:text-gray-300">
|
||||||
|
<span className="w-3 h-3 rounded-sm bg-gray-300 dark:bg-gray-600" />
|
||||||
|
Nicht im Tool
|
||||||
|
</span>
|
||||||
|
<span className="flex items-center gap-1.5 text-xs text-gray-600 dark:text-gray-300">
|
||||||
|
<span className="w-3 h-3 rounded-sm border border-dashed border-gray-400" />
|
||||||
|
Geplant
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Timeline */}
|
||||||
|
<div className="space-y-0">
|
||||||
|
{CE_PROCESS_STEPS.map((step) => (
|
||||||
|
<StepCard key={step.number} step={step} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Norms Coverage Table */}
|
||||||
|
<div className="mt-4">
|
||||||
|
<NormsCoverage />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Disclaimers */}
|
||||||
|
<div className="mt-4 space-y-3">
|
||||||
|
<div className="p-3 bg-amber-50 dark:bg-amber-900/10 border border-amber-200 dark:border-amber-800 rounded-lg">
|
||||||
|
<p className="text-xs text-amber-800 dark:text-amber-300 leading-relaxed">
|
||||||
|
<strong>Hinweis:</strong> Dieses Tool ersetzt NICHT die Fachkompetenz eines CE-Beraters.
|
||||||
|
Es automatisiert die systematische Dokumentation und schlaegt Gefaehrdungen/Massnahmen vor.
|
||||||
|
Die fachliche Bewertung und Verantwortung verbleibt beim CE-Experten und Hersteller.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-3 bg-blue-50 dark:bg-blue-900/10 border border-blue-200 dark:border-blue-800 rounded-lg">
|
||||||
|
<p className="text-xs font-semibold text-blue-800 dark:text-blue-300 mb-2">Normenrecherche — Rechtliche Grundlage</p>
|
||||||
|
<div className="text-xs text-blue-700 dark:text-blue-400 leading-relaxed space-y-2">
|
||||||
|
<div>
|
||||||
|
<p className="font-medium mb-1">Was dieses Tool anzeigt:</p>
|
||||||
|
<ul className="list-disc list-inside space-y-0.5 ml-1">
|
||||||
|
<li>Normennummern (z.B. "ISO 13857:2019") — Identifikatoren, kein geschuetzter Text</li>
|
||||||
|
<li>Offizielle Normentitel — bibliografische Information</li>
|
||||||
|
<li>Abschnittsnummern (z.B. "Abschnitt 4.2, Tabelle 1") — Verweisadressen</li>
|
||||||
|
<li>Eigene Zusammenfassungen des Regelungsbereichs — unser Text, nicht Normtext</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="font-medium mb-1">Was dieses Tool NICHT anzeigt:</p>
|
||||||
|
<ul className="list-disc list-inside space-y-0.5 ml-1">
|
||||||
|
<li>Normtext (auch nicht auszugsweise) — urheberrechtlich geschuetzt durch DIN/ISO/CEN</li>
|
||||||
|
<li>Tabellenwerte oder Grenzwerte aus Normen</li>
|
||||||
|
<li>Diagramme oder Bilder aus Normen</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<p className="text-blue-600 dark:text-blue-300 pt-1">
|
||||||
|
Normtexte muessen separat beschafft werden, z.B. ueber{' '}
|
||||||
|
<a href="https://www.beuth.de" target="_blank" rel="noopener noreferrer" className="underline font-medium hover:text-blue-800">
|
||||||
|
www.beuth.de
|
||||||
|
</a>{' '}
|
||||||
|
(DIN-Normen) oder{' '}
|
||||||
|
<a href="https://www.iso.org" target="_blank" rel="noopener noreferrer" className="underline font-medium hover:text-blue-800">
|
||||||
|
www.iso.org
|
||||||
|
</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { usePathname, useParams } from 'next/navigation'
|
import { usePathname, useParams } from 'next/navigation'
|
||||||
|
import IACEFlowFAB from './[projectId]/_components/IACEFlowFAB'
|
||||||
|
|
||||||
const IACE_NAV_ITEMS = [
|
const IACE_NAV_ITEMS = [
|
||||||
{ id: 'overview', label: 'Uebersicht', href: '', icon: 'grid' },
|
{ id: 'overview', label: 'Uebersicht', href: '', icon: 'grid' },
|
||||||
@@ -112,6 +113,15 @@ export default function IACELayout({ children }: { children: React.ReactNode })
|
|||||||
<h2 className="text-sm font-semibold text-gray-900 dark:text-white mt-2">
|
<h2 className="text-sm font-semibold text-gray-900 dark:text-white mt-2">
|
||||||
CE-Compliance
|
CE-Compliance
|
||||||
</h2>
|
</h2>
|
||||||
|
<Link
|
||||||
|
href="/sdk/iace/lines"
|
||||||
|
className="mt-2 flex items-center gap-1.5 text-xs text-gray-500 hover:text-purple-600 dark:text-gray-400 dark:hover:text-purple-400 transition-colors"
|
||||||
|
>
|
||||||
|
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||||
|
</svg>
|
||||||
|
Produktionslinien
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<nav className="p-2 space-y-0.5">
|
<nav className="p-2 space-y-0.5">
|
||||||
{IACE_NAV_ITEMS.map((item) => (
|
{IACE_NAV_ITEMS.map((item) => (
|
||||||
@@ -136,6 +146,9 @@ export default function IACELayout({ children }: { children: React.ReactNode })
|
|||||||
<main className="flex-1 overflow-auto bg-gray-50 dark:bg-gray-900">
|
<main className="flex-1 overflow-auto bg-gray-50 dark:bg-gray-900">
|
||||||
<div className="p-6">{children}</div>
|
<div className="p-6">{children}</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
{/* CE Process Step Navigator FAB */}
|
||||||
|
{projectId && <IACEFlowFAB />}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
import type { LineDashboard } from '../../_types'
|
||||||
|
|
||||||
|
interface AggregatePanelProps {
|
||||||
|
dashboard: LineDashboard
|
||||||
|
}
|
||||||
|
|
||||||
|
const RISK_DOTS = [
|
||||||
|
{ key: 'critical', label: 'Kritisch', dotColor: 'bg-red-500' },
|
||||||
|
{ key: 'high', label: 'Hoch', dotColor: 'bg-orange-500' },
|
||||||
|
{ key: 'medium', label: 'Mittel', dotColor: 'bg-yellow-500' },
|
||||||
|
{ key: 'low', label: 'Niedrig', dotColor: 'bg-green-500' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export function AggregatePanel({ dashboard }: AggregatePanelProps) {
|
||||||
|
const { line, stations, aggregate } = dashboard
|
||||||
|
|
||||||
|
const totalHazards = stations.reduce((sum, s) => sum + s.hazard_count, 0)
|
||||||
|
const totalMitigations = stations.reduce((sum, s) => sum + s.mitigation_count, 0)
|
||||||
|
const stationCount = stations.length
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-6">
|
||||||
|
{/* Title row */}
|
||||||
|
<div className="flex items-start justify-between mb-3">
|
||||||
|
<div>
|
||||||
|
<h1 className="text-xl font-bold text-gray-900 dark:text-white">
|
||||||
|
{line.name}
|
||||||
|
</h1>
|
||||||
|
{line.description && (
|
||||||
|
<p className="text-sm text-gray-500 dark:text-gray-400 mt-0.5">
|
||||||
|
{line.description}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2 text-xs text-gray-400 dark:text-gray-500">
|
||||||
|
<span>Erstellt: {new Date(line.created_at).toLocaleDateString('de-DE')}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Stats row */}
|
||||||
|
<div className="flex flex-wrap items-center gap-6 mb-3">
|
||||||
|
<StatPill label="Stationen" value={stationCount} />
|
||||||
|
<StatPill label="Gefaehrdungen" value={totalHazards} />
|
||||||
|
<StatPill label="Massnahmen" value={totalMitigations} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Risk dots row */}
|
||||||
|
<div className="flex flex-wrap items-center gap-4">
|
||||||
|
{RISK_DOTS.map((rd) => {
|
||||||
|
const count = aggregate[rd.key] || 0
|
||||||
|
return (
|
||||||
|
<span key={rd.key} className="flex items-center gap-1.5 text-xs text-gray-600 dark:text-gray-300">
|
||||||
|
<span className={`w-2.5 h-2.5 rounded-full ${rd.dotColor}`} />
|
||||||
|
<span className="font-semibold">{count}</span>
|
||||||
|
<span>{rd.label}</span>
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function StatPill({ label, value }: { label: string; value: number }) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center gap-1.5 text-sm">
|
||||||
|
<span className="font-bold text-gray-900 dark:text-white">{value}</span>
|
||||||
|
<span className="text-gray-500 dark:text-gray-400">{label}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { StationIcon } from './StationIcons'
|
||||||
|
import { STATION_TYPES } from '../../_types'
|
||||||
|
import type { StationDashboard } from '../../_types'
|
||||||
|
|
||||||
|
const STATUS_COLORS: Record<string, string> = {
|
||||||
|
draft: 'bg-gray-100 text-gray-700',
|
||||||
|
in_progress: 'bg-blue-100 text-blue-700',
|
||||||
|
review: 'bg-yellow-100 text-yellow-700',
|
||||||
|
approved: 'bg-green-100 text-green-700',
|
||||||
|
archived: 'bg-gray-100 text-gray-500',
|
||||||
|
}
|
||||||
|
|
||||||
|
const STATUS_LABELS: Record<string, string> = {
|
||||||
|
draft: 'Entwurf',
|
||||||
|
in_progress: 'In Bearbeitung',
|
||||||
|
review: 'In Pruefung',
|
||||||
|
approved: 'Freigegeben',
|
||||||
|
archived: 'Archiviert',
|
||||||
|
}
|
||||||
|
|
||||||
|
const RISK_LEVELS = [
|
||||||
|
{ key: 'critical', label: 'Kritisch', color: 'bg-red-500', text: 'text-red-700' },
|
||||||
|
{ key: 'high', label: 'Hoch', color: 'bg-orange-500', text: 'text-orange-700' },
|
||||||
|
{ key: 'medium', label: 'Mittel', color: 'bg-yellow-500', text: 'text-yellow-700' },
|
||||||
|
{ key: 'low', label: 'Niedrig', color: 'bg-green-500', text: 'text-green-700' },
|
||||||
|
]
|
||||||
|
|
||||||
|
interface StationCardProps {
|
||||||
|
station: StationDashboard
|
||||||
|
expanded: boolean
|
||||||
|
onToggle: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StationCard({ station, expanded, onToggle }: StationCardProps) {
|
||||||
|
const stationType = STATION_TYPES[station.station.station_type]
|
||||||
|
const bgColor = stationType?.bgColor || 'bg-gray-50'
|
||||||
|
const accentColor = stationType?.color || '#6B7280'
|
||||||
|
|
||||||
|
const totalRisk = Object.values(station.risk_summary).reduce((a, b) => a + b, 0)
|
||||||
|
const pctBar = station.completeness_pct
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`w-56 flex-shrink-0 rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 overflow-hidden shadow-sm hover:shadow-md transition-shadow`}
|
||||||
|
>
|
||||||
|
{/* Color accent bar */}
|
||||||
|
<div className="h-1.5" style={{ backgroundColor: accentColor }} />
|
||||||
|
|
||||||
|
{/* Collapsed content */}
|
||||||
|
<div className="p-4">
|
||||||
|
{/* Icon + name */}
|
||||||
|
<div className="flex items-center gap-3 mb-2">
|
||||||
|
<div
|
||||||
|
className={`w-10 h-10 ${bgColor} dark:bg-opacity-20 rounded-lg flex items-center justify-center flex-shrink-0`}
|
||||||
|
style={{ color: accentColor }}
|
||||||
|
>
|
||||||
|
<StationIcon type={station.station.station_type} size={22} />
|
||||||
|
</div>
|
||||||
|
<div className="min-w-0">
|
||||||
|
<div className="text-sm font-semibold text-gray-900 dark:text-white truncate">
|
||||||
|
{station.station.station_label}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-gray-500 dark:text-gray-400 truncate">
|
||||||
|
{station.project_name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Hazard count */}
|
||||||
|
<div className="text-xs text-gray-600 dark:text-gray-400 mb-2">
|
||||||
|
{station.hazard_count} Gefaehrdungen
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Completeness bar */}
|
||||||
|
<div className="flex items-center gap-2 mb-2">
|
||||||
|
<div className="flex-1 bg-gray-200 dark:bg-gray-700 rounded-full h-2">
|
||||||
|
<div
|
||||||
|
className="h-2 rounded-full transition-all"
|
||||||
|
style={{
|
||||||
|
width: `${pctBar}%`,
|
||||||
|
backgroundColor: accentColor,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span className="text-xs font-medium text-gray-600 dark:text-gray-400 w-8 text-right">
|
||||||
|
{pctBar}%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* SIL / PL */}
|
||||||
|
{(station.sil_max || station.pl_max) && (
|
||||||
|
<div className="flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400 mb-3">
|
||||||
|
{station.sil_max && <span>SIL {station.sil_max}</span>}
|
||||||
|
{station.sil_max && station.pl_max && <span>|</span>}
|
||||||
|
{station.pl_max && <span>PL {station.pl_max}</span>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Toggle button */}
|
||||||
|
<button
|
||||||
|
onClick={onToggle}
|
||||||
|
className="w-full text-left text-xs text-purple-600 dark:text-purple-400 hover:text-purple-700 dark:hover:text-purple-300 font-medium flex items-center gap-1"
|
||||||
|
>
|
||||||
|
{expanded ? 'Weniger anzeigen' : 'Details anzeigen'}
|
||||||
|
<svg
|
||||||
|
className={`w-3.5 h-3.5 transition-transform ${expanded ? 'rotate-90' : ''}`}
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Expanded content */}
|
||||||
|
{expanded && (
|
||||||
|
<div className="px-4 pb-4 border-t border-gray-100 dark:border-gray-700 pt-3 space-y-3">
|
||||||
|
{/* Risk breakdown */}
|
||||||
|
<div className="space-y-1.5">
|
||||||
|
{RISK_LEVELS.map((level) => {
|
||||||
|
const count = station.risk_summary[level.key] || 0
|
||||||
|
const pct = totalRisk > 0 ? Math.round((count / totalRisk) * 100) : 0
|
||||||
|
return (
|
||||||
|
<div key={level.key} className="flex items-center gap-2">
|
||||||
|
<span className={`text-[10px] font-medium w-12 ${level.text}`}>{level.label}</span>
|
||||||
|
<div className="flex-1 bg-gray-100 dark:bg-gray-700 rounded-full h-2.5 overflow-hidden">
|
||||||
|
<div className={`${level.color} h-2.5 rounded-full`} style={{ width: `${pct}%` }} />
|
||||||
|
</div>
|
||||||
|
<span className="text-xs font-bold text-gray-700 dark:text-gray-300 w-6 text-right">{count}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mitigation count */}
|
||||||
|
<div className="flex items-center justify-between text-xs">
|
||||||
|
<span className="text-gray-500 dark:text-gray-400">Massnahmen</span>
|
||||||
|
<span className="font-semibold text-gray-700 dark:text-gray-300">{station.mitigation_count}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Status badge */}
|
||||||
|
<div className="flex items-center justify-between text-xs">
|
||||||
|
<span className="text-gray-500 dark:text-gray-400">Status</span>
|
||||||
|
<span className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${STATUS_COLORS[station.status] || STATUS_COLORS.draft}`}>
|
||||||
|
{STATUS_LABELS[station.status] || station.status}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Link to project */}
|
||||||
|
<Link
|
||||||
|
href={`/sdk/iace/${station.station.project_id}`}
|
||||||
|
className="block text-center text-xs font-medium text-purple-600 dark:text-purple-400 hover:text-purple-700 bg-purple-50 dark:bg-purple-900/20 rounded-lg py-2 transition-colors"
|
||||||
|
>
|
||||||
|
Zum Projekt →
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
interface StationIconProps {
|
||||||
|
type: string
|
||||||
|
size?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StationIcon({ type, size = 24 }: StationIconProps) {
|
||||||
|
const s = size
|
||||||
|
const sw = 1.5
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'press':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Ram pressing down */}
|
||||||
|
<rect x="7" y="2" width="10" height="4" rx="1" />
|
||||||
|
<line x1="12" y1="6" x2="12" y2="12" />
|
||||||
|
<path d="M6 12h12v3H6z" />
|
||||||
|
<line x1="12" y1="12" x2="12" y2="10" strokeWidth={2.5} />
|
||||||
|
{/* Base block */}
|
||||||
|
<rect x="5" y="18" width="14" height="4" rx="1" />
|
||||||
|
{/* Workpiece */}
|
||||||
|
<rect x="9" y="15" width="6" height="3" rx="0.5" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'robot':
|
||||||
|
case 'cobot':
|
||||||
|
case 'collaborative_robot':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Base */}
|
||||||
|
<rect x="8" y="19" width="8" height="3" rx="1" />
|
||||||
|
{/* Lower arm */}
|
||||||
|
<line x1="12" y1="19" x2="8" y2="13" />
|
||||||
|
{/* Joint */}
|
||||||
|
<circle cx="8" cy="13" r="1.5" />
|
||||||
|
{/* Upper arm */}
|
||||||
|
<line x1="8" y1="13" x2="15" y2="7" />
|
||||||
|
{/* Wrist joint */}
|
||||||
|
<circle cx="15" cy="7" r="1.5" />
|
||||||
|
{/* Gripper */}
|
||||||
|
<line x1="15" y1="7" x2="18" y2="4" />
|
||||||
|
<line x1="18" y1="4" x2="19" y2="3" />
|
||||||
|
<line x1="18" y1="4" x2="19" y2="5" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'conveyor':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Belt top */}
|
||||||
|
<line x1="3" y1="14" x2="21" y2="14" />
|
||||||
|
{/* Belt bottom */}
|
||||||
|
<line x1="3" y1="18" x2="21" y2="18" />
|
||||||
|
{/* Left roller */}
|
||||||
|
<circle cx="5" cy="16" r="2" />
|
||||||
|
{/* Right roller */}
|
||||||
|
<circle cx="19" cy="16" r="2" />
|
||||||
|
{/* Flow arrows */}
|
||||||
|
<path d="M8 10l3-2 3 2" />
|
||||||
|
<path d="M11 8v-2" />
|
||||||
|
{/* Package on belt */}
|
||||||
|
<rect x="9" y="10" width="6" height="4" rx="0.5" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'assembly':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Gear */}
|
||||||
|
<circle cx="12" cy="12" r="4" />
|
||||||
|
<circle cx="12" cy="12" r="1.5" />
|
||||||
|
{/* Gear teeth */}
|
||||||
|
<line x1="12" y1="3" x2="12" y2="6" />
|
||||||
|
<line x1="12" y1="18" x2="12" y2="21" />
|
||||||
|
<line x1="3" y1="12" x2="6" y2="12" />
|
||||||
|
<line x1="18" y1="12" x2="21" y2="12" />
|
||||||
|
<line x1="5.6" y1="5.6" x2="7.8" y2="7.8" />
|
||||||
|
<line x1="16.2" y1="16.2" x2="18.4" y2="18.4" />
|
||||||
|
<line x1="5.6" y1="18.4" x2="7.8" y2="16.2" />
|
||||||
|
<line x1="16.2" y1="7.8" x2="18.4" y2="5.6" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'milling':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Spindle */}
|
||||||
|
<rect x="10" y="2" width="4" height="6" rx="1" />
|
||||||
|
{/* Cutter head */}
|
||||||
|
<circle cx="12" cy="11" r="3" />
|
||||||
|
{/* Rotation arc */}
|
||||||
|
<path d="M7 11a5 5 0 0 1 2.5-4.3" strokeDasharray="2 2" />
|
||||||
|
<path d="M17 11a5 5 0 0 0-2.5-4.3" strokeDasharray="2 2" />
|
||||||
|
{/* Workpiece / table */}
|
||||||
|
<rect x="4" y="17" width="16" height="3" rx="1" />
|
||||||
|
<rect x="8" y="14" width="8" height="3" rx="0.5" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'turning':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Chuck / rotating workpiece */}
|
||||||
|
<circle cx="9" cy="12" r="5" />
|
||||||
|
<circle cx="9" cy="12" r="2" />
|
||||||
|
{/* Tool holder */}
|
||||||
|
<line x1="16" y1="12" x2="14" y2="12" />
|
||||||
|
<path d="M16 9v6l4-1v-4z" />
|
||||||
|
{/* Rotation arrow */}
|
||||||
|
<path d="M5 5a8 8 0 0 1 4 1" />
|
||||||
|
<path d="M5 5l1.5 1.5L4.5 7" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'welding':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Torch body */}
|
||||||
|
<line x1="6" y1="4" x2="12" y2="14" />
|
||||||
|
<path d="M4 3h4l-2 3z" />
|
||||||
|
{/* Weld point */}
|
||||||
|
<circle cx="12" cy="16" r="1" fill="currentColor" />
|
||||||
|
{/* Sparks */}
|
||||||
|
<line x1="12" y1="16" x2="15" y2="13" />
|
||||||
|
<line x1="12" y1="16" x2="16" y2="15" />
|
||||||
|
<line x1="12" y1="16" x2="14" y2="19" />
|
||||||
|
<line x1="12" y1="16" x2="9" y2="19" />
|
||||||
|
{/* Workpiece */}
|
||||||
|
<rect x="3" y="19" width="18" height="3" rx="1" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'inspection':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Magnifying glass */}
|
||||||
|
<circle cx="10" cy="10" r="6" />
|
||||||
|
<line x1="14.5" y1="14.5" x2="20" y2="20" strokeWidth={2} />
|
||||||
|
{/* Checkmark inside */}
|
||||||
|
<path d="M7.5 10l2 2 3.5-4" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'packaging':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Box */}
|
||||||
|
<path d="M3 8l9-5 9 5v10l-9 5-9-5z" />
|
||||||
|
<line x1="12" y1="3" x2="12" y2="23" />
|
||||||
|
<line x1="3" y1="8" x2="12" y2="13" />
|
||||||
|
<line x1="21" y1="8" x2="12" y2="13" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'motor':
|
||||||
|
case 'electric_motor':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Motor body circle */}
|
||||||
|
<circle cx="12" cy="12" r="8" />
|
||||||
|
{/* Lightning bolt */}
|
||||||
|
<path d="M13 6l-3 6h4l-3 6" strokeWidth={2} />
|
||||||
|
{/* Shaft */}
|
||||||
|
<line x1="20" y1="12" x2="23" y2="12" strokeWidth={2} />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'rotary_transfer':
|
||||||
|
case 'rotary_transfer_machine':
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
{/* Circular path */}
|
||||||
|
<circle cx="12" cy="12" r="8" strokeDasharray="4 2" />
|
||||||
|
{/* Center */}
|
||||||
|
<circle cx="12" cy="12" r="2" />
|
||||||
|
{/* Station dots around circle */}
|
||||||
|
<circle cx="12" cy="4" r="1.5" fill="currentColor" />
|
||||||
|
<circle cx="19" cy="8" r="1.5" fill="currentColor" />
|
||||||
|
<circle cx="19" cy="16" r="1.5" fill="currentColor" />
|
||||||
|
<circle cx="12" cy="20" r="1.5" fill="currentColor" />
|
||||||
|
<circle cx="5" cy="16" r="1.5" fill="currentColor" />
|
||||||
|
<circle cx="5" cy="8" r="1.5" fill="currentColor" />
|
||||||
|
{/* Rotation arrow */}
|
||||||
|
<path d="M16 3.5l-1 2h2z" fill="currentColor" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<rect x="4" y="4" width="16" height="16" rx="2" />
|
||||||
|
<circle cx="12" cy="12" r="3" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
import type { TransferInfo } from '../../_types'
|
||||||
|
|
||||||
|
interface TransferLineProps {
|
||||||
|
transfer: TransferInfo
|
||||||
|
color: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TransferLine({ transfer, color }: TransferLineProps) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center justify-center w-20 flex-shrink-0 py-4">
|
||||||
|
<style>{`
|
||||||
|
@keyframes iace-running-dots {
|
||||||
|
0% { stroke-dashoffset: 12; }
|
||||||
|
100% { stroke-dashoffset: 0; }
|
||||||
|
}
|
||||||
|
.iace-transfer-dots {
|
||||||
|
animation: iace-running-dots 0.8s linear infinite;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
<svg width="80" height="32" viewBox="0 0 80 32" className="overflow-visible">
|
||||||
|
{/* Background line */}
|
||||||
|
<line
|
||||||
|
x1="0"
|
||||||
|
y1="16"
|
||||||
|
x2="80"
|
||||||
|
y2="16"
|
||||||
|
stroke={color}
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeOpacity="0.3"
|
||||||
|
/>
|
||||||
|
{/* Animated running dots */}
|
||||||
|
<line
|
||||||
|
x1="0"
|
||||||
|
y1="16"
|
||||||
|
x2="80"
|
||||||
|
y2="16"
|
||||||
|
stroke={color}
|
||||||
|
strokeWidth="2.5"
|
||||||
|
strokeDasharray="4 8"
|
||||||
|
className="iace-transfer-dots"
|
||||||
|
/>
|
||||||
|
{/* Arrowhead */}
|
||||||
|
<polygon
|
||||||
|
points="74,11 80,16 74,21"
|
||||||
|
fill={color}
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{/* Label */}
|
||||||
|
{transfer.label && (
|
||||||
|
<span className="text-[10px] text-gray-500 dark:text-gray-400 mt-1 text-center leading-tight max-w-[80px] truncate">
|
||||||
|
{transfer.label}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, { useState, useEffect, useCallback } from 'react'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { useParams } from 'next/navigation'
|
||||||
|
import { AggregatePanel } from './_components/AggregatePanel'
|
||||||
|
import { StationCard } from './_components/StationCard'
|
||||||
|
import { TransferLine } from './_components/TransferLine'
|
||||||
|
import type { LineDashboard, StationDashboard, TransferInfo } from '../_types'
|
||||||
|
import { TRANSFER_COLORS } from '../_types'
|
||||||
|
|
||||||
|
/** Number of stations per visual row before wrapping */
|
||||||
|
const STATIONS_PER_ROW = 4
|
||||||
|
|
||||||
|
export default function LineDashboardPage() {
|
||||||
|
const params = useParams()
|
||||||
|
const lineId = params.lineId as string
|
||||||
|
const [dashboard, setDashboard] = useState<LineDashboard | null>(null)
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [error, setError] = useState<string | null>(null)
|
||||||
|
const [expandedStation, setExpandedStation] = useState<string | null>(null)
|
||||||
|
|
||||||
|
const fetchDashboard = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
const res = await fetch(`/api/sdk/v1/iace/production-lines/${lineId}/dashboard`)
|
||||||
|
if (!res.ok) {
|
||||||
|
setError('Produktionslinie konnte nicht geladen werden')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const json = await res.json()
|
||||||
|
setDashboard(json)
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to fetch line dashboard:', err)
|
||||||
|
setError('Verbindung zum Backend fehlgeschlagen')
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}, [lineId])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchDashboard()
|
||||||
|
}, [fetchDashboard])
|
||||||
|
|
||||||
|
function handleToggle(stationId: string) {
|
||||||
|
setExpandedStation((prev) => (prev === stationId ? null : stationId))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center h-64">
|
||||||
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600" />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error || !dashboard) {
|
||||||
|
return (
|
||||||
|
<div className="text-center py-12 space-y-3">
|
||||||
|
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">
|
||||||
|
{error || 'Produktionslinie nicht gefunden'}
|
||||||
|
</h2>
|
||||||
|
<Link href="/sdk/iace/lines" className="text-purple-600 hover:text-purple-700">
|
||||||
|
Zurueck zur Uebersicht
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const sortedStations = [...dashboard.stations].sort(
|
||||||
|
(a, b) => a.station.sort_order - b.station.sort_order
|
||||||
|
)
|
||||||
|
|
||||||
|
// Build rows of stations for display
|
||||||
|
const rows = buildStationRows(sortedStations, STATIONS_PER_ROW)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6 max-w-7xl mx-auto">
|
||||||
|
{/* Back link */}
|
||||||
|
<Link
|
||||||
|
href="/sdk/iace/lines"
|
||||||
|
className="inline-flex items-center gap-1 text-sm text-purple-600 hover:text-purple-700 dark:text-purple-400 dark:hover:text-purple-300 font-medium"
|
||||||
|
>
|
||||||
|
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||||
|
</svg>
|
||||||
|
Alle Produktionslinien
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{/* Aggregate panel */}
|
||||||
|
<AggregatePanel dashboard={dashboard} />
|
||||||
|
|
||||||
|
{/* Station flow */}
|
||||||
|
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-6">
|
||||||
|
<h2 className="text-sm font-semibold text-gray-900 dark:text-white mb-4">
|
||||||
|
Stationsuebersicht
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div className="space-y-6 overflow-x-auto">
|
||||||
|
{rows.map((row, rowIndex) => (
|
||||||
|
<StationRow
|
||||||
|
key={rowIndex}
|
||||||
|
stations={row}
|
||||||
|
transfers={dashboard.transfers}
|
||||||
|
expandedStation={expandedStation}
|
||||||
|
onToggle={handleToggle}
|
||||||
|
reversed={rowIndex % 2 === 1}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Split sorted stations into rows of N for layout */
|
||||||
|
function buildStationRows(
|
||||||
|
stations: StationDashboard[],
|
||||||
|
perRow: number
|
||||||
|
): StationDashboard[][] {
|
||||||
|
const rows: StationDashboard[][] = []
|
||||||
|
for (let i = 0; i < stations.length; i += perRow) {
|
||||||
|
rows.push(stations.slice(i, i + perRow))
|
||||||
|
}
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Find the transfer between two adjacent station sort orders */
|
||||||
|
function findTransfer(
|
||||||
|
transfers: TransferInfo[],
|
||||||
|
fromOrder: number,
|
||||||
|
toOrder: number
|
||||||
|
): TransferInfo | null {
|
||||||
|
return (
|
||||||
|
transfers.find(
|
||||||
|
(t) => t.from_station === fromOrder && t.to_station === toOrder
|
||||||
|
) || null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Default transfer for stations without an explicit transfer entry */
|
||||||
|
function defaultTransfer(from: number, to: number): TransferInfo {
|
||||||
|
return { from_station: from, to_station: to, type: 'conveyor', label: '' }
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StationRowProps {
|
||||||
|
stations: StationDashboard[]
|
||||||
|
transfers: TransferInfo[]
|
||||||
|
expandedStation: string | null
|
||||||
|
onToggle: (id: string) => void
|
||||||
|
reversed: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
function StationRow({ stations, transfers, expandedStation, onToggle, reversed }: StationRowProps) {
|
||||||
|
// Reverse even rows for a serpentine layout
|
||||||
|
const ordered = reversed ? [...stations].reverse() : stations
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-start gap-0 overflow-x-auto pb-2">
|
||||||
|
{ordered.map((station, idx) => {
|
||||||
|
const nextStation = ordered[idx + 1]
|
||||||
|
const transfer = nextStation
|
||||||
|
? findTransfer(
|
||||||
|
transfers,
|
||||||
|
station.station.sort_order,
|
||||||
|
nextStation.station.sort_order
|
||||||
|
) ||
|
||||||
|
findTransfer(
|
||||||
|
transfers,
|
||||||
|
nextStation.station.sort_order,
|
||||||
|
station.station.sort_order
|
||||||
|
) ||
|
||||||
|
defaultTransfer(station.station.sort_order, nextStation.station.sort_order)
|
||||||
|
: null
|
||||||
|
|
||||||
|
const transferColor = transfer
|
||||||
|
? TRANSFER_COLORS[transfer.type] || TRANSFER_COLORS.conveyor
|
||||||
|
: '#22C55E'
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment key={station.station.id}>
|
||||||
|
<StationCard
|
||||||
|
station={station}
|
||||||
|
expanded={expandedStation === station.station.id}
|
||||||
|
onToggle={() => onToggle(station.station.id)}
|
||||||
|
/>
|
||||||
|
{transfer && (
|
||||||
|
<TransferLine transfer={transfer} color={transferColor} />
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
export interface ProductionLine {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
created_at: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StationDashboard {
|
||||||
|
station: {
|
||||||
|
id: string
|
||||||
|
line_id: string
|
||||||
|
project_id: string
|
||||||
|
station_type: string
|
||||||
|
station_label: string
|
||||||
|
sort_order: number
|
||||||
|
}
|
||||||
|
project_name: string
|
||||||
|
machine_type: string
|
||||||
|
status: string
|
||||||
|
risk_summary: Record<string, number>
|
||||||
|
hazard_count: number
|
||||||
|
mitigation_count: number
|
||||||
|
completeness_pct: number
|
||||||
|
sil_max: string
|
||||||
|
pl_max: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TransferInfo {
|
||||||
|
from_station: number
|
||||||
|
to_station: number
|
||||||
|
type: string
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LineDashboard {
|
||||||
|
line: ProductionLine
|
||||||
|
stations: StationDashboard[]
|
||||||
|
transfers: TransferInfo[]
|
||||||
|
aggregate: Record<string, number>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const STATION_TYPES: Record<string, { label: string; color: string; bgColor: string }> = {
|
||||||
|
press: { label: 'Presse', color: '#EF4444', bgColor: 'bg-red-50' },
|
||||||
|
robot: { label: 'Roboter', color: '#3B82F6', bgColor: 'bg-blue-50' },
|
||||||
|
cobot: { label: 'Cobot', color: '#3B82F6', bgColor: 'bg-blue-50' },
|
||||||
|
collaborative_robot: { label: 'Cobot', color: '#3B82F6', bgColor: 'bg-blue-50' },
|
||||||
|
conveyor: { label: 'Foerderer', color: '#22C55E', bgColor: 'bg-green-50' },
|
||||||
|
assembly: { label: 'Montage', color: '#F97316', bgColor: 'bg-orange-50' },
|
||||||
|
milling: { label: 'Fraese', color: '#8B5CF6', bgColor: 'bg-purple-50' },
|
||||||
|
turning: { label: 'Drehmaschine', color: '#1D4ED8', bgColor: 'bg-blue-50' },
|
||||||
|
welding: { label: 'Schweissen', color: '#EAB308', bgColor: 'bg-yellow-50' },
|
||||||
|
inspection: { label: 'Pruefung', color: '#06B6D4', bgColor: 'bg-cyan-50' },
|
||||||
|
packaging: { label: 'Verpackung', color: '#92400E', bgColor: 'bg-amber-50' },
|
||||||
|
motor: { label: 'Motor', color: '#6B7280', bgColor: 'bg-gray-50' },
|
||||||
|
electric_motor: { label: 'Elektromotor', color: '#6B7280', bgColor: 'bg-gray-50' },
|
||||||
|
rotary_transfer: { label: 'Rundtakt', color: '#7C3AED', bgColor: 'bg-violet-50' },
|
||||||
|
rotary_transfer_machine: { label: 'Rundtakt', color: '#7C3AED', bgColor: 'bg-violet-50' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TRANSFER_COLORS: Record<string, string> = {
|
||||||
|
conveyor: '#22C55E',
|
||||||
|
robot: '#3B82F6',
|
||||||
|
manual: '#EAB308',
|
||||||
|
crane: '#F97316',
|
||||||
|
agv: '#8B5CF6',
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import Link from 'next/link'
|
||||||
|
|
||||||
|
interface ProductionLineItem {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
station_count: number
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ProductionLinesListPage() {
|
||||||
|
const [lines, setLines] = useState<ProductionLineItem[]>([])
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchLines()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
async function fetchLines() {
|
||||||
|
try {
|
||||||
|
const res = await fetch('/api/sdk/v1/iace/production-lines')
|
||||||
|
if (res.ok) {
|
||||||
|
const json = await res.json()
|
||||||
|
setLines(json.lines || json || [])
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to fetch production lines:', err)
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center h-64">
|
||||||
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600" />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6 max-w-6xl mx-auto">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="flex items-start justify-between">
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center gap-2 mb-1">
|
||||||
|
<Link
|
||||||
|
href="/sdk/iace"
|
||||||
|
className="text-xs text-purple-600 hover:text-purple-700 font-medium flex items-center gap-1"
|
||||||
|
>
|
||||||
|
<svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||||
|
</svg>
|
||||||
|
IACE
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">
|
||||||
|
Produktionslinien
|
||||||
|
</h1>
|
||||||
|
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
Verkettete Fertigungsstrassen mit aggregierter Risikoansicht
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Link
|
||||||
|
href="/sdk/iace/lines/new"
|
||||||
|
className="flex items-center gap-2 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors flex-shrink-0"
|
||||||
|
>
|
||||||
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
||||||
|
</svg>
|
||||||
|
Neue Produktionslinie
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Lines list */}
|
||||||
|
{lines.length > 0 ? (
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
|
{lines.map((line) => (
|
||||||
|
<Link
|
||||||
|
key={line.id}
|
||||||
|
href={`/sdk/iace/lines/${line.id}`}
|
||||||
|
className="block bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-6 hover:shadow-md hover:border-purple-300 transition-all"
|
||||||
|
>
|
||||||
|
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-1">
|
||||||
|
{line.name}
|
||||||
|
</h3>
|
||||||
|
{line.description && (
|
||||||
|
<p className="text-sm text-gray-500 dark:text-gray-400 mb-3 line-clamp-2">
|
||||||
|
{line.description}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
<div className="flex items-center gap-4 text-xs text-gray-500 dark:text-gray-400">
|
||||||
|
<span className="flex items-center gap-1">
|
||||||
|
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||||
|
</svg>
|
||||||
|
{line.station_count} Stationen
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
Aktualisiert: {new Date(line.updated_at || line.created_at).toLocaleDateString('de-DE')}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-12 text-center">
|
||||||
|
<div className="w-16 h-16 mx-auto bg-purple-100 dark:bg-purple-900/30 rounded-full flex items-center justify-center mb-4">
|
||||||
|
<svg className="w-8 h-8 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
|
||||||
|
Noch keine Produktionslinien vorhanden
|
||||||
|
</h3>
|
||||||
|
<p className="mt-2 text-gray-500 dark:text-gray-400 max-w-lg mx-auto">
|
||||||
|
Produktionslinien verketten mehrere CE-Projekte zu einer Fertigungsstrasse.
|
||||||
|
Sie sehen auf einen Blick den Risikostatus aller Stationen und koennen
|
||||||
|
Massnahmen priorisieren.
|
||||||
|
</p>
|
||||||
|
<Link
|
||||||
|
href="/sdk/iace/lines/new"
|
||||||
|
className="inline-block mt-6 px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors font-medium"
|
||||||
|
>
|
||||||
|
Erste Produktionslinie erstellen
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
import { ProcessFlow } from './_components/ProcessFlow'
|
||||||
|
|
||||||
interface IACEProject {
|
interface IACEProject {
|
||||||
id: string
|
id: string
|
||||||
@@ -10,7 +11,7 @@ interface IACEProject {
|
|||||||
manufacturer: string
|
manufacturer: string
|
||||||
status: string
|
status: string
|
||||||
completeness_pct: number
|
completeness_pct: number
|
||||||
risk_summary: {
|
risk_summary?: {
|
||||||
critical: number
|
critical: number
|
||||||
high: number
|
high: number
|
||||||
medium: number
|
medium: number
|
||||||
@@ -54,34 +55,35 @@ function CompletenessBar({ pct }: { pct: number }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function RiskDots({ summary }: { summary: IACEProject['risk_summary'] }) {
|
function RiskDots({ summary }: { summary?: IACEProject['risk_summary'] }) {
|
||||||
|
const s = summary || { critical: 0, high: 0, medium: 0, low: 0 }
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-3 text-xs">
|
<div className="flex items-center gap-3 text-xs">
|
||||||
{summary.critical > 0 && (
|
{s.critical > 0 && (
|
||||||
<span className="flex items-center gap-1">
|
<span className="flex items-center gap-1">
|
||||||
<span className="w-2.5 h-2.5 rounded-full bg-red-500" />
|
<span className="w-2.5 h-2.5 rounded-full bg-red-500" />
|
||||||
<span className="text-gray-600">{summary.critical}</span>
|
<span className="text-gray-600">{s.critical}</span>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{summary.high > 0 && (
|
{s.high > 0 && (
|
||||||
<span className="flex items-center gap-1">
|
<span className="flex items-center gap-1">
|
||||||
<span className="w-2.5 h-2.5 rounded-full bg-orange-500" />
|
<span className="w-2.5 h-2.5 rounded-full bg-orange-500" />
|
||||||
<span className="text-gray-600">{summary.high}</span>
|
<span className="text-gray-600">{s.high}</span>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{summary.medium > 0 && (
|
{s.medium > 0 && (
|
||||||
<span className="flex items-center gap-1">
|
<span className="flex items-center gap-1">
|
||||||
<span className="w-2.5 h-2.5 rounded-full bg-yellow-500" />
|
<span className="w-2.5 h-2.5 rounded-full bg-yellow-500" />
|
||||||
<span className="text-gray-600">{summary.medium}</span>
|
<span className="text-gray-600">{s.medium}</span>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{summary.low > 0 && (
|
{s.low > 0 && (
|
||||||
<span className="flex items-center gap-1">
|
<span className="flex items-center gap-1">
|
||||||
<span className="w-2.5 h-2.5 rounded-full bg-green-500" />
|
<span className="w-2.5 h-2.5 rounded-full bg-green-500" />
|
||||||
<span className="text-gray-600">{summary.low}</span>
|
<span className="text-gray-600">{s.low}</span>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{summary.critical === 0 && summary.high === 0 && summary.medium === 0 && summary.low === 0 && (
|
{s.critical === 0 && s.high === 0 && s.medium === 0 && s.low === 0 && (
|
||||||
<span className="text-gray-400">Keine Risiken</span>
|
<span className="text-gray-400">Keine Risiken</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -142,7 +144,13 @@ export default function IACEDashboardPage() {
|
|||||||
const res = await fetch('/api/sdk/v1/iace/projects')
|
const res = await fetch('/api/sdk/v1/iace/projects')
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const json = await res.json()
|
const json = await res.json()
|
||||||
setProjects(json.projects || json || [])
|
const raw = json.projects || json || []
|
||||||
|
// Map API fields to frontend expectations
|
||||||
|
setProjects(raw.map((p: Record<string, unknown>) => ({
|
||||||
|
...p,
|
||||||
|
completeness_pct: p.completeness_pct ?? p.completeness_score ?? 0,
|
||||||
|
risk_summary: p.risk_summary || { critical: 0, high: 0, medium: 0, low: 0 },
|
||||||
|
})))
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to fetch IACE projects:', err)
|
console.error('Failed to fetch IACE projects:', err)
|
||||||
@@ -219,6 +227,36 @@ export default function IACEDashboardPage() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Production Lines Quick Access */}
|
||||||
|
<Link
|
||||||
|
href="/sdk/iace/lines"
|
||||||
|
className="block bg-gradient-to-r from-purple-50 to-indigo-50 dark:from-purple-900/20 dark:to-indigo-900/20 rounded-xl border border-purple-200 dark:border-purple-800 p-6 hover:shadow-md hover:border-purple-300 transition-all group"
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="w-12 h-12 bg-purple-100 dark:bg-purple-900/40 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||||
|
<svg className="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">
|
||||||
|
Produktionslinien
|
||||||
|
</h2>
|
||||||
|
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
Verkettete Fertigungsstrassen mit aggregierter Risikoansicht und animiertem Stationsfluss
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<svg className="w-5 h-5 text-purple-400 group-hover:text-purple-600 transition-colors flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{/* Process Flow */}
|
||||||
|
<ProcessFlow />
|
||||||
|
|
||||||
{/* Create Form */}
|
{/* Create Form */}
|
||||||
{showCreateForm && (
|
{showCreateForm && (
|
||||||
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-6">
|
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-6">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { usePathname, useSearchParams } from 'next/navigation'
|
|||||||
import { SDKProvider } from '@/lib/sdk'
|
import { SDKProvider } from '@/lib/sdk'
|
||||||
import { SDKSidebar } from '@/components/sdk/Sidebar/SDKSidebar'
|
import { SDKSidebar } from '@/components/sdk/Sidebar/SDKSidebar'
|
||||||
import { CommandBar } from '@/components/sdk/CommandBar'
|
import { CommandBar } from '@/components/sdk/CommandBar'
|
||||||
import { SDKPipelineSidebar } from '@/components/sdk/SDKPipelineSidebar'
|
// SDKPipelineSidebar removed — replaced by per-module FAB navigators
|
||||||
import { ComplianceAdvisorWidget } from '@/components/sdk/ComplianceAdvisorWidget'
|
import { ComplianceAdvisorWidget } from '@/components/sdk/ComplianceAdvisorWidget'
|
||||||
import { CookieBannerOverlay, CookieBannerFAB } from '@/components/sdk/CookieBannerOverlay'
|
import { CookieBannerOverlay, CookieBannerFAB } from '@/components/sdk/CookieBannerOverlay'
|
||||||
import { useSDK } from '@/lib/sdk'
|
import { useSDK } from '@/lib/sdk'
|
||||||
@@ -208,8 +208,7 @@ function SDKInnerLayout({ children }: { children: React.ReactNode }) {
|
|||||||
{/* Command Bar Modal */}
|
{/* Command Bar Modal */}
|
||||||
{isCommandBarOpen && <CommandBar onClose={() => setCommandBarOpen(false)} />}
|
{isCommandBarOpen && <CommandBar onClose={() => setCommandBarOpen(false)} />}
|
||||||
|
|
||||||
{/* Pipeline Sidebar (FAB on mobile/tablet, fixed on desktop xl+) */}
|
{/* Module-specific FAB navigators are rendered by each module's layout */}
|
||||||
<SDKPipelineSidebar />
|
|
||||||
|
|
||||||
{/* Compliance Advisor Widget — immer sichtbar, auch ohne Projekt */}
|
{/* Compliance Advisor Widget — immer sichtbar, auch ohne Projekt */}
|
||||||
<ComplianceAdvisorWidget currentStep={currentStep} />
|
<ComplianceAdvisorWidget currentStep={currentStep} />
|
||||||
|
|||||||
@@ -93,11 +93,9 @@ export function CookieBannerOverlay() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Overlay — leaves sidebar (left 64px/16px) accessible */}
|
{/* Non-blocking banner — no overlay, no pointer-events blocking */}
|
||||||
<div className="fixed inset-0 ml-16 xl:ml-64 bg-black/30 z-[9998]" onClick={() => setIsOpen(false)} />
|
<div className="fixed bottom-0 left-16 xl:left-64 right-0 z-50 pointer-events-none">
|
||||||
|
<div className="max-w-3xl mx-auto m-4 bg-white rounded-2xl shadow-2xl border border-gray-200 overflow-hidden pointer-events-auto">
|
||||||
<div className="fixed bottom-0 left-0 right-0 z-[9999]">
|
|
||||||
<div className="max-w-3xl mx-auto m-4 bg-white rounded-2xl shadow-2xl border border-gray-200 overflow-hidden">
|
|
||||||
|
|
||||||
{/* Header with EWR toggle + close button */}
|
{/* Header with EWR toggle + close button */}
|
||||||
<div className="px-6 pt-5 pb-3">
|
<div className="px-6 pt-5 pb-3">
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { defineConfig, devices } from '@playwright/test'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
testDir: './specs',
|
||||||
|
timeout: 30000,
|
||||||
|
use: {
|
||||||
|
baseURL: 'https://macmini:3007',
|
||||||
|
ignoreHTTPSErrors: true,
|
||||||
|
},
|
||||||
|
projects: [
|
||||||
|
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
|
||||||
|
],
|
||||||
|
})
|
||||||
@@ -0,0 +1,328 @@
|
|||||||
|
import { test, expect, Page } from '@playwright/test'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IACE (CE-Compliance) Module — Comprehensive E2E Tests
|
||||||
|
*
|
||||||
|
* Tests all 4 seeded projects across every tab:
|
||||||
|
* Overview, Components, Hazards, Mitigations, Verification, Evidence, Tech-File, Monitoring.
|
||||||
|
*
|
||||||
|
* Run with:
|
||||||
|
* npx playwright test e2e/specs/iace-module.spec.ts --config e2e/playwright-live.config.ts --reporter=list
|
||||||
|
*/
|
||||||
|
|
||||||
|
const BASE = 'https://macmini:3007'
|
||||||
|
|
||||||
|
const PROJECTS = [
|
||||||
|
{
|
||||||
|
id: 'bb7d5b88-469d-401f-a0e3-ae5b867e4a1c',
|
||||||
|
name: 'Kniehebelpresse HP-500',
|
||||||
|
expectedComps: 14,
|
||||||
|
expectedHazards: 8,
|
||||||
|
expectedMeasures: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'a4c4031e-75a5-461e-a575-159f1eabd6b3',
|
||||||
|
name: 'EIGENBAU-Zelle (Cobot)',
|
||||||
|
expectedComps: 7,
|
||||||
|
expectedHazards: 8,
|
||||||
|
expectedMeasures: 26,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'c43af8df-14e0-43ff-b26f-ab425f803e53',
|
||||||
|
name: 'Gleichstrom-/Asynchronmotor',
|
||||||
|
expectedComps: 6,
|
||||||
|
expectedHazards: 6,
|
||||||
|
expectedMeasures: 16,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '3e0808b2-2eed-4e82-b35d-6dd6857bc379',
|
||||||
|
name: 'Schwingarm-Rundtaktanlage',
|
||||||
|
expectedComps: 7,
|
||||||
|
expectedHazards: 10,
|
||||||
|
expectedMeasures: 38,
|
||||||
|
},
|
||||||
|
] as const
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Dismiss the cookie consent banner if present (blocks all clicks). */
|
||||||
|
async function dismissCookieBanner(page: Page) {
|
||||||
|
try {
|
||||||
|
const acceptBtn = page.locator('button', { hasText: 'Nur notwendige Cookies' })
|
||||||
|
if (await acceptBtn.isVisible({ timeout: 3000 })) {
|
||||||
|
await acceptBtn.click({ force: true })
|
||||||
|
await page.waitForTimeout(500)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Banner not present or already dismissed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Navigate, wait for async data, and dismiss cookie overlay. */
|
||||||
|
async function goTo(page: Page, path: string) {
|
||||||
|
await page.goto(`${BASE}${path}`, { waitUntil: 'networkidle', timeout: 30000 })
|
||||||
|
await page.waitForTimeout(2000)
|
||||||
|
await dismissCookieBanner(page)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Assert that no Next.js / React error overlay is present. */
|
||||||
|
async function assertNoAppError(page: Page) {
|
||||||
|
const body = await page.textContent('body')
|
||||||
|
expect(body).not.toContain('Application error')
|
||||||
|
expect(body).not.toContain('Unhandled Runtime Error')
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// 1. IACE Start Page (/sdk/iace)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
test.describe('IACE Start Page', () => {
|
||||||
|
test.setTimeout(60_000)
|
||||||
|
|
||||||
|
test('page loads without error', async ({ page }) => {
|
||||||
|
await goTo(page, '/sdk/iace')
|
||||||
|
await assertNoAppError(page)
|
||||||
|
// The page title (h1) should contain CE-Compliance
|
||||||
|
const body = await page.innerText('body')
|
||||||
|
expect(body).toContain('CE-Compliance (IACE)')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('page description text visible', async ({ page }) => {
|
||||||
|
await goTo(page, '/sdk/iace')
|
||||||
|
const body = await page.innerText('body')
|
||||||
|
expect(body).toContain('Industrial AI Compliance Engine')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('create project button visible', async ({ page }) => {
|
||||||
|
await goTo(page, '/sdk/iace')
|
||||||
|
await expect(
|
||||||
|
page.locator('button', { hasText: 'Neues Projekt erstellen' })
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('sidebar navigation has IACE link', async ({ page }) => {
|
||||||
|
await goTo(page, '/sdk/iace')
|
||||||
|
// The SDK sidebar should have "CE-Compliance (IACE)" as a link
|
||||||
|
const body = await page.innerText('body')
|
||||||
|
expect(body).toContain('CE-Compliance (IACE)')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// 2–9. Per-project tests
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
for (const project of PROJECTS) {
|
||||||
|
test.describe(`Project: ${project.name}`, () => {
|
||||||
|
test.setTimeout(60_000)
|
||||||
|
|
||||||
|
// ------ Overview ------
|
||||||
|
test('overview page loads', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}`)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
await expect(page.locator('h1')).toContainText(project.name, { timeout: 15000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('overview — status workflow visible', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}`)
|
||||||
|
// Status workflow or risk summary should be visible
|
||||||
|
await expect(
|
||||||
|
page.locator('text=Projektstatus').or(page.locator('text=Risikozusammenfassung'))
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('overview — risk summary section', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}`)
|
||||||
|
await expect(
|
||||||
|
page.locator('text=Risikozusammenfassung')
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('overview — component/hazard/measure counters', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}`)
|
||||||
|
// The risk summary card has three counters
|
||||||
|
const body = await page.innerText('body')
|
||||||
|
expect(body).toContain('Komponenten')
|
||||||
|
expect(body).toContain('Gefaehrdungen')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('overview — completeness gates section', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}`)
|
||||||
|
await expect(
|
||||||
|
page.locator('text=Completeness Gates')
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('overview — quick actions present', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}`)
|
||||||
|
await expect(page.locator('text=Schnellzugriff')).toBeVisible({ timeout: 10000 })
|
||||||
|
await expect(page.locator('text=Komponenten verwalten')).toBeVisible({ timeout: 10000 })
|
||||||
|
await expect(page.locator('text=Hazard Log oeffnen')).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('overview — IACE sidebar navigation visible', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}`)
|
||||||
|
// Sidebar with nav items (may be in aside or nav element)
|
||||||
|
await expect(
|
||||||
|
page.locator('text=Uebersicht').or(page.locator('text=Hazard Log')).first()
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('overview — no crash from norms API', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}`)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
})
|
||||||
|
|
||||||
|
// ------ Components ------
|
||||||
|
test('components tab loads', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/components`)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
await expect(page.locator('h1')).toContainText('Komponenten', { timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('components — "Aus Bibliothek waehlen" button', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/components`)
|
||||||
|
await expect(
|
||||||
|
page.locator('button', { hasText: 'Aus Bibliothek waehlen' })
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('components — "Komponente hinzufuegen" button', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/components`)
|
||||||
|
await expect(
|
||||||
|
page.locator('button', { hasText: 'Komponente hinzufuegen' })
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
// ------ Hazards ------
|
||||||
|
test('hazards tab loads', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/hazards`)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
await expect(page.locator('h1')).toContainText('Hazard Log', { timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('hazards — view toggle exists', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/hazards`)
|
||||||
|
await expect(
|
||||||
|
page.locator('button', { hasText: 'Hazard-Liste' })
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
await expect(
|
||||||
|
page.locator('button', { hasText: 'Risikobewertung' })
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('hazards — switch to risk assessment view', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/hazards`)
|
||||||
|
// Click the "Risikobewertung" toggle
|
||||||
|
await page.locator('button', { hasText: 'Risikobewertung' }).click()
|
||||||
|
// Wait for the RiskAssessmentTable to render (fetches mitigations)
|
||||||
|
await page.waitForTimeout(3000)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
// Risk assessment table renders <select> elements (S/E/P/A dropdowns)
|
||||||
|
const selects = page.locator('select')
|
||||||
|
await expect(selects.first()).toBeVisible({ timeout: 15000 })
|
||||||
|
const selectCount = await selects.count()
|
||||||
|
expect(selectCount).toBeGreaterThan(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('hazards — Auto-Erkennung button visible', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/hazards`)
|
||||||
|
await expect(
|
||||||
|
page.locator('button', { hasText: 'Auto-Erkennung' })
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('hazards — Auto-Erkennung click no crash', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/hazards`)
|
||||||
|
await page.locator('button', { hasText: 'Auto-Erkennung' }).click()
|
||||||
|
await page.waitForTimeout(5000)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('hazards — risk level stats visible', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/hazards`)
|
||||||
|
await expect(
|
||||||
|
page.locator('text=Gesamt').first()
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
// ------ Mitigations ------
|
||||||
|
test('mitigations tab loads', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/mitigations`)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
await expect(page.locator('h1')).toContainText('Massnahmen', { timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('mitigations — 3-column layout visible', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/mitigations`)
|
||||||
|
await expect(page.locator('text=Stufe 1: Design')).toBeVisible({ timeout: 10000 })
|
||||||
|
await expect(page.locator('text=Stufe 2: Schutz')).toBeVisible({ timeout: 10000 })
|
||||||
|
await expect(page.locator('text=Stufe 3: Information')).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('mitigations — column descriptions visible', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/mitigations`)
|
||||||
|
// Check for any of the 3-step hierarchy descriptions
|
||||||
|
await expect(
|
||||||
|
page.locator('text=Inhaerent sichere Konstruktion').or(page.locator('text=Stufe 1'))
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
await expect(
|
||||||
|
page.locator('text=Technische Schutzmassnahmen').or(page.locator('text=Stufe 2'))
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
await expect(
|
||||||
|
page.locator('text=Hinweise und Schulungen')
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('mitigations — add buttons per column', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/mitigations`)
|
||||||
|
const addButtons = page.locator('button', { hasText: '+ Hinzufuegen' })
|
||||||
|
const count = await addButtons.count()
|
||||||
|
expect(count).toBe(3)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('mitigations — "Massnahme hinzufuegen" button', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/mitigations`)
|
||||||
|
await expect(
|
||||||
|
page.locator('button', { hasText: 'Massnahme hinzufuegen' })
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('mitigations — "Bibliothek" button', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/mitigations`)
|
||||||
|
await expect(
|
||||||
|
page.locator('button', { hasText: 'Bibliothek' }).first()
|
||||||
|
).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
// ------ Verification ------
|
||||||
|
test('verification tab loads', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/verification`)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
await expect(page.locator('h1')).toContainText('Verifikationsplan', { timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
// ------ Evidence ------
|
||||||
|
test('evidence tab loads', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/evidence`)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
await expect(page.locator('h1')).toContainText('Nachweise', { timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
// ------ Tech File ------
|
||||||
|
test('tech-file tab loads', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/tech-file`)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
await expect(page.locator('h1')).toContainText('CE-Akte', { timeout: 10000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
// ------ Monitoring ------
|
||||||
|
test('monitoring tab loads', async ({ page }) => {
|
||||||
|
await goTo(page, `/sdk/iace/${project.id}/monitoring`)
|
||||||
|
await assertNoAppError(page)
|
||||||
|
await expect(page.locator('h1')).toContainText('Monitoring', { timeout: 10000 })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -148,9 +148,25 @@ func (h *IACEHandler) ListHazards(c *gin.Context) {
|
|||||||
hazards = []iace.Hazard{}
|
hazards = []iace.Hazard{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enrich hazards with latest risk assessment
|
||||||
|
type enrichedHazard struct {
|
||||||
|
iace.Hazard
|
||||||
|
RiskAssessment interface{} `json:"risk_assessment"`
|
||||||
|
}
|
||||||
|
|
||||||
|
enriched := make([]enrichedHazard, len(hazards))
|
||||||
|
for i, hz := range hazards {
|
||||||
|
enriched[i] = enrichedHazard{Hazard: hz}
|
||||||
|
// Get latest assessment for this hazard
|
||||||
|
assessments, err := h.store.ListAssessments(c.Request.Context(), hz.ID)
|
||||||
|
if err == nil && len(assessments) > 0 {
|
||||||
|
enriched[i].RiskAssessment = assessments[len(assessments)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"hazards": hazards,
|
"hazards": enriched,
|
||||||
"total": len(hazards),
|
"total": len(enriched),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,31 @@ import (
|
|||||||
// Mitigations
|
// Mitigations
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
// ListProjectMitigations handles GET /projects/:id/mitigations
|
||||||
|
// Returns all mitigations for all hazards in a project.
|
||||||
|
func (h *IACEHandler) ListProjectMitigations(c *gin.Context) {
|
||||||
|
projectID, err := uuid.Parse(c.Param("id"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mitigations, err := h.store.ListMitigationsByProject(c.Request.Context(), projectID)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if mitigations == nil {
|
||||||
|
mitigations = []iace.Mitigation{}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"mitigations": mitigations,
|
||||||
|
"total": len(mitigations),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// CreateMitigation handles POST /projects/:id/hazards/:hid/mitigations
|
// CreateMitigation handles POST /projects/:id/hazards/:hid/mitigations
|
||||||
// Creates a new mitigation measure for a hazard.
|
// Creates a new mitigation measure for a hazard.
|
||||||
func (h *IACEHandler) CreateMitigation(c *gin.Context) {
|
func (h *IACEHandler) CreateMitigation(c *gin.Context) {
|
||||||
@@ -88,6 +113,23 @@ func (h *IACEHandler) UpdateMitigation(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, gin.H{"mitigation": mitigation})
|
c.JSON(http.StatusOK, gin.H{"mitigation": mitigation})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteMitigation handles DELETE /projects/:id/mitigations/:mid
|
||||||
|
// Deletes a mitigation by ID.
|
||||||
|
func (h *IACEHandler) DeleteMitigation(c *gin.Context) {
|
||||||
|
mitigationID, err := uuid.Parse(c.Param("mid"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid mitigation ID"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.store.DeleteMitigation(c.Request.Context(), mitigationID); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{"message": "mitigation deleted"})
|
||||||
|
}
|
||||||
|
|
||||||
// VerifyMitigation handles POST /mitigations/:mid/verify
|
// VerifyMitigation handles POST /mitigations/:mid/verify
|
||||||
// Marks a mitigation as verified with a verification result.
|
// Marks a mitigation as verified with a verification result.
|
||||||
func (h *IACEHandler) VerifyMitigation(c *gin.Context) {
|
func (h *IACEHandler) VerifyMitigation(c *gin.Context) {
|
||||||
|
|||||||
@@ -0,0 +1,196 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/breakpilot/ai-compliance-sdk/internal/iace"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Norms Library & Norm Suggestions
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ListNormsLibrary handles GET /norms-library
|
||||||
|
// Returns the full norms library, optionally filtered by ?type=A|B1|B2|C
|
||||||
|
// and ?hazard_category=xxx.
|
||||||
|
func (h *IACEHandler) ListNormsLibrary(c *gin.Context) {
|
||||||
|
normType := c.Query("type")
|
||||||
|
hazardCat := c.Query("hazard_category")
|
||||||
|
|
||||||
|
allNorms := iace.GetNormsLibrary()
|
||||||
|
allNorms = append(allNorms, iace.GetExtendedB2Norms()...)
|
||||||
|
allNorms = append(allNorms, iace.GetCNormsLibrary()...)
|
||||||
|
allNorms = append(allNorms, iace.GetExtendedCNormsLibrary()...)
|
||||||
|
allNorms = append(allNorms, iace.GetWoodMetalCNorms()...)
|
||||||
|
allNorms = append(allNorms, iace.GetFoodPkgCNorms()...)
|
||||||
|
allNorms = append(allNorms, iace.GetLiftMiscCNorms()...)
|
||||||
|
|
||||||
|
var filtered []iace.NormReference
|
||||||
|
for _, norm := range allNorms {
|
||||||
|
if normType != "" && norm.NormType != normType {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if hazardCat != "" && !containsString(norm.HazardCats, hazardCat) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filtered = append(filtered, norm)
|
||||||
|
}
|
||||||
|
|
||||||
|
if filtered == nil {
|
||||||
|
filtered = []iace.NormReference{}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"norms": filtered,
|
||||||
|
"total": len(filtered),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SuggestProjectNorms handles GET /projects/:id/suggested-norms
|
||||||
|
// Returns norm suggestions based on the project's machine type, identified
|
||||||
|
// hazards, and component tags.
|
||||||
|
func (h *IACEHandler) SuggestProjectNorms(c *gin.Context) {
|
||||||
|
projectID, err := uuid.Parse(c.Param("id"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch project to get machine type
|
||||||
|
project, err := h.store.GetProject(c.Request.Context(), projectID)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if project == nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "project not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect unique hazard categories from project hazards
|
||||||
|
hazardCategories := collectHazardCategories(h, c, projectID)
|
||||||
|
|
||||||
|
// Collect tags from component metadata
|
||||||
|
tags := collectComponentTags(h, c, projectID)
|
||||||
|
|
||||||
|
result := iace.SuggestNorms(project.MachineType, hazardCategories, tags)
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"suggestions": result,
|
||||||
|
"machine_type": project.MachineType,
|
||||||
|
"hazard_categories": hazardCategories,
|
||||||
|
"tags": tags,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// collectHazardCategories extracts unique hazard categories from a project's hazards.
|
||||||
|
func collectHazardCategories(h *IACEHandler, c *gin.Context, projectID uuid.UUID) []string {
|
||||||
|
hazards, err := h.store.ListHazards(c.Request.Context(), projectID)
|
||||||
|
if err != nil {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
seen := make(map[string]bool)
|
||||||
|
var categories []string
|
||||||
|
for _, hz := range hazards {
|
||||||
|
if hz.Category != "" && !seen[hz.Category] {
|
||||||
|
seen[hz.Category] = true
|
||||||
|
categories = append(categories, hz.Category)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return categories
|
||||||
|
}
|
||||||
|
|
||||||
|
// collectComponentTags extracts tags from the metadata JSON of project components.
|
||||||
|
// Components store tags in their metadata field as {"tags": ["tag1", "tag2"]}.
|
||||||
|
// Additionally, component types are mapped to tags via the component library.
|
||||||
|
func collectComponentTags(h *IACEHandler, c *gin.Context, projectID uuid.UUID) []string {
|
||||||
|
components, err := h.store.ListComponents(c.Request.Context(), projectID)
|
||||||
|
if err != nil {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
seen := make(map[string]bool)
|
||||||
|
var tags []string
|
||||||
|
|
||||||
|
for _, comp := range components {
|
||||||
|
// Extract tags from metadata JSON
|
||||||
|
extracted := extractTagsFromMetadata(comp.Metadata)
|
||||||
|
for _, t := range extracted {
|
||||||
|
if !seen[t] {
|
||||||
|
seen[t] = true
|
||||||
|
tags = append(tags, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract tags from description field ("Tags: x, y, z" pattern)
|
||||||
|
descTags := parseDescriptionTags(comp.Description)
|
||||||
|
for _, t := range descTags {
|
||||||
|
if !seen[t] {
|
||||||
|
seen[t] = true
|
||||||
|
tags = append(tags, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractTagsFromMetadata parses the component metadata JSON for a "tags" array.
|
||||||
|
func extractTagsFromMetadata(metadata json.RawMessage) []string {
|
||||||
|
if len(metadata) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var m map[string]interface{}
|
||||||
|
if err := json.Unmarshal(metadata, &m); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tagsRaw, ok := m["tags"]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
arr, ok := tagsRaw.([]interface{})
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var tags []string
|
||||||
|
for _, v := range arr {
|
||||||
|
if s, ok := v.(string); ok && s != "" {
|
||||||
|
tags = append(tags, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tags
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseDescriptionTags looks for a "Tags: x, y, z" pattern in the description.
|
||||||
|
func parseDescriptionTags(description string) []string {
|
||||||
|
idx := strings.Index(strings.ToLower(description), "tags:")
|
||||||
|
if idx < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take everything after "Tags:"
|
||||||
|
rest := strings.TrimSpace(description[idx+5:])
|
||||||
|
if rest == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split by comma and trim each tag
|
||||||
|
parts := strings.Split(rest, ",")
|
||||||
|
var tags []string
|
||||||
|
for _, p := range parts {
|
||||||
|
t := strings.TrimSpace(p)
|
||||||
|
if t != "" {
|
||||||
|
tags = append(tags, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tags
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/breakpilot/ai-compliance-sdk/internal/iace"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Production Line Handlers
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// CreateProductionLine handles POST /iace/production-lines
|
||||||
|
// Creates a new production line for the authenticated tenant.
|
||||||
|
func (h *IACEHandler) CreateProductionLine(c *gin.Context) {
|
||||||
|
tenantID, err := getTenantID(c)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var req iace.CreateProductionLineRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
line, err := h.store.CreateProductionLine(c.Request.Context(), tenantID, req.Name, req.Description)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusCreated, gin.H{"line": line})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListProductionLines handles GET /iace/production-lines
|
||||||
|
// Lists all production lines for the authenticated tenant.
|
||||||
|
func (h *IACEHandler) ListProductionLines(c *gin.Context) {
|
||||||
|
tenantID, err := getTenantID(c)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lines, err := h.store.ListProductionLines(c.Request.Context(), tenantID)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if lines == nil {
|
||||||
|
lines = []iace.ProductionLine{}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, iace.ProductionLineListResponse{
|
||||||
|
Lines: lines,
|
||||||
|
Total: len(lines),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProductionLineDashboard handles GET /iace/production-lines/:lid/dashboard
|
||||||
|
// Returns the aggregated risk dashboard for a production line.
|
||||||
|
func (h *IACEHandler) GetProductionLineDashboard(c *gin.Context) {
|
||||||
|
lineID, err := uuid.Parse(c.Param("lid"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid line ID"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dashboard, err := h.store.GetLineDashboard(c.Request.Context(), lineID)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if dashboard == nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "production line not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, dashboard)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddStationToLine handles POST /iace/production-lines/:lid/stations
|
||||||
|
// Adds a station (IACE project reference) to a production line.
|
||||||
|
func (h *IACEHandler) AddStationToLine(c *gin.Context) {
|
||||||
|
lineID, err := uuid.Parse(c.Param("lid"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid line ID"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var req iace.AddStationRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the production line exists
|
||||||
|
line, err := h.store.GetProductionLine(c.Request.Context(), lineID)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if line == nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "production line not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the referenced project exists
|
||||||
|
project, err := h.store.GetProject(c.Request.Context(), req.ProjectID)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if project == nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "referenced project not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
station, err := h.store.AddStation(
|
||||||
|
c.Request.Context(), lineID, req.ProjectID,
|
||||||
|
req.StationType, req.StationLabel, req.SortOrder,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusCreated, gin.H{"station": station})
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveStationFromLine handles DELETE /iace/production-lines/:lid/stations/:sid
|
||||||
|
// Removes a station from a production line.
|
||||||
|
func (h *IACEHandler) RemoveStationFromLine(c *gin.Context) {
|
||||||
|
_, err := uuid.Parse(c.Param("lid"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid line ID"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stationID, err := uuid.Parse(c.Param("sid"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid station ID"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.store.RemoveStation(c.Request.Context(), stationID); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{"message": "station removed"})
|
||||||
|
}
|
||||||
@@ -356,6 +356,7 @@ func registerIACERoutes(v1 *gin.RouterGroup, h *handlers.IACEHandler) {
|
|||||||
{
|
{
|
||||||
iaceRoutes.GET("/hazard-library", h.ListHazardLibrary)
|
iaceRoutes.GET("/hazard-library", h.ListHazardLibrary)
|
||||||
iaceRoutes.GET("/controls-library", h.ListControlsLibrary)
|
iaceRoutes.GET("/controls-library", h.ListControlsLibrary)
|
||||||
|
iaceRoutes.GET("/norms-library", h.ListNormsLibrary)
|
||||||
iaceRoutes.GET("/lifecycle-phases", h.ListLifecyclePhases)
|
iaceRoutes.GET("/lifecycle-phases", h.ListLifecyclePhases)
|
||||||
iaceRoutes.GET("/roles", h.ListRoles)
|
iaceRoutes.GET("/roles", h.ListRoles)
|
||||||
iaceRoutes.GET("/evidence-types", h.ListEvidenceTypes)
|
iaceRoutes.GET("/evidence-types", h.ListEvidenceTypes)
|
||||||
@@ -389,8 +390,11 @@ func registerIACERoutes(v1 *gin.RouterGroup, h *handlers.IACEHandler) {
|
|||||||
iaceRoutes.POST("/projects/:id/mitigations/:mid/suggest-evidence", h.SuggestEvidenceForMitigation)
|
iaceRoutes.POST("/projects/:id/mitigations/:mid/suggest-evidence", h.SuggestEvidenceForMitigation)
|
||||||
iaceRoutes.POST("/projects/:id/hazards/:hid/assess", h.AssessRisk)
|
iaceRoutes.POST("/projects/:id/hazards/:hid/assess", h.AssessRisk)
|
||||||
iaceRoutes.GET("/projects/:id/risk-summary", h.GetRiskSummary)
|
iaceRoutes.GET("/projects/:id/risk-summary", h.GetRiskSummary)
|
||||||
|
iaceRoutes.GET("/projects/:id/suggested-norms", h.SuggestProjectNorms)
|
||||||
iaceRoutes.POST("/projects/:id/hazards/:hid/reassess", h.ReassessRisk)
|
iaceRoutes.POST("/projects/:id/hazards/:hid/reassess", h.ReassessRisk)
|
||||||
|
iaceRoutes.GET("/projects/:id/mitigations", h.ListProjectMitigations)
|
||||||
iaceRoutes.POST("/projects/:id/hazards/:hid/mitigations", h.CreateMitigation)
|
iaceRoutes.POST("/projects/:id/hazards/:hid/mitigations", h.CreateMitigation)
|
||||||
|
iaceRoutes.DELETE("/projects/:id/mitigations/:mid", h.DeleteMitigation)
|
||||||
iaceRoutes.PUT("/mitigations/:mid", h.UpdateMitigation)
|
iaceRoutes.PUT("/mitigations/:mid", h.UpdateMitigation)
|
||||||
iaceRoutes.POST("/mitigations/:mid/verify", h.VerifyMitigation)
|
iaceRoutes.POST("/mitigations/:mid/verify", h.VerifyMitigation)
|
||||||
iaceRoutes.POST("/projects/:id/validate-mitigation-hierarchy", h.ValidateMitigationHierarchy)
|
iaceRoutes.POST("/projects/:id/validate-mitigation-hierarchy", h.ValidateMitigationHierarchy)
|
||||||
@@ -411,6 +415,13 @@ func registerIACERoutes(v1 *gin.RouterGroup, h *handlers.IACEHandler) {
|
|||||||
iaceRoutes.GET("/projects/:id/audit-trail", h.GetAuditTrail)
|
iaceRoutes.GET("/projects/:id/audit-trail", h.GetAuditTrail)
|
||||||
iaceRoutes.POST("/library-search", h.SearchLibrary)
|
iaceRoutes.POST("/library-search", h.SearchLibrary)
|
||||||
iaceRoutes.POST("/projects/:id/tech-file/:section/enrich", h.EnrichTechFileSection)
|
iaceRoutes.POST("/projects/:id/tech-file/:section/enrich", h.EnrichTechFileSection)
|
||||||
|
|
||||||
|
// Production Lines
|
||||||
|
iaceRoutes.POST("/production-lines", h.CreateProductionLine)
|
||||||
|
iaceRoutes.GET("/production-lines", h.ListProductionLines)
|
||||||
|
iaceRoutes.GET("/production-lines/:lid/dashboard", h.GetProductionLineDashboard)
|
||||||
|
iaceRoutes.POST("/production-lines/:lid/stations", h.AddStationToLine)
|
||||||
|
iaceRoutes.DELETE("/production-lines/:lid/stations/:sid", h.RemoveStationFromLine)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,4 +19,12 @@ type HazardPattern struct {
|
|||||||
RequiresExpertCalculation bool `json:"requires_expert_calculation,omitempty"`
|
RequiresExpertCalculation bool `json:"requires_expert_calculation,omitempty"`
|
||||||
ExpertHintDE string `json:"expert_hint_de,omitempty"`
|
ExpertHintDE string `json:"expert_hint_de,omitempty"`
|
||||||
ExpertHintEN string `json:"expert_hint_en,omitempty"`
|
ExpertHintEN string `json:"expert_hint_en,omitempty"`
|
||||||
|
// Detail fields — populated into Hazard DB when pattern fires
|
||||||
|
ScenarioDE string `json:"scenario_de,omitempty"` // Gefahrensituation
|
||||||
|
TriggerDE string `json:"trigger_de,omitempty"` // Gefaehrdendes Ereignis
|
||||||
|
HarmDE string `json:"harm_de,omitempty"` // Moegliche Verletzung
|
||||||
|
AffectedDE string `json:"affected_de,omitempty"` // Betroffene Personen
|
||||||
|
ZoneDE string `json:"zone_de,omitempty"` // Gefahrstelle/Zone
|
||||||
|
DefaultSeverity int `json:"default_severity,omitempty"` // 1-5
|
||||||
|
DefaultExposure int `json:"default_exposure,omitempty"` // 1-5
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,441 +5,16 @@ package iace
|
|||||||
// GetBuiltinHazardPatterns returns ~44 built-in hazard patterns organized
|
// GetBuiltinHazardPatterns returns ~44 built-in hazard patterns organized
|
||||||
// by domain (mechanical, electrical, thermal, hydraulic/pneumatic,
|
// by domain (mechanical, electrical, thermal, hydraulic/pneumatic,
|
||||||
// noise/vibration, ergonomic, software/control, cyber/network, AI-specific).
|
// noise/vibration, ergonomic, software/control, cyber/network, AI-specific).
|
||||||
|
// Each domain is defined in its own file for maintainability.
|
||||||
func GetBuiltinHazardPatterns() []HazardPattern {
|
func GetBuiltinHazardPatterns() []HazardPattern {
|
||||||
return []HazardPattern{
|
var all []HazardPattern
|
||||||
// ====================================================================
|
all = append(all, builtinMechanicalPatterns()...)
|
||||||
// Mechanical Patterns (HP001-HP010)
|
all = append(all, builtinElectricalPatterns()...)
|
||||||
// ====================================================================
|
all = append(all, builtinThermalPatterns()...)
|
||||||
{
|
all = append(all, builtinFluidPatterns()...)
|
||||||
ID: "HP001", NameDE: "Quetschgefahr durch bewegte Teile", NameEN: "Crush risk from moving parts",
|
all = append(all, builtinEnvironmentPatterns()...)
|
||||||
RequiredComponentTags: []string{"moving_part"},
|
all = append(all, builtinSoftwarePatterns()...)
|
||||||
RequiredEnergyTags: []string{"kinetic"},
|
all = append(all, builtinCyberPatterns()...)
|
||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
all = append(all, builtinAIPatterns()...)
|
||||||
SuggestedMeasureIDs: []string{"M001", "M005", "M051", "M054"},
|
return all
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08", "E20"},
|
|
||||||
Priority: 95,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP002", NameDE: "Einzugsgefahr durch rotierende Teile", NameEN: "Entanglement risk from rotating parts",
|
|
||||||
RequiredComponentTags: []string{"rotating_part"},
|
|
||||||
RequiredEnergyTags: []string{"rotational"},
|
|
||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M002", "M051", "M053", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
|
||||||
Priority: 95,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP003", NameDE: "Schnittgefahr durch Schneidwerkzeuge", NameEN: "Cut risk from cutting tools",
|
|
||||||
RequiredComponentTags: []string{"cutting_part"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M003", "M051", "M054", "M131"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
|
||||||
Priority: 90,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP004", NameDE: "Klemmgefahr an Quetsch-/Klemmstellen", NameEN: "Pinch risk at clamping points",
|
|
||||||
RequiredComponentTags: []string{"pinch_point"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M001", "M004", "M051", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP005", NameDE: "Quetschgefahr an Quetschstellen", NameEN: "Crush risk at crush points",
|
|
||||||
RequiredComponentTags: []string{"crush_point"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M001", "M005", "M054"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
|
||||||
Priority: 90,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP006", NameDE: "Gefahr durch hohe Kraefte", NameEN: "Risk from high forces",
|
|
||||||
RequiredComponentTags: []string{"high_force"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M001", "M005", "M051", "M106"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E07", "E08"},
|
|
||||||
Priority: 90,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP007", NameDE: "Gefahr durch hohe Geschwindigkeit", NameEN: "Risk from high speed",
|
|
||||||
RequiredComponentTags: []string{"high_speed"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M002", "M051", "M053", "M054"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP008", NameDE: "Absturzgefahr / Herabfallende Teile", NameEN: "Fall/drop risk",
|
|
||||||
RequiredComponentTags: []string{"gravity_risk"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M009", "M121", "M131"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E20"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP009", NameDE: "Gefahr durch Spannvorrichtungen", NameEN: "Clamping device risk",
|
|
||||||
RequiredComponentTags: []string{"clamping_part"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M004", "M051", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
|
||||||
Priority: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP010", NameDE: "Gefahr durch gespeicherte mechanische Energie", NameEN: "Stored mechanical energy risk",
|
|
||||||
RequiredComponentTags: []string{"stored_energy"},
|
|
||||||
RequiredEnergyTags: []string{"mechanical"},
|
|
||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M010", "M121", "M123"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E20"},
|
|
||||||
Priority: 80,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ====================================================================
|
|
||||||
// Electrical Patterns (HP011-HP015)
|
|
||||||
// ====================================================================
|
|
||||||
{
|
|
||||||
ID: "HP011", NameDE: "Stromschlaggefahr durch Hochspannung", NameEN: "Electric shock risk from high voltage",
|
|
||||||
RequiredComponentTags: []string{"high_voltage"},
|
|
||||||
RequiredEnergyTags: []string{"electrical_energy"},
|
|
||||||
GeneratedHazardCats: []string{"electrical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M061", "M062", "M063", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E04", "E10"},
|
|
||||||
Priority: 95,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP012", NameDE: "Gefahr durch elektrische Komponenten", NameEN: "Risk from electrical components",
|
|
||||||
RequiredComponentTags: []string{"electrical_part"},
|
|
||||||
RequiredEnergyTags: []string{"electrical_energy"},
|
|
||||||
GeneratedHazardCats: []string{"electrical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M061", "M064", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E04", "E10"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP013", NameDE: "Gefahr durch gespeicherte elektrische Energie", NameEN: "Stored electrical energy risk",
|
|
||||||
RequiredComponentTags: []string{"stored_energy"},
|
|
||||||
RequiredEnergyTags: []string{"electrical_energy"},
|
|
||||||
GeneratedHazardCats: []string{"electrical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M062", "M063", "M121", "M123"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E10"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP014", NameDE: "Kurzschluss-/Lichtbogengefahr", NameEN: "Short circuit / arc flash risk",
|
|
||||||
RequiredComponentTags: []string{"high_voltage", "electrical_part"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"electrical_hazard", "thermal_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M061", "M065", "M131"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E04", "E10"},
|
|
||||||
Priority: 90,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP015", NameDE: "EMV-Stoerungsgefahr", NameEN: "EMC interference risk",
|
|
||||||
RequiredComponentTags: []string{"electrical_part"},
|
|
||||||
RequiredEnergyTags: []string{"electromagnetic"},
|
|
||||||
GeneratedHazardCats: []string{"emc_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M066", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E10"},
|
|
||||||
Priority: 70,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ====================================================================
|
|
||||||
// Thermal Patterns (HP016-HP018)
|
|
||||||
// ====================================================================
|
|
||||||
{
|
|
||||||
ID: "HP016", NameDE: "Verbrennungsgefahr durch heisse Oberflaechen", NameEN: "Burn risk from hot surfaces",
|
|
||||||
RequiredComponentTags: []string{"high_temperature"},
|
|
||||||
RequiredEnergyTags: []string{"thermal"},
|
|
||||||
GeneratedHazardCats: []string{"thermal_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M071", "M121", "M131"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E20"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP017", NameDE: "Strahlungsgefahr (Laser/optisch)", NameEN: "Radiation risk (laser/optical)",
|
|
||||||
RequiredComponentTags: []string{"radiation_risk"},
|
|
||||||
RequiredEnergyTags: []string{"radiation"},
|
|
||||||
GeneratedHazardCats: []string{"thermal_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M072", "M051", "M131"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E20"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP018", NameDE: "Verbrennungsgefahr durch Aktuatoren", NameEN: "Burn risk from actuators",
|
|
||||||
RequiredComponentTags: []string{"actuator_part", "high_temperature"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"thermal_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M071", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01"},
|
|
||||||
Priority: 75,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ====================================================================
|
|
||||||
// Hydraulic / Pneumatic Patterns (HP019-HP022)
|
|
||||||
// ====================================================================
|
|
||||||
{
|
|
||||||
ID: "HP019", NameDE: "Hydraulikdruck-Gefahr", NameEN: "Hydraulic pressure hazard",
|
|
||||||
RequiredComponentTags: []string{"hydraulic_part"},
|
|
||||||
RequiredEnergyTags: []string{"hydraulic_pressure"},
|
|
||||||
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
|
||||||
SuggestedMeasureIDs: []string{"M081", "M082", "M121", "M123"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E05", "E11"},
|
|
||||||
Priority: 90,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP020", NameDE: "Pneumatikdruck-Gefahr", NameEN: "Pneumatic pressure hazard",
|
|
||||||
RequiredComponentTags: []string{"pneumatic_part"},
|
|
||||||
RequiredEnergyTags: []string{"pneumatic_pressure"},
|
|
||||||
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
|
||||||
SuggestedMeasureIDs: []string{"M083", "M084", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E06", "E11"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP021", NameDE: "Gefahr durch gespeicherten Hydraulikdruck", NameEN: "Stored hydraulic pressure risk",
|
|
||||||
RequiredComponentTags: []string{"hydraulic_part", "stored_energy"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
|
||||||
SuggestedMeasureIDs: []string{"M081", "M082", "M123"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E05", "E11"},
|
|
||||||
Priority: 90,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP022", NameDE: "Gefahr durch Druckluftspeicher", NameEN: "Stored pneumatic pressure risk",
|
|
||||||
RequiredComponentTags: []string{"pneumatic_part", "stored_energy"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
|
||||||
SuggestedMeasureIDs: []string{"M083", "M084", "M123"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E06", "E11"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ====================================================================
|
|
||||||
// Noise / Vibration Patterns (HP023-HP025)
|
|
||||||
// ====================================================================
|
|
||||||
{
|
|
||||||
ID: "HP023", NameDE: "Laermgefahr", NameEN: "Noise hazard",
|
|
||||||
RequiredComponentTags: []string{"noise_source"},
|
|
||||||
RequiredEnergyTags: []string{"acoustic"},
|
|
||||||
GeneratedHazardCats: []string{"noise_vibration"},
|
|
||||||
SuggestedMeasureIDs: []string{"M091", "M131"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E12"},
|
|
||||||
Priority: 70,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP024", NameDE: "Vibrationsgefahr", NameEN: "Vibration hazard",
|
|
||||||
RequiredComponentTags: []string{"vibration_source"},
|
|
||||||
RequiredEnergyTags: []string{"vibration"},
|
|
||||||
GeneratedHazardCats: []string{"noise_vibration"},
|
|
||||||
SuggestedMeasureIDs: []string{"M092", "M131"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E13"},
|
|
||||||
Priority: 65,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP025", NameDE: "Laerm durch rotierende Hochgeschwindigkeitsteile", NameEN: "Noise from high-speed rotating parts",
|
|
||||||
RequiredComponentTags: []string{"rotating_part", "high_speed"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"noise_vibration"},
|
|
||||||
SuggestedMeasureIDs: []string{"M091", "M092", "M131"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E12", "E13"},
|
|
||||||
Priority: 70,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ====================================================================
|
|
||||||
// Ergonomic Patterns (HP026-HP028)
|
|
||||||
// ====================================================================
|
|
||||||
{
|
|
||||||
ID: "HP026", NameDE: "Ergonomische Belastung an Bedienstationen", NameEN: "Ergonomic risk at operator stations",
|
|
||||||
RequiredComponentTags: []string{"user_interface"},
|
|
||||||
RequiredEnergyTags: []string{"ergonomic"},
|
|
||||||
GeneratedHazardCats: []string{"ergonomic"},
|
|
||||||
SuggestedMeasureIDs: []string{"M126", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E24"},
|
|
||||||
Priority: 50,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP027", NameDE: "Ergonomische Belastung bei Wartung in der Hoehe", NameEN: "Ergonomic risk for work at height",
|
|
||||||
RequiredComponentTags: []string{"structural_part", "gravity_risk"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"ergonomic", "mechanical_hazard"},
|
|
||||||
SuggestedMeasureIDs: []string{"M121", "M131"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E20"},
|
|
||||||
Priority: 60,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP028", NameDE: "Fehlbedienungsgefahr", NameEN: "Mode confusion / misoperation risk",
|
|
||||||
RequiredComponentTags: []string{"user_interface", "programmable"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"hmi_error", "mode_confusion"},
|
|
||||||
SuggestedMeasureIDs: []string{"M126", "M127", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E14", "E24"},
|
|
||||||
Priority: 70,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ====================================================================
|
|
||||||
// Software / Control Patterns (HP029-HP034)
|
|
||||||
// ====================================================================
|
|
||||||
{
|
|
||||||
ID: "HP029", NameDE: "Software-Fehler in Steuerung", NameEN: "Software fault in controller",
|
|
||||||
RequiredComponentTags: []string{"has_software", "programmable"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
ExcludedComponentTags: []string{"has_ai"},
|
|
||||||
GeneratedHazardCats: []string{"software_fault"},
|
|
||||||
SuggestedMeasureIDs: []string{"M101", "M102", "M103"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E14"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP030", NameDE: "Sicherheitsfunktionsversagen", NameEN: "Safety function failure",
|
|
||||||
RequiredComponentTags: []string{"safety_device"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"safety_function_failure"},
|
|
||||||
SuggestedMeasureIDs: []string{"M104", "M105", "M051"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E07", "E08", "E09"},
|
|
||||||
Priority: 95,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP031", NameDE: "Konfigurationsfehler", NameEN: "Configuration error",
|
|
||||||
RequiredComponentTags: []string{"programmable"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"configuration_error"},
|
|
||||||
SuggestedMeasureIDs: []string{"M145", "M146", "M121"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E14"},
|
|
||||||
Priority: 70,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP032", NameDE: "Fehlende Protokollierung / Audit", NameEN: "Missing logging / audit",
|
|
||||||
RequiredComponentTags: []string{"has_software"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"logging_audit_failure"},
|
|
||||||
SuggestedMeasureIDs: []string{"M142", "M149"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01"},
|
|
||||||
Priority: 50,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP033", NameDE: "Update-Fehler / Rollback-Problem", NameEN: "Update failure / rollback problem",
|
|
||||||
RequiredComponentTags: []string{"has_software", "programmable"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"update_failure"},
|
|
||||||
SuggestedMeasureIDs: []string{"M138", "M141", "M146"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E14"},
|
|
||||||
Priority: 65,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP034", NameDE: "Verriegelungs-Umgehungsgefahr", NameEN: "Interlock bypass risk",
|
|
||||||
RequiredComponentTags: []string{"interlocked"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"safety_function_failure"},
|
|
||||||
SuggestedMeasureIDs: []string{"M051", "M104", "M107"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ====================================================================
|
|
||||||
// Cyber / Network Patterns (HP035-HP039)
|
|
||||||
// ====================================================================
|
|
||||||
{
|
|
||||||
ID: "HP035", NameDE: "Unbefugter Netzwerkzugriff", NameEN: "Unauthorized network access",
|
|
||||||
RequiredComponentTags: []string{"networked"},
|
|
||||||
RequiredEnergyTags: []string{"cyber"},
|
|
||||||
GeneratedHazardCats: []string{"unauthorized_access"},
|
|
||||||
SuggestedMeasureIDs: []string{"M111", "M112", "M113", "M140"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E16", "E17"},
|
|
||||||
Priority: 90,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP036", NameDE: "Kommunikationsausfall", NameEN: "Communication failure",
|
|
||||||
RequiredComponentTags: []string{"networked", "it_component"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"communication_failure"},
|
|
||||||
SuggestedMeasureIDs: []string{"M114", "M115"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E17"},
|
|
||||||
Priority: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP037", NameDE: "Firmware-Manipulation", NameEN: "Firmware manipulation",
|
|
||||||
RequiredComponentTags: []string{"has_software", "networked"},
|
|
||||||
RequiredEnergyTags: []string{"cyber"},
|
|
||||||
GeneratedHazardCats: []string{"firmware_corruption"},
|
|
||||||
SuggestedMeasureIDs: []string{"M116", "M138", "M146"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E16", "E18"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP038", NameDE: "Drahtlos-Angriff (WiFi/Bluetooth)", NameEN: "Wireless attack (WiFi/Bluetooth)",
|
|
||||||
RequiredComponentTags: []string{"wireless"},
|
|
||||||
RequiredEnergyTags: []string{"cyber"},
|
|
||||||
GeneratedHazardCats: []string{"unauthorized_access"},
|
|
||||||
SuggestedMeasureIDs: []string{"M111", "M113", "M140"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E16"},
|
|
||||||
Priority: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP039", NameDE: "Supply-Chain-Angriff auf IT-Komponenten", NameEN: "Supply chain attack on IT components",
|
|
||||||
RequiredComponentTags: []string{"it_component", "has_software"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"unauthorized_access", "firmware_corruption"},
|
|
||||||
SuggestedMeasureIDs: []string{"M116", "M118"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E18", "E19"},
|
|
||||||
Priority: 75,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ====================================================================
|
|
||||||
// AI-Specific Patterns (HP040-HP044)
|
|
||||||
// ====================================================================
|
|
||||||
{
|
|
||||||
ID: "HP040", NameDE: "KI-Fehlklassifikation", NameEN: "AI misclassification",
|
|
||||||
RequiredComponentTags: []string{"has_ai"},
|
|
||||||
RequiredEnergyTags: []string{"ai_model"},
|
|
||||||
GeneratedHazardCats: []string{"false_classification"},
|
|
||||||
SuggestedMeasureIDs: []string{"M101", "M102"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E15"},
|
|
||||||
Priority: 90,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP041", NameDE: "Model Drift / Concept Drift", NameEN: "Model drift / concept drift",
|
|
||||||
RequiredComponentTags: []string{"has_ai"},
|
|
||||||
RequiredEnergyTags: []string{"ai_model"},
|
|
||||||
GeneratedHazardCats: []string{"model_drift"},
|
|
||||||
SuggestedMeasureIDs: []string{"M103"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E15"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP042", NameDE: "Data Poisoning / Adversarial Attack", NameEN: "Data poisoning / adversarial attack",
|
|
||||||
RequiredComponentTags: []string{"has_ai"},
|
|
||||||
RequiredEnergyTags: []string{"cyber", "ai_model"},
|
|
||||||
GeneratedHazardCats: []string{"data_poisoning"},
|
|
||||||
SuggestedMeasureIDs: []string{"M101", "M116"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E15", "E16"},
|
|
||||||
Priority: 85,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP043", NameDE: "Unbeabsichtigte KI-Diskriminierung", NameEN: "Unintended AI bias",
|
|
||||||
RequiredComponentTags: []string{"has_ai"},
|
|
||||||
RequiredEnergyTags: []string{"ai_model"},
|
|
||||||
GeneratedHazardCats: []string{"unintended_bias"},
|
|
||||||
SuggestedMeasureIDs: []string{"M101"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E15"},
|
|
||||||
Priority: 75,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "HP044", NameDE: "KI-Sensormanipulation", NameEN: "AI sensor spoofing",
|
|
||||||
RequiredComponentTags: []string{"has_ai", "sensor_part"},
|
|
||||||
RequiredEnergyTags: []string{},
|
|
||||||
GeneratedHazardCats: []string{"sensor_spoofing"},
|
|
||||||
SuggestedMeasureIDs: []string{"M101", "M102"},
|
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E15"},
|
|
||||||
Priority: 80,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ================================================================
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// builtinAIPatterns returns HP040-HP044: AI-specific hazard patterns.
|
||||||
|
func builtinAIPatterns() []HazardPattern {
|
||||||
|
return []HazardPattern{
|
||||||
|
{
|
||||||
|
ID: "HP040", NameDE: "KI-Fehlklassifikation", NameEN: "AI misclassification",
|
||||||
|
RequiredComponentTags: []string{"has_ai"},
|
||||||
|
RequiredEnergyTags: []string{"ai_model"},
|
||||||
|
GeneratedHazardCats: []string{"false_classification"},
|
||||||
|
SuggestedMeasureIDs: []string{"M101", "M102"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E15"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "KI-Modell klassifiziert Objekt oder Zustand falsch und loest darauf basierend eine gefaehrliche Aktion aus.",
|
||||||
|
TriggerDE: "Fehlklassifikation durch untypische Eingangsdaten, unzureichendes Training oder Randbedingung ausserhalb der Trainingsdaten.",
|
||||||
|
HarmDE: "Fehlgesteuerte Aktion (z.B. Roboter greift falsch, Qualitaetskontrolle laesst Fehlteil durch).",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Arbeitsbereich des KI-gesteuerten Systems",
|
||||||
|
ZoneDE: "Wirkbereich des KI-gesteuerten Aktors, Klassifikationszone",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP041", NameDE: "Model Drift / Concept Drift", NameEN: "Model drift / concept drift",
|
||||||
|
RequiredComponentTags: []string{"has_ai"},
|
||||||
|
RequiredEnergyTags: []string{"ai_model"},
|
||||||
|
GeneratedHazardCats: []string{"model_drift"},
|
||||||
|
SuggestedMeasureIDs: []string{"M103"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E15"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "KI-Modell verliert ueber Zeit an Genauigkeit, weil sich Eingangsdaten schleichend veraendern.",
|
||||||
|
TriggerDE: "Veraenderung der Produktionsbedingungen (Material, Beleuchtung, Verschleiss) ohne Re-Training des Modells.",
|
||||||
|
HarmDE: "Zunehmende Fehlentscheidungen, nicht erkannte Defekte, unbemerkte Qualitaetsverschlechterung.",
|
||||||
|
AffectedDE: "Bedienpersonal, Endnutzer der Produkte",
|
||||||
|
ZoneDE: "Alle Bereiche, in denen KI-Entscheidungen Aktionen ausloesen",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP042", NameDE: "Data Poisoning / Adversarial Attack", NameEN: "Data poisoning / adversarial attack",
|
||||||
|
RequiredComponentTags: []string{"has_ai"},
|
||||||
|
RequiredEnergyTags: []string{"cyber", "ai_model"},
|
||||||
|
GeneratedHazardCats: []string{"data_poisoning"},
|
||||||
|
SuggestedMeasureIDs: []string{"M101", "M116"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E15", "E16"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Angreifer manipuliert Trainingsdaten oder Eingangssignale, um das KI-Modell gezielt zu taeuschen.",
|
||||||
|
TriggerDE: "Einschleusen manipulierter Daten in den Trainingsprozess oder Adversarial Patches an Sensoren.",
|
||||||
|
HarmDE: "Gezielte Fehlentscheidung des KI-Systems, Umgehung von Sicherheitspruefungen.",
|
||||||
|
AffectedDE: "Bedienpersonal, alle vom KI-System abhaengigen Personen",
|
||||||
|
ZoneDE: "Datenpipeline, Trainingsinfrastruktur, Sensor-Eingaenge, Kamerasichtfeld",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP043", NameDE: "Unbeabsichtigte KI-Diskriminierung", NameEN: "Unintended AI bias",
|
||||||
|
RequiredComponentTags: []string{"has_ai"},
|
||||||
|
RequiredEnergyTags: []string{"ai_model"},
|
||||||
|
GeneratedHazardCats: []string{"unintended_bias"},
|
||||||
|
SuggestedMeasureIDs: []string{"M101"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E15"},
|
||||||
|
Priority: 75,
|
||||||
|
ScenarioDE: "KI-Modell trifft systematisch ungleiche Entscheidungen fuer bestimmte Personengruppen oder Bedingungen.",
|
||||||
|
TriggerDE: "Verzerrung (Bias) in den Trainingsdaten oder Underrepresentation bestimmter Szenarien.",
|
||||||
|
HarmDE: "Diskriminierende Behandlung, inkonsistente Sicherheitsniveaus fuer verschiedene Nutzergruppen.",
|
||||||
|
AffectedDE: "Personen mit unterrepraesentierten Merkmalen, Bediener verschiedener Erfahrungsstufen",
|
||||||
|
ZoneDE: "Alle Entscheidungspunkte des KI-Systems",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP044", NameDE: "KI-Sensormanipulation", NameEN: "AI sensor spoofing",
|
||||||
|
RequiredComponentTags: []string{"has_ai", "sensor_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"sensor_spoofing"},
|
||||||
|
SuggestedMeasureIDs: []string{"M101", "M102"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E15"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Sensor, der KI-Eingangsdaten liefert, wird manipuliert oder liefert durch Verschmutzung/Defekt falsche Werte.",
|
||||||
|
TriggerDE: "Ueberkleben eines Kamerasensors, EMV-Stoerung eines Radarsensors oder gezielte optische Taeuschung.",
|
||||||
|
HarmDE: "KI trifft Entscheidung auf Basis falscher Sensorwerte, gefaehrliche Aktion bei Personenpraesenz.",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Sensorerfassungsbereich",
|
||||||
|
ZoneDE: "Sensorerfassungsbereich, Kamerasichtfeld, Radar-/Lidar-Abdeckungszone",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,12 @@ func GetCobotHazardPatterns() []HazardPattern {
|
|||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Sicherheitsabstaende und maximal zulaessige Kraefte/Geschwindigkeiten muessen berechnet werden.",
|
ExpertHintDE: "Sicherheitsabstaende und maximal zulaessige Kraefte/Geschwindigkeiten muessen berechnet werden.",
|
||||||
ExpertHintEN: "Safety distances and maximum permissible forces/speeds must be calculated.",
|
ExpertHintEN: "Safety distances and maximum permissible forces/speeds must be calculated.",
|
||||||
|
ScenarioDE: "Bediener arbeitet im gemeinsamen Arbeitsraum mit dem Cobot. Roboterarm bewegt sich mit Werkstueck/Werkzeug in Richtung Bediener.",
|
||||||
|
TriggerDE: "Roboterarm trifft Bediener am Oberkoerper, Kopf oder Haenden. Kraft oder Geschwindigkeit ueberschreitet biomechanische Grenzwerte.",
|
||||||
|
HarmDE: "Prellungen, Quetschungen, Knochenbrueche. Bei Kopfkontakt: Gehirnerschuetterung.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter, Wartungspersonal",
|
||||||
|
ZoneDE: "Kollaborativer Arbeitsraum des Roboters",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP060", NameDE: "Quetschen durch Werkzeug am Cobot", NameEN: "Crushing by tool on cobot",
|
ID: "HP060", NameDE: "Quetschen durch Werkzeug am Cobot", NameEN: "Crushing by tool on cobot",
|
||||||
@@ -31,6 +37,12 @@ func GetCobotHazardPatterns() []HazardPattern {
|
|||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Werkzeug-/Werkstueckgeometrie bestimmt das Quetschrisiko. Separate Beurteilung pro Werkzeug erforderlich.",
|
ExpertHintDE: "Werkzeug-/Werkstueckgeometrie bestimmt das Quetschrisiko. Separate Beurteilung pro Werkzeug erforderlich.",
|
||||||
ExpertHintEN: "Tool/workpiece geometry determines crushing risk. Separate assessment per tool required.",
|
ExpertHintEN: "Tool/workpiece geometry determines crushing risk. Separate assessment per tool required.",
|
||||||
|
ScenarioDE: "Cobot fuehrt Werkzeug (Greifer, Schrauber, Schweisszange) nah am Bediener. Quetschstelle zwischen Werkzeug und festem Gegenstand (Tisch, Werkstueck).",
|
||||||
|
TriggerDE: "Werkzeug klemmt Koerperteil des Bedieners gegen feste Flaeche ein.",
|
||||||
|
HarmDE: "Quetschung Finger/Hand, Schnittverletzung bei scharfkantigem Werkzeug.",
|
||||||
|
AffectedDE: "Bedienpersonal",
|
||||||
|
ZoneDE: "Werkzeugspitze / Greifbereich des Cobots",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP061", NameDE: "Nachlauf nach Stopp (Reaktionszeit)", NameEN: "Afterrun after stop (reaction time)",
|
ID: "HP061", NameDE: "Nachlauf nach Stopp (Reaktionszeit)", NameEN: "Afterrun after stop (reaction time)",
|
||||||
@@ -43,6 +55,12 @@ func GetCobotHazardPatterns() []HazardPattern {
|
|||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Nachlaufwegberechnung erforderlich. Sicherheitsfeld muss entsprechend dimensioniert werden.",
|
ExpertHintDE: "Nachlaufwegberechnung erforderlich. Sicherheitsfeld muss entsprechend dimensioniert werden.",
|
||||||
ExpertHintEN: "Afterrun distance calculation required. Safety field must be dimensioned accordingly.",
|
ExpertHintEN: "Afterrun distance calculation required. Safety field must be dimensioned accordingly.",
|
||||||
|
ScenarioDE: "Schutzeinrichtung (Lichtvorhang, Scanner) loest aus, aber Roboter stoppt nicht sofort. Nachlaufweg fuehrt Roboterarm ueber den Schutzfeld-Rand hinaus.",
|
||||||
|
TriggerDE: "Person betritt Schutzfeld, Roboter bewegt sich waehrend des Bremswegs weiter und trifft die Person.",
|
||||||
|
HarmDE: "Prellungen, Quetschungen durch verzoegerten Stopp.",
|
||||||
|
AffectedDE: "Bedienpersonal, Besucher",
|
||||||
|
ZoneDE: "Uebergangsbereich Schutzfeld / Arbeitsraum",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP062", NameDE: "Fehlprogrammierung Kraft-/Geschwindigkeitsgrenzwerte", NameEN: "Misprogramming of force/speed limits",
|
ID: "HP062", NameDE: "Fehlprogrammierung Kraft-/Geschwindigkeitsgrenzwerte", NameEN: "Misprogramming of force/speed limits",
|
||||||
@@ -53,6 +71,12 @@ func GetCobotHazardPatterns() []HazardPattern {
|
|||||||
SuggestedEvidenceIDs: []string{"E01"},
|
SuggestedEvidenceIDs: []string{"E01"},
|
||||||
Priority: 88,
|
Priority: 88,
|
||||||
ExpertHintDE: "Grenzwerte duerfen nur nach Risikobeurteilung veraendert werden. Zugriffsschutz erforderlich.",
|
ExpertHintDE: "Grenzwerte duerfen nur nach Risikobeurteilung veraendert werden. Zugriffsschutz erforderlich.",
|
||||||
|
ScenarioDE: "Programmierer setzt Kraft- oder Geschwindigkeitsgrenzwerte zu hoch ein. Sicherheitsfunktion greift nicht oder zu spaet.",
|
||||||
|
TriggerDE: "Falsch parametrierte Grenzwerte werden in Produktion uebernommen. Roboter ueberschreitet biomechanische Limits.",
|
||||||
|
HarmDE: "Verletzungen durch zu hohe Kontaktkraft. Schwere abhaengig von Ueberschreitung.",
|
||||||
|
AffectedDE: "Bedienpersonal",
|
||||||
|
ZoneDE: "Gesamter kollaborativer Arbeitsraum",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP063", NameDE: "Werkstueck-Herabfallen vom Roboter", NameEN: "Workpiece drop from robot",
|
ID: "HP063", NameDE: "Werkstueck-Herabfallen vom Roboter", NameEN: "Workpiece drop from robot",
|
||||||
@@ -62,6 +86,12 @@ func GetCobotHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M001", "M051"},
|
SuggestedMeasureIDs: []string{"M001", "M051"},
|
||||||
SuggestedEvidenceIDs: []string{"E08"},
|
SuggestedEvidenceIDs: []string{"E08"},
|
||||||
Priority: 82,
|
Priority: 82,
|
||||||
|
ScenarioDE: "Roboter transportiert Werkstueck. Greifer verliert Halt (Druckverlust, falsches Werkstueck, oelige Oberflaeche).",
|
||||||
|
TriggerDE: "Werkstueck faellt herab und trifft Person oder Koerperteil unterhalb des Roboterarms.",
|
||||||
|
HarmDE: "Prellungen, Knochenbrueche (abhaengig von Werkstueckgewicht und Fallhoehe).",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Umfeld",
|
||||||
|
ZoneDE: "Bereich unterhalb des Roboterarms / Transportweg",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP064", NameDE: "Quetschen im Roboter-Arbeitsraum (nicht-kollaborierend)", NameEN: "Crushing in robot workspace (non-collaborative)",
|
ID: "HP064", NameDE: "Quetschen im Roboter-Arbeitsraum (nicht-kollaborierend)", NameEN: "Crushing in robot workspace (non-collaborative)",
|
||||||
@@ -72,6 +102,12 @@ func GetCobotHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M001", "M005", "M051"},
|
SuggestedMeasureIDs: []string{"M001", "M005", "M051"},
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
Priority: 94,
|
Priority: 94,
|
||||||
|
ScenarioDE: "Person betritt abgesicherten Arbeitsraum eines nicht-kollaborierenden Roboters (z.B. bei Stoerungsbeseitigung, Umgehung der Schutzeinrichtung).",
|
||||||
|
TriggerDE: "Roboter bewegt sich unkontrolliert oder startet unerwartet. Quetschen zwischen Roboterarm und Zelle/Werkstueck.",
|
||||||
|
HarmDE: "Schwere Quetschungen, Amputationen, lebensbedrohliche Verletzungen.",
|
||||||
|
AffectedDE: "Wartungspersonal, Einrichter",
|
||||||
|
ZoneDE: "Abgesicherter Roboter-Arbeitsraum",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP065", NameDE: "Einklemmen am Arbeitstisch (Cobot-Zelle)", NameEN: "Trapping at work table (cobot cell)",
|
ID: "HP065", NameDE: "Einklemmen am Arbeitstisch (Cobot-Zelle)", NameEN: "Trapping at work table (cobot cell)",
|
||||||
@@ -81,6 +117,12 @@ func GetCobotHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M001"},
|
SuggestedMeasureIDs: []string{"M001"},
|
||||||
SuggestedEvidenceIDs: []string{"E08"},
|
SuggestedEvidenceIDs: []string{"E08"},
|
||||||
Priority: 70,
|
Priority: 70,
|
||||||
|
ScenarioDE: "Bediener arbeitet am Arbeitstisch neben dem Cobot. Klemmstelle zwischen Roboterarm/Werkzeug und Tischkante oder Vorrichtung.",
|
||||||
|
TriggerDE: "Roboterarm drueckt Koerperteil gegen Tischkante. Klemmkraft uebersteigt biomechanische Grenzwerte.",
|
||||||
|
HarmDE: "Quetschung Finger, Handgelenk.",
|
||||||
|
AffectedDE: "Bedienpersonal",
|
||||||
|
ZoneDE: "Tischkanten, Vorrichtungen im Arbeitsbereich",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// builtinCyberPatterns returns HP035-HP039: cyber and network hazard patterns.
|
||||||
|
func builtinCyberPatterns() []HazardPattern {
|
||||||
|
return []HazardPattern{
|
||||||
|
{
|
||||||
|
ID: "HP035", NameDE: "Unbefugter Netzwerkzugriff", NameEN: "Unauthorized network access",
|
||||||
|
RequiredComponentTags: []string{"networked"},
|
||||||
|
RequiredEnergyTags: []string{"cyber"},
|
||||||
|
GeneratedHazardCats: []string{"unauthorized_access"},
|
||||||
|
SuggestedMeasureIDs: []string{"M111", "M112", "M113", "M140"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E16", "E17"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Angreifer erlangt ueber Netzwerkzugang Kontrolle ueber Maschinensteuerung oder Sicherheitsfunktionen.",
|
||||||
|
TriggerDE: "Ausnutzung offener Ports, Standardpasswoerter oder ungepatchter Schwachstellen im Steuerungsnetz.",
|
||||||
|
HarmDE: "Unkontrollierte Maschinenbewegung durch manipulierte Steuerbefehle, Produktionsstoerung.",
|
||||||
|
AffectedDE: "Bedienpersonal, gesamte Produktionsumgebung",
|
||||||
|
ZoneDE: "Netzwerkschnittstellen, Steuerungs-LAN, Remote-Zugaenge, OPC-UA-Endpoints",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP036", NameDE: "Kommunikationsausfall", NameEN: "Communication failure",
|
||||||
|
RequiredComponentTags: []string{"networked", "it_component"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"communication_failure"},
|
||||||
|
SuggestedMeasureIDs: []string{"M114", "M115"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E17"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Netzwerkverbindung zwischen Steuerungskomponenten faellt aus; Maschine verliert Synchronisation.",
|
||||||
|
TriggerDE: "Kabelbruch, Switch-Ausfall, Paketverslust im Industrial Ethernet oder Busfehler.",
|
||||||
|
HarmDE: "Asynchrone Achsbewegung, Verlust der Positionsrueckmeldung, unkontrollierter Stillstand mit Last.",
|
||||||
|
AffectedDE: "Bedienpersonal, automatisierte Nachbaranlagen",
|
||||||
|
ZoneDE: "Netzwerk-Switches, Profinet/EtherCAT-Leitungen, Feldbus-Stecker",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP037", NameDE: "Firmware-Manipulation", NameEN: "Firmware manipulation",
|
||||||
|
RequiredComponentTags: []string{"has_software", "networked"},
|
||||||
|
RequiredEnergyTags: []string{"cyber"},
|
||||||
|
GeneratedHazardCats: []string{"firmware_corruption"},
|
||||||
|
SuggestedMeasureIDs: []string{"M116", "M138", "M146"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E16", "E18"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Angreifer spielt manipulierte Firmware auf Steuerung oder Antriebsregler, die Sicherheitsgrenzen deaktiviert.",
|
||||||
|
TriggerDE: "Zugriff ueber ungesicherte Update-Schnittstelle, fehlende Signaturpruefung der Firmware.",
|
||||||
|
HarmDE: "Deaktivierung von Sicherheitsfunktionen, Aenderung von Achsgrenzen, verdeckte Manipulation.",
|
||||||
|
AffectedDE: "Bedienpersonal, gesamte Anlage",
|
||||||
|
ZoneDE: "Steuerungshardware, Antriebsregler, Sicherheits-SPS, IoT-Gateways",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP038", NameDE: "Drahtlos-Angriff (WiFi/Bluetooth)", NameEN: "Wireless attack (WiFi/Bluetooth)",
|
||||||
|
RequiredComponentTags: []string{"wireless"},
|
||||||
|
RequiredEnergyTags: []string{"cyber"},
|
||||||
|
GeneratedHazardCats: []string{"unauthorized_access"},
|
||||||
|
SuggestedMeasureIDs: []string{"M111", "M113", "M140"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E16"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Angreifer nutzt drahtlose Schnittstelle zum Einschleusen von Befehlen oder zum Abhoeren der Kommunikation.",
|
||||||
|
TriggerDE: "Schwache WLAN-Verschluesselung, ungepatchte Bluetooth-Schwachstelle oder offener Wartungszugang.",
|
||||||
|
HarmDE: "Uebernahme der Steuerung, Manipulation von Prozessdaten, Denial-of-Service.",
|
||||||
|
AffectedDE: "Bedienpersonal, angebundene Systeme",
|
||||||
|
ZoneDE: "Funkreichweite der drahtlosen Schnittstelle, HMI-Tablets, IoT-Sensoren",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP039", NameDE: "Supply-Chain-Angriff auf IT-Komponenten", NameEN: "Supply chain attack on IT components",
|
||||||
|
RequiredComponentTags: []string{"it_component", "has_software"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"unauthorized_access", "firmware_corruption"},
|
||||||
|
SuggestedMeasureIDs: []string{"M116", "M118"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E18", "E19"},
|
||||||
|
Priority: 75,
|
||||||
|
ScenarioDE: "Kompromittierte Komponente oder Bibliothek wird in der Lieferkette eingeschleust.",
|
||||||
|
TriggerDE: "Bezug manipulierter Hardware/Software vom Zulieferer, fehlende Integritaetspruefung bei Wareneingang.",
|
||||||
|
HarmDE: "Verdeckte Hintertuer in Steuerung, langfristige Kompromittierung, schwer detektierbar.",
|
||||||
|
AffectedDE: "Bedienpersonal, IT-Sicherheitsverantwortliche, Betreiber",
|
||||||
|
ZoneDE: "Alle IT-Komponenten (SPS, IPC, Switches, Sensoren mit Firmware)",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// builtinElectricalPatterns returns HP011-HP015: electrical hazard patterns.
|
||||||
|
func builtinElectricalPatterns() []HazardPattern {
|
||||||
|
return []HazardPattern{
|
||||||
|
{
|
||||||
|
ID: "HP011", NameDE: "Stromschlaggefahr durch Hochspannung", NameEN: "Electric shock risk from high voltage",
|
||||||
|
RequiredComponentTags: []string{"high_voltage"},
|
||||||
|
RequiredEnergyTags: []string{"electrical_energy"},
|
||||||
|
GeneratedHazardCats: []string{"electrical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M061", "M062", "M063", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E04", "E10"},
|
||||||
|
Priority: 95,
|
||||||
|
ScenarioDE: "Person beruehrt spannungsfuehrende Teile bei Wartung, Stoerungsbeseitigung oder durch defekte Isolation.",
|
||||||
|
TriggerDE: "Direktes oder indirektes Beruehren spannungsfuehrender Leiter ueber 50 V AC / 120 V DC.",
|
||||||
|
HarmDE: "Stromschlag, Herzkammerflimmern, Verbrennungen, Todesfolge bei Hochspannung.",
|
||||||
|
AffectedDE: "Wartungspersonal, Elektrofachkraefte, Bedienpersonal",
|
||||||
|
ZoneDE: "Schaltschrank, Klemmenkasten, Motoranschluss, Frequenzumrichter",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP012", NameDE: "Gefahr durch elektrische Komponenten", NameEN: "Risk from electrical components",
|
||||||
|
RequiredComponentTags: []string{"electrical_part"},
|
||||||
|
RequiredEnergyTags: []string{"electrical_energy"},
|
||||||
|
GeneratedHazardCats: []string{"electrical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M061", "M064", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E04", "E10"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Elektrische Bauteile (Motoren, Netzteile, Schaltgeraete) stellen bei Defekt oder offenem Gehaeuse eine Beruehrungsgefahr dar.",
|
||||||
|
TriggerDE: "Isolationsfehler, offene Gehaeuse oder beschaedigte Leitungen fuehren zu Spannungsverschleppung.",
|
||||||
|
HarmDE: "Stromschlag, lokale Verbrennungen, Muskelverkrampfung.",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal",
|
||||||
|
ZoneDE: "Motorgehaeuse, Anschlussklemmen, Netzteile, Kabelkanaele",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP013", NameDE: "Gefahr durch gespeicherte elektrische Energie", NameEN: "Stored electrical energy risk",
|
||||||
|
RequiredComponentTags: []string{"stored_energy"},
|
||||||
|
RequiredEnergyTags: []string{"electrical_energy"},
|
||||||
|
GeneratedHazardCats: []string{"electrical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M062", "M063", "M121", "M123"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E10"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Kondensatoren, Batterien oder Frequenzumrichter halten nach Abschalten gefaehrliche Restspannung.",
|
||||||
|
TriggerDE: "Wartungsarbeiten am Geraet ohne Warten der Entladezeit oder ohne Spannungsfreiheitspruefung.",
|
||||||
|
HarmDE: "Stromschlag, Verbrennungen durch Lichtbogen, Explosion bei Lithium-Akkus.",
|
||||||
|
AffectedDE: "Elektrofachkraefte, Wartungspersonal",
|
||||||
|
ZoneDE: "Zwischenkreiskondensatoren, Batteriefaecher, USV-Anlagen",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP014", NameDE: "Kurzschluss-/Lichtbogengefahr", NameEN: "Short circuit / arc flash risk",
|
||||||
|
RequiredComponentTags: []string{"high_voltage", "electrical_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"electrical_hazard", "thermal_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M061", "M065", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E04", "E10"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Kurzschluss erzeugt Lichtbogen mit extremer Hitze und Druckwelle im Schaltschrank.",
|
||||||
|
TriggerDE: "Werkzeug ueberbrueckt spannungsfuehrende Teile, Isolationsversagen oder Verschmutzung unter Spannung.",
|
||||||
|
HarmDE: "Schwere Verbrennungen (2./3. Grad), Augenverletzung durch UV-Strahlung, Hoerschaden durch Druckwelle.",
|
||||||
|
AffectedDE: "Elektrofachkraefte, Personen in unmittelbarer Naehe",
|
||||||
|
ZoneDE: "Schaltschrank-Innenraum, Sammelschienen, Leistungsschuetze",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP015", NameDE: "EMV-Stoerungsgefahr", NameEN: "EMC interference risk",
|
||||||
|
RequiredComponentTags: []string{"electrical_part"},
|
||||||
|
RequiredEnergyTags: []string{"electromagnetic"},
|
||||||
|
GeneratedHazardCats: []string{"emc_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M066", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E10"},
|
||||||
|
Priority: 70,
|
||||||
|
ScenarioDE: "Elektromagnetische Stoerungen beeinflussen Steuerungssignale und loesen unerwartete Maschinenbewegungen aus.",
|
||||||
|
TriggerDE: "Nahes Hochfrequenzgeraet, mangelnde Schirmung oder fehlende Filterung stoert Steuersignale.",
|
||||||
|
HarmDE: "Fehlausloesung von Aktoren, unerwartete Bewegung, Ausfall von Sicherheitsfunktionen.",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Maschinenbereich",
|
||||||
|
ZoneDE: "Gesamte Maschinenumgebung, insbesondere Signalleitungen und Sensorik",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// builtinEnvironmentPatterns returns HP023-HP028: noise, vibration, and ergonomic patterns.
|
||||||
|
func builtinEnvironmentPatterns() []HazardPattern {
|
||||||
|
return []HazardPattern{
|
||||||
|
// Noise / Vibration
|
||||||
|
{
|
||||||
|
ID: "HP023", NameDE: "Laermgefahr", NameEN: "Noise hazard",
|
||||||
|
RequiredComponentTags: []string{"noise_source"},
|
||||||
|
RequiredEnergyTags: []string{"acoustic"},
|
||||||
|
GeneratedHazardCats: []string{"noise_vibration"},
|
||||||
|
SuggestedMeasureIDs: []string{"M091", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E12"},
|
||||||
|
Priority: 70,
|
||||||
|
ScenarioDE: "Bediener ist waehrend der Schicht dem Maschinenlaerm ausgesetzt.",
|
||||||
|
TriggerDE: "Dauerhafte Laermexposition ueber 85 dB(A) ohne Gehoerschutz.",
|
||||||
|
HarmDE: "Laermschwerhoerigkeit (BK 2301), Tinnitus, Konzentrationsstoerung.",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Umfeld",
|
||||||
|
ZoneDE: "Gesamter Arbeitsbereich um die Maschine, insbesondere Auslassseite",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP024", NameDE: "Vibrationsgefahr", NameEN: "Vibration hazard",
|
||||||
|
RequiredComponentTags: []string{"vibration_source"},
|
||||||
|
RequiredEnergyTags: []string{"vibration"},
|
||||||
|
GeneratedHazardCats: []string{"noise_vibration"},
|
||||||
|
SuggestedMeasureIDs: []string{"M092", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E13"},
|
||||||
|
Priority: 65,
|
||||||
|
ScenarioDE: "Bediener haelt vibrierende Werkzeuge oder arbeitet auf vibrierendem Untergrund ueber laengere Zeit.",
|
||||||
|
TriggerDE: "Langzeit-Vibrationsexposition ueber Tagesgrenzwert (Hand-Arm 5 m/s2, Ganzkoerper 1.15 m/s2).",
|
||||||
|
HarmDE: "Hand-Arm-Vibrationssyndrom (BK 2104), Durchblutungsstoerung, Gelenkschaeden.",
|
||||||
|
AffectedDE: "Bedienpersonal, Maschinenfuehrer",
|
||||||
|
ZoneDE: "Griffe, Bedienelemente, Standfussbereich, Fahrersitz",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP025", NameDE: "Laerm durch rotierende Hochgeschwindigkeitsteile", NameEN: "Noise from high-speed rotating parts",
|
||||||
|
RequiredComponentTags: []string{"rotating_part", "high_speed"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"noise_vibration"},
|
||||||
|
SuggestedMeasureIDs: []string{"M091", "M092", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E12", "E13"},
|
||||||
|
Priority: 70,
|
||||||
|
ScenarioDE: "Schnelllaufende Spindeln, Luefter oder Schleifscheiben erzeugen hohen Schallpegel und Vibrationen.",
|
||||||
|
TriggerDE: "Betrieb bei hoher Drehzahl ohne Schallschutzkapselung oder Entkopplung.",
|
||||||
|
HarmDE: "Gehoerschaedigung, Tinnitus, erhoehtes Unfallrisiko durch Konzentrationsverlust.",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Hallenbereich",
|
||||||
|
ZoneDE: "Umgebung der Spindel/Schleifscheibe, Maschinengehaeuse, offene Bearbeitungszone",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
// Ergonomic
|
||||||
|
{
|
||||||
|
ID: "HP026", NameDE: "Ergonomische Belastung an Bedienstationen", NameEN: "Ergonomic risk at operator stations",
|
||||||
|
RequiredComponentTags: []string{"user_interface"},
|
||||||
|
RequiredEnergyTags: []string{"ergonomic"},
|
||||||
|
GeneratedHazardCats: []string{"ergonomic"},
|
||||||
|
SuggestedMeasureIDs: []string{"M126", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E24"},
|
||||||
|
Priority: 50,
|
||||||
|
ScenarioDE: "Bediener arbeitet in unguenstiger Koerperhaltung (stehend, gebeugt, verdreht) ueber laengere Schichtdauer.",
|
||||||
|
TriggerDE: "Wiederholte Taetigkeit in Zwangshaltung ohne ausreichende Erholungspausen.",
|
||||||
|
HarmDE: "Muskel-Skelett-Erkrankung, Rueckenbeschwerden (BK 2108), Sehnenscheidenentzuendung.",
|
||||||
|
AffectedDE: "Bedienpersonal",
|
||||||
|
ZoneDE: "Bedienpult, Materialzufuhr, Teileentnahme, Sichtfenster",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP027", NameDE: "Ergonomische Belastung bei Wartung in der Hoehe", NameEN: "Ergonomic risk for work at height",
|
||||||
|
RequiredComponentTags: []string{"structural_part", "gravity_risk"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"ergonomic", "mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M121", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E20"},
|
||||||
|
Priority: 60,
|
||||||
|
ScenarioDE: "Wartungsarbeiten erfordern Zugang zu hoch gelegenen Bauteilen ueber Leitern oder Geruestkonstruktionen.",
|
||||||
|
TriggerDE: "Abrutschen von Leiter, Fehltritt auf Wartungsplattform, fehlende Absturzsicherung.",
|
||||||
|
HarmDE: "Sturzverletzung, Fraktur, Kopfverletzung, in schweren Faellen Todesfolge.",
|
||||||
|
AffectedDE: "Wartungspersonal, Servicetechniker",
|
||||||
|
ZoneDE: "Wartungsplattformen, Leitern, Kranbahnen, obere Maschinenabdeckungen",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP028", NameDE: "Fehlbedienungsgefahr", NameEN: "Mode confusion / misoperation risk",
|
||||||
|
RequiredComponentTags: []string{"user_interface", "programmable"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"hmi_error", "mode_confusion"},
|
||||||
|
SuggestedMeasureIDs: []string{"M126", "M127", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E14", "E24"},
|
||||||
|
Priority: 70,
|
||||||
|
ScenarioDE: "Bediener verwechselt Betriebsarten oder aktiviert falsche Funktion durch unklare HMI-Gestaltung.",
|
||||||
|
TriggerDE: "Betriebsartenwahlschalter nicht eindeutig, missverstaendliche Symbole oder fehlende Rueckmeldung.",
|
||||||
|
HarmDE: "Unerwartete Maschinenbewegung, Anlauf im falschen Modus, Verletzung durch ungesicherten Betrieb.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter",
|
||||||
|
ZoneDE: "Bedienpanel, Touchscreen, Betriebsartenwahlschalter, Freigabetaster",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,652 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// GetExtendedHazardPatterns2 returns 40 additional hazard patterns (HP134-HP173)
|
||||||
|
// covering environmental risks, extended maintenance, electrical/pneumatic/
|
||||||
|
// hydraulic additions, press/forming specifics, robot/cobot extensions,
|
||||||
|
// conveyor systems, software/control failures, and general workplace hazards.
|
||||||
|
func GetExtendedHazardPatterns2() []HazardPattern {
|
||||||
|
return []HazardPattern{
|
||||||
|
// ================================================================
|
||||||
|
// Umgebungsrisiken / Environmental Context (HP134-HP137)
|
||||||
|
// ================================================================
|
||||||
|
{
|
||||||
|
ID: "HP134", NameDE: "Beleuchtungsmaengel am Arbeitsplatz", NameEN: "Insufficient workplace lighting",
|
||||||
|
RequiredComponentTags: []string{"structural_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"ergonomic"},
|
||||||
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 55,
|
||||||
|
ScenarioDE: "Unzureichende Beleuchtung am Arbeitsplatz fuehrt zu Fehlbedienung oder Sturzgefahr.",
|
||||||
|
TriggerDE: "Defekte Beleuchtung, fehlende Ausleuchtung des Arbeitsbereichs",
|
||||||
|
HarmDE: "Fehlbedienung, Stolpern, Augenermuedung, erhoehtes Unfallrisiko",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal",
|
||||||
|
ZoneDE: "Gesamter Arbeitsplatz, Bedienbereich",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP135", NameDE: "Bodenunebenproblem im Maschinenumfeld", NameEN: "Floor irregularities near machinery",
|
||||||
|
RequiredComponentTags: []string{"structural_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 50,
|
||||||
|
ScenarioDE: "Stolperkanten, Kabel, Schlauchleitungen im Gehbereich um die Maschine.",
|
||||||
|
TriggerDE: "Lose Leitungen, Schwellen, Unebenheiten am Boden nahe Maschinenzugang",
|
||||||
|
HarmDE: "Stuerze, Prellungen, Verstauchungen, Knochenbrueche",
|
||||||
|
AffectedDE: "Alle Personen im Maschinenumfeld",
|
||||||
|
ZoneDE: "Verkehrswege und Zugangsbereiche um die Maschine",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP136", NameDE: "Klimatische Belastung (Hitze/Kaelte)", NameEN: "Climatic stress (heat/cold)",
|
||||||
|
RequiredComponentTags: []string{"high_temperature"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"ergonomic"},
|
||||||
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 55,
|
||||||
|
ScenarioDE: "Bediener ist extremer Hitze oder Kaelte am Maschinenarbeitsplatz ausgesetzt.",
|
||||||
|
TriggerDE: "Waermeabstrahlung der Maschine, ungenuegend klimatisierter Arbeitsbereich",
|
||||||
|
HarmDE: "Kreislaufversagen, Konzentrationsstoerung, Erfrierungen, Hitzschlag",
|
||||||
|
AffectedDE: "Bedienpersonal bei Dauereinsatz",
|
||||||
|
ZoneDE: "Bedienstand, Arbeitsbereich im Maschinenumfeld",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP137", NameDE: "Blendung durch Prozesslicht", NameEN: "Glare from process light",
|
||||||
|
RequiredComponentTags: []string{"high_temperature"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M005", "M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 65,
|
||||||
|
ScenarioDE: "Blendung durch Schweisslichtbogen, Laserstrahlung oder helle Prozessbeleuchtung.",
|
||||||
|
TriggerDE: "Direkter Blickkontakt mit Schweisslichtbogen oder Laserstrahl",
|
||||||
|
HarmDE: "Voruebergehende Blindheit, Netzhautschaeden, Reaktionsfehler",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Sichtfeld",
|
||||||
|
ZoneDE: "Prozesszone, Sichtbereich zum Bearbeitungsort",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Instandhaltung erweitert (HP138-HP141)
|
||||||
|
// ================================================================
|
||||||
|
{
|
||||||
|
ID: "HP138", NameDE: "Arbeiten unter Zeitdruck bei Stoerung", NameEN: "Working under time pressure during fault clearing",
|
||||||
|
RequiredComponentTags: []string{"moving_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
RequiredLifecycles: []string{"fault_clearing"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M121", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E14", "E21"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Unter Produktionsdruck werden Sicherheitsmassnahmen bei Stoerungsbeseitigung umgangen.",
|
||||||
|
TriggerDE: "Produktionsstillstand erzeugt Zeitdruck, Schutzeinrichtungen werden ueberbrueckt",
|
||||||
|
HarmDE: "Quetschungen, Schnittverletzungen, Einklemmen durch anlaufende Maschinenteile",
|
||||||
|
AffectedDE: "Instandhaltungspersonal, Maschinenbediener",
|
||||||
|
ZoneDE: "Stoerungsbereich, Gefahrenzone der Maschine",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP139", NameDE: "Fehlende Ersatzteile fuehren zu Improvisation", NameEN: "Missing spare parts lead to improvisation",
|
||||||
|
RequiredComponentTags: []string{"structural_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
RequiredLifecycles: []string{"maintenance"},
|
||||||
|
GeneratedHazardCats: []string{"maintenance_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E14", "E20"},
|
||||||
|
Priority: 70,
|
||||||
|
ScenarioDE: "Nicht-originale Ersatzteile oder improvisierte Reparaturen beeintraechtigen die Sicherheit.",
|
||||||
|
TriggerDE: "Original-Ersatzteile nicht verfuegbar, provisorische Loesung eingebaut",
|
||||||
|
HarmDE: "Versagen der reparierten Komponente, Folgeunfall durch Materialbruch",
|
||||||
|
AffectedDE: "Wartungspersonal, nachfolgendes Bedienpersonal",
|
||||||
|
ZoneDE: "Reparaturstelle, betroffene Maschinenbaugruppe",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP140", NameDE: "Kontamination bei Oelwechsel", NameEN: "Contamination during oil change",
|
||||||
|
RequiredComponentTags: []string{"hydraulic_part", "oil_mist_risk"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
RequiredLifecycles: []string{"maintenance"},
|
||||||
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 55,
|
||||||
|
ScenarioDE: "Hautkontakt mit Hydraulikoel, Kuehlschmierstoff beim Wechsel ohne Schutzhandschuhe.",
|
||||||
|
TriggerDE: "Oelwechsel oder Nachfuellen ohne persoenliche Schutzausruestung",
|
||||||
|
HarmDE: "Hautreizung, allergische Kontaktdermatitis, langfristige Hautschaeden",
|
||||||
|
AffectedDE: "Wartungspersonal",
|
||||||
|
ZoneDE: "Hydraulikaggregat, Kuehlmittelbehaelter",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP141", NameDE: "Vergessenes Werkzeug in der Maschine", NameEN: "Forgotten tool inside machine",
|
||||||
|
RequiredComponentTags: []string{"moving_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
RequiredLifecycles: []string{"maintenance"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M121", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E14"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Nach Wartung vergessenes Werkzeug wird beim Anlauf der Maschine zum Geschoss.",
|
||||||
|
TriggerDE: "Werkzeug liegt im Arbeitsraum, Maschine wird ohne Kontrolle gestartet",
|
||||||
|
HarmDE: "Wegschleudern des Werkzeugs, schwere Verletzungen durch Projektil",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Umfeld",
|
||||||
|
ZoneDE: "Arbeitsraum, Schleuderbereich der Maschine",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Elektrische Zusatzrisiken (HP142-HP144)
|
||||||
|
// ================================================================
|
||||||
|
{
|
||||||
|
ID: "HP142", NameDE: "Elektrostatische Aufladung bei Kunststoffverarbeitung", NameEN: "Electrostatic charge in plastics processing",
|
||||||
|
RequiredComponentTags: []string{"electrical_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"electrical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M014"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E10"},
|
||||||
|
Priority: 55,
|
||||||
|
ScenarioDE: "Statische Aufladung bei Folientransport oder Granulat fuehrt zu Funkenbildung.",
|
||||||
|
TriggerDE: "Reibung bei Folienlauf, Granulattransport ohne Erdung",
|
||||||
|
HarmDE: "Zuendung brennbarer Atmosphaere, Stromschlag, Erschrecken",
|
||||||
|
AffectedDE: "Bedienpersonal an Kunststoffmaschinen",
|
||||||
|
ZoneDE: "Folienlauf, Trichter, Transportleitungen",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP143", NameDE: "Fehlerhafte Schutzleiterverbindung", NameEN: "Defective protective conductor connection",
|
||||||
|
RequiredComponentTags: []string{"electrical_part", "high_voltage"},
|
||||||
|
RequiredEnergyTags: []string{"electrical_energy"},
|
||||||
|
GeneratedHazardCats: []string{"electrical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M061", "M062"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E10", "E14"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Korrodierte oder unterbrochene Schutzleiter fuehren bei Isolationsfehler zu Koerperdurchstroemung.",
|
||||||
|
TriggerDE: "Korrosion, lose Klemme, mechanische Beschaedigung des Schutzleiters",
|
||||||
|
HarmDE: "Elektrischer Schlag, Herzkammerflimmern, Tod",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal",
|
||||||
|
ZoneDE: "Maschinengehaeuse, Schaltschrank, Klemmkasten",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP144", NameDE: "Restspannung nach Abschaltung", NameEN: "Residual voltage after shutdown",
|
||||||
|
RequiredComponentTags: []string{"electrical_part", "stored_energy"},
|
||||||
|
RequiredEnergyTags: []string{"electrical_energy"},
|
||||||
|
GeneratedHazardCats: []string{"electrical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M061", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E10", "E14"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Kondensatoren oder Zwischenkreise halten Spannung nach Abschaltung.",
|
||||||
|
TriggerDE: "Wartung beginnt ohne Spannungsfreiheitspruefung, Entladezeit nicht abgewartet",
|
||||||
|
HarmDE: "Elektrischer Schlag, Lichtbogenverbrennungen, Herzkammerflimmern",
|
||||||
|
AffectedDE: "Wartungspersonal, Elektriker",
|
||||||
|
ZoneDE: "Frequenzumrichter, Zwischenkreis, Kondensatorbatterien",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Pneumatik/Hydraulik erweitert (HP145-HP147)
|
||||||
|
// ================================================================
|
||||||
|
{
|
||||||
|
ID: "HP145", NameDE: "Peitscheneffekt bei Schlauchbruch", NameEN: "Whiplash effect from hose rupture",
|
||||||
|
RequiredComponentTags: []string{"hydraulic_part", "high_pressure"},
|
||||||
|
RequiredEnergyTags: []string{"hydraulic_pressure"},
|
||||||
|
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
SuggestedMeasureIDs: []string{"M021", "M054"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E11", "E20"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Hydraulikschlauch reisst unter Druck und peitscht unkontrolliert.",
|
||||||
|
TriggerDE: "Materialermuedung, Schlauch-Ueberschreitung der Lebensdauer, Knickbelastung",
|
||||||
|
HarmDE: "Peitschenverletzung, Hochdruckinjektion, Knochenbrueche",
|
||||||
|
AffectedDE: "Wartungspersonal, Bedienpersonal im Nahbereich",
|
||||||
|
ZoneDE: "Schlauchverlauf, Arbeitsbereich unterhalb der Hydraulikleitungen",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP146", NameDE: "Oelaustritt auf heisse Oberflaeche", NameEN: "Oil leak onto hot surface",
|
||||||
|
RequiredComponentTags: []string{"hydraulic_part", "high_temperature"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
|
SuggestedMeasureIDs: []string{"M021", "M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E11", "E20"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Leckierendes Hydraulikoel tropft auf heisse Maschinenteile und entzuendet sich.",
|
||||||
|
TriggerDE: "Leckage an Schlauchverbindung, Dichtungsversagen nahe Waermequelle",
|
||||||
|
HarmDE: "Brand, Verbrennungen, Rauchgasvergiftung",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Brandbereich",
|
||||||
|
ZoneDE: "Hydraulikleitungen oberhalb heisser Maschinenbauteile",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP147", NameDE: "Druckstoss in Pneumatikleitung", NameEN: "Pressure surge in pneumatic line",
|
||||||
|
RequiredComponentTags: []string{"pneumatic_part"},
|
||||||
|
RequiredEnergyTags: []string{"pneumatic_pressure"},
|
||||||
|
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
SuggestedMeasureIDs: []string{"M022"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E11"},
|
||||||
|
Priority: 70,
|
||||||
|
ScenarioDE: "Schlagartiger Druckaufbau in Pneumatikleitung bei Ventilversagen.",
|
||||||
|
TriggerDE: "Defektes Ventil oeffnet schlagartig, Druckminderer versagt",
|
||||||
|
HarmDE: "Unkontrollierte Zylinderbewegung, Leitungsabriss, Verletzung durch Druckwelle",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal",
|
||||||
|
ZoneDE: "Pneumatikverteilung, Zylinderbereich",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Spezifisch Pressen/Umformung (HP148-HP150)
|
||||||
|
// ================================================================
|
||||||
|
{
|
||||||
|
ID: "HP148", NameDE: "Splitterflug bei Werkzeugbruch", NameEN: "Fragment ejection from tool fracture",
|
||||||
|
RequiredComponentTags: []string{"high_force", "crush_point"},
|
||||||
|
RequiredEnergyTags: []string{"kinetic"},
|
||||||
|
RequiredLifecycles: []string{"normal_operation"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M001", "M005"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E08", "E20"},
|
||||||
|
Priority: 95,
|
||||||
|
ScenarioDE: "Werkzeug bricht unter Last, Splitter werden mit hoher Energie geschleudert.",
|
||||||
|
TriggerDE: "Werkzeugbruch durch Materialermuedung, Ueberlast oder Fehlausrichtung",
|
||||||
|
HarmDE: "Durchdringende Verletzungen, Augenverlust, toedliche Treffer",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Schleuderbereich",
|
||||||
|
ZoneDE: "Pressraum, Schleuderbereich vor und seitlich der Presse",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP149", NameDE: "Rueckschlag bei exzentrischem Pressen", NameEN: "Kickback from eccentric pressing",
|
||||||
|
RequiredComponentTags: []string{"high_force", "moving_part"},
|
||||||
|
RequiredEnergyTags: []string{"kinetic"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M003", "M005"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E08"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Exzentrische Belastung des Stoessels fuehrt zu seitlichem Ausbrechen des Werkstuecks.",
|
||||||
|
TriggerDE: "Werkstueck nicht korrekt positioniert, seitliche Kraftkomponente entsteht",
|
||||||
|
HarmDE: "Aufprallverletzung durch geschleudertes Werkstueck, Quetschung",
|
||||||
|
AffectedDE: "Bedienpersonal an der Presse",
|
||||||
|
ZoneDE: "Seiten- und Frontbereich des Pressenwerkzeugs",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP150", NameDE: "Herabfallen der Abstreifplatte", NameEN: "Stripper plate falling",
|
||||||
|
RequiredComponentTags: []string{"gravity_risk", "high_force"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M004", "M005"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E08", "E20"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Abstreifplatte loest sich bei Rueckhub und faellt auf Haende/Arme des Bedieners.",
|
||||||
|
TriggerDE: "Verschleiss der Halterung, falsche Montage der Abstreifplatte",
|
||||||
|
HarmDE: "Quetschung, Knochenbrueche an Haenden und Unterarmen",
|
||||||
|
AffectedDE: "Bedienpersonal beim Teileentnahme",
|
||||||
|
ZoneDE: "Einlege-/Entnahmebereich der Presse",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Roboter/Cobot erweitert (HP151-HP154)
|
||||||
|
// ================================================================
|
||||||
|
{
|
||||||
|
ID: "HP151", NameDE: "Kollision bei Teach-In-Betrieb", NameEN: "Collision during teach-in operation",
|
||||||
|
RequiredComponentTags: []string{"programmable", "moving_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
RequiredLifecycles: []string{"setup"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M082", "M106", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E09", "E21"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Programmierer fuehrt Roboter manuell. Unbeabsichtigte Bewegung bei Programmfehler.",
|
||||||
|
TriggerDE: "Fehlerhafter Teach-Befehl, versehentliche Tastenaktivierung am Handgeraet",
|
||||||
|
HarmDE: "Quetschung, Aufprallverletzung durch Roboterarm oder Werkzeug",
|
||||||
|
AffectedDE: "Programmierpersonal, Inbetriebnahme-Techniker",
|
||||||
|
ZoneDE: "Roboter-Arbeitsraum, Teach-Zone",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP152", NameDE: "Greifer oeffnet unbeabsichtigt", NameEN: "Gripper opens unintentionally",
|
||||||
|
RequiredComponentTags: []string{"moving_part", "gravity_risk"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M004", "M082"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E08", "E14"},
|
||||||
|
Priority: 70,
|
||||||
|
ScenarioDE: "Greifer verliert Werkstueck durch Druckverlust, Signalausfall oder Softwarefehler.",
|
||||||
|
TriggerDE: "Druckluftausfall am Greifer, Signalverlust, fehlerhafter Greifbefehl",
|
||||||
|
HarmDE: "Herabfallendes Werkstueck trifft Personen, Quetschung, Fussverletzung",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen unterhalb des Roboters",
|
||||||
|
ZoneDE: "Greifbereich, Fallzone unterhalb des Roboterarms",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP153", NameDE: "Quetschen an Kabelfuehrung/Energiekette", NameEN: "Pinching at cable carrier/energy chain",
|
||||||
|
RequiredComponentTags: []string{"moving_part", "pinch_point"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M003", "M051"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E08"},
|
||||||
|
Priority: 60,
|
||||||
|
ScenarioDE: "Finger eingeklemmt zwischen Energiekette und Robotersockel bei Drehbewegung.",
|
||||||
|
TriggerDE: "Eingriff in Energiekette waehrend Roboterbewegung, fehlende Abdeckung",
|
||||||
|
HarmDE: "Fingerfraktur, Quetschverletzung, Amputation in schweren Faellen",
|
||||||
|
AffectedDE: "Wartungspersonal, Programmierer",
|
||||||
|
ZoneDE: "Energiekettenfuehrung, Robotersockel-Bereich",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP154", NameDE: "Kollision zweier Roboter", NameEN: "Collision of two robots",
|
||||||
|
RequiredComponentTags: []string{"programmable", "moving_part"},
|
||||||
|
RequiredEnergyTags: []string{"kinetic"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M082", "M103", "M106"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E09", "E14", "E15"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Zwei Roboter arbeiten im ueberlappenden Arbeitsraum. Koordinationsfehler fuehrt zu Kollision.",
|
||||||
|
TriggerDE: "Softwarefehler in der Koordinationslogik, Signalverzoegerung im Bussystem",
|
||||||
|
HarmDE: "Wegschleudern von Teilen, Beschaedigung der Anlage, Personenverletzung",
|
||||||
|
AffectedDE: "Bedienpersonal im Ueberlappungsbereich",
|
||||||
|
ZoneDE: "Ueberlappender Arbeitsraum beider Roboter",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Foerdertechnik (HP155-HP157)
|
||||||
|
// ================================================================
|
||||||
|
{
|
||||||
|
ID: "HP155", NameDE: "Einzug an Bandumlenkung", NameEN: "Nip point at belt deflection",
|
||||||
|
RequiredComponentTags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
RequiredEnergyTags: []string{"rotational"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M001", "M051"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E08", "E20"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Finger oder Kleidung werden an der Bandumlenkstelle eingezogen.",
|
||||||
|
TriggerDE: "Eingriff am laufenden Band, lose Kleidung geraet in Umlenkrolle",
|
||||||
|
HarmDE: "Fingeramputation, Armverletzung, Strangulation durch eingezogene Kleidung",
|
||||||
|
AffectedDE: "Bedienpersonal, Reinigungspersonal",
|
||||||
|
ZoneDE: "Umlenkrollen, Bandlauf-Einzugsstellen",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP156", NameDE: "Herabfallen von Foerdergut", NameEN: "Falling conveyed goods",
|
||||||
|
RequiredComponentTags: []string{"gravity_risk", "moving_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M005", "M052"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 70,
|
||||||
|
ScenarioDE: "Werkstuecke fallen vom Foerderband auf Personen unterhalb.",
|
||||||
|
TriggerDE: "Bandstoerung, Stau, Ueberladung, seitliches Abrutschen",
|
||||||
|
HarmDE: "Kopfverletzung, Quetschung, Fraktur durch herabfallende Last",
|
||||||
|
AffectedDE: "Personen unterhalb der Foerderstrecke",
|
||||||
|
ZoneDE: "Bereich unterhalb erhoehter Foerderabschnitte",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP157", NameDE: "Notstop-Kette nicht vollstaendig", NameEN: "Emergency stop chain incomplete",
|
||||||
|
RequiredComponentTags: []string{"moving_part", "safety_device"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"safety_function_failure"},
|
||||||
|
SuggestedMeasureIDs: []string{"M082", "M106"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E09", "E14"},
|
||||||
|
Priority: 95,
|
||||||
|
ScenarioDE: "Not-Halt-Kette unterbricht nicht alle Antriebe der verketteten Anlage.",
|
||||||
|
TriggerDE: "Fehlerhaft verdrahtete Not-Halt-Kette, nachtraeglich ergaenzte Antriebe nicht eingebunden",
|
||||||
|
HarmDE: "Person betaetigt Not-Halt, Teile der Anlage laufen weiter, schwere Verletzung",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal, alle Personen im Anlagenbereich",
|
||||||
|
ZoneDE: "Gesamte verkettete Anlage, insbesondere nicht abgedeckte Teilbereiche",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Software/Steuerung erweitert (HP158-HP160)
|
||||||
|
// ================================================================
|
||||||
|
{
|
||||||
|
ID: "HP158", NameDE: "Ungetestete Software-Aenderung", NameEN: "Untested software change",
|
||||||
|
RequiredComponentTags: []string{"has_software", "programmable"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"safety_function_failure"},
|
||||||
|
SuggestedMeasureIDs: []string{"M103", "M106"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E14", "E15"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Software-Update wird ohne ausreichende Tests in Produktion uebernommen.",
|
||||||
|
TriggerDE: "Update der Steuerungssoftware ohne Validierung der Sicherheitsfunktionen",
|
||||||
|
HarmDE: "Unvorhergesehenes Maschinenverhalten, sicherheitskritische Fehlfunktion",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Maschinenbereich",
|
||||||
|
ZoneDE: "Gesamte Maschine / Anlage",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP159", NameDE: "Parameterverlust nach Spannungsausfall", NameEN: "Parameter loss after power failure",
|
||||||
|
RequiredComponentTags: []string{"has_software", "programmable"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"safety_function_failure"},
|
||||||
|
SuggestedMeasureIDs: []string{"M103"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E14", "E15"},
|
||||||
|
Priority: 75,
|
||||||
|
ScenarioDE: "Steuerungsparameter gehen bei Spannungsausfall verloren, Maschine startet mit Werkseinstellungen.",
|
||||||
|
TriggerDE: "Spannungsausfall, Batterie der SPS leer, EEPROM-Fehler",
|
||||||
|
HarmDE: "Maschine faehrt mit falschen Geschwindigkeiten oder Kraefte, Kollision",
|
||||||
|
AffectedDE: "Bedienpersonal nach Wiederanlauf",
|
||||||
|
ZoneDE: "Steuerungsschrank, Arbeitsraum der Maschine",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP160", NameDE: "Busausfall/Kommunikationsverlust", NameEN: "Bus failure/communication loss",
|
||||||
|
RequiredComponentTags: []string{"has_software", "programmable"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"safety_function_failure"},
|
||||||
|
SuggestedMeasureIDs: []string{"M082", "M103", "M106"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E09", "E14", "E15"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Feldbus-Kommunikation bricht ab. Antriebe verlieren Sollwerte, unkontrollierte Bewegung.",
|
||||||
|
TriggerDE: "EMV-Stoerung, Kabelbruch, Steckerfehler im Feldbus-System",
|
||||||
|
HarmDE: "Unkontrollierte Achsbewegungen, Kollision, Quetschung",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Bewegungsbereich",
|
||||||
|
ZoneDE: "Alle busgesteuerten Achsen und Antriebe",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Allgemeine Zusatzrisiken (HP161-HP173)
|
||||||
|
// ================================================================
|
||||||
|
{
|
||||||
|
ID: "HP161", NameDE: "Allergische Reaktion auf Kuehlschmierstoff", NameEN: "Allergic reaction to cutting fluid",
|
||||||
|
RequiredComponentTags: []string{"chemical_risk"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 50,
|
||||||
|
ScenarioDE: "Hautkontakt mit Kuehlschmierstoff loest allergische Dermatitis aus.",
|
||||||
|
TriggerDE: "Wiederholter Hautkontakt ohne Handschuhe, Spritzer beim Maschinenbetrieb",
|
||||||
|
HarmDE: "Kontaktekzem, chronische Dermatitis, Atemwegssensibilisierung",
|
||||||
|
AffectedDE: "Bedienpersonal bei zerspanenden Maschinen",
|
||||||
|
ZoneDE: "Bearbeitungszone, Maschinenumgebung mit KSS-Nebel",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP162", NameDE: "Absturz von erhoehtem Standort", NameEN: "Fall from elevated position",
|
||||||
|
RequiredComponentTags: []string{"structural_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
RequiredLifecycles: []string{"maintenance"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M052", "M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Wartungspersonal stuerzt von Leiter, Podest oder Maschinenoberteil.",
|
||||||
|
TriggerDE: "Fehlende Absturzsicherung, defektes Gelaender, rutschige Standflaeche",
|
||||||
|
HarmDE: "Knochenbrueche, Wirbelsaeulenverletzung, toedlicher Sturz",
|
||||||
|
AffectedDE: "Wartungspersonal, Reinigungspersonal",
|
||||||
|
ZoneDE: "Maschinenplattformen, Steigleitern, Wartungspodeste",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP163", NameDE: "Quetschen beim manuellen Materialeinlegen", NameEN: "Crushing during manual material loading",
|
||||||
|
RequiredComponentTags: []string{"moving_part", "crush_point"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M003", "M004", "M082"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E08", "E09"},
|
||||||
|
Priority: 95,
|
||||||
|
ScenarioDE: "Bediener legt Material manuell ein. Maschine startet waehrend Haende im Gefahrenbereich.",
|
||||||
|
TriggerDE: "Zweihandschaltung defekt, Schutzgitter umgangen, vorzeitiger Maschinentakt",
|
||||||
|
HarmDE: "Handquetschung, Amputation, schwere Weichteilverletzung",
|
||||||
|
AffectedDE: "Bedienpersonal an Pressen, Stanzen, Biegemaschinen",
|
||||||
|
ZoneDE: "Einlege- und Entnahmebereich, Werkzeugraum",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP164", NameDE: "Augenverletzung durch Spaeneflug", NameEN: "Eye injury from flying chips",
|
||||||
|
RequiredComponentTags: []string{"cutting_part", "high_speed"},
|
||||||
|
RequiredEnergyTags: []string{"kinetic"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M001", "M005", "M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Metallspaene werden bei der Bearbeitung mit hoher Geschwindigkeit geschleudert.",
|
||||||
|
TriggerDE: "Zerspanung ohne geschlossene Kabine, fehlende Schutzbrille",
|
||||||
|
HarmDE: "Augenverletzung, Hornhautschaeden, Erblindung",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen in der Naehe der Maschine",
|
||||||
|
ZoneDE: "Bearbeitungszone, Spaeneflugbereich",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP165", NameDE: "Stolpern ueber Versorgungsleitungen", NameEN: "Tripping over supply lines",
|
||||||
|
RequiredComponentTags: []string{"structural_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 50,
|
||||||
|
ScenarioDE: "Druckluft-, Hydraulik- oder Elektroleitungen liegen ungesichert auf dem Boden.",
|
||||||
|
TriggerDE: "Nachtraeglich verlegte Leitungen ohne Kabelkanaele oder Ueberfahrschutz",
|
||||||
|
HarmDE: "Stuerze, Prellungen, Verstauchungen, Sekundaerunfall an Maschine",
|
||||||
|
AffectedDE: "Alle Personen im Fertigungsbereich",
|
||||||
|
ZoneDE: "Verkehrswege zwischen Maschinen, Zugangsflaechen",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP166", NameDE: "Rueckschlag bei Schleifmaschine", NameEN: "Kickback at grinding machine",
|
||||||
|
RequiredComponentTags: []string{"rotating_part", "high_speed"},
|
||||||
|
RequiredEnergyTags: []string{"rotational"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M001", "M005"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E08", "E20"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Schleifscheibe verklemmt, Werkstueck wird zurueckgeschleudert.",
|
||||||
|
TriggerDE: "Verkanten des Werkstuecks, Verklemmen der Schleifscheibe",
|
||||||
|
HarmDE: "Aufprallverletzung durch geschleudertes Werkstueck, Handverletzung",
|
||||||
|
AffectedDE: "Bedienpersonal an handgefuehrten und stationaeren Schleifmaschinen",
|
||||||
|
ZoneDE: "Schleifbereich, Bereich gegenueber der Schleifscheibe",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP167", NameDE: "Laserstrahl trifft Reflexion", NameEN: "Laser beam hits reflective surface",
|
||||||
|
RequiredComponentTags: []string{"high_temperature"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
|
SuggestedMeasureIDs: []string{"M005", "M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E10", "E20"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Laserstrahl wird an glaenzender Oberflaeche reflektiert und trifft Person oder brennbares Material.",
|
||||||
|
TriggerDE: "Spiegelndes Werkstueck, ungeplante Reflexion ausserhalb des Strahlfangbereichs",
|
||||||
|
HarmDE: "Augenverletzung, Hautverbrennung, Entzuendung von Material",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Laserbereich",
|
||||||
|
ZoneDE: "Laserbearbeitungskabine, Reflexionswege",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP168", NameDE: "Berstende Schleifscheibe", NameEN: "Bursting grinding wheel",
|
||||||
|
RequiredComponentTags: []string{"rotating_part", "high_speed"},
|
||||||
|
RequiredEnergyTags: []string{"rotational"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M001", "M005"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E08", "E20"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Schleifscheibe berstet bei Ueberdrehzahl. Bruchstuecke als Geschosse.",
|
||||||
|
TriggerDE: "Ueberdrehzahl, Materialfehler in der Schleifscheibe, falsche Scheibe montiert",
|
||||||
|
HarmDE: "Durchdringende Verletzungen, toedliche Treffer durch Bruchstuecke",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Schleuderbereich",
|
||||||
|
ZoneDE: "Schleuderbereich um die Schleifmaschine",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP169", NameDE: "Einatmen von Schweissrauch", NameEN: "Inhalation of welding fumes",
|
||||||
|
RequiredComponentTags: []string{"high_temperature", "chemical_risk"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 65,
|
||||||
|
ScenarioDE: "Schweissrauch enthaelt Metalloxide und Gase. Chronische Lungenerkrankung bei Dauerexposition.",
|
||||||
|
TriggerDE: "Schweissen ohne Absaugung, ungenuegend beluefteter Arbeitsplatz",
|
||||||
|
HarmDE: "Metalldampffieber, chronische Bronchitis, Lungenfibrose, Manganismus",
|
||||||
|
AffectedDE: "Schweisspersonal, Personen im gleichen Raum",
|
||||||
|
ZoneDE: "Schweissarbeitsplatz, gesamter Hallenbereich ohne Absaugung",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP170", NameDE: "Quetschen an Drehteller/Rundtaktanlage", NameEN: "Crushing at rotary table/rotary indexing machine",
|
||||||
|
RequiredComponentTags: []string{"moving_part", "rotating_part"},
|
||||||
|
RequiredEnergyTags: []string{"rotational"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M003", "M051"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E08", "E20"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Hand wird zwischen Drehteller und festem Anschlag eingeklemmt bei Taktbewegung.",
|
||||||
|
TriggerDE: "Eingriff waehrend der Taktbewegung, fehlende Schutzabdeckung am Drehteller",
|
||||||
|
HarmDE: "Quetschung, Fingerfraktur, Amputation von Fingern",
|
||||||
|
AffectedDE: "Bedienpersonal an Rundtaktanlagen",
|
||||||
|
ZoneDE: "Drehteller-Peripherie, Uebergabestationen",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP171", NameDE: "Unkontrollierte Bewegung bei Druckluftausfall", NameEN: "Uncontrolled movement on compressed air failure",
|
||||||
|
RequiredComponentTags: []string{"pneumatic_part", "moving_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
SuggestedMeasureIDs: []string{"M022", "M082"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E11", "E14"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Druckluftausfall fuehrt zu unkontrolliertem Absenken pneumatisch gehaltener Teile.",
|
||||||
|
TriggerDE: "Kompressorausfall, Leitungsbruch, versehentliches Absperren",
|
||||||
|
HarmDE: "Quetschung durch absinkende Achse, Herabfallen gehaltener Teile",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal unterhalb pneumatischer Achsen",
|
||||||
|
ZoneDE: "Bereich unter pneumatisch gehaltenen Baugruppen",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP172", NameDE: "Hautverbrennung durch UV-Strahlung", NameEN: "Skin burn from UV radiation",
|
||||||
|
RequiredComponentTags: []string{"high_temperature"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"thermal_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M005", "M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E10", "E20"},
|
||||||
|
Priority: 65,
|
||||||
|
ScenarioDE: "UV-Strahlung bei Schweissen oder UV-Haertung verursacht Hautverbrennungen.",
|
||||||
|
TriggerDE: "Arbeiten ohne UV-Schutzkleidung, fehlende Abschirmung des UV-Bereichs",
|
||||||
|
HarmDE: "Sonnenbrandaehnliche Verbrennungen, langfristig Hautkrebsrisiko",
|
||||||
|
AffectedDE: "Schweisspersonal, Bediener an UV-Haertungsanlagen",
|
||||||
|
ZoneDE: "Schweissarbeitsplatz, UV-Haertungszone",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP173", NameDE: "Erstickungsgefahr in engen Raeumen", NameEN: "Suffocation hazard in confined spaces",
|
||||||
|
RequiredComponentTags: []string{"chemical_risk"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Sauerstoffmangel in Behaeltern, Silos oder engen Raeumen durch Inertgas oder Gaerung.",
|
||||||
|
TriggerDE: "Betreten von Behaeltern ohne Gasfreimessung, Inertgas-Spuelung nicht abgeschlossen",
|
||||||
|
HarmDE: "Bewusstlosigkeit, Erstickung, Tod innerhalb weniger Minuten",
|
||||||
|
AffectedDE: "Wartungspersonal, Reinigungspersonal in Behaeltern/Silos",
|
||||||
|
ZoneDE: "Behaelterinneres, Silos, Gruben, enge Schaechte",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M001", "M141"},
|
SuggestedMeasureIDs: []string{"M001", "M141"},
|
||||||
Priority: 75,
|
Priority: 75,
|
||||||
|
ScenarioDE: "Kontakt mit scharfen Kanten bei Bearbeitung oder Einrichten", HarmDE: "Schnittverletzungen an Haenden und Armen",
|
||||||
|
TriggerDE: "Greifen an unentgratete Kanten", AffectedDE: "Bedienpersonal", ZoneDE: "Werkzeugbereich", DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP095", NameDE: "Stossgefahr durch bewegte Maschinenteile", NameEN: "Impact by moving machine parts",
|
ID: "HP095", NameDE: "Stossgefahr durch bewegte Maschinenteile", NameEN: "Impact by moving machine parts",
|
||||||
@@ -30,6 +32,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M001", "M005"},
|
SuggestedMeasureIDs: []string{"M001", "M005"},
|
||||||
Priority: 88,
|
Priority: 88,
|
||||||
|
ScenarioDE: "Aufprall durch schnell bewegte Maschinenteile", HarmDE: "Prellungen, Knochenbrueche, innere Verletzungen",
|
||||||
|
TriggerDE: "Versagen der Schutzeinrichtung", AffectedDE: "Bedienpersonal", ZoneDE: "Bewegungsraum der Maschine", DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP096", NameDE: "Reibung/Abrieb durch rotierende Oberflaechen", NameEN: "Friction/abrasion by rotating surfaces",
|
ID: "HP096", NameDE: "Reibung/Abrieb durch rotierende Oberflaechen", NameEN: "Friction/abrasion by rotating surfaces",
|
||||||
@@ -38,6 +42,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M001"},
|
SuggestedMeasureIDs: []string{"M001"},
|
||||||
Priority: 60,
|
Priority: 60,
|
||||||
|
ScenarioDE: "Reibung an rotierender Welle oder Walze bei Wartung", HarmDE: "Hautabschuerfungen, Verbrennungen durch Reibungswaerme",
|
||||||
|
TriggerDE: "Beruehrung laufender Teile", AffectedDE: "Wartungspersonal", ZoneDE: "Walzen-/Wellenbereich", DefaultSeverity: 2, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP097", NameDE: "Hochdruckstrahl (Wasser/Oel) verletzt Haut", NameEN: "High-pressure jet injures skin",
|
ID: "HP097", NameDE: "Hochdruckstrahl (Wasser/Oel) verletzt Haut", NameEN: "High-pressure jet injures skin",
|
||||||
@@ -47,6 +53,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M054", "M141"},
|
SuggestedMeasureIDs: []string{"M054", "M141"},
|
||||||
Priority: 85,
|
Priority: 85,
|
||||||
ExpertHintDE: "Hochdruckinjektionsverletzung — sofortige chirurgische Behandlung erforderlich.",
|
ExpertHintDE: "Hochdruckinjektionsverletzung — sofortige chirurgische Behandlung erforderlich.",
|
||||||
|
ScenarioDE: "Austritt von Hochdruckstrahl bei Leitungsbruch", HarmDE: "Hochdruckinjektionsverletzung, Gewebezerstoerung",
|
||||||
|
TriggerDE: "Leckage oder Bruch einer Druckleitung", AffectedDE: "Bedienpersonal", ZoneDE: "Druckleitungsbereich", DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP098", NameDE: "Wegschleudern von Teilen/Splittern", NameEN: "Ejection of parts/fragments",
|
ID: "HP098", NameDE: "Wegschleudern von Teilen/Splittern", NameEN: "Ejection of parts/fragments",
|
||||||
@@ -55,6 +63,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M001", "M005"},
|
SuggestedMeasureIDs: []string{"M001", "M005"},
|
||||||
Priority: 90,
|
Priority: 90,
|
||||||
|
ScenarioDE: "Wegschleudern von Bruchstuecken bei Werkzeugbruch", HarmDE: "Augenverletzungen, Schnittwunden, Durchdringung",
|
||||||
|
TriggerDE: "Bersten rotierender Teile", AffectedDE: "Bedienpersonal, Umstehende", ZoneDE: "Schleuderbereich", DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP099", NameDE: "Stolpern/Stuerzen durch Bodenunebenheiten", NameEN: "Tripping/falling due to floor irregularities",
|
ID: "HP099", NameDE: "Stolpern/Stuerzen durch Bodenunebenheiten", NameEN: "Tripping/falling due to floor irregularities",
|
||||||
@@ -63,6 +73,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 50,
|
Priority: 50,
|
||||||
|
ScenarioDE: "Stolpern ueber Leitungen, Kabel oder Unebenheiten am Boden", HarmDE: "Prellungen, Verstauchungen, Knochenbrueche",
|
||||||
|
TriggerDE: "Unebener Boden oder herumliegende Gegenstaende", AffectedDE: "Alle Personen im Bereich", ZoneDE: "Verkehrswege, Arbeitsflaeche", DefaultSeverity: 2, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP100", NameDE: "Erfassen durch offene Zahnraeder/Ketten", NameEN: "Entanglement by open gears/chains",
|
ID: "HP100", NameDE: "Erfassen durch offene Zahnraeder/Ketten", NameEN: "Entanglement by open gears/chains",
|
||||||
@@ -71,6 +83,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M001", "M005"},
|
SuggestedMeasureIDs: []string{"M001", "M005"},
|
||||||
Priority: 92,
|
Priority: 92,
|
||||||
|
ScenarioDE: "Erfassen von Koerperteilen durch offene Zahnraeder oder Ketten", HarmDE: "Quetschung, Abtrennung von Gliedmassen",
|
||||||
|
TriggerDE: "Hineingreifen in ungesicherten Antrieb", AffectedDE: "Bedienpersonal, Wartungspersonal", ZoneDE: "Getriebe-/Kettenbereich", DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP101", NameDE: "Aufwickeln von Kleidung/Haaren", NameEN: "Winding up of clothing/hair",
|
ID: "HP101", NameDE: "Aufwickeln von Kleidung/Haaren", NameEN: "Winding up of clothing/hair",
|
||||||
@@ -79,6 +93,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M001", "M141"},
|
SuggestedMeasureIDs: []string{"M001", "M141"},
|
||||||
Priority: 85,
|
Priority: 85,
|
||||||
|
ScenarioDE: "Aufwickeln langer Haare oder loser Kleidung an Welle", HarmDE: "Skalpierung, Strangulation, schwere Weichteilverletzung",
|
||||||
|
TriggerDE: "Lose Kleidung geraet in rotierende Teile", AffectedDE: "Bedienpersonal", ZoneDE: "Rotierende Wellen/Spindeln", DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP102", NameDE: "Pendelnde/schwingende Lasten", NameEN: "Swinging/pendulating loads",
|
ID: "HP102", NameDE: "Pendelnde/schwingende Lasten", NameEN: "Swinging/pendulating loads",
|
||||||
@@ -87,6 +103,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M051"},
|
SuggestedMeasureIDs: []string{"M051"},
|
||||||
Priority: 80,
|
Priority: 80,
|
||||||
|
ScenarioDE: "Unkontrolliertes Schwingen einer angehobenen Last", HarmDE: "Quetschung, Erschlagen durch pendelnde Last",
|
||||||
|
TriggerDE: "Schraeger Zug oder ploetzliches Abstoppen", AffectedDE: "Kranfuehrer, Anschlaeger", ZoneDE: "Schwenkbereich des Krans", DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP103", NameDE: "Rueckschlag von Werkzeugen", NameEN: "Kickback of tools",
|
ID: "HP103", NameDE: "Rueckschlag von Werkzeugen", NameEN: "Kickback of tools",
|
||||||
@@ -95,6 +113,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M001", "M141"},
|
SuggestedMeasureIDs: []string{"M001", "M141"},
|
||||||
Priority: 82,
|
Priority: 82,
|
||||||
|
ScenarioDE: "Rueckschlag einer Handkreissaege oder Fraese bei Verklemmen", HarmDE: "Schnittverletzungen, Frakturen an Haenden/Armen",
|
||||||
|
TriggerDE: "Verklemmen des Werkzeugs im Werkstueck", AffectedDE: "Bedienpersonal", ZoneDE: "Schnittbereich", DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -108,6 +128,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 95,
|
Priority: 95,
|
||||||
ExpertHintDE: "Lichtbogenschutz (Arc Flash) — PSA Kategorie und Schutzabstand berechnen.",
|
ExpertHintDE: "Lichtbogenschutz (Arc Flash) — PSA Kategorie und Schutzabstand berechnen.",
|
||||||
|
ScenarioDE: "Lichtbogenbildung bei Kurzschluss in Schaltanlage", HarmDE: "Schwere Verbrennungen, Augenverletzungen, Gehoerschaden",
|
||||||
|
TriggerDE: "Kurzschluss durch Werkzeug oder Fehlschaltung", AffectedDE: "Elektrofachkraft", ZoneDE: "Schaltschrank, Sammelschiene", DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP105", NameDE: "Kondensator-Restladung nach Abschaltung", NameEN: "Capacitor residual charge after shutdown",
|
ID: "HP105", NameDE: "Kondensator-Restladung nach Abschaltung", NameEN: "Capacitor residual charge after shutdown",
|
||||||
@@ -117,6 +139,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 88,
|
Priority: 88,
|
||||||
ExpertHintDE: "Entladezeit abwarten oder Entladewiderstand vorsehen. Spannungsfreiheit messen.",
|
ExpertHintDE: "Entladezeit abwarten oder Entladewiderstand vorsehen. Spannungsfreiheit messen.",
|
||||||
|
ScenarioDE: "Elektrischer Schlag durch geladenen Kondensator nach Abschaltung", HarmDE: "Elektrischer Schlag, Herzrhythmusstoerungen",
|
||||||
|
TriggerDE: "Beruehrung spannungsfuehrender Teile nach Abschaltung", AffectedDE: "Elektrofachkraft", ZoneDE: "Kondensatorbaugruppe", DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP106", NameDE: "Statische Aufladung (ESD) zuendet Atmosphaere", NameEN: "Static charge (ESD) ignites atmosphere",
|
ID: "HP106", NameDE: "Statische Aufladung (ESD) zuendet Atmosphaere", NameEN: "Static charge (ESD) ignites atmosphere",
|
||||||
@@ -125,6 +149,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"electrical_hazard"},
|
GeneratedHazardCats: []string{"electrical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 72,
|
Priority: 72,
|
||||||
|
ScenarioDE: "Statische Entladung zuendet brennbare Atmosphaere", HarmDE: "Verbrennung, Explosion",
|
||||||
|
TriggerDE: "Funkenentladung bei ungeerdetem Material", AffectedDE: "Bedienpersonal", ZoneDE: "Ex-Bereich, Lackierzone", DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP107", NameDE: "Erdungsfehler fuehrt zu Koerperdurchstroemung", NameEN: "Grounding fault causes body current",
|
ID: "HP107", NameDE: "Erdungsfehler fuehrt zu Koerperdurchstroemung", NameEN: "Grounding fault causes body current",
|
||||||
@@ -133,6 +159,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"electrical_hazard"},
|
GeneratedHazardCats: []string{"electrical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 92,
|
Priority: 92,
|
||||||
|
ScenarioDE: "Koerperdurchstroemung bei defekter Schutzerdung", HarmDE: "Elektrischer Schlag, Herzkammerflimmern, Tod",
|
||||||
|
TriggerDE: "Beruehrung eines fehlerhaft geerdeten Gehaeuses", AffectedDE: "Bedienpersonal", ZoneDE: "Maschinengehaeuse, Schaltschrank", DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP108", NameDE: "Induktionsspannung in abgeschalteten Leitungen", NameEN: "Induced voltage in disconnected lines",
|
ID: "HP108", NameDE: "Induktionsspannung in abgeschalteten Leitungen", NameEN: "Induced voltage in disconnected lines",
|
||||||
@@ -141,6 +169,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"electrical_hazard"},
|
GeneratedHazardCats: []string{"electrical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 70,
|
Priority: 70,
|
||||||
|
ScenarioDE: "Gefaehrliche Induktionsspannung in abgeschalteter Leitung", HarmDE: "Elektrischer Schlag",
|
||||||
|
TriggerDE: "Parallelfuehrung zu aktiven Hochspannungsleitungen", AffectedDE: "Elektrofachkraft", ZoneDE: "Kabeltrasse, Freileitungsbereich", DefaultSeverity: 3, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP109", NameDE: "Ueberstrom/Ueberlast fuehrt zu Brand", NameEN: "Overcurrent/overload causes fire",
|
ID: "HP109", NameDE: "Ueberstrom/Ueberlast fuehrt zu Brand", NameEN: "Overcurrent/overload causes fire",
|
||||||
@@ -149,6 +179,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"electrical_hazard", "thermal_hazard"},
|
GeneratedHazardCats: []string{"electrical_hazard", "thermal_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 85,
|
Priority: 85,
|
||||||
|
ScenarioDE: "Kabelbrand durch Ueberstrom bei fehlender Absicherung", HarmDE: "Verbrennungen, Rauchvergiftung, Anlagenbrand",
|
||||||
|
TriggerDE: "Ueberlast oder defekte Sicherung", AffectedDE: "Alle Personen im Gebaeude", ZoneDE: "Kabelkanal, Verteiler", DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -163,6 +195,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
Priority: 95,
|
Priority: 95,
|
||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Explosionsschutz-Dokument erforderlich. Zoneneinteilung und Zuendquellenanalyse.",
|
ExpertHintDE: "Explosionsschutz-Dokument erforderlich. Zoneneinteilung und Zuendquellenanalyse.",
|
||||||
|
ScenarioDE: "Aufwirbeln brennbarer Staeube in geschlossenem Raum", HarmDE: "Explosion, toedliche Druckwelle, Verbrennungen",
|
||||||
|
TriggerDE: "Zuendquelle bei explosionsfaehiger Staubkonzentration", AffectedDE: "Alle Personen im Bereich", ZoneDE: "Silos, Filteranlagen, Muehlen", DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP111", NameDE: "Einatmen von Loesemitteldaempfen", NameEN: "Inhalation of solvent vapors",
|
ID: "HP111", NameDE: "Einatmen von Loesemitteldaempfen", NameEN: "Inhalation of solvent vapors",
|
||||||
@@ -171,6 +205,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M124", "M141"},
|
SuggestedMeasureIDs: []string{"M124", "M141"},
|
||||||
Priority: 78,
|
Priority: 78,
|
||||||
|
ScenarioDE: "Einatmen von Loesemitteldaempfen bei unzureichender Belueftung", HarmDE: "Kopfschmerzen, Schwindel, Leber-/Nierenschaeden",
|
||||||
|
TriggerDE: "Offener Umgang mit Loesemitteln ohne Absaugung", AffectedDE: "Bedienpersonal", ZoneDE: "Reinigungs-/Lackierarbeitsplatz", DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP112", NameDE: "Hautreizung durch Kuehlschmierstoffe", NameEN: "Skin irritation from cutting fluids",
|
ID: "HP112", NameDE: "Hautreizung durch Kuehlschmierstoffe", NameEN: "Skin irritation from cutting fluids",
|
||||||
@@ -179,6 +215,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 65,
|
Priority: 65,
|
||||||
|
ScenarioDE: "Hautkontakt mit Kuehlschmierstoff bei Maschinenarbeit", HarmDE: "Kontaktekzem, allergische Hautreaktion",
|
||||||
|
TriggerDE: "Spritzer oder laengerer Hautkontakt ohne Schutz", AffectedDE: "Maschinenbediener", ZoneDE: "Bearbeitungszentrum, Drehmaschine", DefaultSeverity: 2, DefaultExposure: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP113", NameDE: "Schweissrauch-Exposition", NameEN: "Welding fume exposure",
|
ID: "HP113", NameDE: "Schweissrauch-Exposition", NameEN: "Welding fume exposure",
|
||||||
@@ -187,6 +225,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M124", "M141"},
|
SuggestedMeasureIDs: []string{"M124", "M141"},
|
||||||
Priority: 80,
|
Priority: 80,
|
||||||
|
ScenarioDE: "Einatmen von Schweissrauch bei unzureichender Absaugung", HarmDE: "Atemwegserkrankung, Metallrauchfieber, Lungenkrebs",
|
||||||
|
TriggerDE: "Schweissen ohne lokale Absaugung", AffectedDE: "Schweisser, Nachbarpersonal", ZoneDE: "Schweissarbeitsplatz", DefaultSeverity: 4, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP114", NameDE: "Veraetzung durch Saeure/Lauge", NameEN: "Chemical burns from acid/alkali",
|
ID: "HP114", NameDE: "Veraetzung durch Saeure/Lauge", NameEN: "Chemical burns from acid/alkali",
|
||||||
@@ -195,6 +235,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 85,
|
Priority: 85,
|
||||||
|
ScenarioDE: "Veraetzung durch Kontakt mit konzentrierter Saeure oder Lauge", HarmDE: "Chemische Veraetzung von Haut und Augen",
|
||||||
|
TriggerDE: "Spritzer bei Umfuellen ohne Schutzausruestung", AffectedDE: "Laborpersonal, Bedienpersonal", ZoneDE: "Chemikalienlager, Mischanlage", DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP115", NameDE: "Erstickungsgefahr in Behaeltern/Schaechten", NameEN: "Suffocation in tanks/shafts",
|
ID: "HP115", NameDE: "Erstickungsgefahr in Behaeltern/Schaechten", NameEN: "Suffocation in tanks/shafts",
|
||||||
@@ -205,6 +247,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
Priority: 95,
|
Priority: 95,
|
||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Befahrerlaubnis und Gasfreimessung vor Betreten enger Raeume.",
|
ExpertHintDE: "Befahrerlaubnis und Gasfreimessung vor Betreten enger Raeume.",
|
||||||
|
ScenarioDE: "Sauerstoffmangel in Behaelter oder engem Raum", HarmDE: "Bewusstlosigkeit, Erstickungstod",
|
||||||
|
TriggerDE: "Einsteigen ohne Gasfreimessung", AffectedDE: "Wartungspersonal, Retter", ZoneDE: "Behaelter, Schacht, Kanal", DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP116", NameDE: "Biologische Kontamination in Fluidsystemen", NameEN: "Biological contamination in fluid systems",
|
ID: "HP116", NameDE: "Biologische Kontamination in Fluidsystemen", NameEN: "Biological contamination in fluid systems",
|
||||||
@@ -213,6 +257,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 55,
|
Priority: 55,
|
||||||
|
ScenarioDE: "Keimbelastung in Kuehlschmierstoff- oder Hydrauliksystem", HarmDE: "Hautinfektion, Atemwegserkrankung",
|
||||||
|
TriggerDE: "Hautkontakt mit kontaminiertem Fluid", AffectedDE: "Maschinenbediener, Wartungspersonal", ZoneDE: "Fluidsystem, Tank", DefaultSeverity: 2, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP117", NameDE: "Asbest-/Mineralfaserfreisetzung bei Demontage", NameEN: "Asbestos/mineral fiber release during dismantling",
|
ID: "HP117", NameDE: "Asbest-/Mineralfaserfreisetzung bei Demontage", NameEN: "Asbestos/mineral fiber release during dismantling",
|
||||||
@@ -221,6 +267,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 90,
|
Priority: 90,
|
||||||
|
ScenarioDE: "Freisetzung von Asbestfasern bei Demontage alter Anlagen", HarmDE: "Asbestose, Mesotheliom (Langzeitfolge)",
|
||||||
|
TriggerDE: "Mechanische Bearbeitung asbesthaltiger Bauteile", AffectedDE: "Demontagepersonal", ZoneDE: "Altanlagen, Isolierung", DefaultSeverity: 5, DefaultExposure: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -234,6 +282,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M001", "M141"},
|
SuggestedMeasureIDs: []string{"M001", "M141"},
|
||||||
Priority: 90,
|
Priority: 90,
|
||||||
ExpertHintDE: "Laserklasse bestimmen. Ab Klasse 3B: Laserschutzbeauftragter erforderlich.",
|
ExpertHintDE: "Laserklasse bestimmen. Ab Klasse 3B: Laserschutzbeauftragter erforderlich.",
|
||||||
|
ScenarioDE: "Augentreffer durch Laserstrahl bei Justierung", HarmDE: "Netzhautverbrennung, dauerhafte Erblindung",
|
||||||
|
TriggerDE: "Reflexion oder direkter Blick in Laserstrahl", AffectedDE: "Bedienpersonal, Justierpersonal", ZoneDE: "Laserbearbeitungszelle", DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP119", NameDE: "UV-Strahlung bei Schweiss-/Haerteprozessen", NameEN: "UV radiation from welding/curing",
|
ID: "HP119", NameDE: "UV-Strahlung bei Schweiss-/Haerteprozessen", NameEN: "UV radiation from welding/curing",
|
||||||
@@ -242,6 +292,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M001", "M141"},
|
SuggestedMeasureIDs: []string{"M001", "M141"},
|
||||||
Priority: 78,
|
Priority: 78,
|
||||||
|
ScenarioDE: "UV-Strahlung bei Schweiss- oder UV-Haerteprozess", HarmDE: "Verblitzen der Augen, Hautverbrennung",
|
||||||
|
TriggerDE: "Fehlender Augenschutz beim Schweissen", AffectedDE: "Schweisser, Nachbarpersonal", ZoneDE: "Schweissarbeitsplatz", DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP120", NameDE: "Infrarot-Waermestrahlung", NameEN: "Infrared heat radiation",
|
ID: "HP120", NameDE: "Infrarot-Waermestrahlung", NameEN: "Infrared heat radiation",
|
||||||
@@ -250,6 +302,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"thermal_hazard"},
|
GeneratedHazardCats: []string{"thermal_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M054", "M141"},
|
SuggestedMeasureIDs: []string{"M054", "M141"},
|
||||||
Priority: 65,
|
Priority: 65,
|
||||||
|
ScenarioDE: "Waermestrahlung von heissen Oberflaechen oder Schmelze", HarmDE: "Hautverbrennungen, Hitzschlag bei Dauerexposition",
|
||||||
|
TriggerDE: "Aufenthalt nahe heisser Flaeche ohne Abschirmung", AffectedDE: "Bedienpersonal", ZoneDE: "Ofen, Giessereibereich", DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP121", NameDE: "Elektromagnetische Felder (Induktionserwaermung)", NameEN: "EMF from induction heating",
|
ID: "HP121", NameDE: "Elektromagnetische Felder (Induktionserwaermung)", NameEN: "EMF from induction heating",
|
||||||
@@ -258,6 +312,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 70,
|
Priority: 70,
|
||||||
|
ScenarioDE: "Exposition gegenueber elektromagnetischen Feldern bei Induktionsanlage", HarmDE: "Erwaermung von Implantaten, Herzschrittmacher-Stoerung",
|
||||||
|
TriggerDE: "Aufenthalt im Nahfeld ohne Abschirmung", AffectedDE: "Bedienpersonal, Implantattraeger", ZoneDE: "Induktionsanlage", DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP122", NameDE: "Ionisierende Strahlung (Roentgen/Gamma)", NameEN: "Ionizing radiation (X-ray/gamma)",
|
ID: "HP122", NameDE: "Ionisierende Strahlung (Roentgen/Gamma)", NameEN: "Ionizing radiation (X-ray/gamma)",
|
||||||
@@ -268,6 +324,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
Priority: 95,
|
Priority: 95,
|
||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Strahlenschutzbeauftragter und Genehmigung erforderlich.",
|
ExpertHintDE: "Strahlenschutzbeauftragter und Genehmigung erforderlich.",
|
||||||
|
ScenarioDE: "Exposition gegenueber ionisierender Strahlung bei Pruefung", HarmDE: "Strahlenkrankheit, Langzeitkrebs",
|
||||||
|
TriggerDE: "Betreten des Kontrollbereichs ohne Freigabe", AffectedDE: "Pruefpersonal", ZoneDE: "Kontrollbereich, Roentgenkabine", DefaultSeverity: 5, DefaultExposure: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP123", NameDE: "Blendung durch starke Lichtquellen", NameEN: "Glare from intense light sources",
|
ID: "HP123", NameDE: "Blendung durch starke Lichtquellen", NameEN: "Glare from intense light sources",
|
||||||
@@ -276,6 +334,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 55,
|
Priority: 55,
|
||||||
|
ScenarioDE: "Blendung durch Scheinwerfer oder Plasmalichtbogen", HarmDE: "Voruebergehende Sehstoerung, Unfallgefahr",
|
||||||
|
TriggerDE: "Direkter Blick in starke Lichtquelle", AffectedDE: "Bedienpersonal", ZoneDE: "Beleuchtungsbereich, Buehne", DefaultSeverity: 2, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -288,6 +348,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"thermal_hazard"},
|
GeneratedHazardCats: []string{"thermal_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 88,
|
Priority: 88,
|
||||||
|
ScenarioDE: "Ueberhitzung elektrischer Bauteile fuehrt zu Schwelbrand", HarmDE: "Verbrennungen, Rauchvergiftung, Anlagenschaden",
|
||||||
|
TriggerDE: "Defekte Kuehlung oder Ueberlast", AffectedDE: "Alle Personen im Gebaeude", ZoneDE: "Schaltschrank, Serverschrank", DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP125", NameDE: "Explosion entzuendlicher Gase/Daempfe", NameEN: "Explosion of flammable gases/vapors",
|
ID: "HP125", NameDE: "Explosion entzuendlicher Gase/Daempfe", NameEN: "Explosion of flammable gases/vapors",
|
||||||
@@ -298,6 +360,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
Priority: 96,
|
Priority: 96,
|
||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Explosionsschutz-Dokument. ATEX-Zoneneinteilung erforderlich.",
|
ExpertHintDE: "Explosionsschutz-Dokument. ATEX-Zoneneinteilung erforderlich.",
|
||||||
|
ScenarioDE: "Explosion entzuendlicher Gase/Daempfe in geschlossenem Raum", HarmDE: "Toedliche Druckwelle, Verbrennungen, Truemmerflug",
|
||||||
|
TriggerDE: "Zuendquelle in explosionsfaehiger Atmosphaere", AffectedDE: "Alle Personen im Bereich", ZoneDE: "Ex-Zone 0/1/2, Tanklager", DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP126", NameDE: "Hydraulikoelbrand bei Leckage auf heisse Flaeche", NameEN: "Hydraulic oil fire from leakage on hot surface",
|
ID: "HP126", NameDE: "Hydraulikoelbrand bei Leckage auf heisse Flaeche", NameEN: "Hydraulic oil fire from leakage on hot surface",
|
||||||
@@ -306,6 +370,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"thermal_hazard", "material_environmental"},
|
GeneratedHazardCats: []string{"thermal_hazard", "material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M054", "M131"},
|
SuggestedMeasureIDs: []string{"M054", "M131"},
|
||||||
Priority: 88,
|
Priority: 88,
|
||||||
|
ScenarioDE: "Entzuendung von Hydraulikoel an heisser Oberflaeche bei Leckage", HarmDE: "Grossbrand, schwere Verbrennungen",
|
||||||
|
TriggerDE: "Leckage Druckleitung auf heisses Bauteil", AffectedDE: "Bedienpersonal", ZoneDE: "Hydraulikaggregat, Pressenbereich", DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP127", NameDE: "Metallbrand (Aluminium-/Magnesiumstaub)", NameEN: "Metal fire (aluminum/magnesium dust)",
|
ID: "HP127", NameDE: "Metallbrand (Aluminium-/Magnesiumstaub)", NameEN: "Metal fire (aluminum/magnesium dust)",
|
||||||
@@ -315,6 +381,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M054", "M124"},
|
SuggestedMeasureIDs: []string{"M054", "M124"},
|
||||||
Priority: 92,
|
Priority: 92,
|
||||||
ExpertHintDE: "Metallbraende nur mit Spezialloeschmittel (Klasse D). Kein Wasser!",
|
ExpertHintDE: "Metallbraende nur mit Spezialloeschmittel (Klasse D). Kein Wasser!",
|
||||||
|
ScenarioDE: "Metallbrand bei Schleifen/Fraesen von Leichtmetallstaub", HarmDE: "Unkontrollierbarer Brand, Explosion bei Wasserloeschversuch",
|
||||||
|
TriggerDE: "Zuendung von Metallstaub durch Funken", AffectedDE: "Bedienpersonal, Feuerwehr", ZoneDE: "Schleifbereich, Staubabsaugung", DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP128", NameDE: "Druckbehaelter-Bersten", NameEN: "Pressure vessel burst",
|
ID: "HP128", NameDE: "Druckbehaelter-Bersten", NameEN: "Pressure vessel burst",
|
||||||
@@ -325,6 +393,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
Priority: 96,
|
Priority: 96,
|
||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Druckbehaelter-Pruefung nach BetrSichV. Wiederkehrende Prueffristen beachten.",
|
ExpertHintDE: "Druckbehaelter-Pruefung nach BetrSichV. Wiederkehrende Prueffristen beachten.",
|
||||||
|
ScenarioDE: "Bersten eines Druckbehaelters bei Ueberdruck", HarmDE: "Toedliche Splitter, Druckwelle, Quetschung",
|
||||||
|
TriggerDE: "Versagen des Sicherheitsventils", AffectedDE: "Alle Personen im Umkreis", ZoneDE: "Druckbehaelter, Kompressorraum", DefaultSeverity: 5, DefaultExposure: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP129", NameDE: "Sauerstoffanreicherung erhoehte Brandgefahr", NameEN: "Oxygen enrichment increased fire risk",
|
ID: "HP129", NameDE: "Sauerstoffanreicherung erhoehte Brandgefahr", NameEN: "Oxygen enrichment increased fire risk",
|
||||||
@@ -333,6 +403,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 80,
|
Priority: 80,
|
||||||
|
ScenarioDE: "Erhoehte Entzuendbarkeit aller Materialien bei Sauerstoffanreicherung", HarmDE: "Schnelle Brandausbreitung, schwere Verbrennungen",
|
||||||
|
TriggerDE: "Sauerstoffleckage in geschlossenem Raum", AffectedDE: "Alle Personen im Bereich", ZoneDE: "Sauerstoff-Versorgungsanlage", DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP130", NameDE: "Selbstentzuendung oelgetraenkter Lappen/Filter", NameEN: "Spontaneous combustion of oil-soaked rags",
|
ID: "HP130", NameDE: "Selbstentzuendung oelgetraenkter Lappen/Filter", NameEN: "Spontaneous combustion of oil-soaked rags",
|
||||||
@@ -341,6 +413,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"thermal_hazard", "material_environmental"},
|
GeneratedHazardCats: []string{"thermal_hazard", "material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 70,
|
Priority: 70,
|
||||||
|
ScenarioDE: "Selbstentzuendung oelgetraenkter Putzlappen in geschlossenem Behaelter", HarmDE: "Schwelbrand, Vollbrand in Werkstatt",
|
||||||
|
TriggerDE: "Unsachgemaesse Lagerung oeliger Lappen", AffectedDE: "Alle Personen im Gebaeude", ZoneDE: "Werkstatt, Lagerbereich", DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -353,6 +427,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"ergonomic"},
|
GeneratedHazardCats: []string{"ergonomic"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 55,
|
Priority: 55,
|
||||||
|
ScenarioDE: "Repetitive Handbewegungen bei Serienfertigung ohne Rotation", HarmDE: "Sehnenscheidenentzuendung, Karpaltunnelsyndrom",
|
||||||
|
TriggerDE: "Gleichfoermige Belastung ueber Stunden", AffectedDE: "Montagepersonal", ZoneDE: "Montagearbeitsplatz", DefaultSeverity: 2, DefaultExposure: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP132", NameDE: "Ganzkoepervibrration bei Fahrzeugen/Maschinen", NameEN: "Whole-body vibration from vehicles/machines",
|
ID: "HP132", NameDE: "Ganzkoepervibrration bei Fahrzeugen/Maschinen", NameEN: "Whole-body vibration from vehicles/machines",
|
||||||
@@ -361,6 +437,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"noise_vibration"},
|
GeneratedHazardCats: []string{"noise_vibration"},
|
||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 65,
|
Priority: 65,
|
||||||
|
ScenarioDE: "Ganzkoerpervibration bei Fahren von Flurfoerderfahrzeugen", HarmDE: "Wirbelsaeulenschaeden, Bandscheibenvorfall",
|
||||||
|
TriggerDE: "Langzeitexposition auf ungefedertem Sitz", AffectedDE: "Fahrpersonal", ZoneDE: "Fahrzeugfuehrerstand", DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP133", NameDE: "Hand-Arm-Vibration bei handgefuehrten Werkzeugen", NameEN: "Hand-arm vibration from handheld tools",
|
ID: "HP133", NameDE: "Hand-Arm-Vibration bei handgefuehrten Werkzeugen", NameEN: "Hand-arm vibration from handheld tools",
|
||||||
@@ -369,6 +447,8 @@ func GetDGUVExtendedPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"noise_vibration"},
|
GeneratedHazardCats: []string{"noise_vibration"},
|
||||||
SuggestedMeasureIDs: []string{"M054", "M141"},
|
SuggestedMeasureIDs: []string{"M054", "M141"},
|
||||||
Priority: 70,
|
Priority: 70,
|
||||||
|
ScenarioDE: "Hand-Arm-Vibration durch handgefuehrtes Schlagwerkzeug", HarmDE: "Durchblutungsstoerungen, Weissfingerkrankheit",
|
||||||
|
TriggerDE: "Laengerer Einsatz vibrierender Werkzeuge", AffectedDE: "Bedienpersonal", ZoneDE: "Werkzeugarbeitsplatz", DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// builtinFluidPatterns returns HP019-HP022: hydraulic and pneumatic hazard patterns.
|
||||||
|
func builtinFluidPatterns() []HazardPattern {
|
||||||
|
return []HazardPattern{
|
||||||
|
{
|
||||||
|
ID: "HP019", NameDE: "Hydraulikdruck-Gefahr", NameEN: "Hydraulic pressure hazard",
|
||||||
|
RequiredComponentTags: []string{"hydraulic_part"},
|
||||||
|
RequiredEnergyTags: []string{"hydraulic_pressure"},
|
||||||
|
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
SuggestedMeasureIDs: []string{"M081", "M082", "M121", "M123"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E05", "E11"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Unter Druck stehendes Hydraulikoel tritt durch undichte Verschraubungen oder geplatzte Leitungen aus.",
|
||||||
|
TriggerDE: "Schlauchbruch, Dichtungsversagen oder Loesen einer Verschraubung unter Betriebsdruck.",
|
||||||
|
HarmDE: "Hochdruckinjektion durch die Haut (Notfall!), Augen-/Hautkontakt mit heissem Oel, Rutschgefahr.",
|
||||||
|
AffectedDE: "Wartungspersonal, Bedienpersonal",
|
||||||
|
ZoneDE: "Schlauchleitungen, Verschraubungen, Zylinderanschluesse, Aggregat",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP020", NameDE: "Pneumatikdruck-Gefahr", NameEN: "Pneumatic pressure hazard",
|
||||||
|
RequiredComponentTags: []string{"pneumatic_part"},
|
||||||
|
RequiredEnergyTags: []string{"pneumatic_pressure"},
|
||||||
|
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
SuggestedMeasureIDs: []string{"M083", "M084", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E06", "E11"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Druckluft entweicht unkontrolliert aus Leitungen, Zylindern oder Ventilen und trifft Personen.",
|
||||||
|
TriggerDE: "Schlauch loest sich, Ventil versagt oder Zylinderdichtung bricht unter Betriebsdruck.",
|
||||||
|
HarmDE: "Druckluftverletzung (Augen, Ohren), peitschender Schlauch, Verletzung durch unkontrollierten Aktor.",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal",
|
||||||
|
ZoneDE: "Druckluftleitungen, Zylinderanschluesse, Ventilinseln, Wartungseinheiten",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP021", NameDE: "Gefahr durch gespeicherten Hydraulikdruck", NameEN: "Stored hydraulic pressure risk",
|
||||||
|
RequiredComponentTags: []string{"hydraulic_part", "stored_energy"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
SuggestedMeasureIDs: []string{"M081", "M082", "M123"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E05", "E11"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Druckspeicher oder gesperrte Zylinder halten nach Abschalten gefaehrlichen Restdruck.",
|
||||||
|
TriggerDE: "Oeffnen einer Verschraubung oder Demontage eines Zylinders ohne vorherige Druckentlastung.",
|
||||||
|
HarmDE: "Hochdruckinjektion, unkontrollierte Zylinderbewegung, Oel-Austritt unter Druck.",
|
||||||
|
AffectedDE: "Wartungspersonal, Elektrofachkraefte",
|
||||||
|
ZoneDE: "Druckspeicher, gesperrte Zylinder, Sperrventile, Hydraulikaggregate",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP022", NameDE: "Gefahr durch Druckluftspeicher", NameEN: "Stored pneumatic pressure risk",
|
||||||
|
RequiredComponentTags: []string{"pneumatic_part", "stored_energy"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
SuggestedMeasureIDs: []string{"M083", "M084", "M123"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E06", "E11"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Druckluftbehaelter oder gesperrte Zylinder halten nach Abschalten gefaehrliche Restenergie.",
|
||||||
|
TriggerDE: "Loesung einer Verschraubung oder Ventilbetaetigung ohne vollstaendige Druckentlastung.",
|
||||||
|
HarmDE: "Schlagartige Druckfreisetzung, unkontrollierte Aktorbewegung, Gehoeerschaeden durch Druckknall.",
|
||||||
|
AffectedDE: "Wartungspersonal",
|
||||||
|
ZoneDE: "Druckluftbehaelter, Zylinderräume, Schlauchkupplungen",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// builtinMechanicalPatterns returns HP001-HP010: mechanical hazard patterns.
|
||||||
|
func builtinMechanicalPatterns() []HazardPattern {
|
||||||
|
return []HazardPattern{
|
||||||
|
{
|
||||||
|
ID: "HP001", NameDE: "Quetschgefahr durch bewegte Teile", NameEN: "Crush risk from moving parts",
|
||||||
|
RequiredComponentTags: []string{"moving_part"},
|
||||||
|
RequiredEnergyTags: []string{"kinetic"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M001", "M005", "M051", "M054"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E08", "E20"},
|
||||||
|
Priority: 95,
|
||||||
|
ScenarioDE: "Bediener greift in den Bereich beweglicher Maschinenteile waehrend des Betriebs oder bei Stoerungsbeseitigung.",
|
||||||
|
TriggerDE: "Bewegliches Teil (Schlitten, Stempel, Greifer) erfasst Finger oder Hand des Bedieners.",
|
||||||
|
HarmDE: "Quetschung, Amputation von Fingern/Hand. Schwere abhaengig von Schliesskraft und Masse.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter",
|
||||||
|
ZoneDE: "Bewegungsbereich des Schlittens/Stempels, Einzugsstelle",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP002", NameDE: "Einzugsgefahr durch rotierende Teile", NameEN: "Entanglement risk from rotating parts",
|
||||||
|
RequiredComponentTags: []string{"rotating_part"},
|
||||||
|
RequiredEnergyTags: []string{"rotational"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M002", "M051", "M053", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
|
Priority: 95,
|
||||||
|
ScenarioDE: "Kleidung, Haare oder Handschuhe werden von rotierenden Wellen, Walzen oder Kupplungen erfasst.",
|
||||||
|
TriggerDE: "Kontakt mit freiliegender rotierender Welle oder Kupplung waehrend Betrieb oder Einrichtung.",
|
||||||
|
HarmDE: "Einzug, Umschlingung, Skalpierung, Frakturen, in schweren Faellen Todesfolge.",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal",
|
||||||
|
ZoneDE: "Wellenenden, Kupplungen, Walzenspalte, Antriebselemente",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP003", NameDE: "Schnittgefahr durch Schneidwerkzeuge", NameEN: "Cut risk from cutting tools",
|
||||||
|
RequiredComponentTags: []string{"cutting_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M003", "M051", "M054", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Bediener kommt mit scharfen Schneid- oder Stanzwerkzeugen in Kontakt beim Einlegen, Entnehmen oder Ruestvorgang.",
|
||||||
|
TriggerDE: "Unbeabsichtigter Kontakt mit Schneide waehrend manueller Taetigkeiten am Werkzeug.",
|
||||||
|
HarmDE: "Schnittverletzung, tiefe Schnittwunde, ggf. Sehnen-/Nervenverletzung.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter",
|
||||||
|
ZoneDE: "Schneidzone, Werkzeugwechselbereich, Materialzufuhr",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP004", NameDE: "Klemmgefahr an Quetsch-/Klemmstellen", NameEN: "Pinch risk at clamping points",
|
||||||
|
RequiredComponentTags: []string{"pinch_point"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M001", "M004", "M051", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Finger oder Hand geraten zwischen zwei sich aufeinander zu bewegende Maschinenteile.",
|
||||||
|
TriggerDE: "Bediener greift in Klemmstelle waehrend automatischem Zyklus oder bei manueller Beschickung.",
|
||||||
|
HarmDE: "Klemmung, Quetschung von Fingern, Haematom, ggf. Fraktur.",
|
||||||
|
AffectedDE: "Bedienpersonal",
|
||||||
|
ZoneDE: "Klemmstellen zwischen beweglichen Teilen, Zufuehrbereich",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP005", NameDE: "Quetschgefahr an Quetschstellen", NameEN: "Crush risk at crush points",
|
||||||
|
RequiredComponentTags: []string{"crush_point"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M001", "M005", "M054"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Koerperteile geraten in Quetschstelle zwischen Maschine und festem Anschlag oder Gegenstand.",
|
||||||
|
TriggerDE: "Maschinenteil bewegt sich gegen feste Struktur und erfasst Koerperteil des Bedieners.",
|
||||||
|
HarmDE: "Schwere Quetschung, Fraktur, in Extremfaellen Amputation.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter",
|
||||||
|
ZoneDE: "Quetschstelle zwischen beweglichem Teil und Rahmen/Anschlag",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP006", NameDE: "Gefahr durch hohe Kraefte", NameEN: "Risk from high forces",
|
||||||
|
RequiredComponentTags: []string{"high_force"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M001", "M005", "M051", "M106"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E07", "E08"},
|
||||||
|
Priority: 90,
|
||||||
|
ScenarioDE: "Maschine uebt hohe Presskraefte oder Vorschubkraefte aus, die bei Koerperkontakt schwere Verletzungen verursachen.",
|
||||||
|
TriggerDE: "Bediener befindet sich im Kraftwirkbereich waehrend des Arbeitshubes oder bei Stoerungsbeseitigung.",
|
||||||
|
HarmDE: "Schwere Quetschung, Fraktur, innere Verletzungen, Todesfolge bei Ganzkompression.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter, Wartungspersonal",
|
||||||
|
ZoneDE: "Kraftwirkbereich (Pressenraum, Vorschubachse), Einlegestelle",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP007", NameDE: "Gefahr durch hohe Geschwindigkeit", NameEN: "Risk from high speed",
|
||||||
|
RequiredComponentTags: []string{"high_speed"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M002", "M051", "M053", "M054"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Maschinenteile bewegen sich mit hoher Geschwindigkeit; Reaktionszeit reicht nicht fuer Ausweichen.",
|
||||||
|
TriggerDE: "Bediener kommt in Kontakt mit schnell bewegtem Teil oder wird von Auswurfmaterial getroffen.",
|
||||||
|
HarmDE: "Prellung, Fraktur, Schnittverletzung durch Auswurf, Schleudertrauma.",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Umfeld",
|
||||||
|
ZoneDE: "Bewegungsraum schneller Achsen, Auswurfbereich, Spindelumgebung",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP008", NameDE: "Absturzgefahr / Herabfallende Teile", NameEN: "Fall/drop risk",
|
||||||
|
RequiredComponentTags: []string{"gravity_risk"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M009", "M121", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E20"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Schwere Maschinenteile, Werkzeuge oder Werkstuecke fallen unkontrolliert herab oder Person stuerzt von Arbeitsplattform.",
|
||||||
|
TriggerDE: "Versagen einer Halterung, Bruch eines Lastaufnahmemittels oder Abrutschen bei Wartungsarbeiten in der Hoehe.",
|
||||||
|
HarmDE: "Kopfverletzung, Fraktur, Quetschung durch herabfallende Last; Sturzverletung.",
|
||||||
|
AffectedDE: "Wartungspersonal, Bedienpersonal, Personen im Gefahrenbereich",
|
||||||
|
ZoneDE: "Bereich unterhalb angehobener Lasten, Wartungsplattformen, Kran-/Hebezeugbereich",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP009", NameDE: "Gefahr durch Spannvorrichtungen", NameEN: "Clamping device risk",
|
||||||
|
RequiredComponentTags: []string{"clamping_part"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M004", "M051", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Werkstueck wird nicht sicher gespannt oder Spannvorrichtung schliesst unerwartet waehrend manueller Taetigkeiten.",
|
||||||
|
TriggerDE: "Spannmechanismus loest sich oder schliesst bei Hand im Spannbereich; Werkstueck fliegt aus Spannfutter.",
|
||||||
|
HarmDE: "Quetschung der Finger/Hand, Fraktur; Werkstueckauswurf kann Prellungen verursachen.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter",
|
||||||
|
ZoneDE: "Spannfutter, Schraubstock, Klemmbereich der Vorrichtung",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP010", NameDE: "Gefahr durch gespeicherte mechanische Energie", NameEN: "Stored mechanical energy risk",
|
||||||
|
RequiredComponentTags: []string{"stored_energy"},
|
||||||
|
RequiredEnergyTags: []string{"mechanical"},
|
||||||
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M010", "M121", "M123"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E20"},
|
||||||
|
Priority: 80,
|
||||||
|
ScenarioDE: "Gespannte Federn, angehobene Lasten oder gespannte Riemen geben gespeicherte Energie unkontrolliert frei.",
|
||||||
|
TriggerDE: "Loesung einer Arretierung oder Demontage eines vorgespannten Bauteils ohne vorherige Energieableitung.",
|
||||||
|
HarmDE: "Schlagartige Freisetzung: Prellung, Fraktur, Schnittverletzung durch zurueckschnellendes Teil.",
|
||||||
|
AffectedDE: "Wartungspersonal, Einrichter",
|
||||||
|
ZoneDE: "Federpaket, Gegengewicht, Riemenspannbereich, angehobene Baugruppen",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
Priority: 94,
|
Priority: 94,
|
||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Energiefreischaltung (LOTO) vor manuellen Eingriffen zwingend erforderlich.",
|
ExpertHintDE: "Energiefreischaltung (LOTO) vor manuellen Eingriffen zwingend erforderlich.",
|
||||||
|
ScenarioDE: "Bediener beseitigt Materialstau manuell bei nicht freigeschalteter Maschine",
|
||||||
|
TriggerDE: "Verklemmtes Teil loest sich schlagartig durch gespeicherte Federkraft oder Eigengewicht",
|
||||||
|
HarmDE: "Quetschung, Fraktur oder Schnittverletzung an Hand/Arm durch unkontrollierte Bewegung",
|
||||||
|
AffectedDE: "Bedienpersonal, Instandhaltungspersonal",
|
||||||
|
ZoneDE: "Materialzufuehrung, Werkzeugraum, Foerderband-Einzugsstelle",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP067", NameDE: "Schlauch platzt unter Druck", NameEN: "Hose bursts under pressure",
|
ID: "HP067", NameDE: "Schlauch platzt unter Druck", NameEN: "Hose bursts under pressure",
|
||||||
@@ -27,6 +33,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M131", "M054"},
|
SuggestedMeasureIDs: []string{"M131", "M054"},
|
||||||
Priority: 92,
|
Priority: 92,
|
||||||
ExpertHintDE: "Schlauch-Fangvorrichtungen und Druckentlastung vor Wartung vorsehen.",
|
ExpertHintDE: "Schlauch-Fangvorrichtungen und Druckentlastung vor Wartung vorsehen.",
|
||||||
|
ScenarioDE: "Bediener arbeitet nahe Hydraulikleitungen bei Stoerungsbeseitigung unter Betriebsdruck",
|
||||||
|
TriggerDE: "Schlauch platzt oder Kupplung loest sich unter Restdruck waehrend Fehlersuche",
|
||||||
|
HarmDE: "Peitscheneffekt mit Prellungen, Hydraulikoelinjektionsverletzung der Haut",
|
||||||
|
AffectedDE: "Bedienpersonal, Instandhaltungspersonal",
|
||||||
|
ZoneDE: "Hydraulikaggregate, Schlauchleitungen, Zylinderbereich",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP068", NameDE: "Unerwarteter Wiederanlauf nach Stoerung", NameEN: "Unexpected restart after fault",
|
ID: "HP068", NameDE: "Unerwarteter Wiederanlauf nach Stoerung", NameEN: "Unexpected restart after fault",
|
||||||
@@ -37,6 +49,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
Priority: 96,
|
Priority: 96,
|
||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Wiederanlaufsperre mit manueller Quittierung erforderlich. SIL/PL-Nachweis.",
|
ExpertHintDE: "Wiederanlaufsperre mit manueller Quittierung erforderlich. SIL/PL-Nachweis.",
|
||||||
|
ScenarioDE: "Bediener befindet sich im Gefahrenbereich bei Stoerungsbeseitigung an SPS-Maschine",
|
||||||
|
TriggerDE: "Steuerung startet Maschine automatisch nach Fehlerbehebung ohne manuelle Quittierung",
|
||||||
|
HarmDE: "Erfassen, Quetschen oder Aufwickeln durch ploetzlich anlaufende Maschinenteile",
|
||||||
|
AffectedDE: "Bedienpersonal, Instandhaltungspersonal",
|
||||||
|
ZoneDE: "Gesamter Arbeitsraum der Maschine, Werkzeugraum",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP069", NameDE: "Restenergie nach Abschaltung (gespeichert)", NameEN: "Residual stored energy after shutdown",
|
ID: "HP069", NameDE: "Restenergie nach Abschaltung (gespeichert)", NameEN: "Residual stored energy after shutdown",
|
||||||
@@ -46,6 +64,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M054", "M001"},
|
SuggestedMeasureIDs: []string{"M054", "M001"},
|
||||||
Priority: 93,
|
Priority: 93,
|
||||||
ExpertHintDE: "Energiefreischaltung, Wartezeit und Messung vor Beginn der Arbeiten.",
|
ExpertHintDE: "Energiefreischaltung, Wartezeit und Messung vor Beginn der Arbeiten.",
|
||||||
|
ScenarioDE: "Wartungspersonal oeffnet Abdeckung nach Abschaltung ohne Restenergieabbau",
|
||||||
|
TriggerDE: "Gespeicherte Energie (Feder, Druckspeicher, Kondensator) entlaedt sich beim Oeffnen",
|
||||||
|
HarmDE: "Stromschlag, Quetschung durch absenkende Last oder Verbrennung durch Lichtbogen",
|
||||||
|
AffectedDE: "Instandhaltungspersonal, Elektrofachkraefte",
|
||||||
|
ZoneDE: "Energiespeicher, Druckspeicher, Kondensatoren, Federelemente",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP070", NameDE: "Eingriff in laufende Maschine bei Stoerung", NameEN: "Intervention in running machine during fault",
|
ID: "HP070", NameDE: "Eingriff in laufende Maschine bei Stoerung", NameEN: "Intervention in running machine during fault",
|
||||||
@@ -56,6 +80,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M005", "M051"},
|
SuggestedMeasureIDs: []string{"M005", "M051"},
|
||||||
Priority: 97,
|
Priority: 97,
|
||||||
ExpertHintDE: "Betriebsartenwahlschalter mit reduzierter Geschwindigkeit fuer Stoerungsbeseitigung.",
|
ExpertHintDE: "Betriebsartenwahlschalter mit reduzierter Geschwindigkeit fuer Stoerungsbeseitigung.",
|
||||||
|
ScenarioDE: "Bediener greift in laufende Maschine um Stoerung schnell zu beseitigen",
|
||||||
|
TriggerDE: "Hand oder Arm geraet in bewegte Teile mangels Verriegelung oder Stillsetzung",
|
||||||
|
HarmDE: "Amputation, schwere Quetschung oder Fraktur der oberen Extremitaeten",
|
||||||
|
AffectedDE: "Bedienpersonal",
|
||||||
|
ZoneDE: "Werkzeugraum, Foerdereinrichtung, Antriebselemente ohne Schutzabdeckung",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP071", NameDE: "Materialstau loest sich schlagartig", NameEN: "Material jam releases suddenly",
|
ID: "HP071", NameDE: "Materialstau loest sich schlagartig", NameEN: "Material jam releases suddenly",
|
||||||
@@ -64,6 +94,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M001", "M054"},
|
SuggestedMeasureIDs: []string{"M001", "M054"},
|
||||||
Priority: 88,
|
Priority: 88,
|
||||||
|
ScenarioDE: "Bediener beseitigt Materialstau manuell im Foerderbereich bei laufender Maschine",
|
||||||
|
TriggerDE: "Gestautes Material loest sich schlagartig und bewegte Teile setzen sich in Gang",
|
||||||
|
HarmDE: "Quetschung oder Einziehen von Fingern/Hand durch ploetzliche Materialbewegung",
|
||||||
|
AffectedDE: "Bedienpersonal",
|
||||||
|
ZoneDE: "Materialzufuehrung, Foerderband, Auswurfbereich",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP072", NameDE: "Herabfallende Teile bei Stoerungsbeseitigung", NameEN: "Falling parts during fault clearing",
|
ID: "HP072", NameDE: "Herabfallende Teile bei Stoerungsbeseitigung", NameEN: "Falling parts during fault clearing",
|
||||||
@@ -72,6 +108,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M051", "M141"},
|
SuggestedMeasureIDs: []string{"M051", "M141"},
|
||||||
Priority: 82,
|
Priority: 82,
|
||||||
|
ScenarioDE: "Bediener arbeitet unterhalb angehobener Maschinenteile bei Stoerungsbeseitigung",
|
||||||
|
TriggerDE: "Lose oder ungesicherte Teile fallen durch Vibration oder versehentliches Loesen",
|
||||||
|
HarmDE: "Kopfverletzung, Prellung oder Fraktur durch herabfallende Bauteile",
|
||||||
|
AffectedDE: "Bedienpersonal, Instandhaltungspersonal",
|
||||||
|
ZoneDE: "Bereich unterhalb angehobener Baugruppen, Wartungsoeffnungen",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -86,6 +128,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
Priority: 96,
|
Priority: 96,
|
||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "LOTO-Verfahren (Lockout/Tagout) fuer alle Energiequellen definieren und schulen.",
|
ExpertHintDE: "LOTO-Verfahren (Lockout/Tagout) fuer alle Energiequellen definieren und schulen.",
|
||||||
|
ScenarioDE: "Wartungspersonal arbeitet an der Maschine ohne Energiefreischaltung (LOTO)",
|
||||||
|
TriggerDE: "Maschine wird versehentlich von Dritten oder durch Steuerung gestartet",
|
||||||
|
HarmDE: "Erfassen, Quetschen oder Schneiden durch unerwartet anlaufende bewegte Teile",
|
||||||
|
AffectedDE: "Instandhaltungspersonal",
|
||||||
|
ZoneDE: "Gesamter Maschinenarbeitsraum, Antriebsbereich, Energieversorgung",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP074", NameDE: "Sturz von Wartungsbuehne / Leiter", NameEN: "Fall from maintenance platform / ladder",
|
ID: "HP074", NameDE: "Sturz von Wartungsbuehne / Leiter", NameEN: "Fall from maintenance platform / ladder",
|
||||||
@@ -94,6 +142,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M051"},
|
SuggestedMeasureIDs: []string{"M051"},
|
||||||
Priority: 78,
|
Priority: 78,
|
||||||
|
ScenarioDE: "Wartungspersonal steigt auf Buehne oder Leiter fuer Arbeiten an erhoehter Stelle",
|
||||||
|
TriggerDE: "Abrutschen von Leiter oder Stolpern auf Wartungsbuehne ohne Gelaender",
|
||||||
|
HarmDE: "Sturzverletzung mit Frakturen, Kopfverletzung bei Fall aus Hoehe",
|
||||||
|
AffectedDE: "Instandhaltungspersonal, Reinigungspersonal",
|
||||||
|
ZoneDE: "Wartungsbuehne, Steigleiter, Podeste an Maschinenoberseite",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP075", NameDE: "Kontakt mit heissen Teilen bei Wartung", NameEN: "Contact with hot parts during maintenance",
|
ID: "HP075", NameDE: "Kontakt mit heissen Teilen bei Wartung", NameEN: "Contact with hot parts during maintenance",
|
||||||
@@ -103,6 +157,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M054", "M141"},
|
SuggestedMeasureIDs: []string{"M054", "M141"},
|
||||||
Priority: 80,
|
Priority: 80,
|
||||||
ExpertHintDE: "Abkuehlzeit definieren. Temperaturanzeige oder -messung vor Arbeitsbeginn.",
|
ExpertHintDE: "Abkuehlzeit definieren. Temperaturanzeige oder -messung vor Arbeitsbeginn.",
|
||||||
|
ScenarioDE: "Wartungspersonal beruehrt Maschinenteile kurz nach Abschaltung ohne Abkuehlzeit",
|
||||||
|
TriggerDE: "Kontakt mit heisser Oberflaeche mangels Temperaturkennzeichnung oder Wartezeit",
|
||||||
|
HarmDE: "Verbrennung 2. oder 3. Grades an Haenden oder Unterarmen",
|
||||||
|
AffectedDE: "Instandhaltungspersonal",
|
||||||
|
ZoneDE: "Heizplatten, Extruder, Schmelztiegel, Ofenbereich",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP076", NameDE: "Kontakt mit Gefahrstoffen bei Wartung", NameEN: "Contact with hazardous substances during maintenance",
|
ID: "HP076", NameDE: "Kontakt mit Gefahrstoffen bei Wartung", NameEN: "Contact with hazardous substances during maintenance",
|
||||||
@@ -111,6 +171,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 75,
|
Priority: 75,
|
||||||
|
ScenarioDE: "Wartungspersonal oeffnet Behaelter oder Leitungen mit Gefahrstoffen ohne PSA",
|
||||||
|
TriggerDE: "Austritt von Kuehlschmierstoff, Hydraulikoel oder Loesungsmittel bei Demontage",
|
||||||
|
HarmDE: "Hautveraetzung, Atemwegsreizung oder allergische Reaktion durch Gefahrstoffkontakt",
|
||||||
|
AffectedDE: "Instandhaltungspersonal, Reinigungspersonal",
|
||||||
|
ZoneDE: "Kuehlmitteltank, Hydraulikleitungen, Schmierstoffbehaelter",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP077", NameDE: "Elektrischer Schlag bei Wartungsarbeiten", NameEN: "Electric shock during maintenance",
|
ID: "HP077", NameDE: "Elektrischer Schlag bei Wartungsarbeiten", NameEN: "Electric shock during maintenance",
|
||||||
@@ -121,6 +187,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
Priority: 95,
|
Priority: 95,
|
||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Freischaltung, Sicherung gegen Wiedereinschalten, Spannungsfreiheit feststellen.",
|
ExpertHintDE: "Freischaltung, Sicherung gegen Wiedereinschalten, Spannungsfreiheit feststellen.",
|
||||||
|
ScenarioDE: "Elektrofachkraft arbeitet im Schaltschrank ohne vollstaendige Freischaltung",
|
||||||
|
TriggerDE: "Beruehrung spannungsfuehrender Teile mangels Spannungsfreiheitspruefung",
|
||||||
|
HarmDE: "Stromschlag mit Herzkammerflimmern, Verbrennungen durch Lichtbogen",
|
||||||
|
AffectedDE: "Elektrofachkraefte, Instandhaltungspersonal",
|
||||||
|
ZoneDE: "Schaltschrank, Klemmenkasten, Frequenzumrichter, Motoranschluesse",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP078", NameDE: "Ergonomische Belastung bei Wartungszugang", NameEN: "Ergonomic strain at maintenance access",
|
ID: "HP078", NameDE: "Ergonomische Belastung bei Wartungszugang", NameEN: "Ergonomic strain at maintenance access",
|
||||||
@@ -129,6 +201,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"ergonomic"},
|
GeneratedHazardCats: []string{"ergonomic"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 55,
|
Priority: 55,
|
||||||
|
ScenarioDE: "Wartungspersonal muss in Zwangshaltung an schwer zugaenglicher Stelle arbeiten",
|
||||||
|
TriggerDE: "Langandauernde gebeugte oder kniende Koerperhaltung bei wiederholter Wartung",
|
||||||
|
HarmDE: "Muskel-Skelett-Erkrankung, Rueckenbeschwerden durch Fehlhaltung",
|
||||||
|
AffectedDE: "Instandhaltungspersonal",
|
||||||
|
ZoneDE: "Enge Wartungsoeffnungen, Maschinenunterseite, schwer zugaengliche Baugruppen",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP079", NameDE: "Unkontrolliertes Absenken hydraulischer Last", NameEN: "Uncontrolled lowering of hydraulic load",
|
ID: "HP079", NameDE: "Unkontrolliertes Absenken hydraulischer Last", NameEN: "Uncontrolled lowering of hydraulic load",
|
||||||
@@ -138,6 +216,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M131", "M054"},
|
SuggestedMeasureIDs: []string{"M131", "M054"},
|
||||||
Priority: 94,
|
Priority: 94,
|
||||||
ExpertHintDE: "Mechanische Absturzsicherung oder Abstuetzung vor Beginn der Arbeiten.",
|
ExpertHintDE: "Mechanische Absturzsicherung oder Abstuetzung vor Beginn der Arbeiten.",
|
||||||
|
ScenarioDE: "Wartungspersonal arbeitet unter hydraulisch angehobener Last ohne mechanische Sicherung",
|
||||||
|
TriggerDE: "Hydraulikleitung versagt oder Ventil oeffnet sich, Last senkt sich unkontrolliert ab",
|
||||||
|
HarmDE: "Toedliches Quetschen oder schwere Fraktur durch absinkende Maschinenbaugruppe",
|
||||||
|
AffectedDE: "Instandhaltungspersonal",
|
||||||
|
ZoneDE: "Unter Hydraulikzylindern, Pressenstoessel, angehobene Werkzeuge",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -151,6 +235,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M001", "M054"},
|
SuggestedMeasureIDs: []string{"M001", "M054"},
|
||||||
Priority: 92,
|
Priority: 92,
|
||||||
ExpertHintDE: "Werkzeugwechsel nur bei gesichertem Stossel/Stempel. LOTO erforderlich.",
|
ExpertHintDE: "Werkzeugwechsel nur bei gesichertem Stossel/Stempel. LOTO erforderlich.",
|
||||||
|
ScenarioDE: "Einrichter wechselt Werkzeug im Werkzeugraum bei nicht gesichertem Stoesselantrieb",
|
||||||
|
TriggerDE: "Stossel oder Stempel faehrt unbeabsichtigt herunter waehrend Haende im Quetschbereich",
|
||||||
|
HarmDE: "Amputation oder schwere Quetschung der Finger/Haende zwischen Werkzeughaelften",
|
||||||
|
AffectedDE: "Einrichter, Werkzeugmacher",
|
||||||
|
ZoneDE: "Werkzeugraum, Pressenstoessel, Spannbereich",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP081", NameDE: "Verbrennung bei Werkzeugausbau (heiss)", NameEN: "Burns during hot tool removal",
|
ID: "HP081", NameDE: "Verbrennung bei Werkzeugausbau (heiss)", NameEN: "Burns during hot tool removal",
|
||||||
@@ -160,6 +250,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 78,
|
Priority: 78,
|
||||||
ExpertHintDE: "Abkuehlzeit einhalten. Schutzhandschuhe verwenden.",
|
ExpertHintDE: "Abkuehlzeit einhalten. Schutzhandschuhe verwenden.",
|
||||||
|
ScenarioDE: "Einrichter baut heisses Werkzeug direkt nach Produktionsende ohne Abkuehlphase aus",
|
||||||
|
TriggerDE: "Kontakt mit ueber 60 Grad heisser Werkzeugoberflaeche beim manuellen Ausbau",
|
||||||
|
HarmDE: "Kontaktverbrennung an Haenden und Unterarmen, Blasenbildung",
|
||||||
|
AffectedDE: "Einrichter, Werkzeugmacher",
|
||||||
|
ZoneDE: "Werkzeugspannbereich, Heisskanalsystem, Formwerkzeug",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP082", NameDE: "Schweres Werkzeug faellt bei Wechsel", NameEN: "Heavy tool drops during change",
|
ID: "HP082", NameDE: "Schweres Werkzeug faellt bei Wechsel", NameEN: "Heavy tool drops during change",
|
||||||
@@ -169,6 +265,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M051"},
|
SuggestedMeasureIDs: []string{"M051"},
|
||||||
Priority: 85,
|
Priority: 85,
|
||||||
ExpertHintDE: "Hebezeug fuer Werkzeuge ueber 25 kg verwenden.",
|
ExpertHintDE: "Hebezeug fuer Werkzeuge ueber 25 kg verwenden.",
|
||||||
|
ScenarioDE: "Einrichter hebt schweres Werkzeug manuell ohne Hebezeug bei Werkzeugwechsel",
|
||||||
|
TriggerDE: "Werkzeug rutscht aus der Halterung oder Hebezeug versagt beim Anheben",
|
||||||
|
HarmDE: "Quetschung oder Fraktur der Fuesse/Beine durch herabfallendes Werkzeug",
|
||||||
|
AffectedDE: "Einrichter, Werkzeugmacher",
|
||||||
|
ZoneDE: "Werkzeugwechselbereich, Boden vor der Maschine, Werkzeuglager",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP083", NameDE: "Unbeabsichtigter Hub bei Einrichtbetrieb", NameEN: "Unintended stroke in setup mode",
|
ID: "HP083", NameDE: "Unbeabsichtigter Hub bei Einrichtbetrieb", NameEN: "Unintended stroke in setup mode",
|
||||||
@@ -179,6 +281,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
Priority: 94,
|
Priority: 94,
|
||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "Einrichtbetrieb nur mit reduzierter Geschwindigkeit und Zweihandschaltung.",
|
ExpertHintDE: "Einrichtbetrieb nur mit reduzierter Geschwindigkeit und Zweihandschaltung.",
|
||||||
|
ScenarioDE: "Einrichter befindet sich im Werkzeugraum waehrend Testlauf im Einrichtbetrieb",
|
||||||
|
TriggerDE: "Stossel fuehrt vollen Hub statt Tipphub aus wegen Softwarefehler oder Fehlbedienung",
|
||||||
|
HarmDE: "Toedliches Quetschen oder Amputation durch vollen Pressenhub bei Anwesenheit",
|
||||||
|
AffectedDE: "Einrichter",
|
||||||
|
ZoneDE: "Werkzeugraum, Pressenhubraum, Stanzbereich",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP084", NameDE: "Falsche Parametereinstellung nach Umruestung", NameEN: "Wrong parameters after changeover",
|
ID: "HP084", NameDE: "Falsche Parametereinstellung nach Umruestung", NameEN: "Wrong parameters after changeover",
|
||||||
@@ -188,6 +296,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M106"},
|
SuggestedMeasureIDs: []string{"M106"},
|
||||||
Priority: 82,
|
Priority: 82,
|
||||||
ExpertHintDE: "Parameterverifikation nach jedem Werkzeugwechsel. Checkliste verwenden.",
|
ExpertHintDE: "Parameterverifikation nach jedem Werkzeugwechsel. Checkliste verwenden.",
|
||||||
|
ScenarioDE: "Einrichter uebernimmt falsche Steuerungsparameter nach Werkzeugwechsel",
|
||||||
|
TriggerDE: "Maschine faehrt mit falscher Kraft, Geschwindigkeit oder Position nach Umruestung",
|
||||||
|
HarmDE: "Werkzeugbruch mit Splitterflug, Quetschung durch ueberhoehlte Schliesskraft",
|
||||||
|
AffectedDE: "Einrichter, Bedienpersonal im Erstanlauf",
|
||||||
|
ZoneDE: "Werkzeugraum, Auswurfbereich, Steuerungspult",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP085", NameDE: "Testzyklus trifft Einrichter", NameEN: "Test cycle hits setup personnel",
|
ID: "HP085", NameDE: "Testzyklus trifft Einrichter", NameEN: "Test cycle hits setup personnel",
|
||||||
@@ -197,6 +311,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M005", "M106"},
|
SuggestedMeasureIDs: []string{"M005", "M106"},
|
||||||
Priority: 90,
|
Priority: 90,
|
||||||
ExpertHintDE: "Schutztuer geschlossen bei Testzyklen. Alternativ: Tippbetrieb mit Zustimmtaster.",
|
ExpertHintDE: "Schutztuer geschlossen bei Testzyklen. Alternativ: Tippbetrieb mit Zustimmtaster.",
|
||||||
|
ScenarioDE: "Einrichter steht im Gefahrenbereich waehrend automatischer Testzyklus gestartet wird",
|
||||||
|
TriggerDE: "Kollege startet Testzyklus ohne Ruecksprache, Schutztuer nicht verriegelt",
|
||||||
|
HarmDE: "Erfassen oder Quetschen durch Maschinenbewegung im automatischen Testlauf",
|
||||||
|
AffectedDE: "Einrichter, Inbetriebnahmepersonal",
|
||||||
|
ZoneDE: "Werkzeugraum, Roboterzelle, Bearbeitungsraum",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -209,6 +329,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M051"},
|
SuggestedMeasureIDs: []string{"M051"},
|
||||||
Priority: 85,
|
Priority: 85,
|
||||||
|
ScenarioDE: "Maschine wird mittels Kran oder Gabelstapler transportiert, Schwerpunkt nicht korrekt",
|
||||||
|
TriggerDE: "Maschine kippt wegen falsch gesetzter Anschlagpunkte oder asymmetrischer Last",
|
||||||
|
HarmDE: "Toedliches Quetschen oder schwere Fraktur durch kippende Maschinenstruktur",
|
||||||
|
AffectedDE: "Transportpersonal, Montagepersonal, umstehende Personen",
|
||||||
|
ZoneDE: "Transportweg, Aufstellbereich, Kranradius",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP087", NameDE: "Quetschen bei Montage/Aufstellung", NameEN: "Crushing during installation",
|
ID: "HP087", NameDE: "Quetschen bei Montage/Aufstellung", NameEN: "Crushing during installation",
|
||||||
@@ -217,6 +343,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M051"},
|
SuggestedMeasureIDs: []string{"M051"},
|
||||||
Priority: 82,
|
Priority: 82,
|
||||||
|
ScenarioDE: "Montagepersonal positioniert schwere Maschinenkomponente bei Erstaufstellung",
|
||||||
|
TriggerDE: "Bauteil rutscht von Unterlage oder Hebezeug versagt beim Absetzen",
|
||||||
|
HarmDE: "Quetschung von Haenden/Fuessen zwischen Maschinenteil und Fundament",
|
||||||
|
AffectedDE: "Montagepersonal, Inbetriebnahmepersonal",
|
||||||
|
ZoneDE: "Aufstellflaeche, Fundamentbereich, Montagezone",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP088", NameDE: "Unkontrollierte Bewegung bei Inbetriebnahme", NameEN: "Uncontrolled movement during commissioning",
|
ID: "HP088", NameDE: "Unkontrollierte Bewegung bei Inbetriebnahme", NameEN: "Uncontrolled movement during commissioning",
|
||||||
@@ -225,6 +357,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M005", "M106"},
|
SuggestedMeasureIDs: []string{"M005", "M106"},
|
||||||
Priority: 90,
|
Priority: 90,
|
||||||
|
ScenarioDE: "Inbetriebnahmepersonal testet erstmals Bewegungsablaeufe der programmierten Maschine",
|
||||||
|
TriggerDE: "Programmierfehler oder falsche Endlagen fuehren zu unkontrollierter Achsbewegung",
|
||||||
|
HarmDE: "Quetschen oder Erfassen durch unerwartet schnelle oder weite Maschinenbewegung",
|
||||||
|
AffectedDE: "Inbetriebnahmepersonal, Programmierer",
|
||||||
|
ZoneDE: "Gesamter Bewegungsraum der Achsen, Roboterzelle, Arbeitsraum",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP089", NameDE: "Restmedien bei Demontage (Oel, Gas, Druck)", NameEN: "Residual media during dismantling",
|
ID: "HP089", NameDE: "Restmedien bei Demontage (Oel, Gas, Druck)", NameEN: "Residual media during dismantling",
|
||||||
@@ -233,6 +371,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental", "pneumatic_hydraulic"},
|
GeneratedHazardCats: []string{"material_environmental", "pneumatic_hydraulic"},
|
||||||
SuggestedMeasureIDs: []string{"M054"},
|
SuggestedMeasureIDs: []string{"M054"},
|
||||||
Priority: 75,
|
Priority: 75,
|
||||||
|
ScenarioDE: "Demontagepersonal loest Leitungen oder Behaelter mit Restmedien bei Ausserbetriebnahme",
|
||||||
|
TriggerDE: "Austritt von Restoel, Druckluft oder Gas beim Loesen von Verschraubungen",
|
||||||
|
HarmDE: "Veraetzung durch Hydraulikoel, Verletzung durch Druckentladung, Vergiftung durch Gas",
|
||||||
|
AffectedDE: "Demontagepersonal, Entsorger",
|
||||||
|
ZoneDE: "Hydraulikleitungen, Druckspeicher, Kuehlmittelkreislauf",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP090", NameDE: "Scharfe Kanten bei Demontage", NameEN: "Sharp edges during dismantling",
|
ID: "HP090", NameDE: "Scharfe Kanten bei Demontage", NameEN: "Sharp edges during dismantling",
|
||||||
@@ -241,6 +385,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 60,
|
Priority: 60,
|
||||||
|
ScenarioDE: "Demontagepersonal handhabt zerlegte Maschinenteile mit scharfen Schneidkanten",
|
||||||
|
TriggerDE: "Greifen oder Transportieren von Bauteilen ohne Schnittschutzhandschuhe",
|
||||||
|
HarmDE: "Schnittverletzungen an Haenden und Unterarmen durch scharfe Metallkanten",
|
||||||
|
AffectedDE: "Demontagepersonal, Entsorger",
|
||||||
|
ZoneDE: "Demontagebereich, Zwischenlager fuer zerlegte Bauteile",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -253,6 +403,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 65,
|
Priority: 65,
|
||||||
|
ScenarioDE: "Reinigungspersonal bewegt sich auf nassem oder oelverschmutztem Boden um die Maschine",
|
||||||
|
TriggerDE: "Ausrutschen auf Kuehlschmierstoff, Hydraulikoel oder Reinigungswasser am Boden",
|
||||||
|
HarmDE: "Sturzverletzung mit Prellungen, Frakturen oder Kopfverletzung",
|
||||||
|
AffectedDE: "Reinigungspersonal, Bedienpersonal",
|
||||||
|
ZoneDE: "Maschinenumgebung, Bodenbereich, Ablaufrinnen",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP092", NameDE: "Chemische Exposition bei Reinigung", NameEN: "Chemical exposure during cleaning",
|
ID: "HP092", NameDE: "Chemische Exposition bei Reinigung", NameEN: "Chemical exposure during cleaning",
|
||||||
@@ -261,6 +417,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"material_environmental"},
|
GeneratedHazardCats: []string{"material_environmental"},
|
||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
Priority: 70,
|
Priority: 70,
|
||||||
|
ScenarioDE: "Reinigungspersonal verwendet Loesungsmittel oder aggressive Reiniger ohne Absaugung",
|
||||||
|
TriggerDE: "Einatmen von Loesungsmitteldaempfen oder Hautkontakt mit Reinigungschemikalien",
|
||||||
|
HarmDE: "Atemwegsreizung, Hautveraetzung oder allergische Reaktion durch Chemikalienkontakt",
|
||||||
|
AffectedDE: "Reinigungspersonal",
|
||||||
|
ZoneDE: "Maschineninneres, Werkzeugraum, geschlossene Reinigungsbereiche",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP093", NameDE: "Einziehen in rotierende Teile bei Reinigung", NameEN: "Draw-in by rotating parts during cleaning",
|
ID: "HP093", NameDE: "Einziehen in rotierende Teile bei Reinigung", NameEN: "Draw-in by rotating parts during cleaning",
|
||||||
@@ -270,6 +432,12 @@ func GetOperationalHazardPatterns() []HazardPattern {
|
|||||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||||
SuggestedMeasureIDs: []string{"M001", "M054"},
|
SuggestedMeasureIDs: []string{"M001", "M054"},
|
||||||
Priority: 88,
|
Priority: 88,
|
||||||
|
ScenarioDE: "Reinigungspersonal greift mit Lappen in rotierende Teile bei laufender Maschine",
|
||||||
|
TriggerDE: "Lappen oder Kleidung wird von rotierender Welle erfasst und zieht Hand ein",
|
||||||
|
HarmDE: "Amputation, Skalpierung oder schwere Quetschung durch Einzug in Drehbewegung",
|
||||||
|
AffectedDE: "Reinigungspersonal",
|
||||||
|
ZoneDE: "Offene Antriebswellen, Walzen, Spindeln ohne Verkleidung",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
RequiresExpertCalculation: true,
|
RequiresExpertCalculation: true,
|
||||||
ExpertHintDE: "SIL/PL-Nachweis fuer Stoesselabsturzsicherung erforderlich.",
|
ExpertHintDE: "SIL/PL-Nachweis fuer Stoesselabsturzsicherung erforderlich.",
|
||||||
ExpertHintEN: "SIL/PL verification for ram drop protection required.",
|
ExpertHintEN: "SIL/PL verification for ram drop protection required.",
|
||||||
|
ScenarioDE: "Stoessel faellt unkontrolliert ab bei Druckverlust im Hydrauliksystem oder Versagen der mechanischen Haltevorrichtung.",
|
||||||
|
TriggerDE: "Leitungsbruch, Dichtungsversagen oder Defekt des Rueckschlagventils im Hydraulikkreis.",
|
||||||
|
HarmDE: "Toedliche Quetschverletzung, Amputation von Gliedmassen.",
|
||||||
|
AffectedDE: "Einrichter, Bedienpersonal im Werkzeugeinbauraum.",
|
||||||
|
ZoneDE: "Werkzeugeinbauraum unterhalb des Stoessels.",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP046", NameDE: "Quetschen im Werkzeugeinbauraum", NameEN: "Crushing in die space",
|
ID: "HP046", NameDE: "Quetschen im Werkzeugeinbauraum", NameEN: "Crushing in die space",
|
||||||
@@ -27,6 +33,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M001", "M005", "M051", "M106"},
|
SuggestedMeasureIDs: []string{"M001", "M005", "M051", "M106"},
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
Priority: 97,
|
Priority: 97,
|
||||||
|
ScenarioDE: "Einrichter arbeitet im Werkzeugeinbauraum bei nicht gesichertem Stoessel oder laufendem Automatikbetrieb.",
|
||||||
|
TriggerDE: "Unbeabsichtigter Hub waehrend Einrichtarbeiten, Manipulation der Schutztuer-Verriegelung.",
|
||||||
|
HarmDE: "Toedliche Quetschverletzung, Amputation der oberen Extremitaeten.",
|
||||||
|
AffectedDE: "Einrichter, Werkzeugbauer, Instandhaltungspersonal.",
|
||||||
|
ZoneDE: "Werkzeugeinbauraum zwischen Ober- und Unterwerkzeug.",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP047", NameDE: "Oelnebelexposition Atemwege", NameEN: "Oil mist inhalation exposure",
|
ID: "HP047", NameDE: "Oelnebelexposition Atemwege", NameEN: "Oil mist inhalation exposure",
|
||||||
@@ -36,6 +48,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M124", "M141"},
|
SuggestedMeasureIDs: []string{"M124", "M141"},
|
||||||
SuggestedEvidenceIDs: []string{"E20"},
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
Priority: 80,
|
Priority: 80,
|
||||||
|
ScenarioDE: "Oelnebel entsteht beim Pressen durch Leckagen oder Verdampfung des Hydraulikoels und wird vom Bediener eingeatmet.",
|
||||||
|
TriggerDE: "Leckage an Hochdruckleitungen, ueberhitztes Hydraulikoel, fehlende oder defekte Absaugung.",
|
||||||
|
HarmDE: "Atemwegsreizung, chronische Lungenerkrankung bei Langzeitexposition.",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Nahbereich der Presse.",
|
||||||
|
ZoneDE: "Arbeitsbereich rund um die Presse, insbesondere Bedienerseite.",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP048", NameDE: "Verbrennung durch heisse Werkstuecke", NameEN: "Burns from hot workpieces",
|
ID: "HP048", NameDE: "Verbrennung durch heisse Werkstuecke", NameEN: "Burns from hot workpieces",
|
||||||
@@ -45,6 +63,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M054", "M141"},
|
SuggestedMeasureIDs: []string{"M054", "M141"},
|
||||||
SuggestedEvidenceIDs: []string{"E08"},
|
SuggestedEvidenceIDs: []string{"E08"},
|
||||||
Priority: 85,
|
Priority: 85,
|
||||||
|
ScenarioDE: "Heisse Werkstuecke oder Werkzeuge werden beim Warmumformen manuell entnommen oder fallen aus der Matrize.",
|
||||||
|
TriggerDE: "Manuelles Handling ohne Hitzeschutz, Ausfall der automatischen Entnahme.",
|
||||||
|
HarmDE: "Verbrennungen zweiten oder dritten Grades an Haenden und Unterarmen.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter bei Werkzeugwechsel.",
|
||||||
|
ZoneDE: "Entnahmebereich, Werkzeugeinbauraum, Ablagetisch.",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP049", NameDE: "Schwebende Last (Hubwerk/Aufzug)", NameEN: "Suspended load (hoist/elevator)",
|
ID: "HP049", NameDE: "Schwebende Last (Hubwerk/Aufzug)", NameEN: "Suspended load (hoist/elevator)",
|
||||||
@@ -54,6 +78,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M001", "M005", "M051"},
|
SuggestedMeasureIDs: []string{"M001", "M005", "M051"},
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
Priority: 95,
|
Priority: 95,
|
||||||
|
ScenarioDE: "Schweres Werkzeug oder Pressenoberteil haengt am Kran/Hubwerk und kann bei Seilriss oder Bremsenversagen herabfallen.",
|
||||||
|
TriggerDE: "Seilriss, Versagen der Kranbremse, ueberladung des Hubwerks.",
|
||||||
|
HarmDE: "Toedliche Verletzung durch herabfallende Last, Knochenbrueche.",
|
||||||
|
AffectedDE: "Personen im Gefahrenbereich unter der schwebenden Last.",
|
||||||
|
ZoneDE: "Bereich unterhalb des Hubwerks, Werkzeugwechselzone.",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP050", NameDE: "Einziehen/Scheren Transfersystem", NameEN: "Draw-in/shearing at transfer system",
|
ID: "HP050", NameDE: "Einziehen/Scheren Transfersystem", NameEN: "Draw-in/shearing at transfer system",
|
||||||
@@ -63,6 +93,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M001", "M005", "M051"},
|
SuggestedMeasureIDs: []string{"M001", "M005", "M051"},
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
Priority: 90,
|
Priority: 90,
|
||||||
|
ScenarioDE: "Transferbalken oder Greiferleisten bewegen sich im Automatikbetrieb und erfassen Koerperteile des Bedieners.",
|
||||||
|
TriggerDE: "Eingriff in den Transferbereich bei laufendem Betrieb, Defekt der Zugangsabsicherung.",
|
||||||
|
HarmDE: "Schnittverletzungen, Amputation von Fingern, Quetschungen.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter bei Stoerungsbeseitigung.",
|
||||||
|
ZoneDE: "Transferbereich zwischen den Pressenstationen.",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP051", NameDE: "Sturzgefahr Auswurfbereich", NameEN: "Fall hazard at ejection area",
|
ID: "HP051", NameDE: "Sturzgefahr Auswurfbereich", NameEN: "Fall hazard at ejection area",
|
||||||
@@ -73,6 +109,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M051", "M141"},
|
SuggestedMeasureIDs: []string{"M051", "M141"},
|
||||||
SuggestedEvidenceIDs: []string{"E20"},
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
Priority: 75,
|
Priority: 75,
|
||||||
|
ScenarioDE: "Bediener stolpert oder stuerzt im Auswurfbereich ueber herumliegende Teile oder oelverschmierte Boeden.",
|
||||||
|
TriggerDE: "Verschmutzter Boden, fehlende Bodenmarkierung, ungesicherte Hoehendifferenz am Auswurfschacht.",
|
||||||
|
HarmDE: "Knochenbrueche, Prellungen, Kopfverletzungen bei Sturz.",
|
||||||
|
AffectedDE: "Bedienpersonal, Logistikmitarbeiter im Auswurfbereich.",
|
||||||
|
ZoneDE: "Auswurfschacht und angrenzender Bodenbereich.",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP052", NameDE: "Druckfreisetzung Hydraulikspeicher", NameEN: "Pressure release from hydraulic accumulator",
|
ID: "HP052", NameDE: "Druckfreisetzung Hydraulikspeicher", NameEN: "Pressure release from hydraulic accumulator",
|
||||||
@@ -82,6 +124,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M051", "M131"},
|
SuggestedMeasureIDs: []string{"M051", "M131"},
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
Priority: 92,
|
Priority: 92,
|
||||||
|
ScenarioDE: "Hydraulikspeicher entlaedt sich schlagartig bei Wartungsarbeiten oder Leitungsbruch.",
|
||||||
|
TriggerDE: "Oeffnen einer Leitung ohne vorherige Druckentlastung, Berstversagen des Speichers.",
|
||||||
|
HarmDE: "Schwere Schnittverletzungen durch Oelstrahl, Augenverletzungen, Verbrennungen.",
|
||||||
|
AffectedDE: "Instandhaltungspersonal, Hydraulik-Fachkraefte.",
|
||||||
|
ZoneDE: "Hydraulikaggregat, Speicherbereich, Leitungsfuehrung.",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP053", NameDE: "Impulslaerm Pressvorgang", NameEN: "Impact noise during press operation",
|
ID: "HP053", NameDE: "Impulslaerm Pressvorgang", NameEN: "Impact noise during press operation",
|
||||||
@@ -91,6 +139,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
SuggestedEvidenceIDs: []string{"E20"},
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
Priority: 70,
|
Priority: 70,
|
||||||
|
ScenarioDE: "Jeder Presshub erzeugt Impulslaerm ueber 85 dB(A), der bei Dauerbetrieb das Gehoer schaedigt.",
|
||||||
|
TriggerDE: "Normaler Pressbetrieb bei hoher Hubzahl, fehlende Laermkapselung.",
|
||||||
|
HarmDE: "Laermschwerhoerigkeit, Tinnitus bei Langzeitexposition.",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen in angrenzenden Arbeitsbereichen.",
|
||||||
|
ZoneDE: "Gesamter Pressenbereich, Radius ca. 5-10 m um die Maschine.",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP054", NameDE: "Schwungrad-Restenergie nach Abschaltung", NameEN: "Flywheel residual energy after shutdown",
|
ID: "HP054", NameDE: "Schwungrad-Restenergie nach Abschaltung", NameEN: "Flywheel residual energy after shutdown",
|
||||||
@@ -100,6 +154,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M001", "M054"},
|
SuggestedMeasureIDs: []string{"M001", "M054"},
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
Priority: 88,
|
Priority: 88,
|
||||||
|
ScenarioDE: "Schwungrad dreht nach Abschaltung der Presse noch mehrere Minuten nach und speichert gefaehrliche Rotationsenergie.",
|
||||||
|
TriggerDE: "Zugang zur Maschine vor vollstaendigem Stillstand, fehlende Nachlaufueberwachung.",
|
||||||
|
HarmDE: "Erfassen durch rotierende Teile, schwere Schnittverletzungen, Skalpierung.",
|
||||||
|
AffectedDE: "Instandhaltungspersonal, Einrichter nach Maschinenstopp.",
|
||||||
|
ZoneDE: "Schwungradbereich, Kupplungsraum, Antriebsseite der Presse.",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP055", NameDE: "Umgehung Schutzeinrichtung (Pressentuer)", NameEN: "Bypass of safety guard (press door)",
|
ID: "HP055", NameDE: "Umgehung Schutzeinrichtung (Pressentuer)", NameEN: "Bypass of safety guard (press door)",
|
||||||
@@ -109,6 +169,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M005", "M106"},
|
SuggestedMeasureIDs: []string{"M005", "M106"},
|
||||||
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
Priority: 96,
|
Priority: 96,
|
||||||
|
ScenarioDE: "Bediener manipuliert die Schutztuerverriegelung, um bei geoeffneter Tuer einen Pressenhub auszuloesen.",
|
||||||
|
TriggerDE: "Absichtliche Manipulation des Sicherheitsschalters, defekter Zuhaltungsmechanismus.",
|
||||||
|
HarmDE: "Toedliche Quetsch- oder Scherverletzungen bei Eingriff in den Gefahrenbereich.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter bei Stoerungsbeseitigung.",
|
||||||
|
ZoneDE: "Gesamter Werkzeugeinbauraum hinter der Schutztuer.",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP056", NameDE: "Fehlbedienung Zweihandschaltung", NameEN: "Two-hand control misoperation",
|
ID: "HP056", NameDE: "Fehlbedienung Zweihandschaltung", NameEN: "Two-hand control misoperation",
|
||||||
@@ -118,6 +184,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M106"},
|
SuggestedMeasureIDs: []string{"M106"},
|
||||||
SuggestedEvidenceIDs: []string{"E01"},
|
SuggestedEvidenceIDs: []string{"E01"},
|
||||||
Priority: 90,
|
Priority: 90,
|
||||||
|
ScenarioDE: "Zweihandschaltung wird mit Hilfsmitteln ueberbrueckt oder ein Taster wird fixiert, sodass Einhandbedienung moeglich wird.",
|
||||||
|
TriggerDE: "Manipulation der Taster, Fixierung mit Klebeband oder Keil, Defekt der Gleichzeitigkeitsueberwachung.",
|
||||||
|
HarmDE: "Quetschverletzungen der freien Hand im Werkzeugbereich.",
|
||||||
|
AffectedDE: "Bedienpersonal an der Pressenbedienung.",
|
||||||
|
ZoneDE: "Gefahrenbereich zwischen Ober- und Unterwerkzeug.",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP057", NameDE: "Hydraulikoelleckage + Rutschgefahr", NameEN: "Hydraulic oil leakage + slip hazard",
|
ID: "HP057", NameDE: "Hydraulikoelleckage + Rutschgefahr", NameEN: "Hydraulic oil leakage + slip hazard",
|
||||||
@@ -127,6 +199,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
SuggestedEvidenceIDs: []string{"E20"},
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
Priority: 65,
|
Priority: 65,
|
||||||
|
ScenarioDE: "Hydraulikoel tritt aus defekten Dichtungen oder Verschraubungen aus und bildet Lachen auf dem Hallenboden.",
|
||||||
|
TriggerDE: "Verschleiss von Dichtungen, lockere Verschraubungen, Schlauchbruch.",
|
||||||
|
HarmDE: "Sturzverletzungen durch Ausrutschen, Hautreizungen bei Hautkontakt.",
|
||||||
|
AffectedDE: "Bedienpersonal, Logistikmitarbeiter, alle Personen im Pressenbereich.",
|
||||||
|
ZoneDE: "Bodenbereich rund um das Hydraulikaggregat und unter der Presse.",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "HP058", NameDE: "Ergonomische Belastung Kistenwechsel", NameEN: "Ergonomic strain during bin changeover",
|
ID: "HP058", NameDE: "Ergonomische Belastung Kistenwechsel", NameEN: "Ergonomic strain during bin changeover",
|
||||||
@@ -136,6 +214,12 @@ func GetPressHazardPatterns() []HazardPattern {
|
|||||||
SuggestedMeasureIDs: []string{"M141"},
|
SuggestedMeasureIDs: []string{"M141"},
|
||||||
SuggestedEvidenceIDs: []string{"E20"},
|
SuggestedEvidenceIDs: []string{"E20"},
|
||||||
Priority: 55,
|
Priority: 55,
|
||||||
|
ScenarioDE: "Bediener hebt schwere Teilebehaelter manuell an oder bewegt sie ohne Hebehilfe im Auswurfbereich.",
|
||||||
|
TriggerDE: "Fehlende Hebehilfen, hohe Taktzahl erzwingt schnellen manuellen Kistenwechsel.",
|
||||||
|
HarmDE: "Rueckenverletzungen, Bandscheibenvorfall, Muskel-Skelett-Erkrankungen.",
|
||||||
|
AffectedDE: "Bedienpersonal, Logistikmitarbeiter an der Presse.",
|
||||||
|
ZoneDE: "Auswurfbereich, Palettenstellplatz neben der Presse.",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 5,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// builtinSoftwarePatterns returns HP029-HP034: software and control system hazard patterns.
|
||||||
|
func builtinSoftwarePatterns() []HazardPattern {
|
||||||
|
return []HazardPattern{
|
||||||
|
{
|
||||||
|
ID: "HP029", NameDE: "Software-Fehler in Steuerung", NameEN: "Software fault in controller",
|
||||||
|
RequiredComponentTags: []string{"has_software", "programmable"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
ExcludedComponentTags: []string{"has_ai"},
|
||||||
|
GeneratedHazardCats: []string{"software_fault"},
|
||||||
|
SuggestedMeasureIDs: []string{"M101", "M102", "M103"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E14"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Softwarefehler (Logikfehler, Race Condition, Ueberlauf) fuehrt zu unbeabsichtigter Maschinenbewegung.",
|
||||||
|
TriggerDE: "Nicht abgefangener Fehlerzustand, falsche Parametrierung oder Timing-Problem in der SPS/Steuerung.",
|
||||||
|
HarmDE: "Unerwartete Aktorbewegung, Versagen der Abschaltfunktion, unkontrollierter Dauerlauf.",
|
||||||
|
AffectedDE: "Bedienpersonal, Personen im Maschinenbereich",
|
||||||
|
ZoneDE: "Gesamte Maschine (Wirkbereich aller softwaregesteuerter Aktoren)",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP030", NameDE: "Sicherheitsfunktionsversagen", NameEN: "Safety function failure",
|
||||||
|
RequiredComponentTags: []string{"safety_device"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"safety_function_failure"},
|
||||||
|
SuggestedMeasureIDs: []string{"M104", "M105", "M051"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E07", "E08", "E09"},
|
||||||
|
Priority: 95,
|
||||||
|
ScenarioDE: "Sicherheitsrelevante Funktion (Not-Halt, Schutztuer, Lichtvorhang) versagt im Anforderungsfall.",
|
||||||
|
TriggerDE: "Hardware-Defekt, systematischer Fehler oder unentdeckter gefaehrlicher Ausfall der Sicherheitskomponente.",
|
||||||
|
HarmDE: "Kein rechtzeitiger Maschinenstopp, Verletzung durch fehlende Schutzfunktion, schwere Folgen.",
|
||||||
|
AffectedDE: "Bedienpersonal, alle Personen im Gefahrenbereich",
|
||||||
|
ZoneDE: "Schutzbereich hinter Schutzzaun, Lichtvorhang-Ebene, Not-Halt-Wirkbereich",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP031", NameDE: "Konfigurationsfehler", NameEN: "Configuration error",
|
||||||
|
RequiredComponentTags: []string{"programmable"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"configuration_error"},
|
||||||
|
SuggestedMeasureIDs: []string{"M145", "M146", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E14"},
|
||||||
|
Priority: 70,
|
||||||
|
ScenarioDE: "Falsche Parametrierung von Achsgrenzen, Geschwindigkeiten oder Sicherheitsgrenzen nach Umruestung.",
|
||||||
|
TriggerDE: "Bediener oder Einrichter aendert Parameter ohne Validierung oder nutzt falsches Rezept/Programm.",
|
||||||
|
HarmDE: "Ueberfahren mechanischer Anschlaege, zu hohe Kraefte/Geschwindigkeiten, Kollision.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter",
|
||||||
|
ZoneDE: "Gesamte Maschine (alle parametrierbaren Achsen und Funktionen)",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP032", NameDE: "Fehlende Protokollierung / Audit", NameEN: "Missing logging / audit",
|
||||||
|
RequiredComponentTags: []string{"has_software"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"logging_audit_failure"},
|
||||||
|
SuggestedMeasureIDs: []string{"M142", "M149"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01"},
|
||||||
|
Priority: 50,
|
||||||
|
ScenarioDE: "Sicherheitsrelevante Ereignisse werden nicht protokolliert; Ursachenanalyse nach Vorfall unmoeglich.",
|
||||||
|
TriggerDE: "Fehlende oder unvollstaendige Logging-Implementierung fuer sicherheitsrelevante Zustandswechsel.",
|
||||||
|
HarmDE: "Kein direkter Personenschaden, aber erschwerter Nachweis und verzoegerte Fehlerbeseitigung.",
|
||||||
|
AffectedDE: "Indirekt alle Bediener (Wiederholungsgefahr unerkannter Fehler)",
|
||||||
|
ZoneDE: "Steuerungssystem, Sicherheits-SPS, HMI-Audit-Trail",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP033", NameDE: "Update-Fehler / Rollback-Problem", NameEN: "Update failure / rollback problem",
|
||||||
|
RequiredComponentTags: []string{"has_software", "programmable"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"update_failure"},
|
||||||
|
SuggestedMeasureIDs: []string{"M138", "M141", "M146"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E14"},
|
||||||
|
Priority: 65,
|
||||||
|
ScenarioDE: "Software-Update der Steuerung scheitert oder fuehrt zu inkompatiblem Zustand mit Sicherheitsfunktionen.",
|
||||||
|
TriggerDE: "Unterbrochenes Update, inkompatible Firmware-Version oder fehlender Rollback-Mechanismus.",
|
||||||
|
HarmDE: "Steuerungsausfall, Verlust der Sicherheitslogik, unkontrollierter Maschinenzustand.",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal",
|
||||||
|
ZoneDE: "Steuerungssystem, Sicherheits-SPS, Antriebsregler",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP034", NameDE: "Verriegelungs-Umgehungsgefahr", NameEN: "Interlock bypass risk",
|
||||||
|
RequiredComponentTags: []string{"interlocked"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"safety_function_failure"},
|
||||||
|
SuggestedMeasureIDs: []string{"M051", "M104", "M107"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E08"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Sicherheitsverriegelung (Schutztuer, Zweihandsteuerung) wird vom Bediener umgangen oder manipuliert.",
|
||||||
|
TriggerDE: "Festklemmen des Tuerschalters, Ueberbruecken der Zweihandbedienung oder Dauerbetaetigung mit Kabelbinder.",
|
||||||
|
HarmDE: "Voller Zugang zum Gefahrenbereich bei laufender Maschine, schwere Quetsch-/Schnittverletzung.",
|
||||||
|
AffectedDE: "Bedienpersonal, Einrichter",
|
||||||
|
ZoneDE: "Schutztuerbereich, Zweihand-Bedienpult, Verriegelungsschalter",
|
||||||
|
DefaultSeverity: 5, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// builtinThermalPatterns returns HP016-HP018: thermal and radiation hazard patterns.
|
||||||
|
func builtinThermalPatterns() []HazardPattern {
|
||||||
|
return []HazardPattern{
|
||||||
|
{
|
||||||
|
ID: "HP016", NameDE: "Verbrennungsgefahr durch heisse Oberflaechen", NameEN: "Burn risk from hot surfaces",
|
||||||
|
RequiredComponentTags: []string{"high_temperature"},
|
||||||
|
RequiredEnergyTags: []string{"thermal"},
|
||||||
|
GeneratedHazardCats: []string{"thermal_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M071", "M121", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E20"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Bediener beruehrt heisse Maschinenteile (Heizelemente, Duesenstoecke, Ofenwaende) bei Betrieb oder kurz nach Abschalten.",
|
||||||
|
TriggerDE: "Unbeabsichtigter Hautkontakt mit Oberflaeche ueber 65 Grad C ohne Schutzhandschuhe.",
|
||||||
|
HarmDE: "Kontaktverbrennung 1.-3. Grades, Blasenbildung, Narbenbildung.",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal",
|
||||||
|
ZoneDE: "Heizelemente, Formwerkzeuge, Auspuffleitung, Motoroberflaeche",
|
||||||
|
DefaultSeverity: 3, DefaultExposure: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP017", NameDE: "Strahlungsgefahr (Laser/optisch)", NameEN: "Radiation risk (laser/optical)",
|
||||||
|
RequiredComponentTags: []string{"radiation_risk"},
|
||||||
|
RequiredEnergyTags: []string{"radiation"},
|
||||||
|
GeneratedHazardCats: []string{"thermal_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M072", "M051", "M131"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01", "E20"},
|
||||||
|
Priority: 85,
|
||||||
|
ScenarioDE: "Bediener wird Laserstrahlung, UV-Strahlung oder intensiver optischer Strahlung ausgesetzt.",
|
||||||
|
TriggerDE: "Reflexion oder direkter Strahlaustritt durch offene Schutzhaube, defekte Abschirmung oder Justierarbeiten.",
|
||||||
|
HarmDE: "Augenschaeden (Netzhautverbrennung, Hornhautschaedigung), Hautverbrennungen, Langzeitschaeden.",
|
||||||
|
AffectedDE: "Bedienpersonal, Wartungspersonal, Personen im Strahlbereich",
|
||||||
|
ZoneDE: "Strahlaustrittsoeffnung, Bearbeitungszone, Reflexionsbereich",
|
||||||
|
DefaultSeverity: 4, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "HP018", NameDE: "Verbrennungsgefahr durch Aktuatoren", NameEN: "Burn risk from actuators",
|
||||||
|
RequiredComponentTags: []string{"actuator_part", "high_temperature"},
|
||||||
|
RequiredEnergyTags: []string{},
|
||||||
|
GeneratedHazardCats: []string{"thermal_hazard"},
|
||||||
|
SuggestedMeasureIDs: []string{"M071", "M121"},
|
||||||
|
SuggestedEvidenceIDs: []string{"E01"},
|
||||||
|
Priority: 75,
|
||||||
|
ScenarioDE: "Aktuatoren (Servomotoren, Linearantriebe) erwaermen sich im Dauerbetrieb ueber die Beruehrtemperaturgrenze.",
|
||||||
|
TriggerDE: "Beruehren heisser Motorgehaeuse bei Wartung oder Stoerungsbeseitigung ohne ausreichende Abkuehlzeit.",
|
||||||
|
HarmDE: "Kontaktverbrennung, Blasenbildung an Haenden.",
|
||||||
|
AffectedDE: "Wartungspersonal, Einrichter",
|
||||||
|
ZoneDE: "Motorgehaeuse, Getriebegehaeuse, Linearantrieb",
|
||||||
|
DefaultSeverity: 2, DefaultExposure: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Production Line Entities
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ProductionLine represents a chain of IACE projects forming a production line
|
||||||
|
type ProductionLine struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
TenantID uuid.UUID `json:"tenant_id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Layout json.RawMessage `json:"layout,omitempty"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProductionLineStation links a production line to an IACE project as a station
|
||||||
|
type ProductionLineStation struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
LineID uuid.UUID `json:"line_id"`
|
||||||
|
ProjectID uuid.UUID `json:"project_id"`
|
||||||
|
StationType string `json:"station_type"`
|
||||||
|
StationLabel string `json:"station_label,omitempty"`
|
||||||
|
SortOrder int `json:"sort_order"`
|
||||||
|
PositionX float64 `json:"position_x"`
|
||||||
|
PositionY float64 `json:"position_y"`
|
||||||
|
Metadata json.RawMessage `json:"metadata,omitempty"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Dashboard Aggregation Types
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// StationDashboard contains the per-station risk and compliance summary
|
||||||
|
type StationDashboard struct {
|
||||||
|
Station ProductionLineStation `json:"station"`
|
||||||
|
ProjectName string `json:"project_name"`
|
||||||
|
MachineType string `json:"machine_type"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
RiskSummary map[string]int `json:"risk_summary"`
|
||||||
|
HazardCount int `json:"hazard_count"`
|
||||||
|
MitigationCount int `json:"mitigation_count"`
|
||||||
|
CompletenessPct int `json:"completeness_pct"`
|
||||||
|
SILMax string `json:"sil_max"`
|
||||||
|
PLMax string `json:"pl_max"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LineDashboard aggregates all stations for a production line overview
|
||||||
|
type LineDashboard struct {
|
||||||
|
Line ProductionLine `json:"line"`
|
||||||
|
Stations []StationDashboard `json:"stations"`
|
||||||
|
Transfers []TransferInfo `json:"transfers"`
|
||||||
|
Aggregate map[string]int `json:"aggregate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TransferInfo describes a material/data flow between adjacent stations
|
||||||
|
type TransferInfo struct {
|
||||||
|
FromStation int `json:"from_station"`
|
||||||
|
ToStation int `json:"to_station"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// API Request/Response Types
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// CreateProductionLineRequest is the API request for creating a production line
|
||||||
|
type CreateProductionLineRequest struct {
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddStationRequest is the API request for adding a station to a production line
|
||||||
|
type AddStationRequest struct {
|
||||||
|
ProjectID uuid.UUID `json:"project_id" binding:"required"`
|
||||||
|
StationType string `json:"station_type,omitempty"`
|
||||||
|
StationLabel string `json:"station_label,omitempty"`
|
||||||
|
SortOrder int `json:"sort_order"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProductionLineListResponse is the API response for listing production lines
|
||||||
|
type ProductionLineListResponse struct {
|
||||||
|
Lines []ProductionLine `json:"lines"`
|
||||||
|
Total int `json:"total"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
import "sort"
|
||||||
|
|
||||||
|
// NormSuggestion represents a single norm matched to a project context.
|
||||||
|
type NormSuggestion struct {
|
||||||
|
Norm NormReference `json:"norm"`
|
||||||
|
Reason string `json:"reason"` // Why this norm was suggested
|
||||||
|
Confidence float64 `json:"confidence"` // 0.0-1.0 relevance score
|
||||||
|
Sources []string `json:"sources"` // What triggered the match
|
||||||
|
}
|
||||||
|
|
||||||
|
// NormSuggestionResult groups suggested norms by hierarchy type.
|
||||||
|
type NormSuggestionResult struct {
|
||||||
|
ANorms []NormSuggestion `json:"a_norms"`
|
||||||
|
B1Norms []NormSuggestion `json:"b1_norms"`
|
||||||
|
B2Norms []NormSuggestion `json:"b2_norms"`
|
||||||
|
CNorms []NormSuggestion `json:"c_norms"`
|
||||||
|
Total int `json:"total"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SuggestNorms matches relevant norms for a project based on its machine type,
|
||||||
|
// identified hazard categories, and component/energy tags.
|
||||||
|
// A-norms are always included (they apply universally). B/C norms are matched
|
||||||
|
// by machine type (confidence 0.9), hazard category (0.8), or tag (0.7).
|
||||||
|
func SuggestNorms(machineType string, hazardCategories []string, tags []string) *NormSuggestionResult {
|
||||||
|
allNorms := GetNormsLibrary()
|
||||||
|
allNorms = append(allNorms, GetExtendedB2Norms()...)
|
||||||
|
allNorms = append(allNorms, GetCNormsLibrary()...)
|
||||||
|
allNorms = append(allNorms, GetExtendedCNormsLibrary()...)
|
||||||
|
allNorms = append(allNorms, GetWoodMetalCNorms()...)
|
||||||
|
allNorms = append(allNorms, GetFoodPkgCNorms()...)
|
||||||
|
allNorms = append(allNorms, GetLiftMiscCNorms()...)
|
||||||
|
|
||||||
|
// Build lookup sets for efficient matching
|
||||||
|
hazardSet := toSet(hazardCategories)
|
||||||
|
tagSet := toSet(tags)
|
||||||
|
|
||||||
|
seen := make(map[string]bool)
|
||||||
|
var suggestions []NormSuggestion
|
||||||
|
|
||||||
|
for _, norm := range allNorms {
|
||||||
|
if seen[norm.ID] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
suggestion := matchNorm(norm, machineType, hazardSet, tagSet)
|
||||||
|
if suggestion != nil {
|
||||||
|
seen[norm.ID] = true
|
||||||
|
suggestions = append(suggestions, *suggestion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return groupByType(suggestions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// matchNorm checks a single norm against the project context and returns
|
||||||
|
// a suggestion if it matches, or nil otherwise.
|
||||||
|
func matchNorm(norm NormReference, machineType string, hazardSet, tagSet map[string]bool) *NormSuggestion {
|
||||||
|
// A-norms always apply to all machines
|
||||||
|
if norm.NormType == "A" {
|
||||||
|
return &NormSuggestion{
|
||||||
|
Norm: norm,
|
||||||
|
Reason: "Grundnorm — gilt fuer alle Maschinen",
|
||||||
|
Confidence: 1.0,
|
||||||
|
Sources: []string{"norm_type:A"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var bestConfidence float64
|
||||||
|
var reasons []string
|
||||||
|
var sources []string
|
||||||
|
|
||||||
|
// Machine type match
|
||||||
|
machineTypeMatched := false
|
||||||
|
if machineType != "" && len(norm.MachineTypes) > 0 {
|
||||||
|
for _, mt := range norm.MachineTypes {
|
||||||
|
if mt == machineType {
|
||||||
|
bestConfidence = 0.9
|
||||||
|
reasons = append(reasons, "Maschinentyp: "+machineType)
|
||||||
|
sources = append(sources, "machine_type:"+machineType)
|
||||||
|
machineTypeMatched = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// C-norms with machine_types ONLY match via machine type — skip tag/hazard matching
|
||||||
|
// to avoid suggesting e.g. lathe norms for a press just because both have "rotating_part"
|
||||||
|
if norm.NormType == "C" && len(norm.MachineTypes) > 0 && !machineTypeMatched {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hazard category match (B-norms and C-norms without machine_types)
|
||||||
|
for _, hc := range norm.HazardCats {
|
||||||
|
if hazardSet[hc] {
|
||||||
|
if 0.8 > bestConfidence {
|
||||||
|
bestConfidence = 0.8
|
||||||
|
}
|
||||||
|
reasons = append(reasons, "Gefaehrdung: "+hc)
|
||||||
|
sources = append(sources, "hazard_cat:"+hc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tag match
|
||||||
|
for _, t := range norm.Tags {
|
||||||
|
if tagSet[t] {
|
||||||
|
if 0.7 > bestConfidence {
|
||||||
|
bestConfidence = 0.7
|
||||||
|
}
|
||||||
|
reasons = append(reasons, "Tag: "+t)
|
||||||
|
sources = append(sources, "tag:"+t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if bestConfidence == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &NormSuggestion{
|
||||||
|
Norm: norm,
|
||||||
|
Reason: joinReasons(reasons),
|
||||||
|
Confidence: bestConfidence,
|
||||||
|
Sources: sources,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// groupByType sorts suggestions by confidence and groups them by norm type.
|
||||||
|
func groupByType(suggestions []NormSuggestion) *NormSuggestionResult {
|
||||||
|
sort.Slice(suggestions, func(i, j int) bool {
|
||||||
|
return suggestions[i].Confidence > suggestions[j].Confidence
|
||||||
|
})
|
||||||
|
|
||||||
|
result := &NormSuggestionResult{
|
||||||
|
ANorms: []NormSuggestion{},
|
||||||
|
B1Norms: []NormSuggestion{},
|
||||||
|
B2Norms: []NormSuggestion{},
|
||||||
|
CNorms: []NormSuggestion{},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range suggestions {
|
||||||
|
switch s.Norm.NormType {
|
||||||
|
case "A":
|
||||||
|
result.ANorms = append(result.ANorms, s)
|
||||||
|
case "B1":
|
||||||
|
result.B1Norms = append(result.B1Norms, s)
|
||||||
|
case "B2":
|
||||||
|
result.B2Norms = append(result.B2Norms, s)
|
||||||
|
case "C":
|
||||||
|
result.CNorms = append(result.CNorms, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Total = len(suggestions)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// joinReasons combines multiple reason strings with "; ".
|
||||||
|
func joinReasons(reasons []string) string {
|
||||||
|
if len(reasons) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
result := reasons[0]
|
||||||
|
for i := 1; i < len(reasons); i++ {
|
||||||
|
result += "; " + reasons[i]
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,414 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// NormReference represents a machinery safety norm with its metadata and mappings.
|
||||||
|
// Only norm numbers, official titles, and our own scope descriptions are stored —
|
||||||
|
// no copyrighted norm text is included.
|
||||||
|
type NormReference struct {
|
||||||
|
ID string `json:"id"` // e.g. "ISO-12100"
|
||||||
|
Number string `json:"number"` // e.g. "ISO 12100:2010"
|
||||||
|
TitleDE string `json:"title_de"` // Official German title
|
||||||
|
NormType string `json:"norm_type"` // "A", "B1", "B2", "C"
|
||||||
|
ScopeDE string `json:"scope_de"` // Brief scope in our own words
|
||||||
|
MachineTypes []string `json:"machine_types"` // Machine types this applies to (empty = all)
|
||||||
|
HazardCats []string `json:"hazard_cats"` // Hazard categories
|
||||||
|
Tags []string `json:"tags"` // Component/energy tags that trigger this
|
||||||
|
Mandatory bool `json:"mandatory"` // Typically mandatory vs recommended
|
||||||
|
RelevantSections []string `json:"relevant_sections,omitempty"` // e.g. ["Abschnitt 4.2", "Tabelle 1"]
|
||||||
|
BeuthURL string `json:"beuth_url,omitempty"` // e.g. "https://www.beuth.de/de/norm/din-en-iso-12100"
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNormsLibrary returns A-norms (Grundnormen) and B-norms (Sicherheitsgrundnormen
|
||||||
|
// and Sicherheitsfachgrundnormen) for machinery safety CE compliance.
|
||||||
|
func GetNormsLibrary() []NormReference {
|
||||||
|
return []NormReference{
|
||||||
|
// ── A-Normen (Grundnormen) ──────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-12100", Number: "ISO 12100:2010",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Allgemeine Gestaltungsleitsaetze, Risikobeurteilung und Risikominderung",
|
||||||
|
NormType: "A",
|
||||||
|
ScopeDE: "Zentrale Grundnorm fuer alle Maschinen: definiert den Risikobeurteilungsprozess und das Drei-Stufen-Verfahren zur Risikominderung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{},
|
||||||
|
Tags: []string{},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Risikobeurteilung)", "Abschnitt 5 (Risikominderung)", "Abschnitt 6 (3-Stufen-Verfahren)", "Anhang A (Gefaehrdungsliste)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-12100",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── B1-Normen (Sicherheitsgrundnormen) ─────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-13849-1", Number: "ISO 13849-1:2023",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Sicherheitsbezogene Teile von Steuerungen — Teil 1: Allgemeine Gestaltungsleitsaetze",
|
||||||
|
NormType: "B1",
|
||||||
|
ScopeDE: "Legt das Performance-Level-Verfahren (PL a–e) fuer sicherheitsbezogene Steuerungsteile fest, einschliesslich Kategorien und Diagnosedeckungsgrad.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure", "mechanical_hazard", "electrical_hazard"},
|
||||||
|
Tags: []string{"programmable", "safety_device"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Gestaltungsleitsaetze)", "Abschnitt 5 (PL-Bestimmung)", "Tabelle 3 (PL vs. Kategorie)", "Anhang A (PL-Zuordnung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-13849-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-13849-2", Number: "ISO 13849-2:2012",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Sicherheitsbezogene Teile von Steuerungen — Teil 2: Validierung",
|
||||||
|
NormType: "B1",
|
||||||
|
ScopeDE: "Beschreibt die Validierung der nach ISO 13849-1 ausgelegten sicherheitsbezogenen Steuerungsteile durch Analyse und Tests.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure", "mechanical_hazard", "electrical_hazard"},
|
||||||
|
Tags: []string{"programmable", "safety_device"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Validierungsplan)", "Abschnitt 5 (Analyse)", "Abschnitt 6 (Tests)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-13849-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "IEC-62061", Number: "IEC 62061:2021",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Funktionale Sicherheit sicherheitsbezogener Steuerungssysteme",
|
||||||
|
NormType: "B1",
|
||||||
|
ScopeDE: "Alternatives Verfahren zu ISO 13849 auf Basis von SIL (Safety Integrity Level) fuer komplexe elektronische Steuerungssysteme.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure", "mechanical_hazard", "electrical_hazard"},
|
||||||
|
Tags: []string{"programmable", "safety_device"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (SIL-Zuordnung)", "Abschnitt 6 (Entwurf SRECS)", "Tabelle 3 (SIL-Grenzwerte)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iec-62061",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── B2-Normen (Sicherheitsfachgrundnormen) ──────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-13857", Number: "ISO 13857:2019",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Sicherheitsabstaende gegen das Erreichen von Gefahrstellen mit den oberen und unteren Gliedmassen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Definiert Mindestabstaende, die verhindern, dass Bediener mit Haenden oder Armen Gefahrstellen erreichen koennen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"crush_point", "pinch_point", "shear_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Obere Gliedmassen)", "Tabelle 1 (Sicherheitsabstaende)", "Abschnitt 5 (Untere Gliedmassen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-13857",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-13855", Number: "ISO 13855:2010",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Anordnung von Schutzeinrichtungen im Hinblick auf Annaeherungsgeschwindigkeiten von Koerperteilen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Legt Berechnungsverfahren fuer Mindestabstaende von Schutzeinrichtungen unter Beruecksichtigung der Nachlaufzeit und Annaeherungsgeschwindigkeit fest.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"moving_part", "afterrun_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Berechnung Mindestabstand)", "Abschnitt 6 (Annaeherungsgeschwindigkeit)", "Tabelle 1 (Nachlaufwege)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-13855",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-14120", Number: "ISO 14120:2015",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Trennende Schutzeinrichtungen — Allgemeine Anforderungen fuer Gestaltung und Bau fester und beweglicher trennender Schutzeinrichtungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Anforderungen an die Gestaltung, Berechnung und Konstruktion trennender Schutzeinrichtungen (fest und beweglich) fuer Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"guard", "moving_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Gestaltung)", "Abschnitt 6 (Befestigung)", "Anhang A (Materialauswahl)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-14120",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-14119", Number: "ISO 14119:2013",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Verriegelungseinrichtungen in Verbindung mit trennenden Schutzeinrichtungen — Leitsaetze fuer Gestaltung und Auswahl",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Gestaltungsleitsaetze fuer Verriegelungseinrichtungen (mechanisch, magnetisch, elektronisch) an trennenden Schutzeinrichtungen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"guard", "interlocked"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Auswahl Verriegelungsart)", "Abschnitt 6 (Gestaltung)", "Anhang A (Beispiele)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-14119",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-60204-1", Number: "EN 60204-1:2018",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Elektrische Ausruestung von Maschinen — Teil 1: Allgemeine Anforderungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Anforderungen an die elektrische Ausruestung von Maschinen (Verdrahtung, Schutzleiter, Schutzeinrichtungen, Schaltgeraete, Dokumentation).",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"electrical_hazard"},
|
||||||
|
Tags: []string{"electrical_part", "high_voltage"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Anschluss)", "Abschnitt 6 (Schutz gegen elektrischen Schlag)", "Abschnitt 9 (Steuerkreise)", "Abschnitt 12 (Anschlussleiter)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-60204-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-13850", Number: "ISO 13850:2015",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Not-Halt-Funktion — Gestaltungsleitsaetze",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Gestaltungsleitsaetze fuer die Not-Halt-Funktion: Ausloeser, Betaetigungselemente, Reihenfolge der Abschaltung und Ruecksetzbedingungen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure"},
|
||||||
|
Tags: []string{"moving_part"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Gestaltungsgrundsaetze)", "Abschnitt 5 (Funktionale Aspekte)", "Abschnitt 6 (Farbe/Form)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-13850",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "IEC-61496-1", Number: "IEC 61496-1:2012",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Beruehrungslos wirkende Schutzeinrichtungen — Teil 1: Allgemeine Anforderungen und Pruefungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Anforderungen an beruehrungslos wirkende Schutzeinrichtungen (BWS, z.B. Lichtvorhaenge, Laserscanner) fuer den Personenschutz.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "crush_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Anforderungen)", "Abschnitt 6 (Pruefungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iec-61496-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-4413", Number: "ISO 4413:2010",
|
||||||
|
TitleDE: "Fluidtechnik — Hydraulik — Allgemeine Regeln und sicherheitstechnische Anforderungen an Anlagen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Sicherheitstechnische Anforderungen an hydraulische Anlagen: Druckbegrenzung, Leitungssicherung, Sperrventile, Leckageschutz.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"hydraulic_part", "high_pressure"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)", "Abschnitt 6 (Druckbegrenzung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-4413",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-4414", Number: "ISO 4414:2010",
|
||||||
|
TitleDE: "Fluidtechnik — Pneumatik — Allgemeine Regeln und sicherheitstechnische Anforderungen an Anlagen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Sicherheitstechnische Anforderungen an pneumatische Anlagen: Druckluftaufbereitung, Druckabsicherung, Entlueftung, Leitungssicherung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"pneumatic_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)", "Abschnitt 6 (Druckluftaufbereitung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-4414",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1037", Number: "EN 1037:1995+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Vermeidung von unerwartetem Anlauf",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Massnahmen zur Vermeidung von unerwartetem Anlauf: Energietrennung, gespeicherte Energie, Verriegelung, Absperren und Kennzeichnen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"moving_part", "stored_energy"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Massnahmen zur Vermeidung)", "Abschnitt 5 (Energietrennung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1037",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-11228-1", Number: "ISO 11228-1:2021",
|
||||||
|
TitleDE: "Ergonomie — Manuelles Handhaben von Lasten — Teil 1: Heben, Halten und Tragen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Grenzwerte und Empfehlungen fuer manuelles Heben, Halten und Tragen von Lasten am Arbeitsplatz zur Vermeidung von Muskel-Skelett-Erkrankungen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{"structural_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Heben/Senken)", "Tabelle A.1 (Grenzwerte)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11228-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-11204", Number: "ISO 11204:2010",
|
||||||
|
TitleDE: "Akustik — Geraeuschemmission von Maschinen und Geraeten — Messung der Emissionsschalldruckpegel am Arbeitsplatz und an anderen festgelegten Orten",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Messverfahren fuer Geraeuschemmission am Arbeitsplatz zur Bewertung der Laermbelastung und zum Nachweis der Einhaltung von Grenzwerten.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"noise_vibration"},
|
||||||
|
Tags: []string{"noise_source", "vibration_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Messbedingungen)", "Abschnitt 7 (Unsicherheit)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11204",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-13732-1", Number: "ISO 13732-1:2006",
|
||||||
|
TitleDE: "Ergonomie der thermischen Umgebung — Verfahren zur Beurteilung der Reaktion des Menschen bei Kontakt mit Oberflaechen — Teil 1: Heisse Oberflaechen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Beurteilungsverfahren und Grenzwerte fuer die Beruehrung heisser Oberflaechen: Verbrennungsschwellen nach Material und Kontaktdauer.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"thermal_hazard"},
|
||||||
|
Tags: []string{"high_temperature"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Verbrennungsschwellen)", "Tabelle 1 (Grenztemperaturen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-13732-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-14122-1", Number: "ISO 14122-1:2016",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Ortsfeste Zugaenge zu maschinellen Anlagen — Teil 1: Wahl eines ortsfesten Zugangs und allgemeine Anforderungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Auswahl und allgemeine Anforderungen fuer ortsfeste Zugaenge (Treppen, Leitern, Laufstege) zu Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "ergonomic"},
|
||||||
|
Tags: []string{"structural_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Wahl des Zugangs)", "Abschnitt 5 (Allgemeine Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-14122-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-14122-2", Number: "ISO 14122-2:2016",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Ortsfeste Zugaenge — Teil 2: Arbeitsbuehnen und Laufstege",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Gestaltung und Abmessungen von Arbeitsbuehnen und Laufstegen fuer Wartung und Bedienung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"structural_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Abmessungen)", "Abschnitt 5 (Gelaender)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-14122-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-14122-3", Number: "ISO 14122-3:2016",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Ortsfeste Zugaenge — Teil 3: Treppen, Treppenleitern und Gelaender",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Anforderungen an Treppen, Treppenleitern und Gelaender als ortsfeste Zugaenge zu Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"structural_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Treppen)", "Abschnitt 5 (Treppenleitern)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-14122-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-19353", Number: "ISO 19353:2019",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Brandverhuetung und Brandschutz",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Brandschutzanforderungen fuer Maschinen: Zuendquellen, brennbare Stoffe, Branderkennungs- und Loeschsysteme.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"material_environmental"},
|
||||||
|
Tags: []string{"high_temperature", "chemical_risk", "oil_mist_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Risikobeurteilung Brand)", "Abschnitt 5 (Schutzmassnahmen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-19353",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-842", Number: "EN 842:1996+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Optische Gefahrensignale — Allgemeine Anforderungen, Gestaltung und Pruefung",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Anforderungen an optische Gefahrensignale (Warn- und Signalleuchten) an Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure"},
|
||||||
|
Tags: []string{"user_interface"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Anforderungen)", "Abschnitt 5 (Farben)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-842",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-7731", Number: "ISO 7731:2003",
|
||||||
|
TitleDE: "Ergonomie — Gefahrensignale fuer oeffentliche Bereiche und Arbeitsstaetten — Akustische Gefahrensignale",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Gestaltung akustischer Gefahrensignale, damit sie unter Umgebungsgeraeuschbedingungen wahrgenommen werden.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure", "noise_vibration"},
|
||||||
|
Tags: []string{"noise_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Gestaltungsgrundsaetze)", "Abschnitt 5 (Signalarten)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-7731",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-894-1", Number: "EN 894-1:1997+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Ergonomische Anforderungen an die Gestaltung von Anzeigen und Stellteilen — Teil 1: Allgemeine Leitsaetze",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Allgemeine ergonomische Anforderungen an Anzeigen und Stellteile fuer Maschinenbediener.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{"user_interface", "has_software"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Allgemeine Leitsaetze)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-894-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-894-2", Number: "EN 894-2:1997+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Ergonomische Anforderungen — Teil 2: Anzeigen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Ergonomische Gestaltung visueller Anzeigen (Displays, Skalen, Leuchten) an Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{"user_interface"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Anforderungen Anzeigen)", "Abschnitt 5 (Sichtbarkeit)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-894-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-894-3", Number: "EN 894-3:2000+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Ergonomische Anforderungen — Teil 3: Stellteile",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Ergonomische Gestaltung von Stellteilen (Hebel, Taster, Schalter, Handraeder) an Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{"user_interface"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Anforderungen Stellteile)", "Abschnitt 5 (Betaetigungskraefte)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-894-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "IEC-60529", Number: "IEC 60529:2013",
|
||||||
|
TitleDE: "Schutzarten durch Gehaeuse (IP-Code)",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Klassifizierung des Schutzes gegen Eindringen von Fremdkoerpern und Wasser (IP-Schutzarten) fuer elektrische Betriebsmittel.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"electrical_hazard"},
|
||||||
|
Tags: []string{"electrical_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Bezeichnungen)", "Abschnitt 5 (Schutzgrade)", "Tabelle 2 (IP-Code)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iec-60529",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-11688-1", Number: "ISO 11688-1:2009",
|
||||||
|
TitleDE: "Akustik — Empfohlenes Verfahren fuer die Gestaltung laermarmer Maschinen und Geraete — Teil 1: Planung",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Konstruktive Massnahmen zur Laermminderung an der Quelle waehrend der Entwurfsphase von Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"noise_vibration"},
|
||||||
|
Tags: []string{"noise_source", "vibration_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Konstruktive Massnahmen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11688-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-15534-1", Number: "ISO 15534-1:2000",
|
||||||
|
TitleDE: "Ergonomische Gestaltung fuer die Sicherheit von Maschinen — Teil 1: Prinzipien zur Bestimmung der Abmessungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Koerpermasse und Abmessungen fuer die Gestaltung von Zugangs- und Bedienoeffnungen an Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{"structural_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Koerpermasse)", "Tabelle 1 (Abmessungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-15534-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-11553-1", Number: "ISO 11553-1:2005",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Laserbearbeitungsmaschinen — Teil 1: Allgemeine Sicherheitsanforderungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Laserbearbeitungsmaschinen: Strahlschutz, Absaugung, Zugangskontrolle.",
|
||||||
|
MachineTypes: []string{"laser_machine", "laser_cutter"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "material_environmental"},
|
||||||
|
Tags: []string{"high_temperature"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Gefahrenidentifizierung)", "Abschnitt 5 (Schutzmassnahmen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11553-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13478", Number: "EN 13478:2001+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Brandschutz",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Allgemeine Brandschutzanforderungen bei Gestaltung und Konstruktion von Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"material_environmental"},
|
||||||
|
Tags: []string{"high_temperature", "chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Brandschutzkonzept)", "Abschnitt 5 (Massnahmen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13478",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-20607", Number: "ISO 20607:2019",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Betriebsanleitung — Allgemeine Gestaltungsleitsaetze",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Anforderungen an Inhalt, Struktur und Darstellung der Betriebsanleitung fuer Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{},
|
||||||
|
Tags: []string{},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Inhalt)", "Abschnitt 5 (Struktur)", "Abschnitt 6 (Darstellung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-20607",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,372 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// GetExtendedB2Norms returns additional B2 safety norms (Sicherheitsfachgrundnormen)
|
||||||
|
// covering electrical safety, vibration/noise, ergonomics, thermal/fire, fluid power,
|
||||||
|
// guards/interlocks, software/cyber safety, and emissions/environment.
|
||||||
|
func GetExtendedB2Norms() []NormReference {
|
||||||
|
return []NormReference{
|
||||||
|
// ── Electrical Safety (erweitert) ────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-61439-1", Number: "EN 61439-1:2011",
|
||||||
|
TitleDE: "Niederspannungs-Schaltgeraetekombinationen — Teil 1: Allgemeine Festlegungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Allgemeine Anforderungen an Niederspannungs-Schaltgeraetekombinationen: Bauartnachweis, Stuecknachweis, Schutzgrad.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{},
|
||||||
|
Tags: []string{"electrical_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 8 (Bauartnachweis)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-61439-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-62311", Number: "EN 62311:2020",
|
||||||
|
TitleDE: "Bewertung elektronischer und elektrischer Geraete bezueglich der Beschraenkungen der Exposition von Personen in elektromagnetischen Feldern (0 Hz — 300 GHz)",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Bewertungsverfahren fuer die EMF-Exposition durch elektronische und elektrische Geraete im Hinblick auf Personenschutz.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{},
|
||||||
|
Tags: []string{"electrical_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Grenzwerte)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-62311",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "IEC-61508-1", Number: "IEC 61508-1:2010",
|
||||||
|
TitleDE: "Funktionale Sicherheit sicherheitsbezogener elektrischer/elektronischer/programmierbarer elektronischer Systeme — Teil 1: Allgemeine Anforderungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Allgemeine Anforderungen an die funktionale Sicherheit von E/E/PE-Systemen ueber den gesamten Sicherheitslebenszyklus.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure"},
|
||||||
|
Tags: []string{"programmable"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 7 (SIL-Gesamtlebenszyklus)", "Tabelle 2 (SIL-Stufen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-61508-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "IEC-61508-2", Number: "IEC 61508-2:2010",
|
||||||
|
TitleDE: "Funktionale Sicherheit sicherheitsbezogener E/E/PE-Systeme — Teil 2: Anforderungen an sicherheitsbezogene E/E/PE-Systeme",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Hardware-spezifische Anforderungen an sicherheitsbezogene E/E/PE-Systeme: Architektur, Ausfallraten, Diagnosedeckungsgrad.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure"},
|
||||||
|
Tags: []string{"programmable"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 7 (Hardware-Architektur)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-61508-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "IEC-61508-3", Number: "IEC 61508-3:2010",
|
||||||
|
TitleDE: "Funktionale Sicherheit sicherheitsbezogener E/E/PE-Systeme — Teil 3: Anforderungen an Software",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Software-Anforderungen fuer sicherheitsbezogene E/E/PE-Systeme: Lebenszyklus, Verifikation, Validierung, Konfigurationsmanagement.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure"},
|
||||||
|
Tags: []string{"has_software", "programmable"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 7 (Software-Lebenszyklus)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-61508-3",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Vibration / Noise (erweitert) ───────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-5349-1", Number: "ISO 5349-1:2001",
|
||||||
|
TitleDE: "Mechanische Schwingungen — Messung und Bewertung der Einwirkung von Hand-Arm-Schwingungen — Teil 1: Allgemeine Anforderungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Messverfahren und Bewertungskriterien fuer die Hand-Arm-Schwingungsbelastung von Bedienern an Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"noise_vibration"},
|
||||||
|
Tags: []string{"vibration_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Messverfahren)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-5349-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-2631-1", Number: "ISO 2631-1:1997",
|
||||||
|
TitleDE: "Mechanische Schwingungen und Stoesse — Bewertung der Einwirkung von Ganzkoerper-Schwingungen auf den Menschen — Teil 1: Allgemeine Anforderungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Bewertungsverfahren fuer die Einwirkung von Ganzkoerper-Schwingungen auf Gesundheit, Komfort und Wahrnehmung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"noise_vibration"},
|
||||||
|
Tags: []string{"vibration_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 6 (Bewertung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-2631-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-3744", Number: "ISO 3744:2010",
|
||||||
|
TitleDE: "Akustik — Bestimmung der Schallleistungs- und Schallenergiepegel von Geraeuschquellen — Huellflaechen-Verfahren der Genauigkeitsklasse 2 im Freifeld",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Messverfahren zur Bestimmung von Schallleistungspegeln mittels Huellflaechen-Verfahren in reflexionsarmer Umgebung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"noise_vibration"},
|
||||||
|
Tags: []string{"noise_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 6 (Messanordnung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-3744",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-3746", Number: "ISO 3746:2010",
|
||||||
|
TitleDE: "Akustik — Bestimmung der Schallleistungs- und Schallenergiepegel von Geraeuschquellen — Uebersichtsverfahren mit einer umhuellenden Messflaeche",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Vereinfachtes Uebersichtsverfahren zur Bestimmung der Schallleistungspegel fuer Geraeuschquellen in Situ.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"noise_vibration"},
|
||||||
|
Tags: []string{"noise_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 6 (Messverfahren)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-3746",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-11689", Number: "ISO 11689:1996",
|
||||||
|
TitleDE: "Akustik — Vorgehensweise fuer den Vergleich von Geraeuschemissionsdaten von Maschinen und Geraeten",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Standardisierte Vorgehensweise zum Vergleich von Geraeuschemissionsdaten verschiedener Maschinen und Geraete.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"noise_vibration"},
|
||||||
|
Tags: []string{"noise_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Vergleichsverfahren)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-iso-11689",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Ergonomics (erweitert) ──────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-11228-2", Number: "ISO 11228-2:2007",
|
||||||
|
TitleDE: "Ergonomie — Manuelles Handhaben von Lasten — Teil 2: Ziehen und Schieben",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Grenzwerte und Empfehlungen fuer manuelles Ziehen und Schieben von Lasten zur Vermeidung von Muskel-Skelett-Erkrankungen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{"structural_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Grenzwerte)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11228-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-11228-3", Number: "ISO 11228-3:2007",
|
||||||
|
TitleDE: "Ergonomie — Manuelles Handhaben von Lasten — Teil 3: Hantieren geringer Lasten bei hoher Frequenz",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Risikobeurteilung und Grenzwerte fuer repetitives Hantieren geringer Lasten zur Vorbeugung von Ueberlastungsschaeden.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Risikobeurteilung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11228-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1005-1", Number: "EN 1005-1:2001+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Menschliche koerperliche Leistung — Teil 1: Begriffe",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Begriffe und allgemeine Grundsaetze zur Bewertung der menschlichen koerperlichen Leistung bei der Bedienung von Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Begriffe)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1005-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1005-2", Number: "EN 1005-2:2003+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Menschliche koerperliche Leistung — Teil 2: Manuelle Handhabung von Gegenstaenden in Verbindung mit Maschinen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Bewertungsverfahren und Grenzwerte fuer manuelles Heben und Senken bei Maschinenbedienung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{"structural_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Heben/Senken)", "Tabelle 1 (Grenzwerte)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1005-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1005-3", Number: "EN 1005-3:2002+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Menschliche koerperliche Leistung — Teil 3: Empfohlene Kraftgrenzen fuer Maschinenbetaetigung",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Empfohlene Kraftgrenzen fuer die Betaetigung von Maschinen zur Vermeidung von Ueberlastung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Kraftgrenzen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1005-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1005-4", Number: "EN 1005-4:2005+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Menschliche koerperliche Leistung — Teil 4: Bewertung von Koerperhaltungen und -bewegungen bei der Arbeit an Maschinen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Bewertungsmethoden fuer Koerperhaltungen und -bewegungen bei der Maschinenbedienung zur ergonomischen Gestaltung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Bewertungsmethoden)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1005-4",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Thermal / Fire (erweitert) ──────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-13732-3", Number: "ISO 13732-3:2005",
|
||||||
|
TitleDE: "Ergonomie der thermischen Umgebung — Verfahren zur Beurteilung der Reaktion des Menschen bei Kontakt mit Oberflaechen — Teil 3: Kalte Oberflaechen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Beurteilungsverfahren und Grenzwerte fuer die Beruehrung kalter Oberflaechen: Kaelteverbrennungsschwellen nach Material und Kontaktdauer.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"thermal_hazard"},
|
||||||
|
Tags: []string{"high_temperature"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Kontakttemperaturen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-13732-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1127-1", Number: "EN 1127-1:2019",
|
||||||
|
TitleDE: "Explosionsfaehige Atmosphaeren — Explosionsschutz — Teil 1: Grundlagen und Methodik",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Grundlagen und Methodik des Explosionsschutzes: Zuendquellen, Schutzkonzepte, Zoneneinteilung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"material_environmental"},
|
||||||
|
Tags: []string{"chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Zuendquellen)", "Abschnitt 6 (Schutzmassnahmen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1127-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13463-1", Number: "EN 13463-1:2009",
|
||||||
|
TitleDE: "Nichtelektrische Geraete fuer explosionsgefaehrdete Bereiche — Teil 1: Grundlagen und Anforderungen",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Grundlegende Anforderungen an nichtelektrische Geraete zum Einsatz in explosionsgefaehrdeten Bereichen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"material_environmental"},
|
||||||
|
Tags: []string{"chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13463-1",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Fluid Power (erweitert) ─────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-4021", Number: "ISO 4021:1992",
|
||||||
|
TitleDE: "Hydraulik — Bestimmung der Partikelkontamination — Probenahme aus der laufenden Anlage",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Probenahme-Verfahren zur Bestimmung der Partikelkontamination in hydraulischen Anlagen waehrend des Betriebs.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"hydraulic_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Probenahme)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-iso-4021",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-982", Number: "EN 982:1996+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Sicherheitstechnische Anforderungen an fluidtechnische Anlagen und deren Bauteile — Hydraulik",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen an hydraulische Anlagen und Bauteile: Druckbegrenzung, Absicherung, Leckagesicherung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"hydraulic_part", "high_pressure"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-982",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-983", Number: "EN 983:1996+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Sicherheitstechnische Anforderungen an fluidtechnische Anlagen und deren Bauteile — Pneumatik",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen an pneumatische Anlagen und Bauteile: Druckluftaufbereitung, Druckabsicherung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"pneumatic_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-983",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Guards / Interlocks (erweitert) ──────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-14118", Number: "ISO 14118:2017",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Vermeidung von unerwartetem Anlauf",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Gestaltungsgrundsaetze und Massnahmen zur Vermeidung von unerwartetem Anlauf: Energietrennung, Verriegelung, Absicherung gespeicherter Energie.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"moving_part", "stored_energy"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Gestaltungsgrundsaetze)", "Abschnitt 5 (Energietrennung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-14118",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-574", Number: "EN 574:1996+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Zweihandschaltung — Gestaltung und Auswahl",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Gestaltung, Auswahl und Typen von Zweihandschaltungen fuer Maschinen zur Vermeidung von Handverletzungen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure"},
|
||||||
|
Tags: []string{"two_hand_control_required"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Typen)", "Abschnitt 5 (Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-574",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Software / Cyber Safety ─────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "IEC-62443-4-2", Number: "IEC 62443-4-2:2019",
|
||||||
|
TitleDE: "Industrielle Kommunikationsnetze — IT-Sicherheit fuer Netze und Systeme — Teil 4-2: Technische Sicherheitsanforderungen an IACS-Komponenten",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Technische Sicherheitsanforderungen an Komponenten industrieller Automatisierungs- und Steuerungssysteme (IACS).",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure"},
|
||||||
|
Tags: []string{"has_software", "programmable"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iec-62443-4-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "IEC-62443-3-3", Number: "IEC 62443-3-3:2013",
|
||||||
|
TitleDE: "Industrielle Kommunikationsnetze — IT-Sicherheit fuer Netze und Systeme — Teil 3-3: Systemanforderungen zur IT-Sicherheit und Security-Level",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Systemanforderungen fuer die IT-Sicherheit industrieller Automatisierungssysteme und Zuordnung zu Security-Levels.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure"},
|
||||||
|
Tags: []string{"has_software"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsstufen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iec-62443-3-3",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Emissions / Environment ─────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-12198-1", Number: "EN 12198-1:2000+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Bewertung und Verringerung des Risikos der von Maschinen emittierten Strahlung — Teil 1: Allgemeine Leitsaetze",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Allgemeine Leitsaetze zur Bewertung und Verringerung des Risikos durch Strahlungsemissionen von Maschinen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"material_environmental"},
|
||||||
|
Tags: []string{},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Bewertungsverfahren)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12198-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-626-1", Number: "EN 626-1:1994+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Verringerung des Gesundheitsrisikos durch Gefahrstoffe, die von Maschinen ausgehen — Teil 1: Grundsaetze und Festlegungen fuer Maschinenhersteller",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Grundsaetze zur Verringerung des Gesundheitsrisikos durch von Maschinen emittierte Gefahrstoffe fuer Maschinenhersteller.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"material_environmental"},
|
||||||
|
Tags: []string{"chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Grundsaetze)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-626-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-626-2", Number: "EN 626-2:1996+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Verringerung des Gesundheitsrisikos durch Gefahrstoffe, die von Maschinen ausgehen — Teil 2: Methodik fuer die Erstellung von Pruefverfahren",
|
||||||
|
NormType: "B2",
|
||||||
|
ScopeDE: "Methodik zur Erstellung von Pruefverfahren fuer die Bewertung der von Maschinen ausgehenden Gefahrstoffemissionen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"material_environmental"},
|
||||||
|
Tags: []string{"chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Methodik)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-626-2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,409 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// GetCNormsLibrary returns C-norms (maschinenspezifische Normen) for
|
||||||
|
// specific machine types like presses, robots, conveyors, and machining centers.
|
||||||
|
func GetCNormsLibrary() []NormReference {
|
||||||
|
return []NormReference{
|
||||||
|
// ── Pressen ─────────────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-692", Number: "EN 692:2005+A1:2009",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Mechanische Pressen — Sicherheit",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Spezifische Sicherheitsanforderungen fuer mechanische Pressen: Kupplungs-/Bremssteuerung, Werkzeugeinrichtbetrieb, Schutzeinrichtungen.",
|
||||||
|
MachineTypes: []string{"press"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"crush_point", "high_force"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)", "Abschnitt 6 (Schutzeinrichtungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-692",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-693", Number: "EN 693:2001+A2:2011",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Hydraulische Pressen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer hydraulische Pressen: Druckueberwachung, Ventilsteuerung, Werkzeugwechsel, Schutzeinrichtungen.",
|
||||||
|
MachineTypes: []string{"press", "hydraulic_press"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"hydraulic_part", "high_force"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)", "Abschnitt 6 (Steuerung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-693",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12622", Number: "EN 12622:2009+A1:2013",
|
||||||
|
TitleDE: "Sicherheit von Werkzeugmaschinen — Hydraulische Abkantpressen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer hydraulische Abkantpressen: Oberwangensteuerung, Hinteranschlag, Fingerscanner, Biegewerkzeuge.",
|
||||||
|
MachineTypes: []string{"press_brake"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"crush_point", "high_force"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)", "Abschnitt 6 (Schutzeinrichtungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12622",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Roboter ─────────────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-10218-1", Number: "ISO 10218-1:2011",
|
||||||
|
TitleDE: "Industrieroboter — Sicherheitsanforderungen — Teil 1: Roboter",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen an den Industrieroboter selbst: Stopp-Funktionen, Geschwindigkeits- und Kraftbegrenzung, Betriebsarten.",
|
||||||
|
MachineTypes: []string{"robot", "industrial_robot"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"programmable", "moving_part"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)", "Anhang A (Gefahrenliste)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-10218-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-10218-2", Number: "ISO 10218-2:2011",
|
||||||
|
TitleDE: "Industrieroboter — Sicherheitsanforderungen — Teil 2: Robotersysteme und Integration",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Robotersysteme und deren Integration in Fertigungsanlagen: Zellengestaltung, Schutzraeume, Inbetriebnahme.",
|
||||||
|
MachineTypes: []string{"robot", "industrial_robot", "robot_cell"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"programmable", "moving_part"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Layout)", "Abschnitt 5 (Schutzmassnahmen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-10218-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-TS-15066", Number: "ISO/TS 15066:2016",
|
||||||
|
TitleDE: "Roboter und Robotikgeraete — Kollaborierende Roboter",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer kollaborierende Robotersysteme: Kraft-/Druckgrenzwerte fuer Koerperkontakt, Geschwindigkeitsueberwachung, Arbeitsraumgestaltung.",
|
||||||
|
MachineTypes: []string{"collaborative_robot", "cobot"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"collaborative_operation", "force_limited"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Kollaborationsarten)", "Abschnitt 5 (Grenzwerte Kraft/Druck)", "Tabelle A.2 (Koerperregionen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/technische-regel/din-iso-ts-15066",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Foerdertechnik ──────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-619", Number: "EN 619:2011+A1:2010",
|
||||||
|
TitleDE: "Stetigfoerderer und Systeme — Sicherheits- und EMV-Anforderungen an mechanische Foerdereinrichtungen fuer Stueckgut",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Stetigfoerderer: Einzugstellen, Quetschstellen, Not-Halt-Anordnung, Zugangssicherung.",
|
||||||
|
MachineTypes: []string{"conveyor", "transfer_system"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-619",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-620", Number: "EN 620:2002+A1:2010",
|
||||||
|
TitleDE: "Stetigfoerderer und Systeme — Sicherheits- und EMV-Anforderungen fuer ortsfeste Gurtfoerderer fuer Schuettgut",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Gurtfoerderer: Einzugstellen an Trommeln, Bandschieflaeufe, Schuettgutaustritt, Bandreisserkennung.",
|
||||||
|
MachineTypes: []string{"conveyor", "belt_conveyor"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-620",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Sicherheitsabstaende / Quetschen ────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-349", Number: "EN 349:1993+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Mindestabstaende zur Vermeidung des Quetschens von Koerperteilen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Mindestabstaende zur Vermeidung des Quetschens von Koerperteilen zwischen bewegten Maschinenteilen oder zwischen Maschinenteil und festem Teil.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"crush_point", "pinch_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Mindestabstaende)", "Tabelle 1 (Koerperteile)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-349",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Trennende Schutzeinrichtungen (Vorgaenger) ──────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-953", Number: "EN 953:1997+A1:2009",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Trennende Schutzeinrichtungen — Allgemeine Anforderungen an Gestaltung und Bau fester und beweglicher trennender Schutzeinrichtungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Vorgaengernorm von ISO 14120. Weiterhin als Referenz genutzt fuer Bestandsmaschinen und C-Normen, die darauf verweisen.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"guard"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Allgemeine Anforderungen)", "Abschnitt 5 (Gestaltung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-953",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Integrierte Fertigungssysteme ────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-11161", Number: "ISO 11161:2007",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Integrierte Fertigungssysteme — Grundlegende Anforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer verkettete Fertigungssysteme: Zonenkonzept, gemeinsame Sicherheitsfunktionen, Schnittstellen zwischen Maschinen.",
|
||||||
|
MachineTypes: []string{"transfer_system", "rotary_transfer_machine", "production_line"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"moving_part", "programmable"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsstrategie)", "Abschnitt 6 (Zonenkonzept)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11161",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Druckmaschinen ──────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1010-1", Number: "EN 1010-1:2004+A1:2010",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Sicherheitsanforderungen an Konstruktion und Bau von Druck- und Papierverarbeitungsmaschinen — Teil 1: Gemeinsame Anforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Gemeinsame Sicherheitsanforderungen fuer Druckmaschinen: Einzugstellen an Walzen, Papierweg, Farbwerk, Energietrennung.",
|
||||||
|
MachineTypes: []string{"printing_press"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1010-1",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Bearbeitungszentren / CNC ───────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-12417", Number: "EN 12417:2001+A2:2009",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Bearbeitungszentren",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer CNC-Bearbeitungszentren: Spanraumverkleidung, Werkzeugwechsel, Spannfutter, Betriebsarten.",
|
||||||
|
MachineTypes: []string{"machining_center", "cnc"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "cutting_part", "high_speed"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)", "Abschnitt 6 (Steuerung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12417",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Elektrische Antriebe, funktionale Sicherheit ────────────────────
|
||||||
|
{
|
||||||
|
ID: "IEC-61800-5-2", Number: "IEC 61800-5-2:2016",
|
||||||
|
TitleDE: "Drehzahlveraenderbare elektrische Antriebe — Teil 5-2: Anforderungen an die Sicherheit — Funktionale Sicherheit",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Anforderungen an die funktionale Sicherheit von Frequenzumrichtern und Servoantrieben: sicherer Halt, sichere Geschwindigkeit, STO/SLS/SSM.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"electrical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"electric_motor", "programmable"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (STO, SS1, SS2 Funktionen)", "Tabelle 2 (Sicherheitsfunktionen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iec-61800-5-2",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Kunststoff-/Gummimaschinen ──────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-201", Number: "EN 201:2009",
|
||||||
|
TitleDE: "Kunststoff- und Gummimaschinen — Spritzgiessmaschinen — Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Spritzgiessmaschinen: Schliessbewegung, Einspritzeinheit, Hydraulik, Temperaturueberwachung.",
|
||||||
|
MachineTypes: []string{"injection_molding", "plastics_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"high_force", "high_temperature", "hydraulic_part"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-201",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-289", Number: "EN 289:2014",
|
||||||
|
TitleDE: "Kunststoff- und Gummimaschinen — Pressen — Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Kunststoff- und Gummipressen: Pressbewegung, Werkzeugbereich, Temperaturueberwachung.",
|
||||||
|
MachineTypes: []string{"compression_molding", "plastics_press"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"high_force", "crush_point", "high_temperature"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-289",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-422", Number: "EN 422:2009",
|
||||||
|
TitleDE: "Kunststoff- und Gummimaschinen — Blasformmaschinen — Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Blasformmaschinen: Formschliessbewegung, Heizung, Druckluftsysteme.",
|
||||||
|
MachineTypes: []string{"blow_molding", "plastics_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "pneumatic_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-422",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1114-1", Number: "EN 1114-1:2011",
|
||||||
|
TitleDE: "Kunststoff- und Gummimaschinen — Extruder und Extrusionsanlagen — Teil 1: Sicherheitsanforderungen fuer Extruder",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Extruder: Schneckenantrieb, Zylinderheizung, Einzugstellen, Materialzufuhr.",
|
||||||
|
MachineTypes: []string{"extruder", "plastics_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "rotating_part", "crush_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1114-1",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Holzbearbeitungsmaschinen ───────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-848-1", Number: "EN 848-1:2007+A2:2012",
|
||||||
|
TitleDE: "Sicherheit von Holzbearbeitungsmaschinen — Einseitige Fraesmaschinen — Teil 1: Einspindelige senkrechte Tischfraesmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer einspindelige senkrechte Tischfraesmaschinen: Spindelschutz, Vorschubeinrichtung, Werkzeugbefestigung.",
|
||||||
|
MachineTypes: []string{"woodworking", "milling_machine", "router"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "cutting_part", "high_speed"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-848-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-1", Number: "EN 1870-1:2007+A1:2009",
|
||||||
|
TitleDE: "Sicherheit von Holzbearbeitungsmaschinen — Kreissaegemaschinen — Teil 1: Tischkreissaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Tischkreissaegen: Saegeblattschutz, Spaltkeil, Vorschub, Rueckschlagsicherung.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw", "circular_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "high_speed"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)", "Abschnitt 6 (Schutzeinrichtungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-861", Number: "EN 861:2007+A2:2012",
|
||||||
|
TitleDE: "Sicherheit von Holzbearbeitungsmaschinen — Abrichthobelmaschinen und Dickenhobelmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Abricht- und Dickenhobelmaschinen: Messerwellenabdeckung, Vorschub, Rueckschlagsicherung.",
|
||||||
|
MachineTypes: []string{"woodworking", "planer"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-861",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Metallbearbeitungsmaschinen ─────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-12840", Number: "EN 12840:2001+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Werkzeugmaschinen — Handbetriebene Drehmaschinen mit und ohne Zusatzausruestung",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer handbetriebene Drehmaschinen: Spannfutterschutz, Leitspindel, Drehzahlbegrenzung.",
|
||||||
|
MachineTypes: []string{"lathe", "turning_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "cutting_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12840",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13128", Number: "EN 13128:2001+A2:2009",
|
||||||
|
TitleDE: "Sicherheit von Werkzeugmaschinen — Fraesmaschinen (einschliesslich Bohrmaschinen)",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Fraes- und Bohrmaschinen: Spindelschutz, Spanraumverkleidung, Werkzeugwechsel.",
|
||||||
|
MachineTypes: []string{"milling_machine", "drilling_machine", "cnc"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "cutting_part", "high_speed"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13128",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13218", Number: "EN 13218:2002+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Werkzeugmaschinen — Schleifmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Schleifmaschinen: Schleifscheibenverkleidung, Drehzahlbegrenzung, Schallschutz.",
|
||||||
|
MachineTypes: []string{"grinding_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "noise_vibration"},
|
||||||
|
Tags: []string{"rotating_part", "high_speed", "noise_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13218",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-16092-1", Number: "ISO 16092-1:2017",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Pressen — Teil 1: Allgemeine Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Allgemeine Sicherheitsanforderungen fuer Pressen: Ersetzt EN 692/693 teilweise. Schutzeinrichtungen, Steuerungssicherheit, Betriebsarten.",
|
||||||
|
MachineTypes: []string{"press", "hydraulic_press", "mechanical_press"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "safety_function_failure"},
|
||||||
|
Tags: []string{"crush_point", "high_force"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-16092-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-16092-3", Number: "ISO 16092-3:2018",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Pressen — Teil 3: Sicherheitsanforderungen fuer hydraulische Pressen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Spezifische Sicherheitsanforderungen fuer hydraulische Pressen: Druckueberwachung, Ventilredundanz, Leckageerkennung.",
|
||||||
|
MachineTypes: []string{"press", "hydraulic_press"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"hydraulic_part", "high_force", "crush_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-16092-3",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Verpackungsmaschinen ────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-415-1", Number: "EN 415-1:2014",
|
||||||
|
TitleDE: "Sicherheit von Verpackungsmaschinen — Teil 1: Terminologie und Klassifikation",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Terminologie und Klassifikation von Verpackungsmaschinen: Begriffsbestimmungen, Maschinentypen, Einteilungssystematik.",
|
||||||
|
MachineTypes: []string{"packaging_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Klassifikation)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-415-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-415-5", Number: "EN 415-5:2006+A1:2009",
|
||||||
|
TitleDE: "Sicherheit von Verpackungsmaschinen — Teil 5: Einwickelmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Einwickelmaschinen: Folienwicklung, Einzugstellen, Antriebsschutz.",
|
||||||
|
MachineTypes: []string{"packaging_machine", "wrapping_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "entanglement_risk", "rotating_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-415-5",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Lebensmittelmaschinen ───────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1672-2", Number: "EN 1672-2:2005+A1:2009",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Allgemeine Gestaltungsleitsaetze — Teil 2: Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Hygieneanforderungen fuer Nahrungsmittelmaschinen: Materialauswahl, Oberflaechengestaltung, Reinigbarkeit, Kontaminationsschutz.",
|
||||||
|
MachineTypes: []string{"food_machine"},
|
||||||
|
HazardCats: []string{"material_substance_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"chemical_risk", "high_temperature"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Hygieneanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1672-2",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Foerdertechnik (erweitert) ──────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-617", Number: "EN 617:2001+A1:2010",
|
||||||
|
TitleDE: "Stetigfoerderer und Systeme — Sicherheits- und EMV-Anforderungen fuer die Lagerung von Schuettguetern in Silos, Bunkern, Behaeltern und Trichtern",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Silos, Bunker und Trichter: Brueckenbildung, Austragssysteme, Zugang, Explosionsschutz.",
|
||||||
|
MachineTypes: []string{"silo", "bunker", "conveyor"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "structural_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-617",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-618", Number: "EN 618:2002+A1:2010",
|
||||||
|
TitleDE: "Stetigfoerderer und Systeme — Sicherheits- und EMV-Anforderungen fuer Foerderer fuer Schuettgut, ausgenommen ortsfeste Gurtfoerderer",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Schuettgutfoerderer (Schnecken-, Ketten-, Becherfoerderer): Einzugstellen, Materialfluss, Zugangssicherung.",
|
||||||
|
MachineTypes: []string{"conveyor", "screw_conveyor"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-618",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,290 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// GetExtendedCNormsLibrary returns additional machine-specific C-norms
|
||||||
|
// for less common machine categories.
|
||||||
|
func GetExtendedCNormsLibrary() []NormReference {
|
||||||
|
return []NormReference{
|
||||||
|
// ── Erdbaumaschinen ─────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-474-1", Number: "EN 474-1:2006+A6:2019",
|
||||||
|
TitleDE: "Erdbaumaschinen — Sicherheit — Teil 1: Allgemeine Anforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Allgemeine Sicherheitsanforderungen fuer Erdbaumaschinen: Standsicherheit, Sichtverhaeltnisse, Hydrauliksysteme, Ueberrollschutz.",
|
||||||
|
MachineTypes: []string{"earth_moving", "excavator", "wheel_loader"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"high_force", "gravity_risk", "hydraulic_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)", "Abschnitt 6 (Standsicherheit)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-474-1",
|
||||||
|
},
|
||||||
|
// ── Flurfoerderzeuge ────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1726-1", Number: "EN 1726-1:1998+A1:2008",
|
||||||
|
TitleDE: "Sicherheit von Flurfoerderzeugen — Teil 1: Motorisch angetriebene Flurfoerderzeuge bis einschliesslich 10000 kg",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Flurfoerderzeuge (Gabelstapler): Standsicherheit, Bremsen, Fahrerschutz, Lasthandhabung.",
|
||||||
|
MachineTypes: []string{"forklift", "industrial_truck"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "gravity_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1726-1",
|
||||||
|
},
|
||||||
|
// ── Hebezeuge / Krane ───────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-15011", Number: "EN 15011:2011+A1:2014",
|
||||||
|
TitleDE: "Krane — Brueckenkrane und Portalkrane",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Bruecken- und Portalkrane: Tragfaehigkeit, Endschalter, Ueberlastsicherung, Windlastberuecksichtigung.",
|
||||||
|
MachineTypes: []string{"crane", "bridge_crane", "gantry_crane"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "high_force", "moving_part", "person_under_load"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)", "Abschnitt 6 (Lastaufnahme)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-15011",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-14492-1", Number: "EN 14492-1:2006+A1:2009",
|
||||||
|
TitleDE: "Krane — Kraftbetriebene Winden und Hubwerke — Teil 1: Kraftbetriebene Winden",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer kraftbetriebene Winden: Bremssystem, Seilwicklung, Ueberlastschutz, Endlagenschalter.",
|
||||||
|
MachineTypes: []string{"crane", "winch", "hoist"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "high_force"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-14492-1",
|
||||||
|
},
|
||||||
|
// ── Schweissmaschinen ───────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-60974-1", Number: "EN 60974-1:2012",
|
||||||
|
TitleDE: "Lichtbogenschweisseinrichtungen — Teil 1: Schweissstromquellen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Schweissstromquellen: Isolation, Leerlaufspannung, thermischer Schutz, EMV.",
|
||||||
|
MachineTypes: []string{"welding_machine", "arc_welder"},
|
||||||
|
HazardCats: []string{"electrical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"electrical_part", "high_temperature", "high_voltage"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-60974-1",
|
||||||
|
},
|
||||||
|
// ── Druckmaschinen (erweitert) ──────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1010-2", Number: "EN 1010-2:2006+A1:2010",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Sicherheitsanforderungen an Druckmaschinen — Teil 2: Druck- und Lackiermaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Druck- und Lackiermaschinen: Farbwerk, Lackierwalzen, Loesemittelhandhabung, Explosionsschutz.",
|
||||||
|
MachineTypes: []string{"printing_press", "coating_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "material_substance_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "chemical_risk", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1010-2",
|
||||||
|
},
|
||||||
|
// ── Pumpen / Kompressoren ───────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-809", Number: "EN 809:1998+A1:2009",
|
||||||
|
TitleDE: "Pumpen und Pumpenaggregate fuer Fluessigkeiten — Allgemeine Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Allgemeine Sicherheitsanforderungen fuer Pumpen: Druckbegrenzung, Dichtungen, Leckageschutz, Trockenlaufschutz.",
|
||||||
|
MachineTypes: []string{"pump"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"rotating_part", "hydraulic_part", "high_pressure"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-809",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1012-1", Number: "EN 1012-1:2010",
|
||||||
|
TitleDE: "Kompressoren und Vakuumpumpen — Sicherheitsanforderungen — Teil 1: Kompressoren",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Kompressoren: Druckbehaelter, Ueberdrucksicherung, Kuehlsystem, Laermminderung.",
|
||||||
|
MachineTypes: []string{"compressor"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "noise_vibration"},
|
||||||
|
Tags: []string{"high_pressure", "pneumatic_part", "noise_source", "high_temperature"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1012-1",
|
||||||
|
},
|
||||||
|
// ── Textilmaschinen ─────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-ISO-11111-1", Number: "EN ISO 11111-1:2009",
|
||||||
|
TitleDE: "Textilmaschinen — Sicherheitsanforderungen — Teil 1: Gemeinsame Anforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Gemeinsame Sicherheitsanforderungen fuer Textilmaschinen: Einzugstellen an Walzen, Fadenrisse, Nadelschutz, Laermminderung.",
|
||||||
|
MachineTypes: []string{"textile_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Allgemeine Gefaehrdungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11111-1",
|
||||||
|
},
|
||||||
|
// ── Giessereimaschinen ──────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-710", Number: "EN 710:1997+A1:2008",
|
||||||
|
TitleDE: "Sicherheitsanforderungen an Giessereiformmaschinen und -anlagen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Giessereiformmaschinen: Formschliessbewegung, Sandaufbereitung, Giessvorgaenge, thermische Gefaehrdungen.",
|
||||||
|
MachineTypes: []string{"foundry_machine", "casting_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "high_force"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-710",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-869", Number: "EN 869:2006+A1:2009",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Sicherheitsanforderungen an Druckgiessmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Druckgiessmaschinen: Schliesskraft, Metallspritzer, Hydraulik, Temperaturueberwachung.",
|
||||||
|
MachineTypes: []string{"die_casting", "foundry_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "high_force", "hydraulic_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-869",
|
||||||
|
},
|
||||||
|
// ── Aufzuege ────────────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-81-20", Number: "EN 81-20:2020",
|
||||||
|
TitleDE: "Sicherheitsregeln fuer die Konstruktion und den Einbau von Aufzuegen — Teil 20: Personen- und Lastenaufzuege",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsregeln fuer Personen- und Lastenaufzuege: Triebwerk, Fangvorrichtung, Tuersysteme, Steuerung, Notbetrieb.",
|
||||||
|
MachineTypes: []string{"elevator", "lift"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "electrical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "moving_part", "electrical_part"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Mechanik)", "Abschnitt 6 (Elektrik)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-81-20",
|
||||||
|
},
|
||||||
|
// ── Landmaschinen ───────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "ISO-4254-1", Number: "ISO 4254-1:2013",
|
||||||
|
TitleDE: "Landmaschinen — Sicherheit — Teil 1: Allgemeine Anforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Allgemeine Sicherheitsanforderungen fuer Landmaschinen: Gelenkwellenschutz, Zugangsleitern, Betriebsanleitung, Standsicherheit.",
|
||||||
|
MachineTypes: []string{"agricultural_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "rotating_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Allgemeine Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-4254-1",
|
||||||
|
},
|
||||||
|
// ── Zentrifugen ─────────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-12547", Number: "EN 12547:2009",
|
||||||
|
TitleDE: "Zentrifugen — Allgemeine Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Zentrifugen: Unwuchtschutz, Deckelverriegelung, Drehzahlueberwachung, Berstschutz.",
|
||||||
|
MachineTypes: []string{"centrifuge"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "high_speed"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12547",
|
||||||
|
},
|
||||||
|
// ── Trocknungsanlagen / Oefen ───────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1539", Number: "EN 1539:2015",
|
||||||
|
TitleDE: "Trockner und Oefen mit Freisetzung brennbarer Stoffe — Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Trockner und Oefen: Explosionsschutz, Lueftung, Temperaturueberwachung, Inertisierung.",
|
||||||
|
MachineTypes: []string{"dryer", "oven", "kiln"},
|
||||||
|
HazardCats: []string{"thermal_hazard", "material_substance_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Risikobeurteilung)", "Abschnitt 5 (Schutzmassnahmen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1539",
|
||||||
|
},
|
||||||
|
// ── Nahrungsmittelmaschinen (erweitert) ─────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1678", Number: "EN 1678:1998+A1:2010",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Gemuese-Schneidmaschinen — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Gemuese-Schneidmaschinen: Messerabdeckung, Einzugstellen, Reinigbarkeit.",
|
||||||
|
MachineTypes: []string{"food_machine", "food_cutter"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1678",
|
||||||
|
},
|
||||||
|
// ── Gummi-/Kunststoff (erweitert) ───────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1612-1", Number: "EN 1612-1:1997+A1:2008",
|
||||||
|
TitleDE: "Kunststoff- und Gummimaschinen — Reaktionsgiessmaschinen — Teil 1: Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Reaktionsgiessmaschinen: Mischkopf, Chemikalienhandhabung, Druckueberwachung.",
|
||||||
|
MachineTypes: []string{"reaction_molding", "plastics_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "material_substance_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1612-1",
|
||||||
|
},
|
||||||
|
// ── Industrieoefen ──────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-746-1", Number: "EN 746-1:1997+A1:2009",
|
||||||
|
TitleDE: "Industrielle Thermoprozessanlagen — Teil 1: Allgemeine Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Allgemeine Sicherheitsanforderungen fuer industrielle Thermoprozessanlagen: Temperaturueberwachung, Beschickung, Atmosphaerenkontrolle.",
|
||||||
|
MachineTypes: []string{"industrial_furnace", "heat_treatment"},
|
||||||
|
HazardCats: []string{"thermal_hazard", "material_substance_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Schutzmassnahmen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-746-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-746-2", Number: "EN 746-2:2010",
|
||||||
|
TitleDE: "Industrielle Thermoprozessanlagen — Teil 2: Sicherheitsanforderungen an Feuerungen und Brennstoffversorgung",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Feuerungen und Brennstoffversorgung: Flammueberwachung, Gasleckageerkennung, Spuelprogramme.",
|
||||||
|
MachineTypes: []string{"industrial_furnace", "heat_treatment"},
|
||||||
|
HazardCats: []string{"thermal_hazard", "material_substance_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen Feuerung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-746-2",
|
||||||
|
},
|
||||||
|
// ── Mischer / Kneter ────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-453", Number: "EN 453:2000+A1:2009",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Teigknetmaschinen — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Teigknetmaschinen: Knetarmschutz, Deckelverriegelung, Reinigbarkeit.",
|
||||||
|
MachineTypes: []string{"mixer", "kneading_machine", "food_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-453",
|
||||||
|
},
|
||||||
|
// ── Schneidemaschinen Papier ────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1010-3", Number: "EN 1010-3:2002+A1:2009",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Druck- und Papierverarbeitungsmaschinen — Teil 3: Schneidemaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Papierschneidemaschinen: Messerbalken, Zweihandschaltung, Pressbalken, Schnittlaengenbegrenzung.",
|
||||||
|
MachineTypes: []string{"cutting_machine", "paper_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "high_force"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1010-3",
|
||||||
|
},
|
||||||
|
// ── Sicherheitskomponenten (B2-nah, haeufig in C-Norm-Listen) ──────
|
||||||
|
{
|
||||||
|
ID: "EN-ISO-13851", Number: "EN ISO 13851:2019",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Zweihandschaltungen — Gestaltungsleitsaetze",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Gestaltungsleitsaetze fuer Zweihandschaltungen: Typ-Klassifikation (I, II, IIIA, IIIB, IIIC), Betaetigungszeit, Nachlaufueberwachung.",
|
||||||
|
MachineTypes: []string{},
|
||||||
|
HazardCats: []string{"safety_function_failure", "mechanical_hazard"},
|
||||||
|
Tags: []string{"two_hand_control_required", "crush_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Typen)", "Abschnitt 5 (Gestaltung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-13851",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,447 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// GetFoodPkgCNorms returns C-norms for food processing, packaging, textile,
|
||||||
|
// agricultural, and construction/earth-moving machine categories.
|
||||||
|
// Norms already present in norms_library_c.go or norms_library_c_ext.go are
|
||||||
|
// intentionally omitted here to avoid duplicates.
|
||||||
|
func GetFoodPkgCNorms() []NormReference {
|
||||||
|
return []NormReference{
|
||||||
|
// ── Nahrungsmittelmaschinen (EN 1672 + spezifisch) ──────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1672-1", Number: "EN 1672-1:2014",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Allgemeine Gestaltungsleitsaetze — Teil 1: Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Allgemeine Sicherheitsanforderungen fuer Nahrungsmittelmaschinen: mechanische Gefaehrdungen, Hygiene, Reinigbarkeit, Werkstoffauswahl.",
|
||||||
|
MachineTypes: []string{"food_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "cutting_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1672-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13389", Number: "EN 13389:2005+A1:2009",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Mischer — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Mischer in der Nahrungsmittelindustrie: Mischwerkschutz, Deckelverriegelung, Reinigbarkeit.",
|
||||||
|
MachineTypes: []string{"food_machine", "mixer"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13389",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13886", Number: "EN 13886:2005+A1:2010",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Kochkessel — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Kochkessel: Verbruehungsschutz, Druckueberwachung, Deckelverriegelung, Temperaturregelung.",
|
||||||
|
MachineTypes: []string{"food_machine", "cooker"},
|
||||||
|
HazardCats: []string{"thermal_hazard", "pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"high_temperature", "high_pressure"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13886",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12042", Number: "EN 12042:2014+A1:2019",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Teigausrollmaschinen — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Teigausrollmaschinen: Walzenschutz, Einzugstellen, Reinigbarkeit.",
|
||||||
|
MachineTypes: []string{"food_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "crush_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12042",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12331", Number: "EN 12331:2015+A1:2019",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Fleischwoelfe — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Fleischwoelfe: Schneckenzufuhr, Messer-/Lochscheibenschutz, Rueckstosssicherung.",
|
||||||
|
MachineTypes: []string{"food_machine", "meat_grinder"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12331",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12855", Number: "EN 12855:2012+A1:2015",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Kuttermaschinen — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Kuttermaschinen: Messerabdeckung, Deckelverriegelung, Drehzahlueberwachung.",
|
||||||
|
MachineTypes: []string{"food_machine", "cutter"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "high_speed"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12855",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13570", Number: "EN 13570:2005+A1:2010",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Mischer mit horizontalen Mischwerkzeugen — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Horizontalmischer: Mischwerkschutz, Deckelverriegelung, Nachlaufueberwachung.",
|
||||||
|
MachineTypes: []string{"food_machine", "mixer"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13570",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13591", Number: "EN 13591:2005+A1:2009",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Ladewagen — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Ladewagen in der Nahrungsmittelindustrie: Bewegungsteile, Kippschutz, Reinigbarkeit.",
|
||||||
|
MachineTypes: []string{"food_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "gravity_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13591",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-14655", Number: "EN 14655:2005+A1:2010",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Baguette-Formmaschinen — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Baguette-Formmaschinen: Einzugstellen, Walzenschutz, Reinigbarkeit.",
|
||||||
|
MachineTypes: []string{"food_machine", "bakery"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "rotating_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-14655",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13954", Number: "EN 13954:2005+A1:2010",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Brotschneidemaschinen — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Brotschneidemaschinen: Messerschutz, Vorschubeinrichtung, Handschutz.",
|
||||||
|
MachineTypes: []string{"food_machine", "bread_slicer"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13954",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12463", Number: "EN 12463:2004+A1:2011",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Fuellmaschinen und Hilfsmaschinen — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer Fuellmaschinen: Kolbenschutz, Einzugstellen, Reinigbarkeit, Hygiene.",
|
||||||
|
MachineTypes: []string{"food_machine", "filling_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12463",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12984", Number: "EN 12984:2005+A1:2010",
|
||||||
|
TitleDE: "Nahrungsmittelmaschinen — Transportable und/oder handbetriebene Maschinen — Sicherheits- und Hygieneanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Hygieneanforderungen fuer transportable und handbetriebene Nahrungsmittelmaschinen: Messerschutz, Standsicherheit.",
|
||||||
|
MachineTypes: []string{"food_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12984",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Verpackungsmaschinen (EN 415 Serie) ─────────────────────────────
|
||||||
|
// EN 415-1 (Terminologie) und EN 415-5 (Einwickelmaschinen) sind
|
||||||
|
// bereits in norms_library_c.go enthalten und werden hier uebersprungen.
|
||||||
|
{
|
||||||
|
ID: "EN-415-2", Number: "EN 415-2:1999+A1:2009",
|
||||||
|
TitleDE: "Verpackungsmaschinen — Teil 2: Maschinen zum Vorformen, Fuellen und Verschliessen starrer Packungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Maschinen zum Vorformen, Fuellen und Verschliessen starrer Packungen: Quetschstellen, Werkzeugwechsel.",
|
||||||
|
MachineTypes: []string{"packaging_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "crush_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-415-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-415-3", Number: "EN 415-3:1999+A1:2009",
|
||||||
|
TitleDE: "Verpackungsmaschinen — Teil 3: Form-, Fuell- und Verschliessmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Form-, Fuell- und Verschliessmaschinen: Siegelwerkzeuge, Temperaturueberwachung, Einzugstellen.",
|
||||||
|
MachineTypes: []string{"packaging_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"moving_part", "high_temperature"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-415-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-415-4", Number: "EN 415-4:1997+A1:2009",
|
||||||
|
TitleDE: "Verpackungsmaschinen — Teil 4: Palettierer und Depalettierer",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Palettierer und Depalettierer: Greiferbewegung, Absturzsicherung, Zugangskontrolle.",
|
||||||
|
MachineTypes: []string{"packaging_machine", "palletizer"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "gravity_risk", "high_force"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-415-4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-415-6", Number: "EN 415-6:2013",
|
||||||
|
TitleDE: "Verpackungsmaschinen — Teil 6: Einwickelmaschinen fuer Palettenladungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Palettenwickler: Drehteller, Folienabwicklung, Einzugstellen, Lagenbildung.",
|
||||||
|
MachineTypes: []string{"packaging_machine", "pallet_wrapper"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "rotating_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-415-6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-415-7", Number: "EN 415-7:2006+A1:2008",
|
||||||
|
TitleDE: "Verpackungsmaschinen — Teil 7: Sammel- und Gruppiermaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Sammel- und Gruppiermaschinen: Transportbewegungen, Quetschstellen, Produktzufuhr.",
|
||||||
|
MachineTypes: []string{"packaging_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-415-7",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-415-8", Number: "EN 415-8:2008",
|
||||||
|
TitleDE: "Verpackungsmaschinen — Teil 8: Umreifungsmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Umreifungsmaschinen: Spannwerk, Verschlussmechanismus, Einzugstellen.",
|
||||||
|
MachineTypes: []string{"packaging_machine", "strapping_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-415-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-415-9", Number: "EN 415-9:2009",
|
||||||
|
TitleDE: "Verpackungsmaschinen — Teil 9: Geraeuschemmission — Messmethoden",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Messverfahren fuer Geraeuschemmission von Verpackungsmaschinen: Betriebsbedingungen, Messpositionen, Berichtformat.",
|
||||||
|
MachineTypes: []string{"packaging_machine"},
|
||||||
|
HazardCats: []string{"noise_vibration"},
|
||||||
|
Tags: []string{},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Messverfahren)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-415-9",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-415-10", Number: "EN 415-10:2014",
|
||||||
|
TitleDE: "Verpackungsmaschinen — Teil 10: Allgemeine Anforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Allgemeine Sicherheitsanforderungen fuer Verpackungsmaschinen: Ergonomie, Zugangssicherung, Betriebsanleitung.",
|
||||||
|
MachineTypes: []string{"packaging_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-415-10",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Textilmaschinen (EN ISO 11111 Serie) ────────────────────────────
|
||||||
|
// EN ISO 11111-1 (Gemeinsame Anforderungen) ist bereits in
|
||||||
|
// norms_library_c_ext.go enthalten und wird hier uebersprungen.
|
||||||
|
{
|
||||||
|
ID: "EN-ISO-11111-2", Number: "EN ISO 11111-2:2005",
|
||||||
|
TitleDE: "Textilmaschinen — Sicherheitsanforderungen — Teil 2: Spinnereivorbereitungsmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Spinnereivorbereitungsmaschinen: Walzenschutz, Einzugstellen, Kardiermaschinen, Strecken.",
|
||||||
|
MachineTypes: []string{"textile_machine", "spinning_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11111-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-ISO-11111-3", Number: "EN ISO 11111-3:2005",
|
||||||
|
TitleDE: "Textilmaschinen — Sicherheitsanforderungen — Teil 3: Vliesstoffmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Vliesstoffmaschinen: Nadelbalken, Thermobondierung, Kalanderschutz, Temperaturueberwachung.",
|
||||||
|
MachineTypes: []string{"textile_machine", "nonwoven_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "high_temperature"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11111-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-ISO-11111-4", Number: "EN ISO 11111-4:2005",
|
||||||
|
TitleDE: "Textilmaschinen — Sicherheitsanforderungen — Teil 4: Garnverarbeitungsmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Garnverarbeitungsmaschinen: Spulenschutz, Fadenbruchueberwachung, Einzugstellen an Spulkoerpern.",
|
||||||
|
MachineTypes: []string{"textile_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11111-4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-ISO-11111-5", Number: "EN ISO 11111-5:2005",
|
||||||
|
TitleDE: "Textilmaschinen — Sicherheitsanforderungen — Teil 5: Webvorbereitungsmaschinen und Webmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Web- und Webvorbereitungsmaschinen: Schuetzen-/Greiferwebstuehle, Kettbaumschutz, Laermminderung.",
|
||||||
|
MachineTypes: []string{"textile_machine", "weaving_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "noise_vibration"},
|
||||||
|
Tags: []string{"rotating_part", "noise_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11111-5",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-ISO-11111-6", Number: "EN ISO 11111-6:2005",
|
||||||
|
TitleDE: "Textilmaschinen — Sicherheitsanforderungen — Teil 6: Textilveredlungsmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Textilveredlungsmaschinen: Spannrahmen, Trockner, Chemikalieneinsatz, Temperaturueberwachung.",
|
||||||
|
MachineTypes: []string{"textile_machine"},
|
||||||
|
HazardCats: []string{"thermal_hazard", "material_substance_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11111-6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-ISO-11111-7", Number: "EN ISO 11111-7:2005",
|
||||||
|
TitleDE: "Textilmaschinen — Sicherheitsanforderungen — Teil 7: Faerbereimaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Faerbereimaschinen: Chemikalienhandhabung, Verbruehungsschutz, Druckbehaelter, Abluftbehandlung.",
|
||||||
|
MachineTypes: []string{"textile_machine", "dyeing_machine"},
|
||||||
|
HazardCats: []string{"thermal_hazard", "material_substance_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "chemical_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11111-7",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Landmaschinen (ISO 4254 Serie) ──────────────────────────────────
|
||||||
|
// ISO 4254-1 (Allgemeine Anforderungen) ist bereits in
|
||||||
|
// norms_library_c_ext.go enthalten und wird hier uebersprungen.
|
||||||
|
{
|
||||||
|
ID: "ISO-4254-5", Number: "ISO 4254-5:2018",
|
||||||
|
TitleDE: "Landmaschinen — Sicherheit — Teil 5: Motorgetriebene Bodenbearbeitungsmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer motorgetriebene Bodenbearbeitungsmaschinen: Flaechenfraeser, Kreiseleggen, Rueckschlagsicherung.",
|
||||||
|
MachineTypes: []string{"agricultural_machine", "tiller"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "cutting_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-4254-5",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-4254-6", Number: "ISO 4254-6:2020",
|
||||||
|
TitleDE: "Landmaschinen — Sicherheit — Teil 6: Spritz- und Fluessigduengergeraete",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Pflanzenschutzspritzen und Fluessigduengergeraete: Drucksystem, Chemikalienschutz, Reinigung.",
|
||||||
|
MachineTypes: []string{"agricultural_machine", "sprayer"},
|
||||||
|
HazardCats: []string{"material_substance_hazard", "pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"chemical_risk", "high_pressure"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-4254-6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-4254-7", Number: "ISO 4254-7:2017",
|
||||||
|
TitleDE: "Landmaschinen — Sicherheit — Teil 7: Maehdrescher, Feldhaecksler und Baumwollernter",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Maehdrescher, Feldhaecksler und Baumwollernter: Schneidwerk, Dreschtrommel, Einzugstellen, Brandschutz.",
|
||||||
|
MachineTypes: []string{"agricultural_machine", "combine_harvester"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "high_speed"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-4254-7",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-4254-12", Number: "ISO 4254-12:2012",
|
||||||
|
TitleDE: "Landmaschinen — Sicherheit — Teil 12: Rotationsmaehwerke und Schlegelmaehwerke",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Rotations- und Schlegelmaehwerke: Schneidwerkschutz, Steinschlagsicherung, Absicherung gegen Eindringen.",
|
||||||
|
MachineTypes: []string{"agricultural_machine", "mower"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "high_speed"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-4254-12",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-4254-14", Number: "ISO 4254-14:2016",
|
||||||
|
TitleDE: "Landmaschinen — Sicherheit — Teil 14: Wickel- und Rundballenpressen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Wickel- und Rundballenpressen: Einzugstellen, Presskanal, Netz-/Folienwicklung, Auswurf.",
|
||||||
|
MachineTypes: []string{"agricultural_machine", "baler"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk", "crush_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-4254-14",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Erdbaumaschinen (EN 474 Serie) ──────────────────────────────────
|
||||||
|
// EN 474-1 (Allgemeine Anforderungen) ist bereits in
|
||||||
|
// norms_library_c_ext.go enthalten und wird hier uebersprungen.
|
||||||
|
{
|
||||||
|
ID: "EN-474-2", Number: "EN 474-2:2006+A1:2008",
|
||||||
|
TitleDE: "Erdbaumaschinen — Sicherheit — Teil 2: Planiermaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Planiermaschinen (Bulldozer): Schildsteuerung, Sichtverhaeltnisse, Standsicherheit, Ueberrollschutz.",
|
||||||
|
MachineTypes: []string{"earth_moving", "bulldozer"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"high_force", "moving_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-474-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-474-3", Number: "EN 474-3:2006+A1:2009",
|
||||||
|
TitleDE: "Erdbaumaschinen — Sicherheit — Teil 3: Lader",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Rad- und Raupenlader: Hubgeruest, Schaufelsteuerung, Kippstabilitaet, Rueckraumkamera.",
|
||||||
|
MachineTypes: []string{"earth_moving", "wheel_loader"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"high_force", "gravity_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-474-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-474-5", Number: "EN 474-5:2006+A3:2013",
|
||||||
|
TitleDE: "Erdbaumaschinen — Sicherheit — Teil 5: Hydraulikbagger",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Hydraulikbagger: Loeffelbewegung, Absturzsicherung, Hydraulikleitungen, Sichtverhaeltnisse.",
|
||||||
|
MachineTypes: []string{"earth_moving", "excavator"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"high_force", "hydraulic_part", "gravity_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-474-5",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-474-6", Number: "EN 474-6:2006+A1:2010",
|
||||||
|
TitleDE: "Erdbaumaschinen — Sicherheit — Teil 6: Muldenfahrzeuge",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Muldenfahrzeuge (Dumper): Kippbewegung, Bremssystem, Sichtverhaeltnisse, Absturzsicherung.",
|
||||||
|
MachineTypes: []string{"earth_moving", "dump_truck"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "high_force"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-474-6",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,409 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// GetLiftMiscCNorms returns C-norms for lifting equipment, cranes, conveyors,
|
||||||
|
// rubber/plastics, welding, compressors, gates, and miscellaneous machine categories.
|
||||||
|
func GetLiftMiscCNorms() []NormReference {
|
||||||
|
return []NormReference{
|
||||||
|
// ── Krane & Hebezeuge ──────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-13000", Number: "EN 13000:2010+A1:2014",
|
||||||
|
TitleDE: "Krane — Fahrzeugkrane",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Fahrzeugkrane: Standsicherheit, Tragfaehigkeit, Hydraulik, Absturzsicherung.",
|
||||||
|
MachineTypes: []string{"crane", "mobile_crane"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "high_force", "hydraulic_part"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Standsicherheit)", "Abschnitt 5 (Tragfaehigkeit)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13000",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-14439", Number: "EN 14439:2006+A2:2009",
|
||||||
|
TitleDE: "Krane — Sicherheit — Turmdrehkrane",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Turmdrehkrane: Standsicherheit, Tragfaehigkeit, Windlast, Montage und Demontage.",
|
||||||
|
MachineTypes: []string{"crane", "tower_crane"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "high_force"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-14439",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13852-1", Number: "EN 13852-1:2013",
|
||||||
|
TitleDE: "Krane — Offshorekrane — Teil 1: Allzweck-Offshorekrane",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Offshorekrane: Tragfaehigkeit unter Seegang, Korrosionsschutz, dynamische Lasten.",
|
||||||
|
MachineTypes: []string{"crane", "offshore_crane"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "high_force"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13852-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-14985", Number: "EN 14985:2012",
|
||||||
|
TitleDE: "Krane — Schwenkkrane",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Schwenkkrane: Standsicherheit, Schwenkbegrenzung, Lastaufnahmemittel.",
|
||||||
|
MachineTypes: []string{"crane", "slewing_crane"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "high_force"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-14985",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-14492-2", Number: "EN 14492-2:2006+A1:2009",
|
||||||
|
TitleDE: "Krane — Kraftbetriebene Winden und Hubwerke — Teil 2: Kraftbetriebene Hubwerke",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer kraftbetriebene Hubwerke: Tragfaehigkeit, Bremsen, Ueberlastsicherung.",
|
||||||
|
MachineTypes: []string{"crane", "hoist"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "high_force"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-14492-2",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Aufzuege ───────────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-81-50", Number: "EN 81-50:2014",
|
||||||
|
TitleDE: "Aufzuege — Pruefung und Inspektion — Teil 50: Pruefregeln fuer Aufzugskomponenten",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Pruefregeln und -verfahren fuer sicherheitsrelevante Aufzugskomponenten: Fangvorrichtungen, Geschwindigkeitsbegrenzer, Puffer.",
|
||||||
|
MachineTypes: []string{"elevator", "lift"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Pruefverfahren)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-81-50",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-81-70", Number: "EN 81-70:2018",
|
||||||
|
TitleDE: "Aufzuege — Barrierefreiheit fuer Personen einschliesslich Behinderter",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Anforderungen an barrierefreie Aufzuege: Tuermasse, Bedienelemente, taktile und akustische Signale.",
|
||||||
|
MachineTypes: []string{"elevator", "lift"},
|
||||||
|
HazardCats: []string{"ergonomic"},
|
||||||
|
Tags: []string{"user_interface"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-81-70",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Haengende Personenaufnahmemittel & Hubarbeitsbuehnen ───────────
|
||||||
|
{
|
||||||
|
ID: "EN-1808", Number: "EN 1808:2015",
|
||||||
|
TitleDE: "Sicherheitsanforderungen fuer haengende Personenaufnahmemittel — Berechnung, Standsicherheit, Bau — Pruefungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer haengende Arbeitsbuehnen und Gondeln: Tragfaehigkeit, Seilsicherung, Absturzsicherung.",
|
||||||
|
MachineTypes: []string{"suspended_platform", "scaffold"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "person_under_load"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1808",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-280", Number: "EN 280:2013+A1:2015",
|
||||||
|
TitleDE: "Fahrbare Hubarbeitsbuehnen — Berechnung — Standsicherheit — Bau — Sicherheit — Pruefungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer fahrbare Hubarbeitsbuehnen: Standsicherheit, Tragfaehigkeit, Absturzsicherung, Hydraulik.",
|
||||||
|
MachineTypes: []string{"aerial_platform", "cherry_picker"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "person_under_load", "hydraulic_part"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-280",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1570-1", Number: "EN 1570-1:2011+A1:2014",
|
||||||
|
TitleDE: "Sicherheitsanforderungen fuer Hubtische — Teil 1: Hubtische fuer bis zu 2 vorgegebene Haltestellen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Hubtische und Scherenhubtische: Quetschsicherung, Absturzsicherung, Tragfaehigkeit.",
|
||||||
|
MachineTypes: []string{"lift_table", "scissor_lift"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "crush_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1570-1",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Foerder- und Lagertechnik (erweitert) ──────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-741", Number: "EN 741:2000+A1:2010",
|
||||||
|
TitleDE: "Stetigfoerderer und Systeme — Sicherheitsanforderungen an Foerderer fuer Schuettgut in der Luft",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer pneumatische Foerderer: Druckentlastung, Laeermminderung, Staubexplosionsschutz.",
|
||||||
|
MachineTypes: []string{"conveyor", "pneumatic_conveyor"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"pneumatic_part", "noise_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-741",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-528", Number: "EN 528:2008",
|
||||||
|
TitleDE: "Regalbediengeraete — Sicherheit",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer automatisierte Regalbediengeraete: Bewegungsbereich, Quetschschutz, Steuerungssicherheit.",
|
||||||
|
MachineTypes: []string{"storage_retrieval", "automated_warehouse"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "gravity_risk", "programmable"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-528",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1175", Number: "EN 1175:2020",
|
||||||
|
TitleDE: "Sicherheit von Flurfoerderzeugen — Elektrische Anforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Elektrische Sicherheitsanforderungen fuer Flurfoerderzeuge: Isolierung, Batterie, Ladegeraete, EMV.",
|
||||||
|
MachineTypes: []string{"forklift", "industrial_truck"},
|
||||||
|
HazardCats: []string{"electrical_hazard"},
|
||||||
|
Tags: []string{"electrical_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1175",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1459", Number: "EN 1459:2012",
|
||||||
|
TitleDE: "Sicherheit von Flurfoerderzeugen — Gelaendestapler",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Gelaendestapler: Standsicherheit, Hydraulik, Sicht, Kippschutz.",
|
||||||
|
MachineTypes: []string{"forklift", "rough_terrain"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "hydraulic_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1459",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12158-1", Number: "EN 12158-1:2000+A1:2010",
|
||||||
|
TitleDE: "Bauaufzuege fuer den Gueter- und Personentransport — Teil 1",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Bauaufzuege: Tragfaehigkeit, Fangvorrichtung, Absturzsicherung, elektrische Sicherheit.",
|
||||||
|
MachineTypes: []string{"construction_hoist"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"gravity_risk", "person_under_load"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12158-1",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Kunststoff- und Gummimaschinen (erweitert) ─────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1417", Number: "EN 1417:1996+A1:2008",
|
||||||
|
TitleDE: "Kunststoff- und Gummimaschinen — Zweiwalzenmischwerke — Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Zweiwalzenmischwerke: Walzenspalt-Sicherung, Not-Halt, Verbrennungsschutz.",
|
||||||
|
MachineTypes: []string{"plastics_machine", "rubber_machine", "two_roll_mill"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "crush_point", "entanglement_risk", "high_temperature"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1417",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1114-3", Number: "EN 1114-3:2001+A1:2008",
|
||||||
|
TitleDE: "Kunststoff- und Gummimaschinen — Extruder — Teil 3: Sicherheitsanforderungen fuer Abzuege",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Extruder-Abzuege: Einzugssicherung, Quetschschutz an Rollen und Walzen.",
|
||||||
|
MachineTypes: []string{"extruder", "plastics_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1114-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12013", Number: "EN 12013:2000+A1:2008",
|
||||||
|
TitleDE: "Kunststoff- und Gummimaschinen — Innenmischer — Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Innenmischer: Rotorabsicherung, Verbrennungsschutz, Quetschschutz an Beschickung.",
|
||||||
|
MachineTypes: []string{"plastics_machine", "rubber_machine", "internal_mixer"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "high_temperature", "crush_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12013",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12409", Number: "EN 12409:2008+A1:2011",
|
||||||
|
TitleDE: "Kunststoff- und Gummimaschinen — Thermoplast-Formpressen und Gummiformpressen — Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Formpressen: Schliessbewegung, Verbrennungsschutz, Hydraulikabsicherung.",
|
||||||
|
MachineTypes: []string{"plastics_press", "compression_molding"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "crush_point", "high_force"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12409",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13418", Number: "EN 13418:2013+A1:2019",
|
||||||
|
TitleDE: "Kunststoff- und Gummimaschinen — Folien- und Plattenwickelmaschinen — Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Wickelmaschinen: Einzugssicherung, Quetschschutz an Walzen, Not-Halt.",
|
||||||
|
MachineTypes: []string{"plastics_machine", "winding_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13418",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12301", Number: "EN 12301:2000+A1:2008",
|
||||||
|
TitleDE: "Gummi- und Kunststoffmaschinen — Kalandermaschinen — Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Kalander: Walzenspalt-Sicherung, Verbrennungsschutz, Einzugssicherung.",
|
||||||
|
MachineTypes: []string{"plastics_machine", "rubber_machine", "calender"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "crush_point", "high_temperature"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12301",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Schweissen ─────────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-ISO-11611", Number: "EN ISO 11611:2015",
|
||||||
|
TitleDE: "Schutzkleidung fuer Schweissen und verwandte Verfahren",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Anforderungen an Schutzkleidung beim Schweissen: Flammenbestaendigkeit, Spritzerschutz, Strahlungsschutz.",
|
||||||
|
MachineTypes: []string{"welding_machine"},
|
||||||
|
HazardCats: []string{"thermal_hazard"},
|
||||||
|
Tags: []string{},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-11611",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-50504", Number: "EN 50504:2008",
|
||||||
|
TitleDE: "Validierung von Lichtbogenschweissgeraeten",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Validierungsverfahren fuer Lichtbogenschweissgeraete: elektrische Sicherheit, Isolierung, Pruefzyklen.",
|
||||||
|
MachineTypes: []string{"welding_machine", "arc_welder"},
|
||||||
|
HazardCats: []string{"electrical_hazard"},
|
||||||
|
Tags: []string{"electrical_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Validierung)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-50504",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Kompressoren, Vakuum & Druckbehaelter ──────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-1012-2", Number: "EN 1012-2:1996+A1:2009",
|
||||||
|
TitleDE: "Kompressoren und Vakuumpumpen — Teil 2: Vakuumpumpen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Vakuumpumpen: Laermminderung, Dichtheit, Ueberdrucksicherung.",
|
||||||
|
MachineTypes: []string{"vacuum_pump"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"noise_source"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1012-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13445-1", Number: "EN 13445-1:2014",
|
||||||
|
TitleDE: "Unbefeuerte Druckbehaelter — Teil 1: Allgemeines",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Allgemeine Anforderungen an unbefeuerte Druckbehaelter: Werkstoffwahl, Berechnung, Herstellung, Pruefung.",
|
||||||
|
MachineTypes: []string{"pressure_vessel"},
|
||||||
|
HazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"high_pressure"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Grundanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13445-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-14359", Number: "EN 14359:2006+A1:2010",
|
||||||
|
TitleDE: "Hydraulische Speicher — Sicherheitstechnische Anforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Hydrospeicher: Druckbegrenzung, Bruchsicherung, Kennzeichnung, Pruefung.",
|
||||||
|
MachineTypes: []string{"hydraulic_accumulator"},
|
||||||
|
HazardCats: []string{"pneumatic_hydraulic"},
|
||||||
|
Tags: []string{"hydraulic_part", "high_pressure", "stored_energy"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-14359",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Kraftbetaetigte Tore ───────────────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-12453", Number: "EN 12453:2017",
|
||||||
|
TitleDE: "Kraftbetaetigte Tore — Nutzungssicherheit — Anforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer kraftbetaetigte Tore und Tueren: Quetschschutz, Kraftbegrenzung, Sensorik.",
|
||||||
|
MachineTypes: []string{"powered_gate", "industrial_door"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "crush_point"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12453",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12978", Number: "EN 12978:2003+A1:2009",
|
||||||
|
TitleDE: "Tore — Schutzeinrichtungen fuer kraftbetaetigte Tore — Anforderungen und Pruefverfahren",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Anforderungen an Schutzeinrichtungen fuer kraftbetaetigte Tore: Schaltleisten, Lichtschranken, Kontaktmatten.",
|
||||||
|
MachineTypes: []string{"powered_gate", "industrial_door"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "sensor_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12978",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Giesserei & Papierherstellung ──────────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-12545", Number: "EN 12545:2000+A1:2009",
|
||||||
|
TitleDE: "Giessereimaschinen — Sicherheitsanforderungen an Stranggussanlagen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Stranggussanlagen: Verbrennungsschutz, Metallspritzer, Hydraulikabsicherung.",
|
||||||
|
MachineTypes: []string{"foundry_machine", "continuous_casting"},
|
||||||
|
HazardCats: []string{"mechanical_hazard", "thermal_hazard"},
|
||||||
|
Tags: []string{"high_temperature", "high_force"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12545",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1034-1", Number: "EN 1034-1:2000+A1:2010",
|
||||||
|
TitleDE: "Sicherheit von Maschinen — Papierherstellungs- und Ausruestungsmaschinen — Teil 1: Gemeinsame Anforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Gemeinsame Sicherheitsanforderungen fuer Papiermaschinen: Einzugssicherung an Walzen, Quetschschutz, Not-Halt.",
|
||||||
|
MachineTypes: []string{"paper_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1034-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1034-3", Number: "EN 1034-3:2011",
|
||||||
|
TitleDE: "Papierherstellungsmaschinen — Teil 3: Rollenschneider und Umroller",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Rollenschneider und Umroller: Schnittschutz, Einzugssicherung, Bremsen.",
|
||||||
|
MachineTypes: []string{"paper_machine", "slitter_rewinder"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1034-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1034-4", Number: "EN 1034-4:2005+A1:2009",
|
||||||
|
TitleDE: "Papierherstellungsmaschinen — Teil 4: Stoffloesemaschinen und deren Beschickungseinrichtungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Stoffloeser (Pulper): Rotor-Absicherung, Einzugssicherung, Zugangsschutz.",
|
||||||
|
MachineTypes: []string{"paper_machine", "pulper"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "entanglement_risk"},
|
||||||
|
Mandatory: false,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1034-4",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,396 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
// GetWoodMetalCNorms returns C-norms for woodworking and metalworking machines.
|
||||||
|
func GetWoodMetalCNorms() []NormReference {
|
||||||
|
return []NormReference{
|
||||||
|
// ── Holzbearbeitungsmaschinen — Fraesen ─────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-848-2", Number: "EN 848-2:2007+A2:2012",
|
||||||
|
TitleDE: "Sicherheit Holzbearbeitungsmaschinen — Einseitige Fraesmaschinen — Teil 2: Oberfraesmaschinen mit Handvorschub",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Oberfraesmaschinen mit Handvorschub zur Holzbearbeitung.",
|
||||||
|
MachineTypes: []string{"woodworking", "router"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "high_speed"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-848-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-848-3", Number: "EN 848-3:2012",
|
||||||
|
TitleDE: "Holzbearbeitungsmaschinen — Fraesmaschinen — Teil 3: NC-Bohr- und -Fraesmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer numerisch gesteuerte Bohr- und Fraesmaschinen zur Holzbearbeitung.",
|
||||||
|
MachineTypes: []string{"woodworking", "cnc", "milling_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "programmable"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-848-3",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Holzbearbeitungsmaschinen — Hobeln ──────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-859", Number: "EN 859:2007+A2:2012",
|
||||||
|
TitleDE: "Holzbearbeitungsmaschinen — Abrichthobelmaschinen mit Handvorschub",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Abrichthobelmaschinen mit manueller Werkstueckzufuehrung.",
|
||||||
|
MachineTypes: []string{"woodworking", "planer"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-859",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-860", Number: "EN 860:2007+A2:2012",
|
||||||
|
TitleDE: "Holzbearbeitungsmaschinen — Einseiten-Dickenhobelmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer einseitige Dickenhobelmaschinen mit Einzugsgefahr.",
|
||||||
|
MachineTypes: []string{"woodworking", "planer"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "entanglement_risk"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-860",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12750", Number: "EN 12750:2013",
|
||||||
|
TitleDE: "Holzbearbeitungsmaschinen — Sicherheit — Vierseitige Hobelmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer vierseitige Hobelmaschinen mit hohen Drehzahlen.",
|
||||||
|
MachineTypes: []string{"woodworking", "planer"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "high_speed"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12750",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Holzbearbeitungsmaschinen — Kreissaegen EN 1870 Serie ───────────
|
||||||
|
{
|
||||||
|
ID: "EN-1870-2", Number: "EN 1870-2:2007+A1:2009",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 2: Horizontale Plattenkreissaegen mit Druckbalken",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer horizontale Plattenkreissaegen mit Druckbalken.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw", "panel_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-3", Number: "EN 1870-3:2001+A1:2009",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 3: Ablaengsaegen und Aufteilsaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Ablaeng- und Aufteilsaegen.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-4", Number: "EN 1870-4:2012",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 4: Mehrblattkreissaegen fuer Laengsschnitt",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Mehrblattkreissaegen zum Laengsschnitt bei hoher Geschwindigkeit.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "high_speed"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-5", Number: "EN 1870-5:2002+A1:2009",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 5: Kombinierte Tisch-/Formatkreissaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer kombinierte Tisch- und Formatkreissaegen.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw", "table_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-5",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-6", Number: "EN 1870-6:2002+A1:2009",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 6: Brennholzsaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Brennholzsaegen.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-7", Number: "EN 1870-7:2012",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 7: Stammholzkreissaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Stammholzkreissaegen mit hohen Kraefte.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw", "log_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "high_force"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-7",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-8", Number: "EN 1870-8:2012",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 8: Einblatt-Besaeumkreissaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Einblatt-Besaeumkreissaegen.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-9", Number: "EN 1870-9:2012",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 9: Doppelgehrungssaegen mit motorisch bewegter Saege",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Doppelgehrungssaegen mit motorischem Antrieb.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw", "miter_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-9",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-10", Number: "EN 1870-10:2013",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 10: Einblattauftrenn-Formatkreissaegen mit Handvorschub",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Einblattauftrenn-Formatkreissaegen mit manueller Zufuehrung.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-10",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-11", Number: "EN 1870-11:2013",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 11: Automatische horizontale Formatkreissaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer automatische horizontale Formatkreissaegen.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "programmable"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-11",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-12", Number: "EN 1870-12:2013",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 12: Pendelkreissaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Pendelkreissaegen.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-12",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-13", Number: "EN 1870-13:2011",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 13: Horizontale Plattenkreissaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer horizontale Plattenkreissaegen.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw", "panel_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-13",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-14", Number: "EN 1870-14:2011",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 14: Vertikale Plattenkreissaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer vertikale Plattenkreissaegen.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw", "panel_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-14",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-15", Number: "EN 1870-15:2012",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 15: Mehrblattkreissaegen fuer Querschnitt",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Mehrblattkreissaegen fuer den Querschnitt bei hoher Geschwindigkeit.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part", "high_speed"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-15",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-16", Number: "EN 1870-16:2012",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 16: V-Schnitt-Doppelgehrungssaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer V-Schnitt-Doppelgehrungssaegen.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw", "miter_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-16",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-17", Number: "EN 1870-17:2012+A1:2015",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 17: Manuell bediente horizontale Querschnittkreissaegen (Kappsaegen)",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer manuell bediente Kappsaegen — haeufig im Handwerk eingesetzt.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw", "miter_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-17",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-18", Number: "EN 1870-18:2013",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 18: Querschnittkreissaegen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Querschnittkreissaegen.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-18",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-1870-19", Number: "EN 1870-19:2013",
|
||||||
|
TitleDE: "Kreissaegemaschinen — Teil 19: Tischkappsaegen (zusaetzlich zur Gehrungsfunktion)",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Tischkappsaegen mit erweiterter Gehrungsfunktion.",
|
||||||
|
MachineTypes: []string{"woodworking", "saw", "miter_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-1870-19",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Holzbearbeitungsmaschinen — Sonstige ────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-940", Number: "EN 940:2009+A1:2012",
|
||||||
|
TitleDE: "Holzbearbeitungsmaschinen — Kombinierte Maschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer kombinierte Holzbearbeitungsmaschinen (Mehrfachfunktion).",
|
||||||
|
MachineTypes: []string{"woodworking"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-940",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12779", Number: "EN 12779:2004+A1:2009",
|
||||||
|
TitleDE: "Holzbearbeitungsmaschinen — Absauganlagen Holzstaub — Sicherheitsanforderungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheits- und Gesundheitsanforderungen fuer Absauganlagen zur Holzstauberfassung.",
|
||||||
|
MachineTypes: []string{"woodworking"},
|
||||||
|
HazardCats: []string{"material_environmental"},
|
||||||
|
Tags: []string{"chemical_risk", "noise_source"},
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Anforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12779",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Metallbearbeitungsmaschinen — Drehen ────────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-12478", Number: "EN 12478:2000+A1:2008",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Grosse Drehmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer grosse Drehmaschinen mit Einzugs- und Schneidgefahr.",
|
||||||
|
MachineTypes: []string{"lathe", "large_lathe"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "cutting_part", "entanglement_risk"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12478",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12415", Number: "EN 12415:2000+A1:2008",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Kleine Drehmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer kleine numerisch und nicht-numerisch gesteuerte Drehmaschinen.",
|
||||||
|
MachineTypes: []string{"lathe", "small_lathe"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "cutting_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12415",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Metallbearbeitungsmaschinen — Saegen & Bohren ───────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-13898", Number: "EN 13898:2003+A1:2009",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Saegemaschinen fuer Metall",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Metallsaegen inkl. Bandsaegen.",
|
||||||
|
MachineTypes: []string{"metal_saw", "band_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "moving_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13898",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12717", Number: "EN 12717:2001+A1:2009",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Bohrmaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer stationaere Bohrmaschinen.",
|
||||||
|
MachineTypes: []string{"drilling_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"rotating_part", "cutting_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12717",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "ISO-16093", Number: "EN ISO 16093:2017",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Saegemaschinen fuer Kaltmetall",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Kaltmetallsaegen (Kreissaegen, Bandsaegen, Buegelsaegen).",
|
||||||
|
MachineTypes: []string{"metal_saw", "cold_saw"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "rotating_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-iso-16093",
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── Metallbearbeitungsmaschinen — Sonstige ──────────────────────────
|
||||||
|
{
|
||||||
|
ID: "EN-13023", Number: "EN 13023:2003+A1:2010",
|
||||||
|
TitleDE: "Geraeuschemmission von Maschinen zur Holz- und Metallbearbeitung — Betriebsbedingungen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Legt Betriebsbedingungen fuer die Geraeuschmessung an Holz- und Metallbearbeitungsmaschinen fest.",
|
||||||
|
MachineTypes: []string{"woodworking", "metalworking"},
|
||||||
|
HazardCats: []string{"noise_vibration"},
|
||||||
|
Tags: []string{"noise_source"},
|
||||||
|
RelevantSections: []string{"Abschnitt 4 (Betriebsbedingungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13023",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-12653", Number: "EN 12653:2020",
|
||||||
|
TitleDE: "Hebelscheren (Schneidemaschinen fuer Metall)",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Hebelscheren zur Metallbearbeitung mit Quetsch- und Schneidgefahr.",
|
||||||
|
MachineTypes: []string{"shearing_machine", "cutting_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"cutting_part", "high_force", "crush_point"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-12653",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-14070", Number: "EN 14070:2003+A1:2009",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Transfermaschinen und Sondermaschinen",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Transfer- und Sondermaschinen mit programmierbaren Bewegungen.",
|
||||||
|
MachineTypes: []string{"transfer_machine", "rotary_transfer_machine", "special_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"moving_part", "cutting_part", "programmable"},
|
||||||
|
Mandatory: true,
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-14070",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "EN-13788", Number: "EN 13788:2001+A1:2009",
|
||||||
|
TitleDE: "Werkzeugmaschinen — Sicherheit — Blechbearbeitungsmaschinen (Abkant-, Biege-, Falzmaschinen)",
|
||||||
|
NormType: "C",
|
||||||
|
ScopeDE: "Sicherheitsanforderungen fuer Abkant-, Biege- und Falzmaschinen mit Quetschgefahr.",
|
||||||
|
MachineTypes: []string{"bending_machine", "folding_machine"},
|
||||||
|
HazardCats: []string{"mechanical_hazard"},
|
||||||
|
Tags: []string{"crush_point", "high_force", "moving_part"},
|
||||||
|
RelevantSections: []string{"Abschnitt 5 (Sicherheitsanforderungen)"},
|
||||||
|
BeuthURL: "https://www.beuth.de/de/norm/din-en-13788",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,17 @@ type PatternMatch struct {
|
|||||||
PatternName string `json:"pattern_name"`
|
PatternName string `json:"pattern_name"`
|
||||||
Priority int `json:"priority"`
|
Priority int `json:"priority"`
|
||||||
MatchedTags []string `json:"matched_tags"`
|
MatchedTags []string `json:"matched_tags"`
|
||||||
|
// Detail fields from the pattern definition
|
||||||
|
ScenarioDE string `json:"scenario_de,omitempty"`
|
||||||
|
TriggerDE string `json:"trigger_de,omitempty"`
|
||||||
|
HarmDE string `json:"harm_de,omitempty"`
|
||||||
|
AffectedDE string `json:"affected_de,omitempty"`
|
||||||
|
ZoneDE string `json:"zone_de,omitempty"`
|
||||||
|
DefaultSeverity int `json:"default_severity,omitempty"`
|
||||||
|
DefaultExposure int `json:"default_exposure,omitempty"`
|
||||||
|
HazardCats []string `json:"hazard_categories,omitempty"`
|
||||||
|
ExpertHintDE string `json:"expert_hint_de,omitempty"`
|
||||||
|
RequiresExpert bool `json:"requires_expert,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// HazardSuggestion is a suggested hazard from pattern matching.
|
// HazardSuggestion is a suggested hazard from pattern matching.
|
||||||
@@ -61,6 +72,7 @@ func NewPatternEngine() *PatternEngine {
|
|||||||
patterns = append(patterns, GetCobotHazardPatterns()...) // HP059-HP065 cobot-specific
|
patterns = append(patterns, GetCobotHazardPatterns()...) // HP059-HP065 cobot-specific
|
||||||
patterns = append(patterns, GetOperationalHazardPatterns()...) // HP066-HP093 operational states
|
patterns = append(patterns, GetOperationalHazardPatterns()...) // HP066-HP093 operational states
|
||||||
patterns = append(patterns, GetDGUVExtendedPatterns()...) // HP094-HP133 DGUV themes
|
patterns = append(patterns, GetDGUVExtendedPatterns()...) // HP094-HP133 DGUV themes
|
||||||
|
patterns = append(patterns, GetExtendedHazardPatterns2()...) // HP134-HP173 additional hazards
|
||||||
return &PatternEngine{
|
return &PatternEngine{
|
||||||
resolver: NewTagResolver(),
|
resolver: NewTagResolver(),
|
||||||
patterns: patterns,
|
patterns: patterns,
|
||||||
@@ -120,6 +132,16 @@ func (e *PatternEngine) Match(input MatchInput) *MatchOutput {
|
|||||||
PatternName: p.NameDE,
|
PatternName: p.NameDE,
|
||||||
Priority: p.Priority,
|
Priority: p.Priority,
|
||||||
MatchedTags: matchedTags,
|
MatchedTags: matchedTags,
|
||||||
|
ScenarioDE: p.ScenarioDE,
|
||||||
|
TriggerDE: p.TriggerDE,
|
||||||
|
HarmDE: p.HarmDE,
|
||||||
|
AffectedDE: p.AffectedDE,
|
||||||
|
ZoneDE: p.ZoneDE,
|
||||||
|
DefaultSeverity: p.DefaultSeverity,
|
||||||
|
DefaultExposure: p.DefaultExposure,
|
||||||
|
HazardCats: p.GeneratedHazardCats,
|
||||||
|
ExpertHintDE: p.ExpertHintDE,
|
||||||
|
RequiresExpert: p.RequiresExpertCalculation,
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, cat := range p.GeneratedHazardCats {
|
for _, cat := range p.GeneratedHazardCats {
|
||||||
|
|||||||
@@ -157,6 +157,58 @@ func (s *Store) ListMitigations(ctx context.Context, hazardID uuid.UUID) ([]Miti
|
|||||||
return mitigations, nil
|
return mitigations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListMitigationsByProject lists all mitigations for all hazards in a project.
|
||||||
|
func (s *Store) ListMitigationsByProject(ctx context.Context, projectID uuid.UUID) ([]Mitigation, error) {
|
||||||
|
rows, err := s.pool.Query(ctx, `
|
||||||
|
SELECT
|
||||||
|
m.id, m.hazard_id, m.reduction_type, m.name, m.description,
|
||||||
|
m.status, m.verification_method, m.verification_result,
|
||||||
|
m.verified_at, m.verified_by,
|
||||||
|
m.created_at, m.updated_at
|
||||||
|
FROM iace_mitigations m
|
||||||
|
JOIN iace_hazards h ON h.id = m.hazard_id
|
||||||
|
WHERE h.project_id = $1
|
||||||
|
ORDER BY m.created_at ASC
|
||||||
|
`, projectID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("list mitigations by project: %w", err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var mitigations []Mitigation
|
||||||
|
for rows.Next() {
|
||||||
|
var m Mitigation
|
||||||
|
var reductionType, status, verificationMethod string
|
||||||
|
|
||||||
|
err := rows.Scan(
|
||||||
|
&m.ID, &m.HazardID, &reductionType, &m.Name, &m.Description,
|
||||||
|
&status, &verificationMethod, &m.VerificationResult,
|
||||||
|
&m.VerifiedAt, &m.VerifiedBy,
|
||||||
|
&m.CreatedAt, &m.UpdatedAt,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("list mitigations by project scan: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.ReductionType = ReductionType(reductionType)
|
||||||
|
m.Status = MitigationStatus(status)
|
||||||
|
m.VerificationMethod = VerificationMethod(verificationMethod)
|
||||||
|
|
||||||
|
mitigations = append(mitigations, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mitigations, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteMitigation deletes a mitigation by ID.
|
||||||
|
func (s *Store) DeleteMitigation(ctx context.Context, id uuid.UUID) error {
|
||||||
|
_, err := s.pool.Exec(ctx, `DELETE FROM iace_mitigations WHERE id = $1`, id)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("delete mitigation: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetMitigation fetches a single mitigation by ID.
|
// GetMitigation fetches a single mitigation by ID.
|
||||||
func (s *Store) GetMitigation(ctx context.Context, id uuid.UUID) (*Mitigation, error) {
|
func (s *Store) GetMitigation(ctx context.Context, id uuid.UUID) (*Mitigation, error) {
|
||||||
return s.getMitigation(ctx, id)
|
return s.getMitigation(ctx, id)
|
||||||
|
|||||||
@@ -0,0 +1,325 @@
|
|||||||
|
package iace
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Production Line CRUD Operations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// CreateProductionLine creates a new production line for a tenant
|
||||||
|
func (s *Store) CreateProductionLine(ctx context.Context, tenantID uuid.UUID, name, description string) (*ProductionLine, error) {
|
||||||
|
line := &ProductionLine{
|
||||||
|
ID: uuid.New(),
|
||||||
|
TenantID: tenantID,
|
||||||
|
Name: name,
|
||||||
|
Description: description,
|
||||||
|
CreatedAt: time.Now().UTC(),
|
||||||
|
UpdatedAt: time.Now().UTC(),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := s.pool.Exec(ctx, `
|
||||||
|
INSERT INTO iace_production_lines (
|
||||||
|
id, tenant_id, name, description, layout, created_at, updated_at
|
||||||
|
) VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||||
|
`, line.ID, line.TenantID, line.Name, line.Description, json.RawMessage("{}"), line.CreatedAt, line.UpdatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("create production line: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return line, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListProductionLines lists all production lines for a tenant
|
||||||
|
func (s *Store) ListProductionLines(ctx context.Context, tenantID uuid.UUID) ([]ProductionLine, error) {
|
||||||
|
rows, err := s.pool.Query(ctx, `
|
||||||
|
SELECT id, tenant_id, name, description, layout, created_at, updated_at
|
||||||
|
FROM iace_production_lines
|
||||||
|
WHERE tenant_id = $1
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
`, tenantID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("list production lines: %w", err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var lines []ProductionLine
|
||||||
|
for rows.Next() {
|
||||||
|
var l ProductionLine
|
||||||
|
var layout []byte
|
||||||
|
err := rows.Scan(&l.ID, &l.TenantID, &l.Name, &l.Description, &layout, &l.CreatedAt, &l.UpdatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("list production lines scan: %w", err)
|
||||||
|
}
|
||||||
|
json.Unmarshal(layout, &l.Layout)
|
||||||
|
lines = append(lines, l)
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProductionLine retrieves a production line by ID
|
||||||
|
func (s *Store) GetProductionLine(ctx context.Context, id uuid.UUID) (*ProductionLine, error) {
|
||||||
|
var l ProductionLine
|
||||||
|
var layout []byte
|
||||||
|
|
||||||
|
err := s.pool.QueryRow(ctx, `
|
||||||
|
SELECT id, tenant_id, name, description, layout, created_at, updated_at
|
||||||
|
FROM iace_production_lines WHERE id = $1
|
||||||
|
`, id).Scan(&l.ID, &l.TenantID, &l.Name, &l.Description, &layout, &l.CreatedAt, &l.UpdatedAt)
|
||||||
|
if err == pgx.ErrNoRows {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get production line: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
json.Unmarshal(layout, &l.Layout)
|
||||||
|
return &l, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Station CRUD Operations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// AddStation adds a station (project reference) to a production line
|
||||||
|
func (s *Store) AddStation(ctx context.Context, lineID, projectID uuid.UUID, stationType, label string, sortOrder int) (*ProductionLineStation, error) {
|
||||||
|
st := &ProductionLineStation{
|
||||||
|
ID: uuid.New(),
|
||||||
|
LineID: lineID,
|
||||||
|
ProjectID: projectID,
|
||||||
|
StationType: stationType,
|
||||||
|
StationLabel: label,
|
||||||
|
SortOrder: sortOrder,
|
||||||
|
CreatedAt: time.Now().UTC(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if st.StationType == "" {
|
||||||
|
st.StationType = "assembly"
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := s.pool.Exec(ctx, `
|
||||||
|
INSERT INTO iace_production_line_stations (
|
||||||
|
id, line_id, project_id, station_type, station_label,
|
||||||
|
sort_order, position_x, position_y, metadata, created_at
|
||||||
|
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||||
|
`, st.ID, st.LineID, st.ProjectID, st.StationType, st.StationLabel,
|
||||||
|
st.SortOrder, st.PositionX, st.PositionY, json.RawMessage("{}"), st.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("add station: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return st, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListStations lists all stations for a production line ordered by sort_order
|
||||||
|
func (s *Store) ListStations(ctx context.Context, lineID uuid.UUID) ([]ProductionLineStation, error) {
|
||||||
|
rows, err := s.pool.Query(ctx, `
|
||||||
|
SELECT id, line_id, project_id, station_type, station_label,
|
||||||
|
sort_order, position_x, position_y, metadata, created_at
|
||||||
|
FROM iace_production_line_stations
|
||||||
|
WHERE line_id = $1
|
||||||
|
ORDER BY sort_order ASC, created_at ASC
|
||||||
|
`, lineID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("list stations: %w", err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var stations []ProductionLineStation
|
||||||
|
for rows.Next() {
|
||||||
|
var st ProductionLineStation
|
||||||
|
var metadata []byte
|
||||||
|
err := rows.Scan(
|
||||||
|
&st.ID, &st.LineID, &st.ProjectID, &st.StationType, &st.StationLabel,
|
||||||
|
&st.SortOrder, &st.PositionX, &st.PositionY, &metadata, &st.CreatedAt,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("list stations scan: %w", err)
|
||||||
|
}
|
||||||
|
json.Unmarshal(metadata, &st.Metadata)
|
||||||
|
stations = append(stations, st)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stations, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveStation deletes a station from a production line
|
||||||
|
func (s *Store) RemoveStation(ctx context.Context, stationID uuid.UUID) error {
|
||||||
|
_, err := s.pool.Exec(ctx, `DELETE FROM iace_production_line_stations WHERE id = $1`, stationID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("remove station: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Dashboard Aggregation
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// GetLineDashboard builds the full dashboard for a production line by aggregating
|
||||||
|
// risk data from each station's underlying IACE project.
|
||||||
|
func (s *Store) GetLineDashboard(ctx context.Context, lineID uuid.UUID) (*LineDashboard, error) {
|
||||||
|
line, err := s.GetProductionLine(ctx, lineID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get line dashboard - load line: %w", err)
|
||||||
|
}
|
||||||
|
if line == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
stations, err := s.ListStations(ctx, lineID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get line dashboard - list stations: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
aggregate := map[string]int{
|
||||||
|
"total_hazards": 0,
|
||||||
|
"total_mitigations": 0,
|
||||||
|
"critical": 0,
|
||||||
|
"high": 0,
|
||||||
|
"medium": 0,
|
||||||
|
"low": 0,
|
||||||
|
"negligible": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
var dashboards []StationDashboard
|
||||||
|
for _, st := range stations {
|
||||||
|
sd, err := s.buildStationDashboard(ctx, st)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get line dashboard - station %s: %w", st.ID, err)
|
||||||
|
}
|
||||||
|
dashboards = append(dashboards, *sd)
|
||||||
|
|
||||||
|
// Accumulate aggregates
|
||||||
|
aggregate["total_hazards"] += sd.HazardCount
|
||||||
|
aggregate["total_mitigations"] += sd.MitigationCount
|
||||||
|
for level, count := range sd.RiskSummary {
|
||||||
|
aggregate[level] += count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build transfers: linear chain station[i] -> station[i+1]
|
||||||
|
var transfers []TransferInfo
|
||||||
|
for i := 0; i < len(dashboards)-1; i++ {
|
||||||
|
transfers = append(transfers, TransferInfo{
|
||||||
|
FromStation: dashboards[i].Station.SortOrder,
|
||||||
|
ToStation: dashboards[i+1].Station.SortOrder,
|
||||||
|
Type: "material_flow",
|
||||||
|
Label: fmt.Sprintf("%s -> %s", stationDisplayName(dashboards[i]), stationDisplayName(dashboards[i+1])),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return &LineDashboard{
|
||||||
|
Line: *line,
|
||||||
|
Stations: dashboards,
|
||||||
|
Transfers: transfers,
|
||||||
|
Aggregate: aggregate,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildStationDashboard loads project data for a single station and computes
|
||||||
|
// risk metrics including SIL/PL maximums.
|
||||||
|
func (s *Store) buildStationDashboard(ctx context.Context, st ProductionLineStation) (*StationDashboard, error) {
|
||||||
|
project, err := s.GetProject(ctx, st.ProjectID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("load project: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sd := &StationDashboard{
|
||||||
|
Station: st,
|
||||||
|
RiskSummary: map[string]int{},
|
||||||
|
SILMax: "none",
|
||||||
|
PLMax: "a",
|
||||||
|
}
|
||||||
|
|
||||||
|
if project == nil {
|
||||||
|
sd.Status = "missing"
|
||||||
|
return sd, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
sd.ProjectName = project.MachineName
|
||||||
|
sd.MachineType = project.MachineType
|
||||||
|
sd.Status = string(project.Status)
|
||||||
|
sd.CompletenessPct = int(project.CompletenessScore)
|
||||||
|
|
||||||
|
hazards, _ := s.ListHazards(ctx, st.ProjectID)
|
||||||
|
sd.HazardCount = len(hazards)
|
||||||
|
|
||||||
|
mitigations, _ := s.ListMitigationsByProject(ctx, st.ProjectID)
|
||||||
|
sd.MitigationCount = len(mitigations)
|
||||||
|
|
||||||
|
// Compute risk summary and max SIL/PL from latest assessments
|
||||||
|
for _, h := range hazards {
|
||||||
|
latest, _ := s.GetLatestAssessment(ctx, h.ID)
|
||||||
|
if latest == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
levelKey := string(latest.RiskLevel)
|
||||||
|
sd.RiskSummary[levelKey]++
|
||||||
|
|
||||||
|
// Derive SIL/PL from assessment values and track maximums
|
||||||
|
silPL := CalculateSILPL(latest.Severity, latest.Exposure, latest.Probability)
|
||||||
|
if plRank(silPL.RecommendedPL) > plRank(sd.PLMax) {
|
||||||
|
sd.PLMax = silPL.RecommendedPL
|
||||||
|
}
|
||||||
|
if silRank(silPL.RecommendedSIL) > silRank(sd.SILMax) {
|
||||||
|
sd.SILMax = silPL.RecommendedSIL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// stationDisplayName returns a human-readable label for a station dashboard entry
|
||||||
|
func stationDisplayName(sd StationDashboard) string {
|
||||||
|
if sd.Station.StationLabel != "" {
|
||||||
|
return sd.Station.StationLabel
|
||||||
|
}
|
||||||
|
if sd.ProjectName != "" {
|
||||||
|
return sd.ProjectName
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Station %d", sd.Station.SortOrder)
|
||||||
|
}
|
||||||
|
|
||||||
|
// plRank returns a numeric rank for PL comparison (a=1 ... e=5)
|
||||||
|
func plRank(pl string) int {
|
||||||
|
switch pl {
|
||||||
|
case "a":
|
||||||
|
return 1
|
||||||
|
case "b":
|
||||||
|
return 2
|
||||||
|
case "c":
|
||||||
|
return 3
|
||||||
|
case "d":
|
||||||
|
return 4
|
||||||
|
case "e":
|
||||||
|
return 5
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// silRank returns a numeric rank for SIL comparison
|
||||||
|
func silRank(sil string) int {
|
||||||
|
switch sil {
|
||||||
|
case "none":
|
||||||
|
return 0
|
||||||
|
case "SIL 1":
|
||||||
|
return 1
|
||||||
|
case "SIL 2":
|
||||||
|
return 2
|
||||||
|
case "SIL 3":
|
||||||
|
return 3
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
-- Migration 023: IACE Production Lines
|
||||||
|
-- Adds tables for chaining multiple IACE projects into a production line
|
||||||
|
-- dashboard view, where each station maps to an existing IACE project.
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 1. Production lines (top-level grouping entity)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS iace_production_lines (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
name TEXT NOT NULL DEFAULT '',
|
||||||
|
description TEXT DEFAULT '',
|
||||||
|
layout JSONB DEFAULT '{}',
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_iace_pl_tenant ON iace_production_lines(tenant_id);
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 2. Production line stations (link table: line <-> project)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS iace_production_line_stations (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
line_id UUID NOT NULL REFERENCES iace_production_lines(id) ON DELETE CASCADE,
|
||||||
|
project_id UUID NOT NULL REFERENCES iace_projects(id) ON DELETE CASCADE,
|
||||||
|
station_type TEXT NOT NULL DEFAULT 'assembly',
|
||||||
|
station_label TEXT DEFAULT '',
|
||||||
|
sort_order INT DEFAULT 0,
|
||||||
|
position_x FLOAT DEFAULT 0,
|
||||||
|
position_y FLOAT DEFAULT 0,
|
||||||
|
metadata JSONB DEFAULT '{}',
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_pls_line ON iace_production_line_stations(line_id);
|
||||||
Reference in New Issue
Block a user