Files
sam-docs/dev/dev_plans/document-snapshot-architecture-plan.md
권혁성 334c8f3918 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>
2026-03-06 15:52:27 +09:00

12 KiB

문서 스냅샷 아키텍처 계획

작성일: 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 모델의 $fillablerendered_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 인라인화

// 문서 컨텐츠 영역에 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 조각

<div class="document-snapshot">
  <style>/* 필요한 스타일만 추출 */</style>
  <!-- 문서 컨텐츠 -->
</div>

권장: 방법 B — MNG에서 Tailwind가 로드되어 있으므로, Tailwind 클래스를 그대로 사용하되 MNG에 없는 커스텀 스타일만 <style> 태그로 포함. MNG도 Tailwind를 사용하므로 대부분의 클래스가 호환됨.

4.2 MNG 출력 구조 (Phase 3.1)

{{-- 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 스킬로 생성되었습니다.