docs: 문서 스냅샷 아키텍처 계획 + 절곡 문서 매칭 계획

- document-snapshot-architecture-plan.md: B안(HTML 스냅샷) + 구조화 데이터 병행 계획
- mng-bending-document-matching-plan.md: 절곡 중간검사/작업일지 MNG 매칭 계획

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 15:52:27 +09:00
parent 0223c33fd9
commit 334c8f3918
2 changed files with 576 additions and 0 deletions

View File

@@ -0,0 +1,331 @@
# 문서 스냅샷 아키텍처 계획
> **작성일**: 2026-03-06
> **목적**: 문서 보기/인쇄 시 HTML 스냅샷 기반 출력으로 전환 (B안 + 구조화 데이터 병행)
> **상태**: 🔄 진행중
> **영향 범위**: API(저장), React(캡처/전송), MNG(출력)
---
## 현재 진행 상태
| 항목 | 내용 |
|------|------|
| **마지막 완료 작업** | Phase 0+1 (API) + Phase 3 (MNG 출력 로직) |
| **다음 작업** | Phase 2: React HTML 캡처 및 전송 |
| **진행률** | 7/10 (70%) |
| **마지막 업데이트** | 2026-03-06 |
---
## 1. 개요
### 1.1 배경
현재 MNG 문서 보기(`show.blade.php`)는 문서 양식별로 전용 blade partial을 만들어 렌더링한다:
- `bending-inspection-data.blade.php` (절곡 중간검사)
- `bending-worklog.blade.php` (절곡 작업일지)
이 방식의 문제:
1. **확장 불가**: 회사마다 다양한 양식이 존재 → 양식마다 blade 파일 생성 불가
2. **스냅샷 미보장**: 하드코딩된 제품 목록/도면치수가 정책 변경 시 과거 문서를 깨뜨림
3. **이중 렌더링**: React와 MNG에서 동일 문서를 각각 렌더링 → 불일치 발생
### 1.2 목표 아키텍처
```
[React] 문서 저장 시
├── 구조화 데이터 저장 (기존 유지)
│ ├── document_data (EAV 플랫)
│ └── work_order_items.options.inspection_data (JSON 스냅샷)
└── rendered_html 저장 (신규)
└── React가 렌더링한 HTML을 캡처 → documents.rendered_html에 저장
[MNG] 문서 보기 시
├── rendered_html 있으면 → 그대로 출력 (렌더링 로직 0)
└── rendered_html 없으면 → 기존 동적 렌더링 fallback
```
### 1.3 핵심 원칙
```
1. 하나의 view 파일로 모든 문서를 보기 (문서 양식별 blade 파일 금지)
2. rendered_html이 있으면 무조건 그것을 사용 (완전한 스냅샷)
3. 구조화 데이터는 편집/검색/통계용으로 병행 유지
4. React에서만 문서 렌더링 책임 → MNG는 출력만 담당
```
### 1.4 변경 승인 정책
| 분류 | 예시 | 승인 |
|------|------|------|
| 즉시 가능 | blade 템플릿 수정, 기존 partial 정리 | 불필요 |
| 컨펌 필요 | API 저장 로직 변경, React 저장 흐름 변경 | **필수** |
| 금지 | documents 테이블 구조 변경 (이미 rendered_html 존재) | 불필요 |
---
## 2. 현황 분석
### 2.1 DB 현황
`documents` 테이블에 이미 `rendered_html` (LONGTEXT, nullable) 컬럼이 존재:
- 마이그레이션: `api/database/migrations/2026_02_28_100001_add_block_data_to_documents.php`
- 현재 값: 모든 문서에서 NULL (사용 안 됨)
- **DB 변경 불필요**
### 2.2 React 현황
문서 저장 흐름 (`InspectionReportModal.tsx`):
```
handleSave()
├── contentRef.current.getInspectionData() → 구조화 데이터 추출
├── 템플릿 모드: saveInspectionDocument(workOrderId, { data: records })
└── 레거시 모드: saveInspectionData(workOrderId, processType, data)
```
현재 `rendered_html`을 전송하지 않음. 추가 필요:
- 문서 DOM에서 HTML 캡처 → API 전송 시 포함
### 2.3 API 현황
`DocumentService` / `DocumentController`:
- `rendered_html` 필드를 받아서 저장하는 로직 없음
- Document 모델의 `$fillable``rendered_html` 포함 여부 확인 필요
### 2.4 MNG 현황
`show.blade.php`:
- 문서 양식별 조건 분기 + 전용 partial include
- `rendered_html` 출력 로직 없음
- 전용 partial 파일:
- `partials/bending-inspection-data.blade.php`
- `partials/bending-worklog.blade.php`
---
## 3. 작업 범위
### Phase 0: 사전 정리
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 0.1 | API Document 모델 $fillable 확인 및 rendered_html 추가 | ✅ | |
| 0.2 | 기존 절곡 전용 partial 파일 정리 방침 결정 | ✅ | rendered_html 전환 후 삭제 |
### Phase 1: API - rendered_html 저장 지원
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 1.1 | Document 모델 $fillable에 rendered_html 추가 | ✅ | |
| 1.2 | DocumentService store/update에서 rendered_html 저장 | ✅ | |
| 1.3 | StoreRequest/UpdateRequest에 rendered_html 검증 추가 | ✅ | nullable, string |
| 1.4 | WorkOrderService inspection/worklog에 rendered_html 전달 | ✅ | create + update 모두 |
### Phase 2: React - HTML 캡처 및 전송
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 2.1 | 문서 DOM에서 인라인 스타일 포함 HTML 캡처 유틸 | ⏳ | CSS 인라인화 필요 |
| 2.2 | InspectionReportModal 저장 시 rendered_html 포함 전송 | ⏳ | |
| 2.3 | 작업일지 저장 시 rendered_html 포함 전송 | ⏳ | WorkLogModal 등 |
### Phase 3: MNG - 스냅샷 출력
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 3.1 | show.blade.php에 rendered_html 우선 출력 로직 추가 | ✅ | |
| 3.2 | 기존 전용 partial 파일 fallback으로 유지 (과도기) | ✅ | |
| 3.3 | print.blade.php에도 rendered_html 출력 적용 | ⏳ | |
### Phase 4: 검증 및 정리
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 4.1 | 브라우저 검증 (MNG 보기/인쇄) | ⏳ | |
| 4.2 | 기존 전용 partial 파일 삭제 | ⏳ | rendered_html 전환 완료 후 |
---
## 4. 상세 작업 내용
### 4.1 HTML 캡처 방식 (Phase 2.1)
React에서 문서 컨텐츠 영역의 DOM을 캡처할 때 고려사항:
**방법 A: innerHTML 직접 추출 + CSS 인라인화**
```typescript
// 문서 컨텐츠 영역에 ref 부여
const contentRef = useRef<HTMLDivElement>(null);
// 저장 시 HTML 추출
const captureHtml = () => {
const el = contentRef.current;
if (!el) return '';
// Tailwind 클래스 → 인라인 스타일 변환 (또는 스타일시트 포함)
// 방법 1: 계산된 스타일을 인라인으로
// 방법 2: 필요한 Tailwind CSS를 <style> 태그로 포함
return el.innerHTML;
};
```
**방법 B: 자체 CSS 포함 완전한 HTML 조각**
```html
<div class="document-snapshot">
<style>/* 필요한 스타일만 추출 */</style>
<!-- 문서 컨텐츠 -->
</div>
```
**권장: 방법 B** — MNG에서 Tailwind가 로드되어 있으므로, Tailwind 클래스를 그대로 사용하되 MNG에 없는 커스텀 스타일만 `<style>` 태그로 포함. MNG도 Tailwind를 사용하므로 대부분의 클래스가 호환됨.
### 4.2 MNG 출력 구조 (Phase 3.1)
```blade
{{-- show.blade.php --}}
@if($document->rendered_html)
{{-- 스냅샷 모드: React가 생성한 HTML 그대로 출력 --}}
<div class="document-snapshot-container">
{!! $document->rendered_html !!}
</div>
@else
{{-- 동적 모드: 기존 템플릿 기반 렌더링 (fallback) --}}
@include('documents.partials.dynamic-render')
@endif
```
### 4.3 스타일 호환성 전략
| 항목 | React (Tailwind) | MNG (Tailwind) | 호환성 |
|------|------------------|----------------|--------|
| 기본 클래스 | px-2, py-1, border 등 | 동일 | 완전 호환 |
| 반응형 | sm:, md:, lg: | inline style 정책 | 주의 필요 |
| 커스텀 컴포넌트 | shadcn/ui | 없음 | `<style>` 포함 필요 |
**결론**: React에서 문서 영역은 순수 HTML+Tailwind로 렌더링 (shadcn 컴포넌트 미사용) → MNG 호환성 높음.
단, `@media` 쿼리나 MNG에서 빌드되지 않은 Tailwind 클래스가 있을 수 있으므로 필요 시 인라인 스타일 변환.
### 4.4 XSS 보안 고려
`{!! !!}` (unescaped output) 사용 시 XSS 위험:
- `rendered_html`**자체 시스템(React)에서만 생성** → 외부 입력 아님
- API 저장 시 **sanitize** 처리 권장 (script 태그, on* 이벤트 제거)
- 또는 CSP(Content Security Policy)로 인라인 스크립트 차단
---
## 5. 참고 파일
### React (수정 대상)
- `react/src/components/production/WorkOrders/documents/InspectionReportModal.tsx` — 저장 흐름
- `react/src/components/production/WorkOrders/documents/BendingInspectionContent.tsx` — 검사 문서 렌더링
- `react/src/components/production/WorkOrders/documents/BendingWorkLogContent.tsx` — 작업일지 렌더링
- `react/src/components/production/WorkOrders/documents/bending/` — 절곡 섹션 컴포넌트들
### API (수정 대상)
- `api/app/Models/Documents/Document.php` — $fillable
- `api/app/Services/DocumentService.php` — store/update
- `api/app/Http/Requests/Documents/StoreRequest.php` — 검증
- `api/app/Http/Requests/Documents/UpdateRequest.php` — 검증
### MNG (수정 대상)
- `mng/resources/views/documents/show.blade.php` — 메인 보기
- `mng/resources/views/documents/print.blade.php` — 인쇄
- `mng/resources/views/documents/partials/bending-inspection-data.blade.php` — 삭제 예정
- `mng/resources/views/documents/partials/bending-worklog.blade.php` — 삭제 예정
- `mng/app/Http/Controllers/DocumentController.php` — show()
### DB
- `api/database/migrations/2026_02_28_100001_add_block_data_to_documents.php` — rendered_html 컬럼 (이미 존재)
### 문서
- `docs/features/documents/README.md` — 문서관리 시스템
- `docs/system/database/documents.md` — DB 스키마
---
## 6. 의존성 및 순서
```
Phase 0 (사전 정리)
Phase 1 (API: rendered_html 저장)
Phase 2 (React: HTML 캡처 + 전송) ← Phase 1 완료 필요
Phase 3 (MNG: 스냅샷 출력) ← Phase 2 완료 후 데이터 존재
Phase 4 (검증 + 정리) ← 모든 Phase 완료 후
```
Phase 1과 Phase 3의 MNG 코드 수정은 병렬 가능 (fallback 유지).
단, 실제 데이터가 있어야 검증 가능하므로 Phase 2 완료 후 통합 검증.
---
## 7. 리스크 및 대응
| 리스크 | 영향 | 대응 |
|--------|------|------|
| HTML 용량 | 문서당 50-200KB, 수만 건 시 GB | LONGTEXT 이미 사용, 필요 시 gzip 압축 |
| Tailwind 클래스 불일치 | MNG에서 일부 스타일 깨짐 | 인라인 스타일 변환 또는 MNG Tailwind 빌드에 포함 |
| XSS | rendered_html에 악성 코드 | API에서 sanitize, CSP 정책 |
| 과도기 fallback | rendered_html 없는 기존 문서 | 기존 동적 렌더링 유지 |
| React 미경유 문서 | MNG에서만 생성된 문서 | MNG 저장 시에도 rendered_html 생성 검토 |
---
## 8. 변경 이력
| 날짜 | 항목 | 변경 내용 | 파일 | 승인 |
|------|------|----------|------|------|
| 2026-03-06 | - | 계획 문서 작성 | - | - |
---
## 9. 검증 결과
> 작업 완료 후 이 섹션에 검증 결과 추가
### 9.1 성공 기준
| 기준 | 달성 | 비고 |
|------|------|------|
| React 저장 시 rendered_html이 documents 테이블에 저장 | ⏳ | |
| mng.sam.kr/documents/36 에서 rendered_html로 문서 출력 | ⏳ | |
| mng.sam.kr/documents/39 에서 rendered_html로 문서 출력 | ⏳ | |
| rendered_html 없는 기존 문서가 기존대로 렌더링 | ⏳ | |
| 인쇄 시에도 스냅샷 기반 출력 | ⏳ | |
| 양식별 전용 blade 파일 없이 동작 | ⏳ | |
---
## 10. 자기완결성 점검 결과
### 10.1 체크리스트 검증
| # | 검증 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 1 | 작업 목적이 명확한가? | ✅ | 스냅샷 기반 문서 출력 |
| 2 | 성공 기준이 정의되어 있는가? | ✅ | 9.1 참조 |
| 3 | 작업 범위가 구체적인가? | ✅ | 4 Phase, 10개 작업 |
| 4 | 의존성이 명시되어 있는가? | ✅ | 6. 의존성 참조 |
| 5 | 참고 파일 경로가 정확한가? | ✅ | 5. 참고 파일 |
| 6 | 단계별 절차가 실행 가능한가? | ✅ | 3. 작업 범위 |
| 7 | 검증 방법이 명시되어 있는가? | ✅ | 9.1 성공 기준 |
| 8 | 모호한 표현이 없는가? | ✅ | |
### 10.2 새 세션 시뮬레이션 테스트
| 질문 | 답변 가능 | 참조 섹션 |
|------|:--------:|----------|
| Q1. 이 작업의 목적은 무엇인가? | ✅ | 1.1 배경 |
| Q2. 어디서부터 시작해야 하는가? | ✅ | Phase 0 → 1 → 2 → 3 |
| Q3. 어떤 파일을 수정해야 하는가? | ✅ | 5. 참고 파일 |
| Q4. 작업 완료 확인 방법은? | ✅ | 9.1 성공 기준 |
| Q5. 막혔을 때 참고 문서는? | ✅ | 5. 참고 파일, docs/ |
---
*이 문서는 /plan 스킬로 생성되었습니다.*

View File

@@ -0,0 +1,245 @@
# MNG 절곡 문서 React 매칭 계획
> **작성일**: 2026-03-05
> **목적**: MNG 절곡 문서(중간검사성적서 #36, 작업일지 #39)의 상세보기를 React와 동일하게 수정
> **상태**: 🔄 진행중
> **영향 범위**: mng만 (React/API 변경 없음)
---
## 현재 진행 상태
| 항목 | 내용 |
|------|------|
| **마지막 완료 작업** | Task 2.2: 절곡 작업일지 전용 렌더링 블록 추가 |
| **다음 작업** | 브라우저 검증 (사용자 확인 필요) |
| **진행률** | 5/6 (83%) |
| **마지막 업데이트** | 2026-03-05 |
---
## 1. 개요
### 1.1 배경
MNG(`mng.sam.kr/documents/36`, `/documents/39`)에서 절곡 문서의 상세보기가 React(`dev.sam.kr/production/worker-screen` > 절곡공정)와 다르다.
- **MNG**: DB 템플릿(`document_templates`, `document_template_columns`)을 동적으로 읽어 범용 렌더링
- **React**: 전용 하드코딩 컴포넌트(`BendingInspectionContent.tsx`, `BendingWorkLogContent.tsx`)로 렌더링
React가 더 상세하고 정확하므로, MNG를 React에 맞춰 수정한다.
### 1.2 핵심 원칙
- MNG only 수정 (React/API 변경 없음)
- DB 템플릿 컬럼 수정 + show.blade.php 전용 렌더링 블록 추가
- 기존 범용 렌더링 로직은 유지 (다른 문서에 영향 없도록)
### 1.3 변경 승인 정책
| 분류 | 예시 | 승인 |
|------|------|------|
| 즉시 가능 | blade 템플릿 수정, DB 시더/컬럼 업데이트 | 불필요 |
| 컨펌 필요 | DocumentController 로직 변경, 새 쿼리 추가 | **필수** |
| 금지 | 테이블 구조 변경, API 엔드포인트 변경 | 별도 협의 |
---
## 2. 차이점 분석
### 2.1 중간검사성적서 (#36) - 중간검사 DATA 테이블
**React 컬럼 구조** (`BendingInspectionContent.tsx`):
| 컬럼 | 타입 | 비고 |
|------|------|------|
| 분류 | text | KWE01 등 제품코드 |
| 제품명 | text | 가이드레일, 케이스 등 |
| 타입 | text | 벽면형, 측면형 등 |
| 겉모양/절곡상태 | check | 양호/불량 체크 |
| 길이 - 도면치수 | text | 설계값 |
| 길이 - 측정값 | input | 입력값 |
| 너비 - 도면치수 | text | 설계값 |
| 너비 - 측정값 | input | 입력값 |
| 간격 - 포인트 | text | 1~5 등 |
| 간격 - 도면치수 | text | 설계값 |
| 간격 - 측정값 | input | 입력값 |
| 판정 | auto | 적/부 자동판정 |
**핵심 차이**:
- React는 **7개 제품** x **다중 gapPoints**(간격 측정점)로 rowSpan 사용
- MNG 현재 DB에는 "간격" 컬럼, "판정" 컬럼 없음
- MNG "분류/제품명"이 하나로 합쳐져 있을 수 있음
**React 제품 목록** (INITIAL_PRODUCTS):
1. 가이드레일 벽면형 (gapPoints: 5개)
2. 가이드레일 측면형 (gapPoints: 5개)
3. 케이스 (gapPoints: 2개)
4. 하단마감재 (gapPoints: 2개)
5. 하단L-BAR (gapPoints: 1개)
6. 연기차단재 W50 (gapPoints: 1개)
7. 연기차단재 W80 (gapPoints: 2개)
### 2.2 작업일지 (#39) - 절곡 전용 구조
**React 구조** (`BendingWorkLogContent.tsx`):
```
헤더: "작업일지 (절곡)" + 문서번호/작성일자 + 결재란
신청업체/신청내용 테이블 (수주일, 현장명, 수주처, 작업일자, 담당자, LOT NO, 연락처, 생산담당자, 출고예정일)
제품 정보 테이블 (제품명, 재질, 마감, 유형)
4개 카테고리 섹션:
1. GuideRailSection (가이드레일 벽면형/측면형)
2. BottomBarSection (하단마감재)
3. ShutterBoxSection (셔터박스)
4. SmokeBarrierSection (연기차단재 W50/W80)
생산량 합계 [kg] (SUS/EGI)
비고
```
**핵심 차이**:
- MNG 현재: 범용 work_order_items 플랫 테이블 (line 137, 섹션 없는 문서)
- React: 절곡 전용 4개 카테고리 섹션 + 제품정보 + 생산량합계
- React는 `bendingInfo` 데이터(work_order.options.bending_info)를 사용
- MNG Controller에서 bending_info를 아직 view에 전달하지 않음
---
## 3. 작업 범위
### Phase 1: 중간검사성적서 (#36)
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 1.1 | 현재 DB 템플릿 컬럼 조회 (tinker) | ✅ | template_id=60, 7컬럼 (간격/판정 포함) |
| 1.2 | show.blade.php 절곡 검사 전용 렌더링 블록 추가 | ✅ | partials/bending-inspection-data.blade.php |
| 1.3 | 브라우저 검증 | ⏳ | mng.sam.kr/documents/36 |
### Phase 2: 작업일지 (#39)
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 2.1 | DocumentController에 bending_info 전달 추가 | ✅ | work_order.options에서 추출 |
| 2.2 | show.blade.php 절곡 작업일지 전용 렌더링 블록 추가 | ✅ | partials/bending-worklog.blade.php |
| 2.3 | 브라우저 검증 | ⏳ | mng.sam.kr/documents/39 |
---
## 4. 상세 작업 내용
### 4.1 Task 1.2: show.blade.php 절곡 검사 전용 블록
**위치**: `show.blade.php` 섹션 렌더링 영역 (line ~400)
**조건**: template category가 '절곡' 또는 template name에 '절곡' 포함
**렌더링 구조**:
```html
<table>
<thead>
<tr>
<th rowSpan=2>분류</th>
<th rowSpan=2>제품명</th>
<th rowSpan=2>타입</th>
<th rowSpan=2>겉모양/절곡상태</th>
<th colSpan=2>길이</th>
<th colSpan=2>너비</th>
<th colSpan=3>간격</th>
<th rowSpan=2>판정</th>
</tr>
<tr>
<th>도면치수</th><th>측정값</th>
<th>도면치수</th><th>측정값</th>
<th>포인트</th><th>도면치수</th><th>측정값</th>
</tr>
</thead>
<tbody>
<!-- 각 제품별 gapPoints 수만큼 행 (rowSpan 사용) -->
</tbody>
</table>
```
**데이터 소스**: `document_data` EAV + INITIAL_PRODUCTS 정적 구조
- section_id, column_id, row_index, field_key로 조회
- 간격 데이터: field_key `gap_point_{n}`, `gap_design_{n}`, `gap_measured_{n}`
### 4.2 Task 2.1: Controller bending_info 전달
**파일**: `mng/app/Http/Controllers/DocumentController.php` show()
**추가 로직**:
```php
// 절곡 작업일지용: bending_info 추출
$bendingInfo = null;
if ($workOrder) {
$woOptions = json_decode($workOrder->options, true) ?? [];
$bendingInfo = $woOptions['bending_info'] ?? null;
}
```
**view 전달**: `'bendingInfo' => $bendingInfo`
### 4.3 Task 2.2: show.blade.php 절곡 작업일지 전용 블록
**위치**: `show.blade.php` line ~137 (작업일지 전용 영역)
**조건**: 절곡 공정인 경우 (template name에 '절곡' 포함 또는 공정 확인)
**렌더링 구조**:
1. 신청업체/신청내용 테이블
2. 제품 정보 테이블 (제품명, 재질, 마감, 유형)
3. 4개 카테고리 섹션 (가이드레일, 하단마감재, 셔터박스, 연기차단재)
4. 생산량 합계 [kg] (SUS/EGI)
5. 비고
**PHP 유틸 함수 필요**:
- `getMaterialMapping($productCode, $finishMaterial)` - React utils.ts 포팅
- `calculateProductionSummary($bendingInfo, $mapping)` - React utils.ts 포팅
---
## 5. 참고 파일
### React (타겟 - 읽기 전용)
- `react/src/components/production/WorkOrders/documents/BendingInspectionContent.tsx` (547행)
- `react/src/components/production/WorkOrders/documents/BendingWorkLogContent.tsx` (207행)
- `react/src/components/production/WorkOrders/documents/bending/types.ts`
- `react/src/components/production/WorkOrders/documents/bending/utils.ts`
- `react/src/components/production/WorkOrders/documents/bending/GuideRailSection.tsx`
- `react/src/components/production/WorkOrders/documents/bending/BottomBarSection.tsx`
- `react/src/components/production/WorkOrders/documents/bending/ShutterBoxSection.tsx`
- `react/src/components/production/WorkOrders/documents/bending/SmokeBarrierSection.tsx`
- `react/src/components/production/WorkOrders/documents/bending/ProductionSummarySection.tsx`
### MNG (수정 대상)
- `mng/resources/views/documents/show.blade.php` (메인 렌더링)
- `mng/app/Http/Controllers/DocumentController.php` (show 메서드)
### DB 참고
- `mng/database/seeders/MidInspectionTemplateSeeder.php` (절곡 검사 템플릿)
- `mng/database/seeders/WorkLogTemplateSeeder.php` (절곡 작업일지 템플릿)
### 문서
- `docs/features/documents/README.md` - 문서관리 시스템
- `docs/system/database/documents.md` - DB 스키마
- `docs/dev/dev_plans/document-system-mid-inspection.md` - 중간검사 계획
- `docs/dev/dev_plans/document-system-work-log.md` - 작업일지 계획
---
## 6. 변경 이력
| 날짜 | 항목 | 변경 내용 | 파일 | 승인 |
|------|------|----------|------|------|
| 2026-03-05 | - | 계획 문서 작성 | - | - |
---
## 7. 검증 결과
> 작업 완료 후 이 섹션에 검증 결과 추가
### 7.1 성공 기준
| 기준 | 달성 | 비고 |
|------|------|------|
| mng.sam.kr/documents/36 검사 DATA 테이블이 React와 동일 구조 | ⏳ | rowSpan, 간격, 판정 포함 |
| mng.sam.kr/documents/39 작업일지가 React와 동일 구조 | ⏳ | 4개 카테고리, 생산량합계 포함 |
| 기존 다른 문서 렌더링에 영향 없음 | ⏳ | 조건 분기로 절곡 전용만 |