Files
wace_rps/docs/manual/RPS_시스템_사용자_매뉴얼.html
T
chpark 0fc2d699a4 docs(manual): RPS PLM 시스템 사용자 메뉴얼 (HTML) — 8장 구성
- 시스템 개요 / 전체 메뉴 구조 (10개 모듈 매트릭스)
- 업무 프로세스 흐름 — 영업→개발→구매→생산→품질→매출
- Amaranth(ERP) 연계 — 외부 커넥션 7종, 결재상신 11단계 워크플로,
  auth_config 암호화/복호화, 결재 상태 코드, 문제 해결 FAQ
- 대시보드 관리 — 사용자 대시보드 / 3종 모니터링 보드 / 관리자 위젯
- 품질관리 4메뉴 상세 (필터·컬럼·자동 산정 로직)
- 공통 UI (DataGrid / CompactFilterBar / PageHeader) 사용법
- 자주 묻는 질문 5건

self-contained HTML, 좌측 sticky 목차 + 인쇄 친화 CSS.
2026-05-15 16:47:00 +09:00

662 lines
34 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>RPS PLM 시스템 사용자 매뉴얼</title>
<style>
:root {
--bg: #f7f9fc;
--card: #ffffff;
--line: #e2e8f0;
--text: #0f172a;
--muted: #64748b;
--primary: #2563eb;
--primary-soft: #dbeafe;
--success: #059669;
--success-soft: #d1fae5;
--warn: #d97706;
--warn-soft: #fef3c7;
--danger: #dc2626;
--danger-soft: #fee2e2;
--code-bg: #0f172a;
--code-fg: #e2e8f0;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
background: var(--bg);
color: var(--text);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;
font-size: 15px;
line-height: 1.65;
}
.layout { display: grid; grid-template-columns: 260px 1fr; min-height: 100vh; }
nav.toc {
position: sticky; top: 0; align-self: start;
height: 100vh; overflow-y: auto;
background: #fff; border-right: 1px solid var(--line); padding: 24px 16px;
}
nav.toc h2 { font-size: 14px; margin: 0 0 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; }
nav.toc ol { list-style: none; padding: 0; margin: 0; counter-reset: c; }
nav.toc li { counter-increment: c; margin-bottom: 4px; }
nav.toc li::before { content: counter(c) ". "; color: var(--muted); margin-right: 4px; font-variant-numeric: tabular-nums; }
nav.toc a { color: var(--text); text-decoration: none; font-size: 14px; }
nav.toc a:hover { color: var(--primary); }
nav.toc ul { list-style: none; padding: 6px 0 0 16px; margin: 0; border-left: 2px solid var(--line); }
nav.toc ul li { counter-increment: none; margin-bottom: 2px; }
nav.toc ul li::before { content: ""; }
nav.toc ul a { font-size: 13px; color: var(--muted); }
main { padding: 40px 56px 80px; max-width: 1100px; }
header.cover {
background: linear-gradient(135deg, #1e293b 0%, #2563eb 100%);
color: white; border-radius: 12px; padding: 36px 40px; margin-bottom: 36px;
}
header.cover h1 { margin: 0 0 8px; font-size: 32px; }
header.cover p { margin: 0; opacity: .85; }
header.cover .meta { margin-top: 16px; display: flex; gap: 16px; font-size: 13px; opacity: .8; }
h2.section { font-size: 24px; margin: 48px 0 16px; padding-bottom: 8px; border-bottom: 2px solid var(--primary); }
h3 { font-size: 18px; margin: 28px 0 10px; }
h4 { font-size: 15px; margin: 18px 0 8px; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
p, li { line-height: 1.75; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 20px 24px; margin: 16px 0; }
.card.compact { padding: 12px 16px; }
.badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 500; vertical-align: middle; }
.badge.primary { background: var(--primary-soft); color: var(--primary); }
.badge.success { background: var(--success-soft); color: var(--success); }
.badge.warn { background: var(--warn-soft); color: var(--warn); }
.badge.danger { background: var(--danger-soft); color: var(--danger); }
.grid { display: grid; gap: 16px; }
.grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
table { width: 100%; border-collapse: collapse; margin: 12px 0; font-size: 14px; }
th, td { border: 1px solid var(--line); padding: 8px 12px; text-align: left; vertical-align: top; }
th { background: #f1f5f9; font-weight: 600; }
td code { background: #f1f5f9; padding: 1px 5px; border-radius: 3px; font-size: 13px; }
code, pre { font-family: "SF Mono", Menlo, Consolas, monospace; }
pre { background: var(--code-bg); color: var(--code-fg); padding: 16px 20px; border-radius: 8px; overflow-x: auto; font-size: 13px; line-height: 1.55; }
.callout { border-left: 4px solid var(--primary); background: #eff6ff; padding: 12px 16px; margin: 16px 0; border-radius: 6px; }
.callout.warn { border-color: var(--warn); background: #fefce8; }
.callout.success { border-color: var(--success); background: #ecfdf5; }
.callout.danger { border-color: var(--danger); background: #fef2f2; }
.callout strong { display: block; margin-bottom: 4px; }
.flow { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 16px; background: #f8fafc; border-radius: 8px; border: 1px solid var(--line); }
.flow .step { background: white; border: 1px solid var(--primary); color: var(--primary); padding: 6px 12px; border-radius: 6px; font-size: 13px; font-weight: 500; }
.flow .arrow { color: var(--muted); }
.kv { display: grid; grid-template-columns: 140px 1fr; gap: 6px 12px; font-size: 14px; }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; }
.stat-card { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 16px; text-align: center; }
.stat-card .n { font-size: 28px; font-weight: 700; color: var(--primary); }
.stat-card .label { font-size: 12px; color: var(--muted); margin-top: 4px; }
details { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 12px 16px; margin: 8px 0; }
details summary { cursor: pointer; font-weight: 500; }
details[open] summary { margin-bottom: 10px; }
@media print {
.layout { grid-template-columns: 1fr; }
nav.toc { display: none; }
main { padding: 0; max-width: 100%; }
header.cover { break-after: page; }
h2.section { break-after: avoid; }
}
</style>
</head>
<body>
<div class="layout">
<nav class="toc">
<h2>목차</h2>
<ol>
<li><a href="#overview">시스템 개요</a></li>
<li><a href="#menu">전체 메뉴 구조</a></li>
<li><a href="#business">업무 프로세스 흐름</a>
<ul>
<li><a href="#proc-sales">영업·수주</a></li>
<li><a href="#proc-dev">개발·설계</a></li>
<li><a href="#proc-purchase">구매·입고</a></li>
<li><a href="#proc-production">생산</a></li>
<li><a href="#proc-quality">품질</a></li>
<li><a href="#proc-revenue">매출·CS</a></li>
</ul>
</li>
<li><a href="#amaranth">Amaranth(ERP) 연계</a>
<ul>
<li><a href="#amaranth-conn">외부 커넥션 관리</a></li>
<li><a href="#amaranth-approval">결재상신 워크플로</a></li>
<li><a href="#amaranth-troubleshoot">문제 해결</a></li>
</ul>
</li>
<li><a href="#dashboard">대시보드 관리</a></li>
<li><a href="#quality">품질관리 메뉴 가이드</a></li>
<li><a href="#common">공통 UI 사용법</a></li>
<li><a href="#faq">자주 묻는 질문</a></li>
</ol>
</nav>
<main>
<header class="cover">
<h1>RPS PLM 시스템 사용자 매뉴얼</h1>
<p>영업·개발·구매·생산·품질·CS·ECR 전 업무 + Amaranth(ERP) 결재 연계</p>
<div class="meta">
<span>버전: v1.0</span>
<span>대상: 일반 사용자 / 관리자</span>
<span>최종 갱신: 2026-05-15</span>
</div>
</header>
<!-- ======================================================== -->
<h2 class="section" id="overview">1. 시스템 개요</h2>
<p>
RPS PLM 은 영업(견적·수주)부터 개발(E-BOM), 구매(발주·입고), 생산(M-BOM·실적),
품질(수입·공정·반제품·CS·ECR), 매출까지 전사 업무를 단일 시스템으로 처리합니다.
회계·결재·인사 등 ERP 영역은 Wehago/Amaranth 와 REST API 로 연계됩니다.
</p>
<div class="grid cols-4">
<div class="stat-card"><div class="n">11</div><div class="label">주요 모듈</div></div>
<div class="stat-card"><div class="n">40+</div><div class="label">화면 메뉴</div></div>
<div class="stat-card"><div class="n">7</div><div class="label">Amaranth 커넥션</div></div>
<div class="stat-card"><div class="n">3</div><div class="label">모니터링 보드</div></div>
</div>
<h3>시스템 구성</h3>
<table>
<tr><th width="180">레이어</th><th>기술</th><th>역할</th></tr>
<tr><td>프론트엔드</td><td>Next.js 15 + React + Tailwind</td><td>탭 기반 SPA, DataGrid, 그리드 차트/엑셀</td></tr>
<tr><td>백엔드</td><td>Node.js + Express + TypeScript</td><td>REST API, JWT 인증, 외부 ERP 프록시</td></tr>
<tr><td>데이터베이스</td><td>PostgreSQL 15</td><td>업무 데이터 + 메뉴/권한 메타</td></tr>
<tr><td>외부 ERP</td><td>Wehago / Amaranth</td><td>전자결재, 인사, 거래처, 계정과목 마스터</td></tr>
<tr><td>인증</td><td>JWT + Refresh Token</td><td>로그인 세션, 401 자동 갱신</td></tr>
</table>
<!-- ======================================================== -->
<h2 class="section" id="menu">2. 전체 메뉴 구조</h2>
<div class="grid cols-2">
<div class="card compact">
<h4>📋 영업관리</h4>
<ul>
<li>견적관리 — 견적 작성·승인·메일발송</li>
<li>주문서관리 — 수주 등록·확정</li>
<li>판매관리 — 출하 처리</li>
<li>매출관리 — 세금계산서 발행</li>
</ul>
</div>
<div class="card compact">
<h4>📁 프로젝트관리</h4>
<ul>
<li>제품구분_WBS관리 — 제품별 WBS 템플릿</li>
<li>진행관리 — 프로젝트 단계별 진척률</li>
</ul>
</div>
<div class="card compact">
<h4>🛠 개발관리</h4>
<ul>
<li>PART 등록·조회</li>
<li>E-BOM 등록·조회</li>
<li>설계변경 리스트</li>
</ul>
</div>
<div class="card compact">
<h4>🛒 구매관리</h4>
<ul>
<li>M-BOM 관리</li>
<li>구매리스트 / 견적요청서 / 품의서 / 발주서</li>
<li>입고관리 (3가지 뷰)</li>
<li>프로젝트별 발주/입고 현황</li>
</ul>
</div>
<div class="card compact">
<h4>📦 자재관리</h4>
<ul>
<li>자재리스트</li>
<li>불출의뢰서</li>
</ul>
</div>
<div class="card compact">
<h4>🏭 생산관리</h4>
<ul>
<li>M-BOM 관리</li>
<li>생산계획&실적 (일반/장비)</li>
<li>반제품·원자재 소요량</li>
</ul>
</div>
<div class="card compact">
<h4>🔬 품질관리</h4>
<ul>
<li>수입검사 요청·관리</li>
<li>공정검사 관리</li>
<li>반제품검사 관리</li>
</ul>
</div>
<div class="card compact">
<h4>💬 고객CS관리</h4>
<ul>
<li>고객CS관리 — 민원 접수·조치</li>
</ul>
</div>
<div class="card compact">
<h4>📝 ECR관리</h4>
<ul>
<li>ECR관리 — 설계변경요청서</li>
</ul>
</div>
<div class="card compact">
<h4>📊 모니터링</h4>
<ul>
<li>품질 모니터링</li>
<li>생산 모니터링</li>
<li>설비 모니터링</li>
</ul>
</div>
</div>
<!-- ======================================================== -->
<h2 class="section" id="business">3. 업무 프로세스 흐름</h2>
<p>
각 모듈의 작업 결과는 다음 모듈의 입력이 되어 자동으로 흘러갑니다. 한 화면에서 다른 화면으로
<strong>물려 있는</strong> 점이 RPS PLM의 핵심입니다.
</p>
<div class="flow" style="font-size: 13px;">
<div class="step">견적 작성</div>
<span class="arrow"></span>
<div class="step">결재상신 (Amaranth)</div>
<span class="arrow"></span>
<div class="step">수주 확정</div>
<span class="arrow"></span>
<div class="step">M-BOM 생성</div>
<span class="arrow"></span>
<div class="step">발주서</div>
<span class="arrow"></span>
<div class="step">입고·수입검사</div>
<span class="arrow"></span>
<div class="step">생산실적</div>
<span class="arrow"></span>
<div class="step">공정·반제품 검사</div>
<span class="arrow"></span>
<div class="step">출하</div>
<span class="arrow"></span>
<div class="step">매출·세금계산서 (Amaranth)</div>
</div>
<!-- 3.1 영업·수주 -->
<h3 id="proc-sales">3.1 영업·수주</h3>
<div class="card">
<h4>핵심 시나리오</h4>
<ol>
<li><strong>견적요청 등록</strong> — 영업관리 &gt; 견적관리 [+ 견적요청등록]. 주문유형/고객사/유무상/접수일/품목 입력.</li>
<li><strong>견적작성</strong> — 행 선택 후 [견적작성]. 일반/장비 템플릿 중 선택 → 신규 차수 생성.</li>
<li><strong>결재상신</strong> — 견적서가 작성된 행에서 [결재상신] → Amaranth 팝업 → 결재완료까지 대기.</li>
<li><strong>수주 확정</strong> — 결재완료 시 자동으로 contract_result 가 변경되어 주문서관리에 노출됨.</li>
</ol>
<p class="callout warn">
<strong>⚠ 가드 조건</strong>
① 견적서 미작성 → 결재상신 불가 ② 결재중·결재완료 건은 재상신 차단
③ 수주확정(0000964/0000968) 행은 품목 추가/삭제 불가
</p>
</div>
<!-- 3.2 개발·설계 -->
<h3 id="proc-dev">3.2 개발·설계</h3>
<div class="card">
<p>
제품 양산 전 단계의 부품(PART)과 설계 BOM(E-BOM)을 관리합니다.
설계변경(ECR)이 발생하면 E-BOM 의 차수가 올라가고, 변경 이력은 [설계변경 리스트]에서 추적됩니다.
</p>
<div class="flow">
<div class="step">PART 등록</div>
<span class="arrow"></span>
<div class="step">E-BOM 트리 구성</div>
<span class="arrow"></span>
<div class="step">ECR 발의</div>
<span class="arrow"></span>
<div class="step">E-BOM 차수 업데이트</div>
</div>
</div>
<!-- 3.3 구매·입고 -->
<h3 id="proc-purchase">3.3 구매·입고</h3>
<div class="card">
<p>
수주 → M-BOM 분해 → 구매리스트 → 견적요청서 → 품의서(승인) → 발주서 → 입고 → 수입검사 순서로 진행됩니다.
Amaranth 와는 거래처/계정과목 마스터를 실시간 동기화합니다.
</p>
<table>
<tr><th>단계</th><th>메뉴</th><th>핵심 동작</th></tr>
<tr><td>1. 구매대상 추출</td><td>구매리스트관리</td><td>수주 M-BOM 에서 외주/구매 품목만 필터링</td></tr>
<tr><td>2. 견적요청</td><td>견적요청서관리</td><td>거래처별 RFQ 발송 (Amaranth 거래처 조회 연동)</td></tr>
<tr><td>3. 품의 → 결재</td><td>품의서관리</td><td>구매 품의서 작성 후 Amaranth 결재 (formId=품의서)</td></tr>
<tr><td>4. 발주</td><td>발주서관리</td><td>결재완료된 품의서를 발주로 전환</td></tr>
<tr><td>5. 입고</td><td>입고관리 (3가지 뷰)</td><td>전체/품목별/입고일별 입고 확정</td></tr>
<tr><td>6. 수입검사</td><td>품질관리 &gt; 수입검사</td><td>입고된 자재의 검사 진행 + 합/불 판정</td></tr>
</table>
</div>
<!-- 3.4 생산 -->
<h3 id="proc-production">3.4 생산</h3>
<div class="card">
<p>
M-BOM 으로 생산계획을 수립하고 작업지시번호 단위로 실적을 입력합니다.
장비 생산은 별도 메뉴(생산계획&실적관리(장비))에서 처리합니다.
</p>
<ul>
<li><strong>M-BOM 관리</strong> — 구조 트리 + 본 편집(품목 추가/삭제) + 변경이력</li>
<li><strong>반제품/원자재 소요량</strong> — 계획 대비 필요 자재 자동 계산</li>
<li><strong>생산실적</strong> — 작업지시 단위 양품/불량 등록 (반제품검사와 inspection_group_id 로 연계)</li>
</ul>
</div>
<!-- 3.5 품질 -->
<h3 id="proc-quality">3.5 품질</h3>
<div class="card">
<p>품질관리는 4단계로 흐릅니다:</p>
<div class="flow">
<div class="step">수입검사 요청 (발주서 단위)</div>
<span class="arrow"></span>
<div class="step">수입검사 진행 (검사자 판정)</div>
<span class="arrow"></span>
<div class="step">공정검사 (작업 중 SPC)</div>
<span class="arrow"></span>
<div class="step">반제품검사 (양품/불량 분류)</div>
</div>
<p style="margin-top: 12px;">불량 발생 → 책임부서로 통보 → 수정완료 시 재생수량 가산 → 최종양품수량 자동 산정. 자세한 내용은 <a href="#quality">6. 품질관리 메뉴 가이드</a>.</p>
</div>
<!-- 3.6 매출·CS -->
<h3 id="proc-revenue">3.6 매출·CS</h3>
<div class="card">
<p>출하 완료 → 매출 인식 → Amaranth 로 세금계산서 발행. 고객 클레임은 CS 메뉴로 접수되어 분석/조치 후 종결됩니다.</p>
<div class="flow">
<div class="step">판매관리 (출하)</div>
<span class="arrow"></span>
<div class="step">매출관리</div>
<span class="arrow"></span>
<div class="step">세금계산서 발행 (Amaranth)</div>
<span class="arrow"></span>
<div class="step">CS 접수 (필요 시)</div>
<span class="arrow"></span>
<div class="step">ECR (설계 반영 필요 시)</div>
</div>
</div>
<!-- ======================================================== -->
<h2 class="section" id="amaranth">4. Amaranth(ERP) 연계</h2>
<p>
RPS PLM 은 결재·인사·거래처 등 ERP 영역을 Wehago/Amaranth 시스템과
REST API 로 통합합니다. 모든 외부 호출 정보는 [관리자 &gt; 자동화 관리 &gt; 외부 커넥션 관리] 에 등록되어 있고,
자격 증명(accessToken/hashKey)은 AES-256-GCM 으로 암호화 저장됩니다.
</p>
<!-- 4.1 외부 커넥션 관리 -->
<h3 id="amaranth-conn">4.1 외부 커넥션 관리</h3>
<div class="card">
<p>위치: <code>관리자 &gt; 자동화 관리 &gt; 외부 커넥션 관리 &gt; REST API 연결</code></p>
<table>
<tr><th width="200">연결명</th><th>엔드포인트</th><th>용도</th></tr>
<tr><td>Amaranth - 결재</td><td><code>(SSO/결재 호출 시 path 지정)</code></td><td>전자결재 SSO URL 발급, 결재함 조회</td></tr>
<tr><td>Amaranth - Wehago 사용자</td><td><code>/apiproxy/api99u01A11</code></td><td>사용자 인증 토큰 발급</td></tr>
<tr><td>Amaranth - 거래처</td><td><code>/apiproxy/api16S11</code></td><td>거래처 마스터 동기화</td></tr>
<tr><td>Amaranth - 부서</td><td><code>/apiproxy/api16S10</code></td><td>부서 마스터 동기화</td></tr>
<tr><td>Amaranth - 사원</td><td><code>/apiproxy/api16S05</code></td><td>사원 마스터 동기화</td></tr>
<tr><td>Amaranth - 창고</td><td><code>/apiproxy/api20A00S00801</code></td><td>창고 마스터 동기화</td></tr>
<tr><td>Amaranth - 계정과목</td><td><code>/apiproxy/api11A02</code></td><td>계정과목 마스터 동기화</td></tr>
</table>
<p>각 커넥션 카드의 [테스트] 버튼을 누르면 실 호출이 발생하고 <span class="badge success">성공</span> / <span class="badge danger">실패</span> 가 표시됩니다.</p>
</div>
<h4>auth_config 필드</h4>
<pre>{
"callerName": "API_gcmsAmaranth40578", // 평문 (수정 시 즉시 적용)
"groupSeq": "gcmsAmaranth40578", // 평문
"accessToken": "MN5Kz...", // AES-256-GCM 자동 암호화 저장
"hashKey": "22519103...", // AES-256-GCM 자동 암호화 저장
"aesKey": "8441e27489d402cd" // 결재 SSO empSeq AES-128-CBC 키
}</pre>
<p class="callout">
<strong>💡 암호화 동작</strong>
신규 등록/수정 시 accessToken·hashKey 는 자동으로 <code>iv:authTag:cipher</code> 3-part hex 로 변환되어 저장됩니다.
복호화 키는 환경변수 <code>DB_PASSWORD_SECRET</code> 입니다.
</p>
<!-- 4.2 결재상신 워크플로 -->
<h3 id="amaranth-approval">4.2 결재상신 워크플로</h3>
<div class="card">
<p>견적관리/주문서관리/품의서관리/ECR 관리/CS관리 등 결재 대상 화면에서 [결재상신] 버튼을 누를 때 동작하는 흐름입니다.</p>
<ol>
<li>프론트에서 행 선택 후 [결재상신] 클릭</li>
<li>백엔드 <code>POST /api/sales/estimate/:id/amaranth-approval</code> 호출</li>
<li>현재 사용자의 emp_seq 를 user_info 에서 조회 (없으면 401 에러 반환)</li>
<li>견적서(estimate_template) 최신 차수 objid 를 추출하여 <code>target_objid</code> 로 사용</li>
<li><code>amaranth_approval</code> 테이블에서 기존 매핑 조회
<ul>
<li>없음 → 신규 <code>approKey</code> 생성</li>
<li>상태가 <code>reject/delete/create</code> → 재상신용 신규 approKey</li>
<li>그 외(inProcess/complete) → 기존 approKey 재사용</li>
</ul>
</li>
<li><strong>Amaranth 인증</strong>: callerName/accessToken/hashKey 로 wehago-sign(HMAC-SHA256) 헤더 생성</li>
<li>SSO URL 발급 API 호출 → <code>fullUrl</code> 응답 수신</li>
<li><code>amaranth_approval</code> INSERT/UPDATE (approKey + sso_url)</li>
<li>프론트로 <code>fullUrl</code> 반환</li>
<li>프론트가 <code>window.open(fullUrl, "amaranthApproval")</code> 으로 결재 팝업 오픈</li>
<li>사용자가 Amaranth 결재창에서 작성·상신 → 완료 시 Amaranth 의 webhook 으로 상태 변경</li>
</ol>
<div class="callout success">
<strong>✓ 주요 파라미터</strong>
<div class="kv" style="margin-top: 8px;">
<dt>targetType</dt><dd><code>CONTRACT_ESTIMATE</code> (견적) / <code>CONTRACT_ORDER</code> (수주) / 등</dd>
<dt>formId</dt><dd>1162 (견적) / 1161 (수주) — Amaranth 양식 ID</dd>
<dt>compSeq</dt><dd>1000</dd>
<dt>approvalTitle</dt><dd>"견적서 결재 - 26C-0801" 같은 결재함 제목</dd>
</div>
</div>
</div>
<h4>결재 상태 코드</h4>
<table>
<tr><th>코드</th><th>의미</th><th>가능 액션</th></tr>
<tr><td><span class="badge primary">create</span></td><td>임시 저장 (작성중)</td><td>재상신 가능</td></tr>
<tr><td><span class="badge warn">inProcess</span></td><td>결재 진행 중</td><td>상신 불가 (가드)</td></tr>
<tr><td><span class="badge success">complete</span></td><td>결재 완료</td><td>후속 처리 가능 (수주확정 등)</td></tr>
<tr><td><span class="badge danger">reject</span></td><td>반려</td><td>수정 후 재상신</td></tr>
<tr><td><span class="badge danger">delete</span></td><td>회수/삭제</td><td>재상신 가능</td></tr>
<tr><td></td><td>notRequired / N</td><td>결재불필요 처리</td></tr>
</table>
<!-- 4.3 문제 해결 -->
<h3 id="amaranth-troubleshoot">4.3 문제 해결</h3>
<details>
<summary>Q. [결재상신] 클릭 시 "결재 시스템 연동 중 오류" 토스트가 표시됩니다.</summary>
<ol>
<li>[외부 커넥션 관리] 에서 <strong>Amaranth - 결재</strong> 의 [테스트] 버튼 실행</li>
<li>실패 시 auth_config 의 accessToken/hashKey 가 만료됐을 가능성 → 운영팀 또는 Wehago 관리자에게 키 재발급 요청</li>
<li>성공인데 결재상신이 안 되면 백엔드 로그 <code>docker logs rps_backend</code> 에서 <code>SSO API 응답</code> 확인</li>
</ol>
</details>
<details>
<summary>Q. "empSeq 정보가 없습니다" 오류가 납니다.</summary>
<p><code>user_info.emp_seq</code> 가 비어 있는 사용자입니다. 관리자 메뉴 [유저관리] 에서 해당 사용자의 emp_seq 를 Amaranth 사원 마스터의 값으로 채워야 합니다.</p>
</details>
<details>
<summary>Q. 결재 후 PLM 상태가 자동 업데이트되지 않습니다.</summary>
<p>Amaranth 측 webhook (콜백 URL) 설정이 RPS PLM 의 <code>/api/amaranth-approval/callback</code> 으로 등록돼 있어야 합니다. Wehago 관리 콘솔에서 확인 가능.</p>
</details>
<!-- ======================================================== -->
<h2 class="section" id="dashboard">5. 대시보드 관리</h2>
<h3>5.1 사용자 대시보드</h3>
<div class="card">
<p>로그인 후 메인 화면(<code>/dashboard</code>)에서 보여지는 위젯형 대시보드입니다. 회사별로 위젯 구성이 다릅니다.</p>
<ul>
<li><strong>매출 추이</strong> — 월별 매출 합계 라인 차트</li>
<li><strong>수주 잔량</strong> — 미출하 수주 막대 차트</li>
<li><strong>리스크 / 알림</strong> — 기상특보 / 교통사고 / 환율 (외부 API 자동 갱신, 10분 간격)</li>
<li><strong>To-Do</strong> — 결재 대기, 마감 임박 견적, 미입고 발주</li>
</ul>
</div>
<h3>5.2 모니터링 보드</h3>
<table>
<tr><th>보드</th><th>경로</th><th>주요 위젯</th></tr>
<tr>
<td>품질 모니터링</td>
<td><code>/COMPANY_16/monitoring/quality</code></td>
<td>일별 불량률 추이, 검사자 별 처리 건, 불량 유형 Top 10</td>
</tr>
<tr>
<td>생산 모니터링</td>
<td><code>/COMPANY_16/monitoring/production</code></td>
<td>실시간 작업지시 현황, 라인별 가동률, 계획 대비 실적</td>
</tr>
<tr>
<td>설비 모니터링</td>
<td><code>/COMPANY_16/monitoring/equipment</code></td>
<td>설비별 상태(가동/정지/점검), 알람 이력</td>
</tr>
</table>
<h3>5.3 대시보드 관리자 기능</h3>
<div class="card">
<p>위치: <code>관리자 &gt; 화면 관리 &gt; 대시보드 리스트</code></p>
<ul>
<li>회사별 대시보드 신규 생성 / 위젯 배치 / 권한 설정</li>
<li>위젯 종류: 카드 / 라인 차트 / 막대 차트 / 파이 차트 / 그리드 / 외부 URL embed</li>
<li>저장된 대시보드는 <code>/dashboard/{dashboardId}</code> 경로로 접근</li>
</ul>
</div>
<p class="callout">
<strong>💡 그리드 → 차트 즉시 변환</strong>
모든 업무 그리드(견적관리, 매출관리, 품질관리 등)는 우상단 <span class="badge primary">📊</span> 토글로
Top-N 데이터를 막대/파이 차트로 즉시 시각화할 수 있습니다.
</p>
<!-- ======================================================== -->
<h2 class="section" id="quality">6. 품질관리 메뉴 가이드</h2>
<h3>6.1 수입검사 요청</h3>
<div class="card">
<p><strong>경로</strong>: <code>/COMPANY_16/quality/incoming-request</code></p>
<p>발주서 단위로 입고/검사 요청 현황을 한 줄씩 보여줍니다. 검사 디테일이 아직 없으면 "미요청", 있으면 "요청중"/"요청완료".</p>
<h4>필터 (12종)</h4>
<p>품의서 No · 발주서 No · 프로젝트번호 · 품번 · 품명 · 공급업체 · 입고결과 · 제품구분 · 검사여부 · 요청현황 · 요청자 · 요청일 범위</p>
<h4>그리드 컬럼 (12개)</h4>
<p>품의서 No · 발주서 No · 프로젝트번호 · 제품구분 · 품번 · 품명 · 공급업체 · 입고결과 · 요청일 · 요청자 · 검사여부 · 요청현황</p>
</div>
<h3>6.2 수입검사 진행</h3>
<div class="card">
<p><strong>경로</strong>: <code>/COMPANY_16/quality/incoming-mgmt</code></p>
<p>검사자가 실제 검사를 진행하여 합/불 판정과 불량률(검사수량 대비)을 입력하는 화면입니다.</p>
<h4>주요 컬럼 (19개)</h4>
<p>검사일 · 검사자 · 품의서 · 발주서 · 프로젝트번호 · 제품구분 · 품명(모델명) · 부품품번 · 부품명 · 공급업체 · 입고일 · 입고수량 · 입고결과 · 검사수량 · 불량수량 · 불량률 · 검사현황 · 검사성적서(첨부파일)</p>
<p class="callout">불량률 = SUM(defect_qty 서브쿼리) / inspection_qty × 100, 소수점 2자리.</p>
</div>
<h3>6.3 공정검사 관리</h3>
<div class="card">
<p><strong>경로</strong>: <code>/COMPANY_16/quality/process-inspection</code></p>
<p>작업 중 SPC 검사. 마스터 1건당 디테일 N건(검사항목)을 SUM 으로 집계하여 한 줄로 표시.</p>
<h4>필터 (10종, 2행)</h4>
<ul>
<li>1행: 프로젝트번호 · 제품구분 · 품번 · 품명 · 작업환경상태 · 측정기</li>
<li>2행: 검사일 범위 · 검사자 · 검사결과 · 진행공정</li>
</ul>
<h4>그리드 컬럼 (9개)</h4>
<p>검사일 · 검사자 · 프로젝트번호 · 제품구분 · 품번 · 품명 · 검사수량 합계 · 검사결과(OK/NG) · 첨부파일</p>
</div>
<h3>6.4 반제품검사 관리</h3>
<div class="card">
<p><strong>경로</strong>: <code>/COMPANY_16/quality/semi-product-inspection</code></p>
<p>반제품 입고에 대한 양품/불량 판정. 단일 테이블(<code>pms_quality_semi_product_inspection</code>)에 양품 마스터(<code>DATA_TYPE='GOOD'</code>)와 불량 행(<code>'DEFECT'</code>)을 동일 <code>INSPECTION_GROUP_ID</code> 로 묶어 저장합니다.</p>
<h4>자동 산정 컬럼</h4>
<table>
<tr><th>컬럼</th><th>계산식</th></tr>
<tr><td>불량수량 합계</td><td>같은 group_id 의 DEFECT 행 defect_qty 합</td></tr>
<tr><td>불량률(%)</td><td>round(불량수량 / 입고수량 × 100, 2)</td></tr>
<tr><td>재생수량 합계</td><td>DEFECT 행 중 disposition_type='수정완료' 의 defect_qty 합</td></tr>
<tr><td>최종양품수량</td><td>good_qty + 재생수량</td></tr>
</table>
</div>
<!-- ======================================================== -->
<h2 class="section" id="common">7. 공통 UI 사용법</h2>
<h3>7.1 데이터 그리드</h3>
<div class="card">
<p>모든 업무 화면의 표는 동일한 <code>DataGrid</code> 컴포넌트로 통일됩니다.</p>
<ul>
<li><strong>컬럼 드래그</strong> — 헤더 ⋮⋮ 영역을 드래그해 컬럼 순서 변경</li>
<li><strong>정렬</strong> — 헤더 클릭 (asc/desc 토글)</li>
<li><strong>필터</strong> — 헤더 옆 깔때기 아이콘 → 고유값 체크박스 다중 선택</li>
<li><strong>인라인 편집</strong> — 셀 더블클릭 (편집 가능 컬럼만)</li>
<li><strong>🔃 새로고침 / 📊 차트 / ⬇ 엑셀 다운로드 / ⚙ 컬럼 표시 설정</strong> — 그리드 우상단 툴바</li>
<li><strong>페이지 사이즈</strong> — 우하단 드롭다운 (10/15/20/50/100)</li>
</ul>
</div>
<h3>7.2 필터바 (CompactFilterBar)</h3>
<p>화면 상단의 검색 영역. <strong>요청일</strong>·<strong>검사일</strong> 같은 날짜 범위는 캘린더 아이콘 클릭으로 달력 popover가 뜹니다(YYYY-MM-DD 직접 입력도 가능).</p>
<h3>7.3 페이지 헤더</h3>
<p>모든 화면 상단의 [검색] / [초기화] / 업무 액션(등록·삭제·결재상신 등)은 <code>PageHeader</code> 한 곳에 모입니다.</p>
<!-- ======================================================== -->
<h2 class="section" id="faq">8. 자주 묻는 질문</h2>
<details>
<summary>Q. 로그인 후 좌측 메뉴가 안 보입니다.</summary>
<p>해당 계정이 권한 그룹에 속해있지 않습니다. <code>관리자 &gt; 권한 그룹 관리</code>에서 사용자에게 메뉴를 부여하세요.</p>
</details>
<details>
<summary>Q. 그리드의 엑셀 다운로드가 "내보낼 데이터가 없습니다" 토스트만 나옵니다.</summary>
<p>현재 필터로 조회된 결과가 0건이라 그렇습니다. 검색 조건을 변경한 후 다시 [⬇ 엑셀 다운로드] 를 누르세요.</p>
</details>
<details>
<summary>Q. 결재상신 버튼이 비활성화 되어 있습니다.</summary>
<ul>
<li>행을 선택했는지 확인 (체크박스 클릭 또는 셀 클릭)</li>
<li>견적관리의 경우 [견적작성] 으로 견적서(템플릿)가 먼저 생성되어 있어야 함</li>
<li>이미 결재중/결재완료 인 건은 재상신 불가</li>
</ul>
</details>
<details>
<summary>Q. Amaranth 결재 팝업이 안 뜨고 에러만 납니다.</summary>
<p><a href="#amaranth-troubleshoot">4.3 문제 해결</a> 참조.</p>
</details>
<details>
<summary>Q. 화면이 "Loading chunk app/layout failed" 로 깨집니다.</summary>
<p>프론트엔드 dev 서버가 초기 컴파일 중이거나 OOM 으로 재시작 중입니다. 1~2분 기다린 후 하드 새로고침(Cmd+Shift+R / Ctrl+F5).</p>
</details>
<footer style="margin-top: 80px; padding-top: 24px; border-top: 1px solid var(--line); color: var(--muted); font-size: 13px;">
© RPS Korea PLM Team · 본 문서는 시스템 변경 시 함께 업데이트해야 합니다 (docs/manual/).
</footer>
</main>
</div>
</body>
</html>