프로젝트 8개 차원 감사(종합 82/100)에서 확정된 상위 3건 수정.
1. 개선 조치(move_actions)가 유일하게 site 스코프 규율에서 이탈 — 스코프 운영자가
타 현장의 조치 기록(카메라 ID·메모·작성자)을 목록에서 읽고, 타 현장 카메라에
조치를 기록해 그 현장 리포트의 전후 효과 지표를 오염시킬 수 있었다.
- move_actions.site 컬럼 + (site, taken_at) 인덱스, 기존 행 백필 마이그레이션
- 카메라 소유 현장은 이벤트에서 해석 (move_cameras는 등록 플로우가 없어 항상 비어 있음)
- 오타 카메라는 400: 전후 효과가 영원히 0/0이 되는 조치를 애초에 못 만들게 한다
- 타 현장 카메라는 404: 존재 여부를 숨기는 기존 규약 유지
2. README-UPLOAD 업그레이드 절차가 마이그레이션 7종 중 1종만 지시했다. move_ 접두
리네임을 건너뛰면 이후 전부 실패하고 전 요청이 500이 된다 — 순서·적용조건·재실행
비안전성을 표로 명시. 문서 4곳의 테이블 수(10→11)·비프리픽스 표기도 정정.
3. 두 납품 번들 재생성: 8/6 이후 4개 기능 커밋이 반영되지 않아 Report/Export/Actions
컨트롤러와 8/7 마이그레이션이 빠진 채였다. 엣지 소스 패리티도 회복.
검증: pytest 235 passed / PHPUnit 147 passed (PDO 4 skip), 번들 산출물 내부 검증
(28 클래스 해석·전 파일 php -l·SHA256SUMS 55행·휠 11개·HEF 다이제스트 일치).
The operator's daily clicks become durable assets:
Label export (GET /api/export/labels?days=N, JSONL download):
- Every 확인/오탐 click is a human verdict on a detection, and each verdict
carries a blurred 3-frame evidence timeline. The export turns that into a
dataset: one JSON line per event with type/severity/camera/zone/metrics/
spatial, label (confirmed | false_positive | unreviewed), labeled_by, and
snapshot uuids (images fetched via /snap, which re-checks session + site).
ergo_report rows are excluded - statistics are not labelable detections.
- Admin-only ('manage_compliance'): bulk export of detection history is a
compliance decision, not an operator convenience. Site scope applies.
- This is where the deferred P1-C evaluation set will come from for free.
Improvement actions (move_actions + GET/POST /api/actions):
- Record a site fix against a camera ("미끄럼 방지 매트 설치"); the report's
new card compares detection density over EQUAL windows before/after the
fix (capped 30d; under 3 days shows "측정 중" - two days of data is noise,
not a verdict). Improvement shows accent, worsening shows red - the card
reports honestly in both directions, which is exactly what makes the
improvement numbers credible.
- Future timestamps and >1y-old entries are rejected (the comparison could
not be fair). Recording needs edit_zones + CSRF.
Verified: PHPUnit 145 pass (5 new: export perm gate + line shape/labels/
snapshot join, action validation, equal-window effect math, pending state)
+ Chrome real-render (action card with better/worse/pending rows, export
link, no console errors).