기존 소개서의 문제는 문장이 아니라 구조와 최신성이었다. - 기대효과 섹션이 아예 없었다. 기능 목록만 있고 "그래서 뭐가 달라지나"가 없었다. - 왜 만들었나가 4문장이었다. 이미 CCTV 가 있는 현장이 왜 또 사는지에 답하지 못했다. - 내용이 0.9.0 시점이었다. 1.0.0 의 핵심인 통보·에스컬레이션이 로드맵에 "P3 예정"으로 적혀 있었고 테스트 320건·감사 43항목도 옛 수치였다 — 완성된 기능을 미완성으로 소개하는 문서가 고객에게 나갈 뻔했다. 재작성 - 기능 나열을 버리고 감지 → 대응 → 증거의 사슬로 재구성. 어느 한 칸이 비면 나머지가 무의미해진다는 것이 이 제품의 논지이므로 문서 구조도 그래야 한다. - 왜 만들었나를 "CCTV 는 이미 있는데 왜 사고를 못 막나" 세 가지(아무도 안 본다 / 발견이 늦다 / 증명할 자료가 없다)로 세우고, 각각에 대응하는 답을 표로 연결. - 기대효과 신설. 지어낸 ROI 대신 **제품이 스스로 계측해 보여주는 지표**(TTA, 니어미스:사고, 조치 전후 밀도, 오탐율)로 썼다 — 공급자 주장이 아니라 고객 화면의 숫자다. '약속하지 않는 것' 절을 함께 넣었다. 사고를 없애지 못하고, 감지율 100%는 없고, 오탐은 초기에 반드시 난다. 과장은 도입 후에 반드시 되돌아온다. - 설계 제약(감시하지 않는다 / 인터넷 없이 동작한다 / 클라우드를 안 쓴다)을 기능보다 앞에 두었다. 이 제품의 형태는 거기서 나왔다. 수치는 전부 코드와 대조해 교정 - 테스트 535건(pytest 311 + PHPUnit 224), 감사 55건, 감지 17종 + 서버 발행 1종 - "3초 안에 찾아낸다"는 과장이었다. 실제로는 쓰러진 자세가 3초 지속되면 확정이므로 "3초면 알아채고"로 고치고, 근거가 되는 3초를 감지 표에 함께 적었다. 이미지 브리프 신설 (docs/소개서-이미지-브리프.md) - 현장 사진 4장 + 다이어그램 3장의 발주 명세. 각 항목에 "이 이미지가 없으면 전달 안 되는 것", 담을 것, 피할 것, 사양, 캡션안, 우선순위. - 제품 화면 캡처 8장은 이미 확보되어 있어 발주 대상에서 제외. - 개인정보 제약을 최상단에 명시. 얼굴이 식별되는 작업자 사진이 한 장이라도 들어가면 "감시하지 않는다"는 이 제품의 핵심 주장이 무너진다. - 검토했으나 뺀 이미지(쓰러진 순간 프레임, 블러 전/후 비교, 스켈레톤 오버레이)와 그 이유도 기록. 나중에 "왜 없지"가 반복되지 않도록. HTML 은 md-to-html-report 로 재생성(목차·표·콜아웃·인쇄 스타일). 실렌더 확인.
685 lines
34 KiB
HTML
685 lines
34 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>move_detect — 작업장 안전 AI CCTV 프로젝트 소개서</title>
|
|
<style>
|
|
:root {
|
|
--accent: #003478;
|
|
--accent-soft: #d8e0ea;
|
|
--ink: #121417;
|
|
--ink-muted: #4a5160;
|
|
--paper: #ffffff;
|
|
--paper-alt: #f6f7fb;
|
|
--rule: #e3e6ee;
|
|
--callout-bg: #f3f6fc;
|
|
--callout-border: var(--accent);
|
|
--code-bg: #0f172a;
|
|
--code-ink: #e2e8f0;
|
|
--max-w: 920px;
|
|
--font-sans: "Pretendard Variable", "Pretendard", "Noto Sans KR", "Apple SD Gothic Neo",
|
|
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
--font-serif: "Noto Serif KR", "Nanum Myeongjo", Georgia, serif;
|
|
}
|
|
* { box-sizing: border-box; }
|
|
html, body { margin: 0; padding: 0; }
|
|
body {
|
|
font-family: var(--font-sans);
|
|
color: var(--ink);
|
|
background: var(--paper-alt);
|
|
line-height: 1.75;
|
|
font-size: 16px;
|
|
-webkit-font-smoothing: antialiased;
|
|
text-rendering: optimizeLegibility;
|
|
word-break: keep-all;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
.report-shell { max-width: var(--max-w); margin: 0 auto; padding: 64px 32px 96px; background: var(--paper); box-shadow: 0 1px 0 var(--rule); }
|
|
.report-header { border-bottom: 3px solid var(--accent); padding-bottom: 24px; margin-bottom: 40px; }
|
|
.report-header h1 { font-size: 2.2rem; line-height: 1.3; margin: 0 0 12px; color: var(--ink); letter-spacing: -0.01em; }
|
|
.report-header .kicker { font-size: 0.8rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); font-weight: 600; }
|
|
.report-toc { background: var(--paper-alt); border-left: 4px solid var(--accent); padding: 20px 28px; margin: 32px 0 48px; border-radius: 4px; }
|
|
.report-toc h2 { font-size: 0.85rem; letter-spacing: 0.2em; text-transform: uppercase; margin: 0 0 12px; color: var(--accent); }
|
|
.report-toc ol { list-style: none; padding: 0; margin: 0; columns: 2; column-gap: 32px; }
|
|
.report-toc li { margin: 4px 0; font-size: 0.93rem; break-inside: avoid; }
|
|
.report-toc li.toc-l3 { padding-left: 14px; color: var(--ink-muted); }
|
|
.report-toc a { color: inherit; text-decoration: none; border-bottom: 1px dotted transparent; }
|
|
.report-toc a:hover { color: var(--accent); border-bottom-color: var(--accent); }
|
|
h1, h2, h3, h4, h5, h6 { color: var(--ink); letter-spacing: -0.01em; scroll-margin-top: 24px; }
|
|
h2 { font-size: 1.55rem; margin-top: 56px; padding-top: 16px; border-top: 1px solid var(--rule); }
|
|
h3 { font-size: 1.2rem; margin-top: 40px; color: var(--accent); }
|
|
h4 { font-size: 1rem; margin-top: 24px; margin-bottom: 8px; color: var(--ink-muted); letter-spacing: 0.02em; text-transform: uppercase; font-weight: 600; }
|
|
.h4-section { margin: 0 0 12px; }
|
|
.h4-section > p:first-child,
|
|
.h4-section > ul:first-child,
|
|
.h4-section > ol:first-child { margin-top: 4px; }
|
|
.h4-kind-tobe {
|
|
background: var(--accent-soft);
|
|
border-left: 5px solid var(--accent);
|
|
padding: 18px 22px;
|
|
border-radius: 6px;
|
|
margin-bottom: 16px;
|
|
box-shadow: 0 2px 0 rgba(0,52,120,0.04);
|
|
}
|
|
.h4-kind-tobe + h4,
|
|
h3 + h4.h4-kind-tobe-heading { margin-top: 28px; }
|
|
h4:has(+ .h4-kind-tobe) { color: var(--accent); font-weight: 700; letter-spacing: 0.06em; }
|
|
h4:has(+ .h4-kind-action) { color: #b4541b; font-weight: 700; letter-spacing: 0.06em; }
|
|
.h4-kind-action {
|
|
background: #fff6ec;
|
|
border: 1px solid #f2c79b;
|
|
border-left: 5px solid #e27d3c;
|
|
padding: 16px 20px;
|
|
border-radius: 6px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.h4-kind-action ul { margin: 6px 0; padding-left: 1.2em; }
|
|
.h4-kind-action li { margin: 6px 0; }
|
|
.h4-kind-asis, .h4-kind-bench, .h4-kind-default { padding: 0 2px; }
|
|
.h4-kind-bench h5 { margin-top: 0; }
|
|
p { margin: 12px 0; }
|
|
strong { color: var(--ink); font-weight: 700; }
|
|
hr { border: none; border-top: 1px dashed var(--rule); margin: 40px 0; }
|
|
a { color: var(--accent); }
|
|
ul, ol { padding-left: 1.4em; }
|
|
li { margin: 4px 0; }
|
|
blockquote {
|
|
background: var(--callout-bg);
|
|
border-left: 4px solid var(--callout-border);
|
|
padding: 16px 20px;
|
|
margin: 20px 0;
|
|
border-radius: 4px;
|
|
color: var(--ink);
|
|
}
|
|
blockquote p { margin: 6px 0; }
|
|
table { width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 0.92rem; }
|
|
table th, table td { padding: 10px 12px; border-bottom: 1px solid var(--rule); text-align: left; vertical-align: top; }
|
|
table thead th { background: var(--accent); color: #fff; font-weight: 600; border-bottom: none; }
|
|
table tbody tr:nth-child(even) { background: var(--paper-alt); }
|
|
code { background: var(--paper-alt); padding: 1px 6px; border-radius: 3px; font-size: 0.9em; }
|
|
pre { background: var(--code-bg); color: var(--code-ink); padding: 18px; border-radius: 6px; overflow-x: auto; }
|
|
pre code { background: transparent; color: inherit; padding: 0; }
|
|
.mermaid { background: var(--paper); border: 1px solid var(--rule); border-radius: 8px; padding: 20px; margin: 24px 0; text-align: center; overflow-x: auto; break-inside: avoid; }
|
|
.mermaid svg { max-width: 100%; height: auto; }
|
|
.report-figure { margin: 28px 0; padding: 0; background: var(--paper-alt); border: 1px solid var(--rule); border-radius: 8px; overflow: hidden; break-inside: avoid; }
|
|
.report-figure img { display: block; width: 100%; height: auto; }
|
|
.report-figure figcaption { padding: 10px 16px; font-size: 0.85rem; color: var(--ink-muted); background: var(--paper); border-top: 1px solid var(--rule); }
|
|
.report-footer { margin-top: 64px; padding-top: 24px; border-top: 1px solid var(--rule); font-size: 0.85rem; color: var(--ink-muted); }
|
|
.report-unmatched { margin-top: 48px; padding: 20px; background: #fff8e1; border: 1px solid #f0c36d; border-radius: 6px; }
|
|
.report-unmatched h2 { margin-top: 0; border: none; padding: 0; color: #7a5d00; }
|
|
@media (max-width: 720px) {
|
|
.report-shell { padding: 32px 18px 64px; }
|
|
.report-toc ol { columns: 1; }
|
|
.report-header h1 { font-size: 1.6rem; }
|
|
}
|
|
@media print {
|
|
body { background: #fff; font-size: 11pt; }
|
|
.report-shell { max-width: none; box-shadow: none; padding: 0; }
|
|
h2 { page-break-before: always; }
|
|
h2:first-of-type { page-break-before: auto; }
|
|
.report-figure { page-break-inside: avoid; }
|
|
.report-toc { page-break-after: always; }
|
|
a { color: inherit; text-decoration: none; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<main class="report-shell">
|
|
<header class="report-header">
|
|
<div class="kicker">REPORT</div>
|
|
<h1>move_detect — 작업장 안전 AI CCTV 프로젝트 소개서</h1>
|
|
</header>
|
|
<nav class="report-toc"><h2>목차 / Contents</h2><ol><li class="toc-l2"><a href="#1-왜-만들었나">1. 왜 만들었나</a></li><li class="toc-l3"><a href="#1-1-cctv는-이미-있는데-왜-사고를-못-막나">1-1. CCTV는 이미 있는데, 왜 사고를 못 막나</a></li><li class="toc-l3"><a href="#1-2-이-세-가지를-각각-겨냥했습니다">1-2. 이 세 가지를 각각 겨냥했습니다</a></li><li class="toc-l3"><a href="#1-3-설계를-결정한-세-가지-제약">1-3. 설계를 결정한 세 가지 제약</a></li><li class="toc-l2"><a href="#2-무엇을-하는가">2. 무엇을 하는가</a></li><li class="toc-l3"><a href="#2-1-감지-무엇을-알아채는가">2-1. 감지 — 무엇을 알아채는가</a></li><li class="toc-l3"><a href="#2-2-대응-어떻게-사람에게-닿는가">2-2. 대응 — 어떻게 사람에게 닿는가</a></li><li class="toc-l3"><a href="#2-3-증거-나중에-무엇으로-설명하는가">2-3. 증거 — 나중에 무엇으로 설명하는가</a></li><li class="toc-l3"><a href="#2-4-운영-현장이-스스로-굴릴-수-있는가">2-4. 운영 — 현장이 스스로 굴릴 수 있는가</a></li><li class="toc-l2"><a href="#3-기대효과">3. 기대효과</a></li><li class="toc-l3"><a href="#3-1-즉시-달라지는-것">3-1. 즉시 달라지는 것</a></li><li class="toc-l3"><a href="#3-2-시스템이-스스로-측정해-보여주는-효과">3-2. 시스템이 스스로 측정해 보여주는 효과</a></li><li class="toc-l3"><a href="#3-3-관리-부담이-줄어드는-지점">3-3. 관리 부담이 줄어드는 지점</a></li><li class="toc-l3"><a href="#3-4-약속하지-않는-것">3-4. 약속하지 않는 것</a></li><li class="toc-l2"><a href="#4-시스템-구성">4. 시스템 구성</a></li><li class="toc-l3"><a href="#4-1-엣지-노드">4-1. 엣지 노드</a></li><li class="toc-l3"><a href="#4-2-서버대시보드">4-2. 서버·대시보드</a></li><li class="toc-l2"><a href="#5-개인정보-보호와-보안">5. 개인정보 보호와 보안</a></li><li class="toc-l2"><a href="#6-납품과-운영">6. 납품과 운영</a></li><li class="toc-l2"><a href="#7-품질-근거">7. 품질 근거</a></li><li class="toc-l2"><a href="#8-기술-스택">8. 기술 스택</a></li><li class="toc-l2"><a href="#9-현재-한계와-다음-단계">9. 현재 한계와 다음 단계</a></li><li class="toc-l3"><a href="#9-1-모델-확보가-선행되어야-하는-항목">9-1. 모델 확보가 선행되어야 하는 항목</a></li><li class="toc-l3"><a href="#9-2-현장-설치-시-검증할-항목">9-2. 현장 설치 시 검증할 항목</a></li><li class="toc-l3"><a href="#9-3-다음-단계">9-3. 다음 단계</a></li><li class="toc-l2"><a href="#부록-한눈에-보기">부록. 한눈에 보기</a></li></ol></nav>
|
|
<article class="report-body">
|
|
|
|
<blockquote>
|
|
<p><strong>쓰러진 작업자를 3초면 알아채고, 즉시 현장에 울리고, 5분 안에 확인되지 않으면 위로 올립니다.</strong></p>
|
|
<p>실내 공장·창고의 안전사고를 엣지 AI가 실시간으로 감지하고, 감지에서 끝내지 않고 <strong>현장 경광등과<br>
|
|
담당자 통보까지 이어지도록</strong> 만든 온프레미스 안전관리 시스템입니다. 영상은 외부로 나가지<br>
|
|
않습니다 — 사고 순간의 스냅샷 3장(얼굴 자동 블러)만 전달합니다.</p>
|
|
</blockquote>
|
|
<p>버전 1.0.0 · 2026-08-18</p>
|
|
<hr>
|
|
<h2 id="1-왜-만들었나">1. 왜 만들었나</h2>
|
|
<h3 id="1-1-cctv는-이미-있는데-왜-사고를-못-막나">1-1. CCTV는 이미 있는데, 왜 사고를 못 막나</h3>
|
|
<p>대부분의 작업장에는 이미 CCTV가 달려 있습니다. 그런데도 사고가 발생하면 다음 세 가지가<br>
|
|
반복됩니다.</p>
|
|
<p><strong>첫째, 아무도 보고 있지 않습니다.</strong> 카메라 수십 대를 실시간으로 지켜보는 인력은 어디에도<br>
|
|
없습니다. CCTV는 사실상 <strong>사후 확인용 녹화기</strong>로만 쓰이고 있고, 그것은 사고를 막는 장치가<br>
|
|
아니라 사고를 설명하는 장치입니다.</p>
|
|
<p><strong>둘째, 발견이 늦을수록 피해가 커집니다.</strong> 넘어짐 자체보다 위험한 것은 넘어진 뒤 방치되는<br>
|
|
시간입니다. 의식을 잃은 작업자에게 그 시간은 곧 후유장해와 사망 위험의 크기입니다.<br>
|
|
야간·주말·단독 작업 시간대에는 이 공백이 몇 시간 단위로 벌어집니다.</p>
|
|
<p><strong>셋째, 사고 후에 증명할 자료가 없습니다.</strong> 사고가 나면 사업주는 "무엇을 위험으로 보고<br>
|
|
있었고, 어떤 통제를 걸어두었으며, 사건 당시 그것이 작동했는가"를 설명해야 합니다.<br>
|
|
녹화 영상만으로는 그 질문에 답할 수 없습니다.</p>
|
|
<h3 id="1-2-이-세-가지를-각각-겨냥했습니다">1-2. 이 세 가지를 각각 겨냥했습니다</h3>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>문제</th>
|
|
<th>move_detect의 답</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>아무도 안 보고 있다</td>
|
|
<td>AI가 24시간 대신 봅니다. 사람은 <strong>감지된 사건만</strong> 봅니다</td>
|
|
</tr>
|
|
<tr>
|
|
<td>발견이 늦다</td>
|
|
<td>감지 즉시 <strong>현장 경광등</strong>이 울리고, 확인이 없으면 <strong>상위 담당자로 자동 확대</strong>됩니다</td>
|
|
</tr>
|
|
<tr>
|
|
<td>증명할 자료가 없다</td>
|
|
<td>사건마다 증거·통보·조치·위험요인이 묶인 <strong>사고조사 패키지</strong>가 한 번에 나옵니다</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="1-3-설계를-결정한-세-가지-제약">1-3. 설계를 결정한 세 가지 제약</h3>
|
|
<p>이 제품의 형태는 다음 세 제약에서 나왔습니다. 기능보다 이 제약이 먼저입니다.</p>
|
|
<ul>
|
|
<li><strong>작업자를 감시하지 않는다.</strong> 라이브뷰가 없습니다. 영상은 저장도 전송도 하지 않습니다.<br>
|
|
사고 순간의 스냅샷만, 그것도 얼굴을 블러 처리한 뒤에 보냅니다. 근로자 동의를 받기 어려운<br>
|
|
구조로는 현장에 들어갈 수 없습니다.</li>
|
|
<li><strong>인터넷이 끊겨도 동작한다.</strong> 폐쇄망 현장을 전제로 만들었습니다. 정전·회선 장애는 위험이<br>
|
|
오히려 높아지는 시간대인데, 그때 시스템이 함께 죽으면 의미가 없습니다.</li>
|
|
<li><strong>클라우드 GPU를 쓰지 않는다.</strong> 추론은 현장 장비에서 끝납니다. 월 사용료가 없고, 영상이<br>
|
|
외부로 나갈 이유 자체가 없어집니다.</li>
|
|
</ul>
|
|
<hr>
|
|
<h2 id="2-무엇을-하는가">2. 무엇을 하는가</h2>
|
|
<p>기능을 나열하기 전에 구조를 먼저 봅니다. 이 제품은 <strong>하나의 사슬</strong>입니다.</p>
|
|
<pre><code> 감지 대응 증거
|
|
───────── ───────────────── ────────────────────
|
|
17종 이벤트 → 현장 경광등 (즉시) → 사고조사 패키지
|
|
엣지 AI 판정 담당자 통보 증거 3프레임
|
|
얼굴 블러 미확인 시 상위 확대 통보 이력 · 조치 이력
|
|
위·변조 탐지 감사기록
|
|
</code></pre>
|
|
<p>사슬의 어느 한 칸이 비면 나머지가 무의미해집니다. 감지만 있으면 아무도 모르고,<br>
|
|
대응만 있으면 나중에 설명할 수 없습니다.</p>
|
|
<h3 id="2-1-감지-무엇을-알아채는가">2-1. 감지 — 무엇을 알아채는가</h3>
|
|
<p>엣지가 <strong>17종</strong>을 판정하고, 여기에 서버가 발행하는 '미확인 경보 확대' 1종이 더해집니다.<br>
|
|
사람에 대한 것, 구역 규칙에 대한 것, 그리고 <strong>감시 장비 자신</strong>에 대한 것으로 나뉩니다.</p>
|
|
<p><strong>사람의 위험 상태</strong></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>이벤트</th>
|
|
<th>무엇을 잡는가</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>넘어짐</td>
|
|
<td>기립→쓰러짐 전이를 자세로 판정. 쓰러진 자세가 <strong>3초</strong>(조정 가능) 지속되면 확정 — 앉는 동작과 구분</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>넘어짐 후 미동 없음</strong></td>
|
|
<td>쓰러진 뒤 움직임이 없으면 <strong>위급으로 승격</strong> — 의식 소실 의심</td>
|
|
</tr>
|
|
<tr>
|
|
<td>장시간 부동</td>
|
|
<td>자세와 무관하게 오래 움직이지 않는 작업자</td>
|
|
</tr>
|
|
<tr>
|
|
<td>위험 상태 소실</td>
|
|
<td>위험한 상태였던 사람이 화면에서 사라짐 (가림·추락 등)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>넘어질 뻔함 (니어미스)</td>
|
|
<td>사고 직전까지 갔다가 회복 — <strong>사고 전 신호</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>작업자세 부담</td>
|
|
<td>허리·팔 각도 노출 시간 집계 (익명 통계)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><strong>구역 규칙 위반</strong> — 관리자가 카메라 화면 위에 그린 구역에 대해 판정합니다.</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>이벤트</th>
|
|
<th>무엇을 잡는가</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>경고구역 진입 / 제한구역 침입 / 협착구역 침입</td>
|
|
<td>등급별 구역 진입</td>
|
|
</tr>
|
|
<tr>
|
|
<td>단독 작업</td>
|
|
<td>2인 1조 구역에 혼자 있는 상태가 지속</td>
|
|
</tr>
|
|
<tr>
|
|
<td>정원 초과 / 체류 상한 초과</td>
|
|
<td>구역별 인원·체류시간 규칙 위반</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><strong>감시 자신의 건전성</strong> — 이 항목들이 이 제품의 차별점입니다.</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>이벤트</th>
|
|
<th>왜 필요한가</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>카메라 화각 변경</strong></td>
|
|
<td>청소하다 삼각대를 스치면 위험구역이 엉뚱한 바닥을 가리킵니다. 그런데 프레임은 계속 들어오고 화면은 정상으로 보입니다 — 이 <strong>조용한 실패</strong>를 감지합니다</td>
|
|
</tr>
|
|
<tr>
|
|
<td>카메라 가림 / 조도 저하</td>
|
|
<td>렌즈가 덮이거나 조명이 죽어 검출력이 떨어진 상태</td>
|
|
</tr>
|
|
<tr>
|
|
<td>장치 이상 / 감시 성능 저하</td>
|
|
<td>노드·카메라 자체의 장애</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>미확인 경보 확대</strong></td>
|
|
<td>위급 사건을 정해진 시간 동안 아무도 확인하지 않았다는 <strong>사실 자체를 사건으로</strong> 만듭니다</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<blockquote>
|
|
<p>보호구 미착용 · 중장비 근접 · 화재/연기 3종은 감지기 배선과 이벤트 규격이 준비되어 있으나<br>
|
|
<strong>추론 모델이 확보되지 않아 비활성</strong> 상태입니다. 자세한 내용은 9장을 보십시오.</p>
|
|
</blockquote>
|
|
<h3 id="2-2-대응-어떻게-사람에게-닿는가">2-2. 대응 — 어떻게 사람에게 닿는가</h3>
|
|
<p>감지가 화면에만 뜨면 그것은 기록 장치입니다. 이 제품은 세 갈래로 사람에게 닿습니다.</p>
|
|
<ol>
|
|
<li>
|
|
<p><strong>현장 경광등·부저 (즉시, 네트워크 불필요)</strong><br>
|
|
감지한 엣지 노드가 자기 GPIO로 직접 울립니다. 서버도 인터넷도 거치지 않으므로 <strong>회선이<br>
|
|
끊겨도, 서버가 죽어도 동작합니다.</strong> 어떤 현장이든 이것부터 설정하도록 안내합니다.</p>
|
|
</li>
|
|
<li>
|
|
<p><strong>담당자 통보 (메일 · 사내 웹훅/문자 게이트웨이)</strong><br>
|
|
심각도 기준을 채널마다 정할 수 있습니다. 통보에는 <strong>현장 사진이 들어가지 않습니다</strong> —<br>
|
|
링크만 보내고, 사진은 로그인한 사람만 봅니다.</p>
|
|
</li>
|
|
<li>
|
|
<p><strong>미확인 시 자동 확대</strong><br>
|
|
위급 사건이 정해진 시간(기본 5분) 동안 확인되지 않으면 상위 담당자에게 올라갑니다.<br>
|
|
"감지했다"를 "누군가 보게 만들었다"로 바꾸는 장치입니다.</p>
|
|
</li>
|
|
</ol>
|
|
<h3 id="2-3-증거-나중에-무엇으로-설명하는가">2-3. 증거 — 나중에 무엇으로 설명하는가</h3>
|
|
<ul>
|
|
<li><strong>사고조사 패키지 (1클릭)</strong> — 사건 개요와 <strong>대응 소요 시간</strong>, 증거 3프레임,<br>
|
|
<strong>같은 카메라의 전후 30분 타임라인</strong>, 누구에게 언제 통보가 갔는지, 해당 위험요인과 통제<br>
|
|
대책, 그 카메라의 개선 조치 이력, 서명란. 인쇄해 그대로 제출합니다.</li>
|
|
<li><strong>위·변조 탐지 감사기록</strong> — 확인·설정변경·구역편집이 모두 해시로 연결되어 기록됩니다.<br>
|
|
중간을 고치거나 지우면 그 이후 전 구간이 어긋나 <strong>탐지됩니다.</strong></li>
|
|
<li><strong>위험성평가 연계</strong> — 감지 유형별로 어떤 위험요인을 통제하고 있는지 기록하고, 사고조사<br>
|
|
패키지에 함께 실립니다.</li>
|
|
</ul>
|
|
<h3 id="2-4-운영-현장이-스스로-굴릴-수-있는가">2-4. 운영 — 현장이 스스로 굴릴 수 있는가</h3>
|
|
<p>납품 후 고객이 손댈 수 없는 시스템은 결국 꺼집니다.</p>
|
|
<ul>
|
|
<li><strong>감지 임계값 편집</strong> — 허용 범위와 설명이 화면에 붙어 있어 잘못된 값이 저장되지 않습니다</li>
|
|
<li><strong>정비 중 알람 억제</strong> — 계획된 작업 동안 통보만 보류. 사유 필수, 최대 8시간, 자동 만료.<br>
|
|
<strong>감지와 기록은 계속되므로</strong> 그 시간대도 사후에 조사할 수 있습니다</li>
|
|
<li><strong>오탐 관리</strong> — 카메라·유형별 오탐율을 보고 재조정 대상을 고릅니다</li>
|
|
<li><strong>교대 인수인계</strong> — 누가 어떤 미처리 건을 넘겨받았는지 기록</li>
|
|
<li><strong>설비 성능 추이</strong> — "지금 살아 있는가"가 아니라 "점점 나빠지고 있는가"</li>
|
|
<li><strong>설치 점검 화면</strong> — 각 단계가 실제로 동작하는지 조회해서 확인</li>
|
|
</ul>
|
|
<hr>
|
|
<h2 id="3-기대효과">3. 기대효과</h2>
|
|
<h3 id="3-1-즉시-달라지는-것">3-1. 즉시 달라지는 것</h3>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>항목</th>
|
|
<th>도입 전</th>
|
|
<th>도입 후</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>야간·단독 작업 중 쓰러짐</td>
|
|
<td>다음 순찰·교대까지 방치</td>
|
|
<td>감지 즉시 경광등, 미확인 시 상위 확대</td>
|
|
</tr>
|
|
<tr>
|
|
<td>위험구역 관리</td>
|
|
<td>표지판과 교육에 의존</td>
|
|
<td>진입·단독작업·정원초과를 규칙으로 판정</td>
|
|
</tr>
|
|
<tr>
|
|
<td>사고 조사</td>
|
|
<td>녹화 뒤져 반나절</td>
|
|
<td>1클릭 패키지 (전후 맥락·통보·조치 포함)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>CCTV 인력</td>
|
|
<td>봐야 보임</td>
|
|
<td>감지된 사건만 봄</td>
|
|
</tr>
|
|
<tr>
|
|
<td>안전 활동 증빙</td>
|
|
<td>문서로 주장</td>
|
|
<td>시스템 기록으로 제시</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="3-2-시스템이-스스로-측정해-보여주는-효과">3-2. 시스템이 스스로 측정해 보여주는 효과</h3>
|
|
<p><strong>이 제품은 자기 효과를 스스로 계측합니다.</strong> 도입 효과를 공급자 주장이 아니라 고객 화면의<br>
|
|
숫자로 확인할 수 있다는 뜻입니다. 안전 리포트에 다음이 나옵니다.</p>
|
|
<ul>
|
|
<li><strong>평균 대응 시간 (TTA)</strong> — 감지에서 확인까지 걸린 시간. 이 숫자가 줄어드는 것이 곧<br>
|
|
"발견이 빨라졌다"의 증거입니다</li>
|
|
<li><strong>니어미스 : 사고 비율</strong> — 사고 전 신호가 얼마나 먼저 잡히는지. 니어미스가 상대적으로<br>
|
|
많다는 것은 예방이 앞단에서 작동하고 있다는 뜻입니다</li>
|
|
<li><strong>개선 조치 전·후 감지 밀도</strong> — 매트를 깔았더니 그 카메라의 넘어짐이 줄었는가.<br>
|
|
<strong>통계적으로 유의하지 않은 변화는 "판정 보류"로 표시</strong>합니다 — 표본 6건에서 나온<br>
|
|
"33% 개선"을 성과로 적으면 안전회의에서 한 번 반박당하고 그 자료 전체가 신뢰를 잃습니다</li>
|
|
<li><strong>오탐율 추이</strong> — 시스템이 현장에 맞게 조정되고 있는지</li>
|
|
<li><strong>요일×시간 사고 패턴 · 전조 급증 경보</strong> — 인력 배치와 사전 개입의 근거</li>
|
|
</ul>
|
|
<h3 id="3-3-관리-부담이-줄어드는-지점">3-3. 관리 부담이 줄어드는 지점</h3>
|
|
<ul>
|
|
<li>사고조사 자료를 사람이 모으지 않습니다 — 사고 다음 날 반나절을 쓸 수 있는 사람은 없습니다</li>
|
|
<li>위험성평가와 실제 감지가 한 곳에 연결되어 있어 갱신 근거가 자동으로 쌓입니다</li>
|
|
<li>교대 인수인계와 정비 억제가 기록으로 남아, "그때 왜 알람이 없었나"에 답할 수 있습니다</li>
|
|
<li>감사기록 위·변조 탐지로, 제출한 기록의 신뢰성을 별도로 주장할 필요가 없습니다</li>
|
|
</ul>
|
|
<h3 id="3-4-약속하지-않는-것">3-4. 약속하지 않는 것</h3>
|
|
<p>과장은 도입 후 신뢰를 무너뜨리므로 미리 적습니다.</p>
|
|
<ul>
|
|
<li><strong>사고를 없애지 못합니다.</strong> 이 시스템은 사고를 더 빨리 발견하고, 전조를 앞당겨 보여주고,<br>
|
|
대응과 증거를 정리합니다. 사고 자체를 막는 것은 설비·공정·교육이며, 이 시스템은 그 개선의<br>
|
|
<strong>근거를 제공</strong>하는 역할입니다.</li>
|
|
<li><strong>감지율 100%는 없습니다.</strong> 가려짐·역광·극단적 조도에서는 놓칩니다. 그래서 감시 자신의<br>
|
|
건전성(화각 변경·가림·조도)을 별도 이벤트로 감지해 <strong>못 보고 있다는 사실을 알립니다.</strong></li>
|
|
<li><strong>오탐은 초기에 반드시 발생합니다.</strong> 현장마다 조명·동선·작업 자세가 달라, 첫 2~4주는<br>
|
|
임계값 조정 기간으로 잡아야 합니다. 그 조정을 고객이 직접 할 수 있도록 오탐율 통계와<br>
|
|
임계값 편집 화면을 넣었습니다.</li>
|
|
<li><strong>법적 판단을 대신하지 않습니다.</strong> 리포트와 사고조사 패키지는 안전 활동을 뒷받침하는<br>
|
|
보조 자료이며, 공식 재해 통계나 법정 서식을 대체하지 않습니다.</li>
|
|
</ul>
|
|
<hr>
|
|
<h2 id="4-시스템-구성">4. 시스템 구성</h2>
|
|
<pre><code> [카메라 CSI/USB · Pi당 2~4대]
|
|
│
|
|
┌──────────▼──────────────────────────────┐
|
|
│ Raspberry Pi 5 + Hailo-8 (26 TOPS) │ ← 엣지: 자세추정 · 이벤트 판정
|
|
│ · 얼굴 블러 (저장 전) │ · 경광등 GPIO 직접 구동
|
|
│ · 오프라인 큐 (회선 단절 대비) │ · 카메라 무결성 감시
|
|
└──────────┬──────────────────────────────┘
|
|
│ HMAC 서명 POST — 스냅샷 3장 + 메타데이터만 (영상 없음)
|
|
▼
|
|
┌─────────────────────────────────────────┐
|
|
│ 웹 대시보드 (PHP 8 + MySQL) │ ← 일반 웹호스팅에서 동작
|
|
│ 이벤트 콘솔 · 구역 편집 · 안전 리포트 │ 별도 서버 투자 불필요
|
|
│ 안전 관리 · 시스템 설정 · 사고조사 │
|
|
└──────────┬──────────────────────────────┘
|
|
│
|
|
메일 · 사내 웹훅/문자 게이트웨이
|
|
</code></pre>
|
|
<h3 id="4-1-엣지-노드">4-1. 엣지 노드</h3>
|
|
<ul>
|
|
<li>하나의 공유 자세추정 모델로 모든 이벤트를 판정 — 카메라마다 모델을 더 올리지 않습니다</li>
|
|
<li>CSI·USB 카메라 혼용, CPU 폴백 경로 내장</li>
|
|
<li>회선 단절 시 오프라인 큐에 보관 후 복구되면 재전송 (중복 전송은 서버가 제거)</li>
|
|
<li>systemd 상주 + 워치독 + 하트비트 텔레메트리</li>
|
|
<li>감지 타이머는 단조 시계 기반이라 시스템 시각이 바뀌어도 오판하지 않습니다</li>
|
|
</ul>
|
|
<h3 id="4-2-서버대시보드">4-2. 서버·대시보드</h3>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>화면</th>
|
|
<th>누가</th>
|
|
<th>무엇을</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>이벤트</td>
|
|
<td>운영자</td>
|
|
<td>실시간 스트림, 확인·오탐 판정, 날짜 조회, 일괄 처리</td>
|
|
</tr>
|
|
<tr>
|
|
<td>이벤트 상세</td>
|
|
<td>운영자</td>
|
|
<td>증거 3프레임, 판정, 조치 기록, 사고조사 패키지 진입</td>
|
|
</tr>
|
|
<tr>
|
|
<td>구역 설정</td>
|
|
<td>안전관리자</td>
|
|
<td>카메라 화면 위 폴리곤, 등급·점유 규칙, 위험 히트맵</td>
|
|
</tr>
|
|
<tr>
|
|
<td>안전 리포트</td>
|
|
<td>안전관리자</td>
|
|
<td>주간 회의용 지표 한 장 (인쇄)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>안전 관리</td>
|
|
<td>안전관리자</td>
|
|
<td>인수인계 · 정비 억제 · 위험성평가 · 설비 성능</td>
|
|
</tr>
|
|
<tr>
|
|
<td>시스템 설정</td>
|
|
<td>관리자</td>
|
|
<td>통보 경로 · 감지 임계값</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>이 외에 <strong>설치 점검</strong>(구성이 실제로 동작하는지 단계별 확인)과 <strong>사고조사 패키지</strong>(인쇄용<br>
|
|
단일 문서) 화면이 있습니다.</p>
|
|
<hr>
|
|
<h2 id="5-개인정보-보호와-보안">5. 개인정보 보호와 보안</h2>
|
|
<p>작업자 감시 도구로 비치는 순간 현장 도입이 막힙니다. 그래서 프라이버시는 설정이 아니라<br>
|
|
<strong>구조</strong>로 넣었습니다.</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>영역</th>
|
|
<th>적용</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>영상</strong></td>
|
|
<td>라이브뷰 없음, 영상 저장·전송 없음. 사건 스냅샷 3장만</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>얼굴</strong></td>
|
|
<td>저장 전에 자동 블러. 원본은 어디에도 남지 않음</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>접근</strong></td>
|
|
<td>스냅샷은 인증 프록시 경유. 보존기간 경과 시 자동 삭제</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>통보</strong></td>
|
|
<td>알림에 이미지 미포함 — 링크만 전송</td>
|
|
</tr>
|
|
<tr>
|
|
<td>전송 보안</td>
|
|
<td>HMAC 서명 + nonce로 위·변조·재전송 차단, 장치·IP별 rate limit</td>
|
|
</tr>
|
|
<tr>
|
|
<td>인증</td>
|
|
<td>Argon2id, 로그인 잠금(사용자명 열거 차단), 세션 고정 방지</td>
|
|
</tr>
|
|
<tr>
|
|
<td>권한</td>
|
|
<td>역할 기반 접근제어 + 현장 스코프, 전 요청 CSRF</td>
|
|
</tr>
|
|
<tr>
|
|
<td>웹</td>
|
|
<td>CSP nonce (unsafe-inline 없음), DOM 주입은 textContent만</td>
|
|
</tr>
|
|
<tr>
|
|
<td>기록</td>
|
|
<td>감사로그 해시체인 — 수정·삭제·우회삽입 탐지</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<hr>
|
|
<h2 id="6-납품과-운영">6. 납품과 운영</h2>
|
|
<ul>
|
|
<li><strong>웹호스팅 업로드 패키지</strong> — 서버 일체(마이그레이션 8종 포함)를 zip 하나로 업로드,<br>
|
|
설정 파일 한 개만 수정</li>
|
|
<li><strong>Pi 설치 번들</strong> — 온라인 설치와 <strong>폐쇄망 오프라인 번들</strong> 모두 제공.<br>
|
|
런타임 휠·모델·소스를 전부 동봉해 설치 중 네트워크가 필요 없습니다</li>
|
|
<li><strong>동봉 문서</strong> — 설치 안내서 · <strong>역할별 사용 설명서</strong>(실제 화면 캡처 포함 단일 HTML) ·<br>
|
|
변경 내역 · 납품 점검 리포트</li>
|
|
<li><strong>자동 실행 2종</strong> — 통보 디스패처(1분) · 보존기간 정리(일 1회)</li>
|
|
<li><strong>운영 도구</strong> — 백업/복구, 감사기록 무결성 검증, 시연용 데모 데이터 생성</li>
|
|
</ul>
|
|
<hr>
|
|
<h2 id="7-품질-근거">7. 품질 근거</h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>항목</th>
|
|
<th>현황</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>자동화 테스트</td>
|
|
<td><strong>535건</strong> (엣지 Python 311 · 서버 PHP 224), 스킵 0 (하드웨어 항목 제외)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>납품 감사</td>
|
|
<td>1차 43건 + 재감사 12건 = <strong>55건 전량 해소</strong>, 판정 <strong>적합</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>상호운용 검증</td>
|
|
<td>HMAC 골든 벡터로 엣지(Python) ↔ 서버(PHP) 대조</td>
|
|
</tr>
|
|
<tr>
|
|
<td>계층 정합 검증</td>
|
|
<td>감지 유형이 엣지·검증기·DB·화면 네 곳에서 일치하는지 자동 검사</td>
|
|
</tr>
|
|
<tr>
|
|
<td>납품물 검증</td>
|
|
<td>산출물↔소스 패리티, 패키지 내부 클래스 해석·문법 검사, 무결성 해시</td>
|
|
</tr>
|
|
<tr>
|
|
<td>CI</td>
|
|
<td>검증 명령 단일화, 스킵 발생 시 빌드 실패</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<blockquote>
|
|
<p>감사에서 실제로 잡힌 대표 사례: 신규 감지 유형이 서버 검증기에만 누락되어 <strong>감지기가<br>
|
|
구현·배포되고도 아무 이벤트도 남기지 못하던 상태</strong>를 발견해 수정하고, 재발 방지 테스트를<br>
|
|
추가했습니다. 이런 "조용한 실패"를 찾는 것이 이 프로젝트 감사 사이클의 목적입니다.</p>
|
|
</blockquote>
|
|
<hr>
|
|
<h2 id="8-기술-스택">8. 기술 스택</h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>구분</th>
|
|
<th>기술</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>엣지 하드웨어</td>
|
|
<td>Raspberry Pi 5 + AI HAT+ (Hailo-8, 26 TOPS)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>엣지 소프트웨어</td>
|
|
<td>Python, Hailo HEF 자세추정 (CPU 폴백 내장)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>카메라</td>
|
|
<td>CSI (picamera2) · USB (V4L2 MJPEG), Pi당 2~4대</td>
|
|
</tr>
|
|
<tr>
|
|
<td>서버</td>
|
|
<td>PHP 8 + PDO + MySQL — 일반 웹호스팅에서 동작</td>
|
|
</tr>
|
|
<tr>
|
|
<td>프런트엔드</td>
|
|
<td>바닐라 JavaScript (빌드 도구 없음)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>배포</td>
|
|
<td>오프라인 번들 · systemd · zip 업로드 패키지</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<hr>
|
|
<h2 id="9-현재-한계와-다음-단계">9. 현재 한계와 다음 단계</h2>
|
|
<h3 id="9-1-모델-확보가-선행되어야-하는-항목">9-1. 모델 확보가 선행되어야 하는 항목</h3>
|
|
<p>보호구 미착용 · 중장비 근접 · 화재/연기 감지는 <strong>감지기 배선·이벤트 규격·테스트까지 완성되어<br>
|
|
있고 추론 모델만 비어 있습니다.</strong> 라이선스 조건을 만족하는 가중치 확보와 엣지 컴파일이<br>
|
|
선행 조건입니다.</p>
|
|
<p>이 상태를 "곧 됩니다"로 켜두지 않고 <strong>명시적으로 비활성</strong>으로 둔 것은 의도적입니다 —<br>
|
|
켜져 있으면 현장은 감지되고 있다고 믿게 되고, 그 믿음이 가장 위험합니다.</p>
|
|
<h3 id="9-2-현장-설치-시-검증할-항목">9-2. 현장 설치 시 검증할 항목</h3>
|
|
<p>코드로 닫을 수 없고 실장비에서만 확인 가능한 항목입니다. 설치 시 반드시 수행합니다.</p>
|
|
<ul>
|
|
<li>경광등 실제 구동 (배선·극성·유지시간)</li>
|
|
<li>카메라 무결성 임계값을 현장 조명·진동에 맞게 조정</li>
|
|
<li>낙상 판정 타이밍을 실제 영상으로 조정 — 블라인드 조정은 감지 <strong>누락</strong>을 만들 수 있어<br>
|
|
현장 확보 후로 미뤘습니다</li>
|
|
<li>통보 1회 실발송 (시험 발송으로 대상 확인 후)</li>
|
|
</ul>
|
|
<h3 id="9-3-다음-단계">9-3. 다음 단계</h3>
|
|
<ul>
|
|
<li>위 감지 3종 활성화 (모델 확보 시)</li>
|
|
<li>기계 가동 상태 연동 협착 판정 — 협착구역은 기계가 돌 때만 위험합니다</li>
|
|
<li>다현장 통합 운영 (본사 관점 롤업은 이미 제공)</li>
|
|
</ul>
|
|
<hr>
|
|
<h2 id="부록-한눈에-보기">부록. 한눈에 보기</h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th></th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>한 줄 정의</strong></td>
|
|
<td>쓰러진 작업자를 3초면 알아채고, 현장에 즉시 울리고, 5분 안에 확인되지 않으면 위로 올리며, 그 전 과정을 증거로 남기는 시스템</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>핵심 차별점</strong></td>
|
|
<td>① 감지에서 끝나지 않고 <strong>현장 경광등·에스컬레이션까지</strong> ② <strong>감시 자신의 고장</strong>을 감지 ③ <strong>사고조사 패키지 1클릭</strong> ④ 위·변조 탐지 감사기록</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>프라이버시</strong></td>
|
|
<td>라이브뷰·영상 전송 없음 · 얼굴 저장 전 블러 · 알림에 이미지 미포함</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>운영 비용</strong></td>
|
|
<td>클라우드 GPU 없음, 일반 웹호스팅에서 동작</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>감지 유형</strong></td>
|
|
<td>17종 활성 (+ 모델 확보 대기 3종)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>검증</strong></td>
|
|
<td>테스트 535건 · 납품 감사 55건 전량 해소</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</article>
|
|
|
|
<footer class="report-footer">
|
|
생성: md-to-html-report · 이미지 0개 embedded (base64)
|
|
</footer>
|
|
</main>
|
|
</body>
|
|
</html>
|