- FastAPI + SQLAlchemy(aiosqlite) 기반 SR 상태 머신 (RECEIVED → PARSED → PENDING_APPROVAL → APPROVED → IN_PROGRESS → PENDING_PM_VALIDATION → COMPLETED / FAILED_ROLLBACK) - PM 승인 워크플로우 (ApprovalFlow 테이블) - SHA-256 해시 체인 감사 로그 (위변조 방지) - AES-256-GCM 서버 자격증명 암호화 (IP/PW API 미노출) - CMDB: 기관(MOF/MOIS/MSS) + 서버 정보 관리 - 더미 데이터 자동 시딩 (6개 SR, 3개 기관, 6개 서버) - Dark-theme SPA: 대시보드 / 칸반 보드 / SR 목록 / 감사 로그 / CMDB Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
187 lines
6.6 KiB
HTML
187 lines
6.6 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ko">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>GUARDiA ITSM</title>
|
||
<link rel="stylesheet" href="/static/style.css">
|
||
</head>
|
||
<body>
|
||
<div id="app">
|
||
|
||
<!-- ── Sidebar ───────────────────────────────────── -->
|
||
<aside id="sidebar">
|
||
<div id="sidebar-logo">
|
||
<div class="logo-icon">G</div>
|
||
<div>
|
||
<div class="logo-title">GUARDiA ITSM</div>
|
||
<div class="logo-sub">인프라 자동화 플랫폼</div>
|
||
</div>
|
||
</div>
|
||
|
||
<nav id="sidebar-nav">
|
||
<div class="nav-item active" data-view="dashboard">
|
||
<span class="nav-icon">📊</span> 대시보드
|
||
</div>
|
||
<div class="nav-item" data-view="board">
|
||
<span class="nav-icon">🗂️</span> 칸반 보드
|
||
</div>
|
||
<div class="nav-item" data-view="list">
|
||
<span class="nav-icon">📋</span> SR 목록
|
||
</div>
|
||
<div class="nav-item" data-view="audit">
|
||
<span class="nav-icon">🔐</span> 감사 로그
|
||
</div>
|
||
<div class="nav-item" data-view="cmdb">
|
||
<span class="nav-icon">🖥️</span> CMDB
|
||
</div>
|
||
</nav>
|
||
|
||
<div id="sidebar-footer">
|
||
<div class="status-dot online"></div>
|
||
<span>시스템 정상</span>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- ── Main ──────────────────────────────────────── -->
|
||
<main id="main">
|
||
|
||
<!-- Top bar -->
|
||
<header id="topbar">
|
||
<h1 id="page-title">대시보드</h1>
|
||
<div id="topbar-actions">
|
||
<button class="btn btn-primary" id="btn-new-sr">+ 새 SR</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Views -->
|
||
<div id="view-dashboard" class="view active">
|
||
<div class="stats-row" id="stats-row">
|
||
<!-- filled by JS -->
|
||
</div>
|
||
<div class="dashboard-grid">
|
||
<div class="card" id="recent-list-card">
|
||
<div class="card-header">최근 SR</div>
|
||
<div class="card-body" id="recent-list"></div>
|
||
</div>
|
||
<div class="card" id="status-chart-card">
|
||
<div class="card-header">상태별 현황</div>
|
||
<div class="card-body" id="status-chart"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="view-board" class="view">
|
||
<div id="kanban-board">
|
||
<!-- columns rendered by JS -->
|
||
</div>
|
||
</div>
|
||
|
||
<div id="view-list" class="view">
|
||
<div class="list-toolbar">
|
||
<input type="text" id="search-input" placeholder="SR 제목 검색…" class="search-box">
|
||
<select id="filter-status" class="filter-select">
|
||
<option value="">전체 상태</option>
|
||
<option value="RECEIVED">접수</option>
|
||
<option value="PARSED">파싱 완료</option>
|
||
<option value="PENDING_APPROVAL">승인 대기</option>
|
||
<option value="APPROVED">승인됨</option>
|
||
<option value="IN_PROGRESS">진행 중</option>
|
||
<option value="PENDING_PM_VALIDATION">PM 검증 대기</option>
|
||
<option value="COMPLETED">완료</option>
|
||
<option value="FAILED_ROLLBACK">롤백 실패</option>
|
||
<option value="REJECTED">반려</option>
|
||
</select>
|
||
<select id="filter-type" class="filter-select">
|
||
<option value="">전체 유형</option>
|
||
<option value="DEPLOY">배포</option>
|
||
<option value="RESTART">재기동</option>
|
||
<option value="LOG">로그</option>
|
||
<option value="INQUIRY">문의</option>
|
||
<option value="OTHER">기타</option>
|
||
</select>
|
||
</div>
|
||
<table class="sr-table" id="sr-table">
|
||
<thead>
|
||
<tr>
|
||
<th>SR ID</th><th>유형</th><th>제목</th>
|
||
<th>상태</th><th>우선순위</th><th>요청자</th><th>생성일</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="sr-tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div id="view-audit" class="view">
|
||
<div class="audit-header-row">
|
||
<span class="audit-title">감사 로그 (SHA-256 해시 체인)</span>
|
||
<button class="btn btn-secondary" id="btn-verify">체인 무결성 검증</button>
|
||
<span id="verify-result"></span>
|
||
</div>
|
||
<table class="sr-table" id="audit-table">
|
||
<thead>
|
||
<tr>
|
||
<th>#</th><th>SR</th><th>행위자</th><th>액션</th><th>내용</th>
|
||
<th>해시 (앞 12자)</th><th>시각</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="audit-tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div id="view-cmdb" class="view">
|
||
<div class="cmdb-grid" id="cmdb-grid"><!-- filled by JS --></div>
|
||
</div>
|
||
|
||
</main>
|
||
</div>
|
||
|
||
<!-- ── SR Detail Modal ────────────────────────────── -->
|
||
<div id="modal-overlay" class="hidden">
|
||
<div id="modal">
|
||
<button class="modal-close" id="modal-close-btn">×</button>
|
||
<div id="modal-body"><!-- filled by JS --></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── New SR Modal ───────────────────────────────── -->
|
||
<div id="new-sr-overlay" class="hidden">
|
||
<div id="new-sr-modal">
|
||
<button class="modal-close" id="new-sr-close">×</button>
|
||
<h2>새 SR 생성</h2>
|
||
<form id="new-sr-form">
|
||
<label>제목 <input type="text" name="title" required></label>
|
||
<label>설명 <textarea name="description" rows="3"></textarea></label>
|
||
<div class="form-row">
|
||
<label>유형
|
||
<select name="sr_type">
|
||
<option value="OTHER">기타</option>
|
||
<option value="DEPLOY">배포</option>
|
||
<option value="RESTART">재기동</option>
|
||
<option value="LOG">로그</option>
|
||
<option value="INQUIRY">문의</option>
|
||
</select>
|
||
</label>
|
||
<label>우선순위
|
||
<select name="priority">
|
||
<option value="MEDIUM">보통</option>
|
||
<option value="CRITICAL">긴급</option>
|
||
<option value="HIGH">높음</option>
|
||
<option value="LOW">낮음</option>
|
||
</select>
|
||
</label>
|
||
</div>
|
||
<div class="form-row">
|
||
<label>요청자 <input type="text" name="requested_by" required></label>
|
||
<label>기관코드 <input type="text" name="inst_code" placeholder="MOF / MOIS / MSS"></label>
|
||
</div>
|
||
<label>대상 서버 <input type="text" name="target_server" placeholder="예: MOF-WAS-01"></label>
|
||
<button type="submit" class="btn btn-primary" style="width:100%;margin-top:8px">생성</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="/static/app.js"></script>
|
||
</body>
|
||
</html>
|