The benefit made visible: /report folds everything the system collects into
the one printable page a 안전관리자 takes into the weekly safety meeting.
- GET /api/report?days=N (7/30/90): severity totals, per-type counts,
worst-camera ranking, response time (TTA - acknowledged critical/high only,
FP-tagged rows excluded: dismissing a false alarm is not an emergency
response; clock-skew guarded), the near-miss pyramid (near_fall vs
fall/no_motion - the Heinrich argument in one ratio), FP rate, summed
posture-load exposure, occupancy-rule violation counts. ergo_report rows
feed the sums but are excluded from "감지 N건" (bookkeeping, not detection).
Fail-closed site scoping throughout.
- /report view: KPI band (중대 이벤트 / 평균 대응 / 니어미스:사고 / 오탐율,
each with its one-line reading), bar lists for types and cameras (critical
presence highlighted), ergo bands as share-of-observed-time, rule tiles.
Print CSS strips the app chrome - the 인쇄 button produces the meeting
handout. New 리포트 nav tab.
- Events console: event-type filter beside severity - the INFO-volume types
(near_fall, ergo_report) can now be folded out of the live stream, or a
single type isolated for investigation.
Verified: PHPUnit 138 pass (3 new: aggregation math incl. TTA/FP-exclusion/
ergo sums, site scope, auth) + Chrome real-render of the full report (KPIs,
bar lists, rule tiles, footer) and the type filter isolating one type.