feat(iace): Risikograph EN ISO 13849-1 PLr + Methoden-Kopf im Bericht
Phase 17 of the risk-assessment polish. Two pieces:
A) PLr per EN ISO 13849-1 Anhang A (Risikograph)
- HazardPattern.DefaultAvoidability (1 = P1, 2 = P2). Optional;
defaults to P1 if unset (conservative — operator can raise after
review).
- ComputePLr(s,f,p) implements the canonical 8-leaf binary tree
(S1F1P1 -> a, ..., S2F2P2 -> e). Pinned by 8 table-driven tests.
- SeverityToS / ExposureToF map the existing 1-5 fields to the
binary S/F at the documented threshold (3).
- At project initialise, every hazard's Description is appended
with "Risikograph EN ISO 13849-1 (Anhang A): S2 · F1 · P1 -> PLr c"
so the audit value is visible without leaving the hazard view.
- PatternMatch carries DefaultAvoidability so the init handler can
pick it up without a second pattern lookup.
B) Methoden-Kopf am Bericht
- GET /clarifications.html now opens with a standardised methodology
block: ISO 12100 Anhang B (hazard ID) + ISO 13849-1 Anhang A
(PLr graph) + ISO 12100 6.2/6.3/6.4 (reduction hierarchy). Same
wording on every export, ready for the Anlagenbauer-Uebergabe.
- Only norm identifiers — no norm text reproduced.
C) ISO12100Section in Hazard Description
- When a pattern is labeled with ISO12100Section, the hazard
description gets a "Klassifikation: EN ISO 12100 Anhang B,
Abschnitt 6.3.5.4" suffix. Provenance for the auditor.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -415,6 +415,20 @@ func (h *IACEHandler) ExportClarificationsCSV(c *gin.Context) {
|
||||
w.Flush()
|
||||
}
|
||||
|
||||
// methodologyBlock returns the standardised methodology paragraph that
|
||||
// must be printed at the start of every IACE risk-assessment report.
|
||||
// Pure references to norm identifiers (no norm text) — kept here so
|
||||
// the same wording appears in every export.
|
||||
const methodologyBlock = `<section style="background:#f9fafb;border:1px solid #d1d5db;border-radius:6px;padding:12px;margin-bottom:18px;">
|
||||
<h3 style="font-size:11pt;margin:0 0 6px 0;">Methodik der Risikobeurteilung</h3>
|
||||
<ul style="margin:0;padding-left:18px;font-size:9.5pt;line-height:1.45;">
|
||||
<li>Gefaehrdungsidentifikation nach <strong>EN ISO 12100</strong>, Anhang B (Tabelle B.1) — Mechanik, Elektrik, Thermik, Laerm, Vibration, Strahlung, Materialien/Substanzen, Ergonomie.</li>
|
||||
<li>Bestimmung des erforderlichen Performance Levels (PLr) nach <strong>EN ISO 13849-1</strong>, Anhang A (Risikograph) aus S (Schwere), F (Haeufigkeit/Dauer) und P (Vermeidungsmoeglichkeit).</li>
|
||||
<li>Massnahmen-Hierarchie nach ISO 12100, Abschnitt 6: <strong>6.2 Inhaerent sichere Konstruktion</strong> (Design) → <strong>6.3 Technische Schutzmassnahmen</strong> (Protection) → <strong>6.4 Benutzerinformation</strong> (Information).</li>
|
||||
<li>Klaerungspunkte mit dem Anlagenbauer werden separat in der Klaerungs-Liste verwaltet (Audit-Trail mit Bearbeiter und Zeitstempel).</li>
|
||||
</ul>
|
||||
</section>`
|
||||
|
||||
// ExportClarificationsHTML handles GET /projects/:id/clarifications.html
|
||||
// and returns a print-friendly standalone HTML document that the browser
|
||||
// can render to PDF (no server-side PDF dependency needed). The Bediener
|
||||
@@ -492,6 +506,7 @@ section .src { font-size: 8pt; color: #6b7280; margin-bottom: 6px; }
|
||||
<div class="noprint">Tipp: Mit <kbd>Strg+P</kbd> / <kbd>Cmd+P</kbd> als PDF speichern.</div>
|
||||
<h1>Klaerungsliste — %s</h1>
|
||||
<div class="sub">Projekt-ID %s · Stand %s</div>
|
||||
` + methodologyBlock + `
|
||||
<div class="meta">
|
||||
<span class="bar open">%d offen</span>
|
||||
<span class="bar done">%d beantwortet</span>
|
||||
|
||||
@@ -219,6 +219,27 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
|
||||
// scenario itself. Only the aggregated norm-references
|
||||
// block is appended below for an at-a-glance audit trail.
|
||||
desc := mp.ScenarioDE
|
||||
// Phase 17: PLr per EN ISO 13849-1 Anhang A. The graph
|
||||
// inputs come from the pattern's DefaultSeverity/Exposure
|
||||
// (mapped to S1/S2 and F1/F2 at threshold 3) plus
|
||||
// DefaultAvoidability (P1/P2). If avoidability is unset
|
||||
// we default to P1 — the conservative direction is
|
||||
// downward (lower PLr), the operator can raise it
|
||||
// manually after expert review.
|
||||
avoid := 1
|
||||
if mp.DefaultAvoidability == 2 {
|
||||
avoid = 2
|
||||
}
|
||||
if mp.DefaultSeverity > 0 && mp.DefaultExposure > 0 {
|
||||
sBin := iace.SeverityToS(mp.DefaultSeverity)
|
||||
fBin := iace.ExposureToF(mp.DefaultExposure)
|
||||
plr := iace.ComputePLr(sBin, fBin, avoid)
|
||||
desc += fmt.Sprintf("\n\nRisikograph EN ISO 13849-1 (Anhang A): S%d · F%d · P%d → PLr %s",
|
||||
sBin, fBin, avoid, plr)
|
||||
}
|
||||
if mp.ISO12100Section != "" {
|
||||
desc += "\n\nKlassifikation: EN ISO 12100 Anhang B, Abschnitt " + mp.ISO12100Section
|
||||
}
|
||||
|
||||
hz, cerr := h.store.CreateHazard(ctx, iace.CreateHazardRequest{
|
||||
ProjectID: projectID,
|
||||
|
||||
Reference in New Issue
Block a user