587 lines
27 KiB
HTML
587 lines
27 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ko">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>PM_ver4 통합 관리자 어플리케이션 화면설계서</title>
|
||
<!-- Google Fonts - Inter & Noto Sans KR -->
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Noto+Sans+KR:wght@300;400;500;700&display=swap" rel="stylesheet">
|
||
|
||
<style>
|
||
:root {
|
||
--primary: #1e5149;
|
||
--primary-dark: #142e29;
|
||
--primary-soft: #e9eeed;
|
||
--border: #d2dcdb;
|
||
--accent: #4db251;
|
||
--bg: #f4f7f6;
|
||
--card-bg: #ffffff;
|
||
--text-main: #1f2937;
|
||
--text-muted: #4b5563;
|
||
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
||
--sidebar-width: 280px;
|
||
|
||
/* UI Status Colors */
|
||
--color-active: #4db251;
|
||
--bg-active: #eef8ee;
|
||
--color-inactive: #a5b9b6;
|
||
--bg-inactive: #f1f5f9;
|
||
--color-danger: #ef4444;
|
||
--bg-danger: #fee2e2;
|
||
--color-warning: #ff9800;
|
||
--bg-warning: #fff5e6;
|
||
}
|
||
|
||
* {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
font-family: 'Inter', 'Noto Sans KR', sans-serif;
|
||
background-color: var(--bg);
|
||
color: var(--text-main);
|
||
line-height: 1.7;
|
||
margin: 0;
|
||
padding: 0;
|
||
display: flex;
|
||
}
|
||
|
||
/* Sidebar Navigation */
|
||
aside {
|
||
width: var(--sidebar-width);
|
||
background: linear-gradient(180deg, var(--primary-dark) 0%, #0c1a18 100%);
|
||
color: #ffffff;
|
||
height: 100vh;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
overflow-y: auto;
|
||
border-right: 1px solid rgba(255, 255, 255, 0.1);
|
||
padding: 24px;
|
||
z-index: 100;
|
||
}
|
||
|
||
aside h2 {
|
||
font-size: 1.15rem;
|
||
font-weight: 700;
|
||
margin-bottom: 24px;
|
||
color: var(--accent);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
|
||
padding-bottom: 12px;
|
||
}
|
||
|
||
aside ul {
|
||
list-style: none;
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
|
||
aside li {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
aside a {
|
||
color: #b3c5c2;
|
||
text-decoration: none;
|
||
font-size: 0.9rem;
|
||
display: block;
|
||
padding: 8px 12px;
|
||
border-radius: 6px;
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
aside a:hover, aside li.active a {
|
||
color: #ffffff;
|
||
background-color: rgba(255, 255, 255, 0.08);
|
||
padding-left: 16px;
|
||
}
|
||
|
||
aside .category-title {
|
||
font-size: 0.75rem;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.05em;
|
||
color: #628781;
|
||
margin: 16px 0 8px 12px;
|
||
font-weight: 700;
|
||
}
|
||
|
||
/* Main Content */
|
||
main {
|
||
margin-left: var(--sidebar-width);
|
||
flex-grow: 1;
|
||
padding: 40px 50px;
|
||
max-width: 1000px;
|
||
}
|
||
|
||
header {
|
||
border-bottom: 2px solid var(--border);
|
||
padding-bottom: 24px;
|
||
margin-bottom: 40px;
|
||
}
|
||
|
||
header h1 {
|
||
font-size: 2.2rem;
|
||
font-weight: 700;
|
||
margin: 0 0 10px 0;
|
||
color: var(--primary);
|
||
}
|
||
|
||
header .subtitle {
|
||
font-size: 1.1rem;
|
||
color: var(--text-muted);
|
||
margin: 0;
|
||
}
|
||
|
||
/* Content Sections */
|
||
section {
|
||
background-color: var(--card-bg);
|
||
border-radius: 12px;
|
||
padding: 30px;
|
||
margin-bottom: 30px;
|
||
box-shadow: var(--shadow);
|
||
border: 1px solid var(--border);
|
||
}
|
||
|
||
h2.section-title {
|
||
font-size: 1.4rem;
|
||
font-weight: 700;
|
||
color: var(--primary);
|
||
margin-top: 0;
|
||
margin-bottom: 20px;
|
||
border-left: 4px solid var(--accent);
|
||
padding-left: 12px;
|
||
}
|
||
|
||
h3 {
|
||
font-size: 1.2rem;
|
||
font-weight: 600;
|
||
color: var(--primary-dark);
|
||
margin-top: 24px;
|
||
margin-bottom: 12px;
|
||
border-bottom: 1px solid #f1f5f9;
|
||
padding-bottom: 8px;
|
||
}
|
||
|
||
h4 {
|
||
font-size: 1.05rem;
|
||
font-weight: 600;
|
||
color: var(--primary);
|
||
margin-top: 16px;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
p {
|
||
margin: 0 0 16px 0;
|
||
color: var(--text-main);
|
||
}
|
||
|
||
/* Color Chips */
|
||
.color-palette {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 16px;
|
||
margin: 20px 0;
|
||
}
|
||
|
||
.color-chip {
|
||
flex: 1 1 200px;
|
||
border: 1px solid var(--border);
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
background-color: #ffffff;
|
||
box-shadow: var(--shadow);
|
||
}
|
||
|
||
.color-box {
|
||
height: 60px;
|
||
width: 100%;
|
||
}
|
||
|
||
.color-details {
|
||
padding: 10px 12px;
|
||
}
|
||
|
||
.color-name {
|
||
font-weight: 700;
|
||
font-size: 0.85rem;
|
||
margin-bottom: 2px;
|
||
}
|
||
|
||
.color-value {
|
||
font-family: monospace;
|
||
font-size: 0.8rem;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
/* Layout Preview map */
|
||
.layout-preview {
|
||
background-color: #1e293b;
|
||
color: #cbd5e1;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
font-family: monospace;
|
||
font-size: 0.8rem;
|
||
white-space: pre;
|
||
overflow-x: auto;
|
||
margin: 20px 0;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
/* Status Badge */
|
||
.status-badge {
|
||
display: inline-block;
|
||
padding: 2px 8px;
|
||
border-radius: 4px;
|
||
font-size: 0.8rem;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.status-badge-active { background-color: var(--bg-active); color: var(--color-active); }
|
||
.status-badge-inactive { background-color: var(--bg-inactive); color: var(--color-inactive); }
|
||
.status-badge-danger { background-color: var(--bg-danger); color: var(--color-danger); }
|
||
.status-badge-warning { background-color: var(--bg-warning); color: var(--color-warning); }
|
||
|
||
/* Tables */
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin: 16px 0;
|
||
font-size: 0.88rem;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
border: 1px solid var(--border);
|
||
}
|
||
|
||
th {
|
||
background-color: var(--primary-soft);
|
||
color: var(--primary-dark);
|
||
font-weight: 600;
|
||
text-align: left;
|
||
padding: 10px 14px;
|
||
border-bottom: 2px solid var(--border);
|
||
}
|
||
|
||
td {
|
||
padding: 10px 14px;
|
||
border-bottom: 1px solid var(--border);
|
||
color: var(--text-main);
|
||
}
|
||
|
||
tr:last-child td {
|
||
border-bottom: none;
|
||
}
|
||
|
||
/* Lists */
|
||
ul {
|
||
padding-left: 20px;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
li {
|
||
margin-bottom: 6px;
|
||
}
|
||
|
||
.spec-card {
|
||
border: 1px solid var(--border);
|
||
border-radius: 8px;
|
||
padding: 16px;
|
||
margin-bottom: 16px;
|
||
background-color: #f9fafb;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- Sidebar Navigation -->
|
||
<aside>
|
||
<h2>📁 PM_ver4 Spec</h2>
|
||
<ul>
|
||
<li><a href="#overview">설계서 소개</a></li>
|
||
</ul>
|
||
|
||
<div class="category-title">01. 디자인 시스템</div>
|
||
<ul>
|
||
<li><a href="#design-system">디자인 가이드라인</a></li>
|
||
</ul>
|
||
|
||
<div class="category-title">02. 공통 프레임</div>
|
||
<ul>
|
||
<li><a href="#layout">App Frame 레이아웃</a></li>
|
||
</ul>
|
||
|
||
<div class="category-title">03. 화면별 UI/UX 명세</div>
|
||
<ul>
|
||
<li><a href="#screen-dashboard">📊 종합 용량 및 접속자</a></li>
|
||
<li><a href="#screen-project">🏗️ 프로젝트 관리</a></li>
|
||
<li><a href="#screen-banner">📢 실시간 배너 공지</a></li>
|
||
<li><a href="#screen-user">👥 사용자 관리</a></li>
|
||
<li><a href="#screen-audit">🔎 감사 로그 조회</a></li>
|
||
<li><a href="#screen-policy">⚙️ 보관 및 삭제 설정</a></li>
|
||
<li><a href="#screen-codes">🔑 공통 코드 관리</a></li>
|
||
</ul>
|
||
</aside>
|
||
|
||
<!-- Main Content -->
|
||
<main>
|
||
<header id="overview">
|
||
<h1>PM_ver4 통합 관리자 어플리케이션 화면설계서</h1>
|
||
<p class="subtitle">UI/UX Specification - 대시보드 및 관리자 화면 기능 명세서</p>
|
||
</header>
|
||
|
||
<!-- Section 1 -->
|
||
<section id="design-system">
|
||
<h2 class="section-title">1. 공통 UI 가이드라인 및 디자인 시스템</h2>
|
||
<p>관리자 패널의 모든 화면 레이아웃, 컴포넌트 명세, 사용자 액션 및 데이터 정합성 검증 규칙은 본 시스템의 디자인 규칙을 준수합니다.</p>
|
||
|
||
<h3>① 색상 토큰 (Color Tokens)</h3>
|
||
<div class="color-palette">
|
||
<div class="color-chip">
|
||
<div class="color-box" style="background-color: #1e5149;"></div>
|
||
<div class="color-details">
|
||
<div class="color-name">Primary Forest Green</div>
|
||
<div class="color-value">#1e5149</div>
|
||
</div>
|
||
</div>
|
||
<div class="color-chip">
|
||
<div class="color-box" style="background-color: #142e29;"></div>
|
||
<div class="color-details">
|
||
<div class="color-name">Dark Teal Sidebar</div>
|
||
<div class="color-value">#142e29</div>
|
||
</div>
|
||
</div>
|
||
<div class="color-chip">
|
||
<div class="color-box" style="background-color: #d2dcdb;"></div>
|
||
<div class="color-details">
|
||
<div class="color-name">Light Green Gray Border</div>
|
||
<div class="color-value">#d2dcdb</div>
|
||
</div>
|
||
</div>
|
||
<div class="color-chip">
|
||
<div class="color-box" style="background-color: #e9eeed;"></div>
|
||
<div class="color-details">
|
||
<div class="color-name">Soft Accent Green BG</div>
|
||
<div class="color-value">#e9eeed</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<h3>② 서체 (Typography)</h3>
|
||
<ul>
|
||
<li><strong>서체 패밀리</strong>: <code>'Pretendard Variable', 'Pretendard', 'Inter', 'Noto Sans KR', sans-serif</code></li>
|
||
<li><strong>글꼴 크기 명세</strong>:
|
||
<ul>
|
||
<li>페이지 메인 타이틀: <code>1.25rem</code> (700 Bold)</li>
|
||
<li>카드 타이틀: <code>1.05rem</code> (700 Bold)</li>
|
||
<li>일반 본문 및 테이블 데이터: <code>0.875rem</code> (500 Medium / 600 Semi-Bold)</li>
|
||
<li>Muted 보조 텍스트: <code>0.8rem</code> / <code>0.75rem</code></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3>③ 공통 그리드 & 테이블 (Table Grid Rules)</h3>
|
||
<ul>
|
||
<li><strong>순번 표시 (NO)</strong>: 모든 테이블 그리드의 1열은 데이터 인덱스 번호(<code>NO</code>)를 필수 노출합니다.</li>
|
||
<li><strong>가로 구분선</strong>: 답답한 디자인을 방지하기 위해 세로 테두리(Vertical Borders)는 일절 노출하지 않으며, 가로 행 구분선만 노출합니다.</li>
|
||
<li><strong>행 선택 인터랙션</strong>: 마우스 호버 시 <code>var(--primary-soft)</code> 배경색을 지정하며, 클릭 행 활성화 시 텍스트 두께 변경으로 인한 줄높이 왜곡이 없도록 패딩 상속(inherit) 속성을 적용하여 균일한 행 높이를 유지합니다.</li>
|
||
</ul>
|
||
|
||
<h3>④ 공통 모달 팝업 (Modal Overlay Rules)</h3>
|
||
<ul>
|
||
<li><strong>백드롭</strong>: <code>rgba(20, 30, 29, 0.6)</code> 반투명 딤 및 <code>backdrop-filter: blur(4px)</code> 효과로 모달 포커스를 고정합니다.</li>
|
||
<li><strong>트랜지션</strong>: <code>fade-in</code> 및 <code>slide-up (translateY 30px to 0)</code>이 일괄 적용되어 매끄러운 팝업 동작을 보장합니다.</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<!-- Section 2 -->
|
||
<section id="layout">
|
||
<h2 class="section-title">2. 레이아웃 구조 설계 (App Frame Layout)</h2>
|
||
<p>LNB, 상단 헤더, 그리고 메인 콘텐츠 탭 영역의 수평/수직 분할 아키텍처는 다음과 같습니다.</p>
|
||
|
||
<div class="layout-preview">
|
||
+-------------------------------------------------------------------------+
|
||
| LNB (좌측 사이드바) | Main Header (상단 헤더) |
|
||
| 📁 PM_ver4 Admin | [Header Title] [Admin Profile] |
|
||
|-------------------------+-----------------------------------------------|
|
||
| - Dashboards | Main Content (메인 콘텐츠 탭 영역) |
|
||
| 📊 종합 용량/접속자 | |
|
||
| - 프로젝트 관리 | +-----------------------------------------+ |
|
||
| 🏗️ 프로젝트 관리 | | 카드 1 (필터 / 테이블 리스트) | |
|
||
| 📢 실시간 배너 공지 | +-----------------------------------------+ |
|
||
| - 사용자 및 권한 | | 카드 2 (상세정보 뷰 / 팝업 연동 리스트) | |
|
||
| 👥 사용자 관리 | +-----------------------------------------+ |
|
||
| - 시스템 감사 및 환경 | |
|
||
| 🔎 감사 로그 조회 | |
|
||
| ⚙️ 자동 삭제 설정 | |
|
||
| 🔑 공통 코드 관리 | |
|
||
+-------------------------------------------------------------------------+</div>
|
||
</section>
|
||
|
||
<!-- Section 3 -->
|
||
<section id="screen-dashboard">
|
||
<h2 class="section-title">3. 화면별 상세 UI 및 기능 설계</h2>
|
||
|
||
<h3>📊 화면 1: 종합 용량 및 접속자 현황 (Dashboard)</h3>
|
||
<p>상단 3열 KPI 요약 카드와 하단 스토리지 프로그레스바 및 실시간 소켓 접속자 테이블 구조입니다.</p>
|
||
|
||
<div class="spec-card">
|
||
<h4>① 주요 UI 컴포넌트</h4>
|
||
<ul>
|
||
<li><strong>스토리지 KPI 카드</strong>: 전체 현장의 총 한도 용량 대비 누적 사용 용량 실시간 합산 표시 (예: <code>💾 9.70 GB / 20 GB</code>).</li>
|
||
<li><strong>접속자 KPI 카드</strong>: 현재 소켓 서버 연결 세션 수 노출.</li>
|
||
<li><strong>압축작업 KPI 카드</strong>: Redis(BullMQ) 내 대기중인 압축 건수.</li>
|
||
<li><strong>현장별 스토리지 사용 현황</strong>: 각 프로젝트 ID/명칭, 게이지바 및 사용량 정보(GB / 백분율% / 파일수량개) 동시 렌더링.</li>
|
||
</ul>
|
||
|
||
<h4>② 실시간 접속 현황 테이블 사양</h4>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th style="width: 10%;">NO</th>
|
||
<th style="width: 25%;">사용자 ID</th>
|
||
<th style="width: 25%;">접속 IP</th>
|
||
<th style="width: 25%;">현재 조회 경로</th>
|
||
<th style="width: 15%;">작업</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>1</td>
|
||
<td>admin_test</td>
|
||
<td>127.0.0.1</td>
|
||
<td><code>/PM_TEST_01/archive</code></td>
|
||
<td><span class="status-badge status-badge-danger" style="cursor: pointer;">강제퇴장</span></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="screen-project">
|
||
<h3>🏗️ 화면 2: 프로젝트 관리 (Project Management)</h3>
|
||
<p>좌측 프로젝트 목록 그리드와 우측 프로젝트별 참여자 및 배정 통제 그리드 구조입니다.</p>
|
||
|
||
<div class="spec-card">
|
||
<h4>① 프로젝트 목록 테이블 사양 (좌측 카드)</h4>
|
||
<p>출력 컬럼: <code>NO</code> | <code>프로젝트 ID</code> | <code>현장명</code> | <code>카테고리</code> | <code>용량 제한(GB)</code> | <code>상태</code> | <code>관리(수정/삭제)</code></p>
|
||
<ul>
|
||
<li>행 클릭 시, 우측의 '참여 권한 사용자 목록'이 해당 프로젝트 정보로 자동 리바인딩됩니다.</li>
|
||
<li><strong>삭제 제한</strong>: 관련 테이블(tb_data, tb_official_doc_file, tb_banner_notice 등)에 현장 ID 사용 이력이 있으면 삭제 불가능하며 경고 메시지가 발생합니다.</li>
|
||
<li><strong>신규 프로젝트 등록 및 수정 모달 (projectModalOverlay)</strong>: 프로젝트 ID(수정 시 Readonly), 프로젝트명, 단축명, 카테고리 Select, 스토리지 제한(GB), 상태를 편집합니다.</li>
|
||
</ul>
|
||
|
||
<h4>② 참여 권한 사용자 목록 (우측 카드 - 병합 영역)</h4>
|
||
<p>출력 컬럼: <code>NO</code> | <code>사용자 ID</code> | <code>이름</code> | <code>부서/직급</code> | <code>권한 등급</code> | <code>작업(배정제외)</code></p>
|
||
<ul>
|
||
<li><strong>권한 등급 변경</strong>: 인라인 셀렉터(Admin, Sub-Master, Worker, Viewer)로 권한 레벨 즉시 업데이트.</li>
|
||
<li><strong>사용자 배정 추가 팝업 모달 (assignModalOverlay)</strong>: 현재 현장에 미배정된 사용자들을 체크박스로 다중 선택하여 일괄 추가합니다. 또한 목록 선택식을 지원하기 위해 우측 하단 배정 대기 목록에서도 '즉시 배정' 단축 버튼을 제공합니다.</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="screen-banner">
|
||
<h3>📢 화면 3: 실시간 배너 공지 (Banner Notice)</h3>
|
||
<p>상단 배너 등록 폼 카드 및 하단 이력 검색 조건 필터와 이력 목록 그리드 구조입니다.</p>
|
||
|
||
<div class="spec-card">
|
||
<h4>① 배너 공지 등록 폼</h4>
|
||
<ul>
|
||
<li>입력 필드: 대상 프로젝트 선택(특정 현장 또는 전체 현장 'all' 매핑), 등록일(임의 편집 지원), 시작일, 종료일, 공지 자막 텍스트.</li>
|
||
<li>송출 등록 제출 시, 오늘 일자와 비교하여 즉시 이력에 추가되고 상태 배지가 실시간 부여됩니다.</li>
|
||
</ul>
|
||
|
||
<h4>② 이력 목록 필터 및 이력 테이블</h4>
|
||
<ul>
|
||
<li><strong>검색 필터</strong>: 송출 상태(전체, 송출중, 예약됨, 만료) 및 등록일(from ~ to) 날짜 범위 지정 검색.</li>
|
||
<li><strong>테이블 명세</strong>: <code>NO</code> | <code>등록일</code> | <code>대상 프로젝트</code> | <code>공지 내용</code> | <code>시작일</code> | <code>종료일</code> | <code>송출 상태</code> | <code>작업</code></li>
|
||
<li><strong>송출 중지 통제</strong>: 아직 기간이 유효한 행(송출중, 예약됨)에만 <code>[송출 중지]</code> 버튼이 노출 및 활성화되며, 이미 만료된 이력은 <code>[중지 완료]</code> 비활성 텍스트로 대체하여 이중 제어를 차단합니다.</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="screen-user">
|
||
<h3>👥 화면 4: 사용자 관리 (User Management)</h3>
|
||
<p>좌측 사용자 마스터 리스트 및 우측 선택된 사용자의 참여 권한 프로젝트 리스트업 구조입니다.</p>
|
||
|
||
<div class="spec-card">
|
||
<h4>① 사용자 계정 목록 (좌측 카드)</h4>
|
||
<p>출력 컬럼: <code>NO</code> | <code>아이디</code> | <code>이름</code> | <code>소속/직급</code> | <code>그룹</code> | <code>상태</code> | <code>관리(수정/삭제)</code></p>
|
||
<ul>
|
||
<li>행 클릭 시, 해당 사용자가 참여하고 있는 프로젝트 리스트가 우측 카드에 즉시 바인딩됩니다.</li>
|
||
<li><strong>삭제 제한</strong>: 권한 테이블(tb_permission)에 현장 배정/참여 권한 정보가 등록되어 있으면 삭제가 불가능하며 경고 메시지가 발생합니다.</li>
|
||
<li><strong>사용자 등록 및 수정 모달 (userModalOverlay)</strong>: 아이디(수정 시 Readonly), 패스워드, 이름, 회사명, 부서, 직급, 권한 그룹 지정 select, 재직 상태(재직/퇴직잠금) 지정.</li>
|
||
</ul>
|
||
|
||
<h4>② 권한부여 프로젝트 목록 (우측 카드)</h4>
|
||
<p>출력 컬럼: <code>NO</code> | <code>프로젝트 ID</code> | <code>프로젝트명</code> | <code>부여 권한 등급</code></p>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="screen-audit">
|
||
<h3>🔎 화면 5: 감사 로그 조회 (Audit Logs)</h3>
|
||
<p>파일 조작 중요 이벤트(삭제, 이동, 다운로드) 목록 및 검색 조회 화면입니다.</p>
|
||
|
||
<div class="spec-card">
|
||
<h4>① 감사 로그 목록 사양</h4>
|
||
<p>출력 컬럼: <code>NO</code> | <code>일시</code> | <code>프로젝트</code> | <code>사용자 ID</code> | <code>접속 IP</code> | <code>조작 액션</code> | <code>조작 대상 경로(코드박스 스타일)</code></p>
|
||
<ul>
|
||
<li>필터링 항목: 사용자 ID 검색 입력란, 조작 액션 Dropdown, 검색 기능.</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="screen-policy">
|
||
<h3>⚙️ 화면 6: 자동 보관 및 파일 삭제 정책 설정 (Delete Policy)</h3>
|
||
<p>시스템 글로벌 일괄 정책 설정 영역, 실시간 예정 시나리오 요약, 그리고 배치 처리 이력 구조입니다.</p>
|
||
|
||
<div class="spec-card">
|
||
<h4>① 시스템 공통 자동 삭제 정책 설정 폼 [글로벌 정책 공통화]</h4>
|
||
<ul>
|
||
<li><strong>입력 필드</strong>: 정책 활성화 여부(Toggle/Select), 최소 유지 파일 개수 기준(숫자 입력), 자동 삭제 제한 기한(일) (숫자 입력).</li>
|
||
<li><strong>글로벌 통합</strong>: 기존의 프로젝트 개별 Dropdown은 완전히 배제하고, 전체 현장에 동일하게 일괄 반영합니다.</li>
|
||
</ul>
|
||
|
||
<h4>② 보존 정책 실시간 요약 (Dynamic Summary)</h4>
|
||
<ul>
|
||
<li>폼의 입력값을 변경하는 즉시 요약 영역 텍스트가 시나리오 문구로 동적 조합되어 나타납니다.</li>
|
||
<li>예: <code>"현재 전체 공통 설정에 따라, 각 현장의 보관 파일 수가 100개 미만이고 30일이 지나면 자동 삭제 배치 스케줄러가 작동합니다."</code></li>
|
||
</ul>
|
||
|
||
<h4>③ 자동 삭제 처리 이력 테이블 사양</h4>
|
||
<p>출력 컬럼: <code>NO</code> | <code>자동 처리 일자</code> | <code>프로젝트 ID</code> | <code>삭제 처리 폴더 경로</code> | <code>적용 기준</code> | <code>처리 결과(성공 배지)</code></p>
|
||
<ul>
|
||
<li>정책 값 저장 완료 시 이력 로그의 대상 프로젝트 ID 자리에는 <code>'SYSTEM'</code>이 기입됩니다.</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="screen-codes">
|
||
<h3>🔑 화면 7: 공통 코드 관리 (Common Code Management)</h3>
|
||
<p>대분류 마스터 및 세부 코드 리스트가 배치되는 상하 2단 수직 정렬 레이아웃 구조입니다.</p>
|
||
|
||
<div class="spec-card">
|
||
<h4>① 대분류 코드 마스터 (상단 카드)</h4>
|
||
<p>출력 컬럼: <code>NO</code> | <code>대분류 코드</code> | <code>대분류 코드명</code> | <code>사용</code> | <code>관리(수정/삭제)</code></p>
|
||
<ul>
|
||
<li>행을 선택(click)하면 해당 행이 하이라이트(selected)되며, 하단의 세부 코드 그리드가 동적으로 새로고침됩니다.</li>
|
||
<li><strong>대분류 등록 및 수정 모달 (codeMasterModalOverlay)</strong>: 대분류 코드, 명칭, 사용여부, 비고 설명 입력.</li>
|
||
</ul>
|
||
|
||
<h4>② 세부 소분류 코드 목록 (하단 카드)</h4>
|
||
<p>출력 컬럼: <code>NO</code> | <code>소분류 코드</code> | <code>조합 코드 (base_code)</code> | <code>코드 명칭</code> | <code>정렬 순서</code> | <code>사용</code> | <code>관리(수정/삭제)</code></p>
|
||
<ul>
|
||
<li><strong>유효성 방어 차단</strong>: 상단 대분류 테이블에서 행을 클릭하여 선택하지 않은 상태에서는 하단의 <code>[➕ 세부코드 등록]</code> 버튼이 강제 비활성화(disabled)되며, 팝업 접근 시 안내 팝업 및 경고 텍스트(<code>"상단에서 대분류 코드를 선택해 주세요."</code>)를 노출합니다.</li>
|
||
<li><strong>조합 코드(base_code)</strong>: 소분류 생성 완료 제출 시, <code>대분류코드_소분류코드</code> 형태로 자동 결합되어 저장됩니다.</li>
|
||
<li><strong>삭제 제한 (RESTRICT)</strong>: 마스터 대분류 코드를 삭제할 경우, 하위 세부 코드(code_detail)가 존재하면 대분류 삭제가 차단되고 경고 메시지를 노출합니다. (세부 코드가 먼저 삭제되어 비어있을 때만 대분류 삭제 가능)</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
</body>
|
||
</html>
|