- 탭별 기능 (문서목록, 서식관리, FQC현황) - EAV 데이터 저장 패턴 상세 설명 - 서식 빌더 (Legacy/Block) 아키텍처 - 결재 워크플로우 및 자재 LOT 추적 - README에 관련 문서 링크 추가
29 KiB
MNG 문서관리 시스템 상세 기술 명세
작성일: 2026-03-06 상태: 운영 중 프로젝트: SAM MNG (관리자 웹) 관련: README.md (API 명세)
1. 개요
1.1 목적
블라인드/스크린 제조 현장의 검사 성적서, 작업일지, 수입검사 기록 등 품질/생산 문서를 전자화하여 관리하는 시스템. 문서 양식(Template)을 정의하면 EAV 패턴으로 데이터를 동적 저장하며, 다단계 결재 워크플로우를 지원한다.
1.2 핵심 특징
| 특징 | 설명 |
|---|---|
| EAV 패턴 | 양식별로 다른 필드를 하나의 document_data 테이블에 저장 |
| 2가지 양식 빌더 | 레거시 빌더 (DB 정규화) + 블록 빌더 (A4 JSON 스키마) |
| 결재 워크플로우 | 작성 → 검토 → 승인 (다단계 순차 결재) |
| 자동 데이터 매핑 | 작업지시서/수주 데이터에서 기본필드 자동 채움 |
| 다형성 연결 | work_order, sales_order 등 다양한 모델과 연결 |
| 자재 LOT 추적 | 검사 문서에서 투입 자재의 LOT 이력 조회 |
1.3 문서 구조
| 문서 | 설명 |
|---|---|
| README.md | API 엔드포인트, 모델 요약, FormRequest |
| 이 문서 | MNG 화면별 상세, 동작원리, 데이터 흐름 |
2. 메뉴/탭 구조
생산 관리
└── 문서관리
├── 문서 목록 /documents ← 문서 검색/필터/관리
├── 새 문서 작성 /documents/create ← 템플릿 선택 → 폼 입력
├── 문서 상세 /documents/{id} ← 읽기 전용 + 결재 현황
├── 문서 수정 /documents/{id}/edit ← DRAFT/REJECTED만
├── 인쇄 /documents/{id}/print ← 성적서 인쇄용
│
└── 문서양식 관리
├── 양식 목록 /document-templates ← 양식 검색/관리
├── 새 양식 (레거시) /document-templates/create ← 레거시 빌더
├── 양식 수정 /document-templates/{id}/edit ← 자동 빌더 판별
├── 양식 디자이너 /document-templates/block-create ← 블록 빌더
└── 블록 수정 /document-templates/{id}/block-edit ← 블록 빌더 수정
3. 파일 구조
mng/
├── app/Http/Controllers/
│ ├── DocumentController.php ← 문서 CRUD 화면
│ └── DocumentTemplateController.php ← 양식 관리 화면
├── app/Models/Documents/
│ ├── Document.php ← 문서 모델
│ ├── DocumentApproval.php ← 결재 단계
│ ├── DocumentData.php ← EAV 데이터
│ ├── DocumentTemplate.php ← 양식 마스터
│ └── ... (기타 템플릿 관련 모델)
└── resources/views/
├── documents/
│ ├── index.blade.php ← 문서 목록
│ ├── edit.blade.php ← 문서 작성/수정
│ ├── show.blade.php ← 문서 상세
│ └── print.blade.php ← 인쇄 전용
└── document-templates/
├── index.blade.php ← 양식 목록
├── edit.blade.php ← 레거시 빌더
├── block-editor.blade.php ← 블록 빌더
└── partials/
├── block-palette.blade.php ← 블록 타입 목록
├── block-canvas.blade.php ← 편집 캔버스
└── block-properties.blade.php ← 속성 패널
4. 데이터베이스 아키텍처
4.1 테이블 관계도
document_templates (양식 마스터)
├── 1:N → document_template_approval_lines (결재선 정의)
├── 1:N → document_template_basic_fields (기본필드 정의)
├── 1:N → document_template_sections (섹션 정의)
│ └── 1:N → document_template_section_items (검사항목)
├── 1:N → document_template_columns (테이블 컬럼 정의)
├── 1:N → document_template_section_fields (섹션 필드)
├── 1:N → document_template_links (외부 연결 정의)
│ └── 1:N → document_template_link_values (템플릿 레벨 연결값)
│
└── 1:N → documents (문서 인스턴스)
├── 1:N → document_approvals (결재 진행)
├── 1:N → document_data (EAV 필드값)
├── 1:N → document_attachments (첨부파일)
└── 1:N → document_links (문서 레벨 연결)
4.2 documents (문서)
| 컬럼 | 타입 | 설명 |
|---|---|---|
id |
BIGINT PK | |
tenant_id |
BIGINT FK | 테넌트 격리 |
template_id |
BIGINT FK | 사용 양식 |
document_no |
VARCHAR UNIQUE | 문서번호 (자동 채번) |
title |
VARCHAR | 문서 제목 |
status |
VARCHAR(20) | 상태 (5가지) |
linkable_type |
VARCHAR NULL | 다형성 모델 타입 |
linkable_id |
BIGINT NULL | 다형성 모델 ID |
submitted_at |
TIMESTAMP NULL | 결재 요청 일시 |
completed_at |
TIMESTAMP NULL | 결재 완료 일시 |
created_by |
BIGINT FK | 작성자 |
deleted_at |
TIMESTAMP NULL | 소프트 삭제 |
인덱스: (tenant_id, status), document_no, (linkable_type, linkable_id)
4.3 document_data (EAV 필드값)
| 컬럼 | 타입 | 설명 |
|---|---|---|
id |
BIGINT PK | |
document_id |
BIGINT FK | 소속 문서 |
section_id |
BIGINT FK NULL | 소속 섹션 (NULL=기본필드) |
column_id |
BIGINT FK NULL | 소속 컬럼 (테이블 데이터용) |
row_index |
INT | 테이블 행 번호 (기본: 0) |
field_key |
VARCHAR | 필드 식별자 (bf_1, cf_2, col_3) |
field_value |
TEXT NULL | 실제 값 |
인덱스: (document_id, section_id), (document_id, field_key)
4.4 document_approvals (결재)
| 컬럼 | 타입 | 설명 |
|---|---|---|
id |
BIGINT PK | |
document_id |
BIGINT FK | 소속 문서 |
user_id |
BIGINT FK | 결재자 |
step |
INT | 결재 순서 (1, 2, 3...) |
role |
VARCHAR | 역할 (작성, 검토, 승인) |
status |
VARCHAR(20) | PENDING / APPROVED / REJECTED |
comment |
TEXT NULL | 결재 의견 |
acted_at |
TIMESTAMP NULL | 처리 일시 |
인덱스: (document_id, step), (user_id, status)
4.5 document_attachments (첨부파일)
| 컬럼 | 타입 | 설명 |
|---|---|---|
document_id |
BIGINT FK | 소속 문서 |
file_id |
BIGINT FK | File 모델 연결 |
attachment_type |
VARCHAR | general, signature, image, reference |
description |
VARCHAR NULL | 설명 |
created_by |
BIGINT FK | 업로드자 |
5. 양식(Template) 시스템
5.1 두 가지 빌더 방식
| 방식 | 필드명 | 저장 구조 | UI | 상태 |
|---|---|---|---|---|
| 레거시 빌더 | builder_type = null |
정규화 테이블들 | edit.blade.php |
기존 양식용 |
| 블록 빌더 | builder_type = 'block' |
schema JSON |
block-editor.blade.php |
신규 양식용 |
자동 판별 로직:
// DocumentTemplateController::edit()
if ($template->isBlockBuilder()) {
return $this->blockEdit($id); // block-editor.blade.php
} else {
return view('document-templates.edit'); // 레거시
}
5.2 양식 마스터 (document_templates)
| 컬럼 | 타입 | 설명 |
|---|---|---|
name |
VARCHAR | 양식명 (예: "제품검사 성적서") |
category |
VARCHAR | 분류 (common_codes 기반) |
title |
VARCHAR NULL | 문서 제목 템플릿 |
company_name |
VARCHAR NULL | 회사명 |
company_address |
VARCHAR NULL | 회사 주소 |
company_contact |
VARCHAR NULL | 연락처 |
footer_remark_label |
VARCHAR NULL | 비고란 라벨 |
footer_judgement_label |
VARCHAR NULL | 판정란 라벨 |
footer_judgement_options |
JSON NULL | 판정 선택지 (적합/부적합) |
builder_type |
VARCHAR NULL | block 또는 NULL |
schema |
JSON NULL | 블록 빌더 JSON 스키마 |
page_config |
JSON NULL | 페이지 설정 (A4, 여백 등) |
is_active |
BOOLEAN | 활성 여부 |
5.3 레거시 빌더 구성 요소
결재선 (document_template_approval_lines)
step 1: 작성 (작성자 본인)
step 2: 검토 (팀장)
step 3: 승인 (부장)
| 컬럼 | 설명 |
|---|---|
name |
라벨 (작성, 검토, 승인) |
dept |
부서 |
role |
역할 |
sort_order |
순서 |
기본필드 (document_template_basic_fields)
문서 상단의 고정 필드 영역.
| 컬럼 | 설명 |
|---|---|
label |
필드 라벨 (품명, LOT NO, 납기일 등) |
field_key |
식별자 (EAV 저장 시 사용) |
field_type |
입력 타입 (text, date, number, item_search) |
default_value |
기본값 |
sort_order |
순서 |
EAV 저장 시 field_key 패턴:
bf_1 → 기본필드 ID 1 (예: 품명)
bf_2 → 기본필드 ID 2 (예: LOT NO)
bf_3 → 기본필드 ID 3 (예: 납기일)
섹션 (document_template_sections)
검사 기준서의 섹션 단위.
| 컬럼 | 설명 |
|---|---|
title |
섹션 제목 (예: "겉모양 검사", "치수 검사") |
image_path |
도해 이미지 경로 (검사 부위 도면) |
sort_order |
순서 |
검사항목 (document_template_section_items)
각 섹션 내의 개별 검사항목.
| 컬럼 | 타입 | 설명 |
|---|---|---|
category |
VARCHAR | 구분 (겉모양, 치수, 재질) |
item |
VARCHAR | 검사항목명 |
standard |
VARCHAR | 검사기준 (100mm ±5mm) |
tolerance |
JSON NULL | 허용오차 (min/max) |
standard_criteria |
VARCHAR NULL | 판정기준 |
method |
VARCHAR | 검사방법 (육안, 측정) |
measurement_type |
VARCHAR NULL | 측정 유형 |
frequency_n |
INT NULL | 검사건수 N |
frequency_c |
INT NULL | 합격건수 C |
frequency |
VARCHAR NULL | 검사빈도 텍스트 |
field_values |
JSON NULL | 확장 필드 (마이그레이션 없이 추가) |
테이블 컬럼 (document_template_columns)
검사 데이터 테이블의 컬럼 정의.
| 컬럼 | 타입 | 설명 |
|---|---|---|
label |
VARCHAR | 컬럼 라벨 |
width |
INT NULL | 너비 (px) |
column_type |
VARCHAR | text, check, complex, measurement, select |
group_name |
VARCHAR NULL | 상단 병합 헤더명 |
sub_labels |
JSON NULL | complex 타입 하위 라벨 |
sort_order |
INT | 순서 |
컬럼 타입 상세:
| 타입 | 설명 | 예시 |
|---|---|---|
text |
단순 텍스트 입력 | 비고, 메모 |
check |
체크박스 (합격/부적합) | 외관 검사 합격 여부 |
complex |
여러 서브필드 조합 | 측정값 + 단위 + 판정 |
measurement |
수치 입력 | 길이: 100.5mm |
select |
드롭다운 선택 | 판정: 합격/불합격/보류 |
외부 연결 (document_template_links)
템플릿에서 외부 테이블 데이터를 참조하기 위한 정의.
| 컬럼 | 설명 |
|---|---|
link_key |
연결 식별자 |
label |
화면 라벨 |
link_type |
single (1개 선택) / multiple (다중 선택) |
source_table |
소스 테이블 (items, processes, users) |
search_params |
API 검색 추가 조건 (JSON) |
display_fields |
표시 필드 (title, subtitle) |
is_required |
필수 여부 |
5.4 블록 빌더 구조
페이지 설정 (page_config):
{
"size": "A4",
"orientation": "portrait",
"margin": {
"top": 20,
"right": 15,
"bottom": 20,
"left": 15
}
}
스키마 (schema):
블록 배열로 레이아웃 정의. 드래그앤드롭으로 편집.
{
"blocks": [
{ "type": "text", "x": 0, "y": 0, "width": 100, "content": "검사 성적서" },
{ "type": "table", "x": 0, "y": 50, "columns": [...], "rows": [...] },
{ "type": "image", "x": 200, "y": 100, "src": "..." }
]
}
블록 빌더 UI (3패널):
┌──────────┬────────────────────┬──────────┐
│ 블록 │ │ 속성 │
│ 팔레트 │ A4 캔버스 │ 패널 │
│ │ │ │
│ [텍스트] │ ┌──────────────┐ │ 너비: _ │
│ [이미지] │ │ 드래그앤드롭 │ │ 높이: _ │
│ [표] │ │ 블록 배치 │ │ 색상: _ │
│ [선] │ │ │ │ 폰트: _ │
│ [도형] │ └──────────────┘ │ │
└──────────┴────────────────────┴──────────┘
6. EAV 데이터 저장 패턴
6.1 핵심 개념
하나의 document_data 테이블에 모든 양식의 모든 필드값을 저장. 양식이 다르면 field_key가 다르고, 같은 양식이라도 섹션/행이 다르면 section_id/row_index로 구분.
6.2 저장 구조
document_data 레코드 예시:
기본필드 (상단 고정 영역):
┌─────────────┬────────────┬───────────┬───────────┬───────────┬─────────────┐
│ document_id │ section_id │ column_id │ row_index │ field_key │ field_value │
├─────────────┼────────────┼───────────┼───────────┼───────────┼─────────────┤
│ 42 │ NULL │ NULL │ 0 │ bf_1 │ 블라인드A │ ← 품명
│ 42 │ NULL │ NULL │ 0 │ bf_2 │ LOT-2026-001│ ← LOT NO
│ 42 │ NULL │ NULL │ 0 │ bf_3 │ 2026-03-15 │ ← 납기일
├─────────────┼────────────┼───────────┼───────────┼───────────┼─────────────┤
테이블 데이터 (섹션별 검사 결과):
│ 42 │ 10 │ 20 │ 0 │ col_20 │ 합격 │ ← 섹션10, 컬럼20, 1행
│ 42 │ 10 │ 20 │ 1 │ col_20 │ 부적합 │ ← 섹션10, 컬럼20, 2행
│ 42 │ 10 │ 21 │ 0 │ col_21 │ 100.5 │ ← 섹션10, 컬럼21, 1행
└─────────────┴────────────┴───────────┴───────────┴───────────┴─────────────┘
6.3 field_key 네이밍 규칙
| 접두사 | 의미 | 예시 |
|---|---|---|
bf_ |
기본필드 (BasicField) | bf_1, bf_2 |
cf_ |
섹션필드 (SectionField) | cf_5, cf_6 |
col_ |
컬럼 데이터 | col_20, col_21 |
6.4 데이터 조회 패턴
// 기본필드 값 조회
$data = DocumentData::where('document_id', $id)
->whereNull('section_id')
->get()
->keyBy('field_key');
$productName = $data['bf_1']->field_value;
// 섹션별 테이블 데이터 조회
$rows = DocumentData::where('document_id', $id)
->where('section_id', $sectionId)
->get()
->groupBy('row_index');
7. 결재 워크플로우
7.1 상태 전이
DRAFT (작성중)
│
├── submit() → PENDING (결재중)
│ │
│ ├── approve() [step 1] → 다음 step 대기
│ ├── approve() [step 2] → 다음 step 대기
│ ├── approve() [마지막] → APPROVED (승인)
│ │
│ └── reject() → REJECTED (반려)
│ │
│ └── edit → submit() → PENDING (재요청)
│
└── cancel() → CANCELLED (취소)
7.2 상태값 및 라벨
| 코드 | 라벨 | 색상 | 편집 가능 |
|---|---|---|---|
DRAFT |
작성중 | gray | 예 |
PENDING |
결재중 | yellow | 아니오 |
APPROVED |
승인 | green | 아니오 |
REJECTED |
반려 | red | 예 (수정 후 재요청) |
CANCELLED |
취소 | gray | 아니오 |
7.3 결재 단계 (Approval)
DocumentTemplateApprovalLine (양식 정의)
↓ (문서 생성 시 복사)
DocumentApproval (문서별 결재 레코드)
step 1: 작성 → PENDING → 결재자 승인 → APPROVED
step 2: 검토 → PENDING → 결재자 승인 → APPROVED
step 3: 승인 → PENDING → 결재자 승인 → APPROVED → 문서 전체 APPROVED
7.4 결재 판단 메서드
// Document 모델
canEdit() // DRAFT 또는 REJECTED
canSubmit() // DRAFT 또는 REJECTED
canApprove() // PENDING (현재 결재자만)
canCancel() // DRAFT 또는 PENDING (작성자만)
8. 자동 데이터 매핑
8.1 개요
문서 작성/수정 시, 연결된 작업지시서(work_order)/수주(order) 데이터에서 기본필드를 자동으로 채움. 사용자 입력 부담을 줄이고 데이터 정확성을 보장.
8.2 검사 성적서 매핑 (field_key 기반)
| field_key | 라벨 | 소스 |
|---|---|---|
product_name |
품명 | workOrderItem.item_name |
specification |
규격 | workOrderItem.specification |
lot_no |
LOT NO | order.order_no |
lot_size |
LOT 크기 | "N 개소" (개소 수 기반) |
client |
발주처 | order.client_name |
site_name |
현장명 | workOrder.project_name |
inspection_date |
검사일 | workOrderItem.options.inspection_data.inspected_at |
inspector |
검사자 | 검사자 이름 |
8.3 작업일지 매핑 (label 기반)
| label 포함 문자열 | 소스 |
|---|---|
발주처 |
order.client_name |
현장명 |
workOrder.project_name |
작업일자 |
now() |
LOT NO, LOT |
order.order_no |
납기일, 납기 |
order.delivery_date |
작업지시번호 |
workOrder.work_order_no |
수주일 |
order.received_at 또는 order.created_at |
8.4 자동 매핑 흐름
문서 작성/수정 페이지 로드
↓
DocumentController::edit()
↓
resolveAndBackfillBasicFields($template, $document)
↓
linkable_type 확인 (work_order? order?)
↓
field_key 또는 label 매칭
↓
DB에 값이 없으면 → 소스 데이터에서 resolve
↓
뷰에 자동 채움된 값 전달
9. 자재 LOT 추적
9.1 개요
검사 성적서에서 해당 작업지시의 투입 자재 LOT 이력을 조회. stock_transactions 테이블의 OUT(투입)/IN(취소) 트랜잭션을 상쇄하여 순수 투입량을 계산.
9.2 추적 구조
work_orders (작업지시)
│
├── stock_transactions (재고 트랜잭션)
│ ├── OUT (투입): qty < 0
│ └── IN (취소/반납): qty > 0
│ → 순수 투입량 = ABS(SUM(qty)) where qty < 0
│
└── work_order_material_inputs (개소별 투입자재)
└── stock_lots (LOT 정보) JOIN
9.3 표시 내용
| 항목 | 설명 |
|---|---|
| 자재명 | 투입된 원자재/부자재 이름 |
| LOT 번호 | 자재의 LOT 식별 번호 |
| 투입 수량 | OUT 트랜잭션 합계 (절대값) |
| 투입일 | 트랜잭션 일시 |
10. 화면별 상세
10.1 문서 목록 (/documents)
필터 항목:
| 필터 | 타입 | 설명 |
|---|---|---|
| 검색 | text | 문서번호 또는 제목 |
| 상태 | dropdown | DRAFT, PENDING, APPROVED, REJECTED, CANCELLED, 휴지통(admin) |
| 양식분류 | dropdown | category |
| 템플릿 | dropdown | template_id |
| 날짜 범위 | date | created_at (from ~ to) |
목록 테이블 컬럼:
문서번호 | 제목 | 양식 | 상태 | 작성자 | 작성일 | 결재현황
10.2 문서 작성/수정 (/documents/create, /documents/{id}/edit)
폼 구성:
┌──────────────────────────────────────────────┐
│ 템플릿 선택 (읽기전용) │
│ 제목 (필수) │
├──────────────────────────────────────────────┤
│ 기본 필드 (template.basicFields) │
│ ┌─────────────────┬─────────────────┐ │
│ │ 품명: [자동채움] │ LOT NO: [자동] │ │
│ │ 납기일: [날짜] │ 발주처: [자동] │ │
│ └─────────────────┴─────────────────┘ │
├──────────────────────────────────────────────┤
│ 섹션 1: 겉모양 검사 │
│ ┌──────────────────────────────────────┐ │
│ │ 도해 이미지 (있으면) │ │
│ ├──────┬──────┬──────┬──────┬──────┤ │
│ │ 구분 │ 항목 │ 기준 │ 결과1│ 결과2│ │
│ ├──────┼──────┼──────┼──────┼──────┤ │
│ │ 치수 │ 길이 │±5mm │ [ ] │ [ ] │ │
│ │ 외관 │ 흠집 │ 없음 │ [✓] │ [✓] │ │
│ ├──────┴──────┴──────┴──────┴──────┤ │
│ │ [+ 행 추가] [행 삭제] │ │
│ └──────────────────────────────────────┘ │
├──────────────────────────────────────────────┤
│ 외부 연결 (template.links) │
│ 품목 선택: [검색 드롭다운] │
├──────────────────────────────────────────────┤
│ 첨부파일 │
│ [일반 문서] [서명 이미지] [검사 사진] [참고 자료] │
├──────────────────────────────────────────────┤
│ [임시저장] [결재 요청] │
└──────────────────────────────────────────────┘
10.3 문서 상세 (/documents/{id})
읽기 전용 표시:
┌──────────────────────────────────────────────┐
│ 문서번호: DOC-260306-001 상태: [🟢 승인] │
│ 제목: 블라인드A 검사 성적서 │
├──────────────────────────────────────────────┤
│ 기본 필드 (읽기 전용) │
├──────────────────────────────────────────────┤
│ 검사 데이터 테이블 (읽기 전용) │
├──────────────────────────────────────────────┤
│ 결재 현황 │
│ ┌────────┬────────┬────────┐ │
│ │ 작성 │ 검토 │ 승인 │ │
│ │ 홍길동 │ 김과장 │ 박부장 │ │
│ │ ✓승인 │ ✓승인 │ ●대기 │ │
│ └────────┴────────┴────────┘ │
├──────────────────────────────────────────────┤
│ 자재 투입 LOT (작업지시 연결 시) │
│ ┌────────┬──────────┬──────┬──────┐ │
│ │ 자재명 │ LOT 번호 │ 수량 │ 투입일│ │
│ └────────┴──────────┴──────┴──────┘ │
├──────────────────────────────────────────────┤
│ 첨부파일 목록 │
├──────────────────────────────────────────────┤
│ [수정] [인쇄] [결재 승인] [결재 반려] │
└──────────────────────────────────────────────┘
10.4 인쇄 (/documents/{id}/print)
성적서 형식의 인쇄 전용 화면. window.print() 호출. 작업지시 관련 자재(work_order_items) 데이터 포함.
10.5 양식 목록 (/document-templates)
필터:
- 검색: 양식명, 제목, 분류
- 카테고리: common_codes 기반 + 기존 데이터 폴백
- 활성 상태: 활성 / 비활성 / 휴지통(admin)
HTMX: 필터 변경 시 테이블 영역만 부분 로드
11. 첨부파일 유형
| 유형 | 코드 | 용도 | 예시 |
|---|---|---|---|
| 일반 문서 | general |
PDF, 엑셀 등 | 규격서, 보고서 |
| 서명 이미지 | signature |
검사 완료 서명 | 검사자 서명 사진 |
| 검사 사진 | image |
검사 증빙 사진 | 불량 부위 촬영 |
| 참고 자료 | reference |
참고용 문서 | KS 규격, 작업 지침 |
12. API 연동 (MNG → API)
MNG 뷰에서 데이터 저장/삭제는 API 서버를 호출하여 처리. GET 요청(뷰 렌더링)은 MNG 컨트롤러가 직접 처리.
| 작업 | MNG (GET 요청) | API (POST/PUT/DELETE) |
|---|---|---|
| 목록 조회 | DocumentController::index() |
GET /v1/documents |
| 상세 조회 | DocumentController::show() |
GET /v1/documents/{id} |
| 생성 | 폼 표시만 | POST /v1/documents |
| 수정 | 폼 표시만 | PATCH /v1/documents/{id} |
| 삭제 | - | DELETE /v1/documents/{id} |
| 결재 요청 | - | POST /v1/documents/{id}/submit |
| 승인 | - | POST /v1/documents/{id}/approve |
| 반려 | - | POST /v1/documents/{id}/reject |
13. 카테고리 해결 로직
양식 카테고리는 common_codes 테이블에서 조회하되, 없으면 기존 데이터에서 추출하여 폴백.
// DocumentTemplateController::getCategories()
$categories = CommonCode::where('group', 'document_category')
->orderBy('sort_order')
->get();
if ($categories->isEmpty()) {
// 폴백: 기존 템플릿의 category 값에서 중복 제거
$categories = DocumentTemplate::distinct('category')
->pluck('category')
->filter();
}
14. 검사항목 확장 (field_values JSON)
document_template_section_items.field_values JSON 컬럼으로 마이그레이션 없이 새 필드를 추가할 수 있다.
{
"custom_field_1": "추가 기준값",
"min_value": 95.0,
"max_value": 105.0,
"unit": "mm"
}
options JSON 컬럼 정책(
docs/standards/options-column-policy.md) 준용
15. HTMX 전체 페이지 로드 규칙
문서관리 페이지들은 JavaScript를 사용하므로 HTMX 부분 로드 시 스크립트 미실행 문제가 있다. 컨트롤러에서 HX-Request 감지 시 HX-Redirect로 전체 페이지 리로드 강제.
if ($request->header('HX-Request')) {
return response('', 200)->header('HX-Redirect', route('documents.index'));
}
관련 문서
- README.md — API 엔드포인트, 모델 요약, FormRequest
- DB 스키마 — 문서/전자서명 — 테이블 상세
- 게시판 시스템 — 유사한 EAV 패턴 참고
- 결재관리 시스템 — 별도 결재 시스템 (문서관리와 독립)
최종 업데이트: 2026-03-06