542 lines
38 KiB
HTML
542 lines
38 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 프로젝트 로컬 적용 및 디버깅 조치 총괄표</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;600;700&family=Noto+Sans+KR:wght@300;400;500;700&display=swap" rel="stylesheet">
|
|
|
|
<style>
|
|
:root {
|
|
--primary: #f43f5e;
|
|
--primary-dark: #be123c;
|
|
--primary-light: #fff1f2;
|
|
--bg: #f8fafc;
|
|
--card-bg: #ffffff;
|
|
--text-main: #0f172a;
|
|
--text-muted: #475569;
|
|
--border: #e2e8f0;
|
|
--shadow: 0 4px 6px -1px rgb(0 0 0 / 0.05), 0 2px 4px -2px rgb(0 0 0 / 0.05);
|
|
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.05), 0 4px 6px -4px rgb(0 0 0 / 0.05);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 40px auto;
|
|
padding: 40px;
|
|
background-color: var(--card-bg);
|
|
border-radius: 16px;
|
|
box-shadow: var(--shadow-lg);
|
|
border: 1px solid var(--border);
|
|
}
|
|
|
|
/* Header Styling */
|
|
header {
|
|
border-bottom: 2px solid var(--border);
|
|
padding-bottom: 24px;
|
|
margin-bottom: 30px;
|
|
}
|
|
|
|
h1 {
|
|
font-size: 2.2rem;
|
|
font-weight: 700;
|
|
margin: 0 0 8px 0;
|
|
background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
}
|
|
|
|
.subtitle {
|
|
font-size: 1.1rem;
|
|
color: var(--text-muted);
|
|
margin: 0;
|
|
}
|
|
|
|
/* Premium Table Styles */
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin: 24px 0;
|
|
font-size: 0.95rem;
|
|
box-shadow: var(--shadow);
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
border: 1px solid var(--border);
|
|
}
|
|
|
|
th {
|
|
background-color: var(--primary-dark);
|
|
color: #ffffff;
|
|
font-weight: 600;
|
|
text-align: left;
|
|
padding: 14px 16px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
td {
|
|
padding: 14px 16px;
|
|
border-bottom: 1px solid var(--border);
|
|
background-color: #ffffff;
|
|
color: var(--text-muted);
|
|
vertical-align: top;
|
|
}
|
|
|
|
tr:last-child td {
|
|
border-bottom: none;
|
|
}
|
|
|
|
tr:nth-child(even) td {
|
|
background-color: #f8fafc;
|
|
}
|
|
|
|
tr:hover td {
|
|
background-color: var(--primary-light);
|
|
color: var(--text-main);
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.date-badge {
|
|
display: inline-block;
|
|
background-color: #e2e8f0;
|
|
color: #334155;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
font-size: 0.8rem;
|
|
font-weight: 600;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.file-path {
|
|
font-family: monospace;
|
|
font-size: 0.85rem;
|
|
color: #0369a1;
|
|
background-color: #f0f9ff;
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
display: inline-block;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
/* Responsive Design */
|
|
@media (max-width: 1024px) {
|
|
.container {
|
|
margin: 0;
|
|
padding: 20px;
|
|
border-radius: 0;
|
|
box-shadow: none;
|
|
border: none;
|
|
}
|
|
table {
|
|
display: block;
|
|
overflow-x: auto;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="container">
|
|
<header>
|
|
<h1>PM 프로젝트 로컬 적용 및 디버깅 조치 총괄표</h1>
|
|
<p class="subtitle">로컬 개발 및 가동 중 조치된 오류 분석 이력서</p>
|
|
</header>
|
|
|
|
<p>본 표는 프로젝트(<code>PM_ver4</code>)를 로컬 환경에 기동 및 검증하는 과정에서 발견된 에러들의 유발 요인과 대처 및 보완 처리 이력(적용일시 포함)을 총괄 관리하는 명세서입니다.</p>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 5%; text-align: center;">번호</th>
|
|
<th style="width: 15%;">적용일시</th>
|
|
<th style="width: 20%;">작업 영역 (대상 파일)</th>
|
|
<th style="width: 25%;">발생 원인 (Issue)</th>
|
|
<th style="width: 35%;">대처 및 수정 내역 (Solution)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<!-- 24 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">24</td>
|
|
<td><span class="date-badge">2026-06-12 16:35</span></td>
|
|
<td>
|
|
<strong>사용자 관리 모달 수정 기능 복구</strong><br>
|
|
<span class="file-path">views/admin/dashboard.html</span>
|
|
</td>
|
|
<td>
|
|
사용자 관리 탭의 수정 모달 열기 분기(<code>openUserModal</code>) 내부에서 기존 유저 데이터를 폼에 로드하고 서브밋 이벤트를 연결하는 기능이 유실되었으며, 미정의 변수 <code>err</code> 참조 에러(<code>ReferenceError</code>)로 스크립트 실행이 중단됨.
|
|
</td>
|
|
<td>
|
|
1. 수정 모드일 때 비밀번호 칸(<code>form-user-pw</code>)을 숨김(<code>display='none'</code>) 및 required 속성 해제.<br>
|
|
2. API를 통해 기존 사용자 정보를 가져와 모달 입력 폼에 각각 동적 바인딩.<br>
|
|
3. <code>form.onsubmit</code>에 수정 서브밋 함수(<code>submitEditUser</code>)를 바인딩하여 정보 갱신 차단 요인 해결.<br>
|
|
4. 사용자 관리 모달 창의 닫기/취소 버튼 클릭 시 모달이 숨겨지도록 <code>closeUserModal</code> 함수 구현 및 매핑.
|
|
</td>
|
|
</tr>
|
|
<!-- 23 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">23</td>
|
|
<td><span class="date-badge">2026-06-12 15:55</span></td>
|
|
<td>
|
|
<strong>만료 및 삭제 정책 사용자 아카이브 화면 연동</strong><br>
|
|
<span class="file-path">views/main/jsm/archive/pageRenderer.js, controllers/commonController.js, routes/commonRouter.js</span>
|
|
</td>
|
|
<td>
|
|
사용자 아카이브 폴더 만료 임계치(3개, 15일)가 클라이언트 단 스크립트에 하드코딩되어, 관리자 대시보드에서 보존 정책을 변경해도 화면의 만료 안내 배지 및 툴팁에 실시간 반영되지 않음.
|
|
</td>
|
|
<td>
|
|
1. 일반 사용자 권한에서도 정책을 읽어갈 수 있는 공개 API(<code>GET /common/system-policy</code>) 개설.<br>
|
|
2. 아카이브 렌더러가 최초 로딩 시 API를 조회해 임계치 변수를 덮어쓰도록 처리.<br>
|
|
3. 정책 일시 중지(<code>is_active=false</code>) 상태인 경우 화면에 D-day 배지가 노출되지 않도록 정보 정합성 보강.
|
|
</td>
|
|
</tr>
|
|
<!-- 22 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">22</td>
|
|
<td><span class="date-badge">2026-06-12 14:55</span></td>
|
|
<td>
|
|
<strong>보관 삭제 정책 탭 프로젝트 공통 설정화</strong><br>
|
|
<span class="file-path">views/admin/dashboard.html</span>
|
|
</td>
|
|
<td>
|
|
기존의 '설정 대상 프로젝트' Dropdown 및 관련 바인딩 이벤트가 깡통(에러)으로 남아있어 사용자에게 혼선을 유발하고 폼 갱신 시 input ID 불일치 오류가 발생함.
|
|
</td>
|
|
<td>
|
|
1. 프로젝트 선택 셀렉터를 제거하고 <code>"전체 현장 공통 (GLOBAL)"</code> 읽기 전용 텍스트 필드로 대체.<br>
|
|
2. 폼 input ID들을 스크립트 규격과 동기화하고 변경 저장 시 공통 정책 수정 API가 정확히 맵핑되도록 수정.<br>
|
|
3. 기본값 초기화(<code>resetPolicyConfig</code>) 함수를 추가하여 폼 리셋 정상화.
|
|
</td>
|
|
</tr>
|
|
<!-- 21 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">21</td>
|
|
<td><span class="date-badge">2026-06-12 14:45</span></td>
|
|
<td>
|
|
<strong>감사 로그 테이블 렌더링 및 필터링 정상화</strong><br>
|
|
<span class="file-path">views/admin/dashboard.html</span>
|
|
</td>
|
|
<td>
|
|
감사 로그 테이블의 <code><tbody></code> 엘리먼트에 ID(<code>id="audit-log-body"</code>)가 누락되어 스크립트의 데이터 렌더링 과정이 중단되고 템플릿의 하드코딩 샘플 데이터가 계속 노출됨.
|
|
</td>
|
|
<td>
|
|
1. 테이블 tbody에 <code>id="audit-log-body"</code>를 부여하고 기존의 하드코딩 tr 샘플 행 완전 제거.<br>
|
|
2. 필터 검색란의 유저 검색창 및 액션 셀렉터에 ID를 부여하고 검색 버튼 클릭 시 <code>renderAuditLogs()</code>가 작동하도록 연동.
|
|
</td>
|
|
</tr>
|
|
<!-- 20 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">20</td>
|
|
<td><span class="date-badge">2026-06-12 10:00</span></td>
|
|
<td>
|
|
<strong>감사 로그 조회 실데이터 미반영 수정</strong><br>
|
|
<span class="file-path">controllers/admin/adminController.js, controllers/archiveController.js</span>
|
|
</td>
|
|
<td>
|
|
로그 수집 테이블과 연동된 컨트롤러에서 최신 데이터가 반영되지 않는 현상.
|
|
</td>
|
|
<td>
|
|
로그 수집 DB 쿼리 파라미터 최신화 및 캐시 무효화 적용.
|
|
</td>
|
|
</tr>
|
|
<!-- 19 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">19</td>
|
|
<td><span class="date-badge">2026-06-11 16:25</span></td>
|
|
<td>
|
|
<strong>자동 삭제 보존 정책 공통화 및 스키마 구조 변경</strong><br>
|
|
<span class="file-path">관리자화면_통합대시보드_UI제안.html</span>
|
|
</td>
|
|
<td>
|
|
자동 보관 및 파일 삭제 정책 설정이 프로젝트(현장)별로 각각 제어되도록 설계되어 있었으나, 모든 현장에 일괄적으로 일관성 있게 공통(글로벌) 적용되는 형태로 비즈니스 정책이 간소화됨. 이에 따라 기존 프로젝트별 컬럼(<code>tb_project.limit_file_count</code>, <code>tb_project.limit_days</code>)을 이용해 개별 제어하던 기능과 LNB/UI Dropdown을 일괄 제거하고, 시스템 공통 정책 별도 테이블로의 마이그레이션이 필요함.
|
|
</td>
|
|
<td>
|
|
1. UI 제안서 HTML 마크업에서 자동 삭제 정책 탭 내의 '설정 대상 프로젝트' Dropdown 셀렉터를 완전히 제거하고, 시스템 공통 단일 설정 폼으로 축소/재편함.<br>
|
|
2. JS Mock 데이터 상에서 기존 프로젝트별 <code>policySettings</code> 맵 객체를 제거하고, 단일 글로벌 정책 객체(<code>globalPolicy = { active, files, days }</code>)를 신설하여 CRUD 시뮬레이션을 연결함.<br>
|
|
3. projects dropdown sync 로직에서 자동 삭제 셀렉터 매핑 처리를 탈락시키고, 이력 기록 시 프로젝트 ID가 아닌 'SYSTEM'으로 공통 등록되도록 변경 조치함.<br>
|
|
4. 주의사항 가이드 텍스트를 수정하여 실제 적용 시 <code>tb_project</code> 컬럼이 아닌 신설 테이블 <code>tb_system_policy</code>에 저장됨을 명시함.
|
|
</td>
|
|
</tr>
|
|
<!-- 18 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">18</td>
|
|
<td><span class="date-badge">2026-06-11 16:10</span></td>
|
|
<td>
|
|
<strong>대시보드 스토리지 사용현황 파일수량 추가 표시</strong><br>
|
|
<span class="file-path">관리자화면_통합대시보드_UI제안.html</span>
|
|
</td>
|
|
<td>
|
|
종합 대시보드 화면 내 프로젝트별 스토리지 사용 현황 그리드(프로그레스 바) 목록에 물리 디스크 용량(GB) 정보만 노출되어 있어, 각 현장에 적재된 실제 파일 개수(수량)가 어떻게 되는지 한눈에 직관적으로 파악하기 어려움.
|
|
</td>
|
|
<td>
|
|
대시보드 렌더러 함수(<code>renderDashboard</code>)를 개선하여 각 프로젝트별 가상의 파일 수량 데이터를 추가하고, 프로그레스 바 우측 정보 라벨의 가로폭(<code>width</code>)을 180px로 확장 및 텍스트 템플릿을 수정하여 <strong>"사용 용량 (백분율%) / 파일 수량(개)"</strong> 형태로 실시간 병합 표시되도록 기능을 고도화함.
|
|
</td>
|
|
</tr>
|
|
<!-- 17 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">17</td>
|
|
<td><span class="date-badge">2026-06-11 16:00</span></td>
|
|
<td>
|
|
<strong>공통 코드 마스터 및 세부 코드 관리 화면 통합 추가</strong><br>
|
|
<span class="file-path">관리자화면_통합대시보드_UI제안.html</span>
|
|
</td>
|
|
<td>
|
|
기존 시스템에 프로젝트 구분, 사용자 그룹, 배너 공지 상태 등 시스템 전반의 핵심 파라미터를 유기적으로 정의하고 동적 제어할 수 있는 공통 코드(code_master, code_detail) 관리 기능 및 UI 메뉴가 부재함. 이로 인해 코드 데이터가 정적이고 변경 시 소스 수정이 필요함.
|
|
</td>
|
|
<td>
|
|
1. LNB 메뉴에 "🔑 공통 코드 관리" 항목을 신설하고, 대분류(code_master) 하단에 소분류(code_detail)가 배치되는 상하 수직 정렬 레이아웃 화면을 적용함.<br>
|
|
2. 대분류 행 클릭 시 해당 대분류에 속한 세부 코드들만 하단 영역에 자동 필터링 로드되도록 연동하고, 대분류를 선택하지 않은 상태에서는 하단의 [세부코드 등록] 버튼 및 등록 모달이 활성화되지 않도록 유효성 차단 설정을 적용함.<br>
|
|
3. 대분류와 소분류 각각에 대해 등록 및 수정 시 모달을 제공하여 UI 공간 활용성을 극대화하고, 소분류 등록 시 대/소분류 코드가 자동 결합된 조합 키(base_code)가 생성되도록 데이터 정합성 보존 로직을 적용한 Mock DB CRUD 시뮬레이션을 구현함.
|
|
</td>
|
|
</tr>
|
|
<!-- 16 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">16</td>
|
|
<td><span class="date-badge">2026-06-11 15:30</span></td>
|
|
<td>
|
|
<strong>관리자 화면 UI 기능 및 레이아웃 수정 제안</strong><br>
|
|
<span class="file-path">관리자화면_통합대시보드_UI제안.html</span>
|
|
</td>
|
|
<td>
|
|
1. 모든 관리자 화면 테이블에 행 순번(NO)이 제공되지 않아 가독성 및 직관성이 부족함.<br>
|
|
2. 프로젝트 CRUD 기능과 프로젝트 권한 배정 기능이 별개의 LNB 메뉴 및 탭으로 분리되어 있어 사용자 접근성이 떨어지고 배정이 불편함.<br>
|
|
3. 실시간 배너공지 이력 목록에 송출상태 및 날짜 범위 검색 필터가 부재하며, 송출 중지가 모든 배너에 대해 일괄적으로만 가능해 개별적 세부 통제가 불가능함.<br>
|
|
4. 사용자 CRUD 기능이 고정 폼으로 되어있어 비주얼 디자인이 협소하며, 선택된 사용자의 권한부여 프로젝트 상세 리스트를 직관적으로 파악할 수 있는 화면 뷰가 부재함.
|
|
</td>
|
|
<td>
|
|
1. <strong>공통</strong>: 실시간 소켓 접속, 프로젝트, 참여 유저, 배너이력, 감사로그, 정책 이력 등 모든 테이블에 1부터 순차 증가하는 NO 컬럼을 추가 적용함. 또한, 테이블 그리드 선택 시 시각적 이질감을 줄이기 위해 세로 강조선(border-left)을 제거하고, 폰트 두께 변화로 인한 줄높이의 왜곡 현상을 원천 차단하기 위해 weight 상속 형태를 유지하여 선택되지 않은 다른 행과 완벽하게 동일한 높이를 보존하도록 보강함.<br>
|
|
2. <strong>프로젝트 관리</strong>: '프로젝트 CRUD'와 '권한 배정' 메뉴를 단일 '프로젝트 관리' 탭으로 병합하고, 프로젝트 선택 시 참여 유저 목록이 우측에 로드되며, 사용자 배정은 팝업(모달) 형태로 다중 선택 가능하도록 구현함. 프로젝트 데이터에 <code>category</code> 코드(tdc, gpd, bimproject, overseas)를 추가하여 등록/수정/목록에 통합 반영함.<br>
|
|
3. <strong>실시간 배너공지</strong>: 이력 목록 상단에 송출상태 및 등록일 기간(from~to) 검색 필터를 신설하여 JS로 필터링하고, 이력 각 행마다 [송출중지] 버튼을 배치하여 기간이 만료되지 않은 배너만 개별적으로 중지시킬 수 있도록 개선함.<br>
|
|
4. <strong>사용자 관리</strong>: 메뉴명을 '사용자 관리'로 바꾸고 등록 및 수정을 모달 팝업으로 전환함. 사용자 행을 클릭하면 우측/하단 카드에 해당 사용자가 참여 권한을 보유한 프로젝트 상세 목록(ID, 명, 레벨)이 실시간 렌더링되도록 연동함.
|
|
</td>
|
|
</tr>
|
|
<!-- 15 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">15</td>
|
|
<td><span class="date-badge">2026-06-11 14:28</span></td>
|
|
<td>
|
|
<strong>AI 요약 기능 백그라운드 큐 및 DB 연동</strong><br>
|
|
<span class="file-path">queue.js</span><br>
|
|
<span class="file-path">archiveController.js</span>
|
|
</td>
|
|
<td>
|
|
아카이브 및 공문 탭에서 AI 요약 요청 시, BullMQ 대기열에 작업은 정상 적재(Push)되나 이를 실질적으로 처리해 주는 <code>Worker</code> 인스턴스가 존재하지 않아 작업이 <code>waiting</code> 상태로 정체되어 무한 로딩이 발생함. 또한 요약 완료 시 원본 데이터 테이블(<code>tb_data</code> / <code>_test_tb_data</code>)의 <code>ai_summary</code> 컬럼에 최종 텍스트를 반영하는 DB UPDATE 로직이 누락되어 있음. 추가적으로 요약 작업 수행 시간이 길어질 경우 BullMQ가 작업이 정지된 것으로 오인해 <code>job stalled</code> 에러가 터지고 작업을 취소하는 이슈 발생.
|
|
</td>
|
|
<td>
|
|
1. <code>queue.js</code> 파일에 <code>ai-summarize</code> 및 <code>api-summarize</code> 대기열을 비동기 처리하는 BullMQ <code>Worker</code>들을 신규 생성하고 <code>gemini-2.5-flash</code> API 연동을 완료함.<br>
|
|
2. <code>archiveController.js</code>의 <code>addSummarizeAiLog</code> 함수 내부에 요약 성공 시 DB의 <code>ai_summary</code>와 <code>memo</code> 컬럼을 동시 업데이트하는 쿼리를 추가하여, 상세창 리로드 시 요약본이 정상 출력되고 수정/저장이 원활히 연동되도록 조치함.<br>
|
|
3. AI 요약 호출에 오랜 시간이 걸려 작업이 유실 및 중지(Stalled)되는 것을 막기 위해, 두 Worker의 <code>lockDuration</code> 설정을 기본 30초에서 90초(<code>90000ms</code>)로 대폭 확장함.
|
|
</td>
|
|
</tr>
|
|
<!-- 14 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">14</td>
|
|
<td><span class="date-badge">2026-06-11 13:55</span></td>
|
|
<td>
|
|
<strong>데이터베이스 테이블 명세서 고도화</strong><br>
|
|
<span class="file-path">테이블명세서.html</span>
|
|
</td>
|
|
<td>
|
|
기존의 <code>테이블명세서.html</code> 파일에 실제 물리 스키마(<code>ver4_init_schema.sql</code>) 대비 누락되거나 축소 표기된 테이블(시설 스펙, 일정 등 6개 테이블) 및 각 테이블의 상세 컬럼들이 대다수 누락되어 개발 시 참조 문서로서 정합성이 맞지 않는 상태임.
|
|
</td>
|
|
<td>
|
|
1. 초기 DDL(<code>ver4_init_schema.sql</code>)에 지정된 14개 테이블 및 전체 컬럼 스펙을 한 개도 빠짐없이 정식 등재하고 타입과 제약조건(PK/FK/NotNull 등)을 100% 매핑하여 완전 동기화함.<br>
|
|
2. 왼쪽 LNB 스크롤 플로팅 퀵 메뉴바를 추가하여 원하는 테이블 정의서로 즉시 점핑할 수 있는 편의성을 탑재하고, <code>pm_ver4</code>의 포레스트 그린 테마 스타일로 명세서 디자인을 리뉴얼함.
|
|
</td>
|
|
</tr>
|
|
<!-- 13 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">13</td>
|
|
<td><span class="date-badge">2026-06-11 12:30</span></td>
|
|
<td>
|
|
<strong>관리자 화면 UI 디자인 테마 동기화</strong><br>
|
|
<span class="file-path">관리자화면_통합대시보드_UI제안.html</span>
|
|
</td>
|
|
<td>
|
|
기존의 관리자 화면 UI가 일반적인 슬레이트 그레이 및 로즈(Rose) 계열 핑크톤으로 구현되어 있어, <code>pm_ver4</code> 고유의 포레스트 그린(Teal-Green) 디자인 컨셉 및 서체 스타일과 어긋나는 시각적 이질감이 발생함.
|
|
</td>
|
|
<td>
|
|
1. 관리자 화면의 CSS 디자인 토큰 및 변수(<code>:root</code>)를 <code>pm_ver4</code>의 포레스트 그린 테마 스케일(<code>#1e5149</code>, <code>#142e29</code>, <code>#d2dcdb</code> 등)로 전면 교체하여 일관성 있는 룩앤필(Look and Feel)을 구현함.<br>
|
|
2. 폰트 서체를 기존 Inter/Noto Sans에서 <code>pm_ver4</code> 메인과 동일한 <code>Pretendard Variable</code>로 전환하고, 테두리 둥글기(Radius) 및 그림자 효과를 <code>pm_ver4</code> 규격에 맞춰 자연스럽게 축소/조정함.
|
|
</td>
|
|
</tr>
|
|
<!-- 12 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">12</td>
|
|
<td><span class="date-badge">2026-06-11 12:25</span></td>
|
|
<td>
|
|
<strong>관리자 화면 UI 기능 개선</strong><br>
|
|
<span class="file-path">관리자화면_통합대시보드_UI제안.html</span>
|
|
</td>
|
|
<td>
|
|
1. 실시간 배너 공지의 등록일이 기존 readonly(읽기 전용)로 고정되어 시작일~종료일 범위와 등록일을 사용자가 원하는 임의의 날짜로 유연하게 제어하지 못함.<br>
|
|
2. 프로젝트 권한 배정 화면에서 배정 대상 사용자를 오직 모달 팝업 창을 통해서만 추가할 수 있어, 직관적이고 빠른 다중 선택/등록 조작을 병행하기 어려움.
|
|
</td>
|
|
<td>
|
|
1. 실시간 배너 공지 등록일의 <code>readonly</code> 속성을 제거하여 사용자가 등록일을 임의 편집/등록할 수 있도록 개방하고, 하단의 이력 list 테이블 및 JS 파라미터 전달 체계를 완전 연동시킴.<br>
|
|
2. 프로젝트 권한 배정의 우측 영역을 이원화(배정된 목록 & 배정 대기 목록)하여, 화면에 표시된 미배정 사용자 목록에서 개별 [즉시 배정] 단축 버튼 클릭 및 체크박스 다중 선택을 통한 [선택 사용자 배정 추가] 일괄 적용 기능을 동시 탑재함으로써 팝업 및 목록 선택식 등록 요구사항을 완벽히 충족시킴.
|
|
</td>
|
|
</tr>
|
|
<!-- 11 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">11</td>
|
|
<td><span class="date-badge">2026-06-11 11:23</span></td>
|
|
<td>
|
|
<strong>로컬 루프백 바인딩 & 스토리지 버킷 소멸</strong><br>
|
|
<span class="file-path">server.js</span><br>
|
|
<span class="file-path">MinIO S3 스토리지</span>
|
|
</td>
|
|
<td>
|
|
1. WSL2 도커 초기화 과정에서 DB 및 Redis 컨테이너 중단으로 Node.js가 크래시 및 다운됨.<br>
|
|
2. Node.js 재기동 시 <code>localhost</code>가 IPv6(<code>::1</code>)에만 바인딩되어, 브라우저가 IPv4(<code>127.0.0.1</code>)로 접속을 시도할 때 "사이트에 연결할 수 없음" 오류가 계속 발생함.<br>
|
|
3. 도커 완전 리셋으로 인해 MinIO 내 로컬 파일 업로드 버킷(<code>pm-test-01</code> 등)이 모두 소멸함.
|
|
</td>
|
|
<td>
|
|
1. <code>server.js</code> 호스트 바인딩 설정을 <code>localhost</code>에서 <code>0.0.0.0</code>으로 변경하여 IPv4/IPv6 접속을 동시 수락하도록 보완.<br>
|
|
2. 소멸된 로컬 MinIO 버킷(<code>pm-test-01</code>, <code>pm-test-02</code>)을 동적으로 재생성하는 임시 스크립트를 작성하여 스토리지 복구 완료.<br>
|
|
3. 초기화된 DB 스키마의 상태를 전체 점검하여, 1~9번에 달하는 기존의 모든 수동 DDL 마이그레이션이 유실 없이 올바르게 적용되어 있음을 교차 검증 완료.
|
|
</td>
|
|
</tr>
|
|
<!-- 10 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">10</td>
|
|
<td><span class="date-badge">2026-06-11 09:40</span></td>
|
|
<td>
|
|
<strong>Nodemon 파일 잠금 오류</strong><br>
|
|
<span class="file-path">nodemon.json</span>
|
|
</td>
|
|
<td>윈도우 탐색기나 사용자 조작으로 인해 생성되는 텍스트 문서(예: <code>새 텍스트 문서.txt</code>) 리소스가 잠겨 있는 상태에서, nodemon이 이를 watch하려다 <code>EBUSY: resource busy or locked</code> 에러가 발생해 웹 서버가 강제 종료됨.</td>
|
|
<td>
|
|
1. <code>nodemon.json</code> 설정을 보강하여 <code>*.txt</code>, <code>*.md</code>, <code>*.html</code>, <code>*.bat</code>, <code>*.zip</code> 등 코드 실행에 무관한 모든 문서 및 정적 파일 확장자를 감시 대상(ignore)에서 제외.<br>
|
|
2. 감시 대상 확장자를 오직 <code>js,json</code> 파일로만 엄격하게 국한(ext 설정)하여 충돌 가능성을 원천 차단.
|
|
</td>
|
|
</tr>
|
|
<!-- 9 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">9</td>
|
|
<td><span class="date-badge">2026-06-11 09:12</span></td>
|
|
<td>
|
|
<strong>아카이브 정보 조회 에러</strong><br>
|
|
<span class="file-path">archiveController.js</span><br>
|
|
<span class="file-path">tb_data 테이블</span>
|
|
</td>
|
|
<td>아카이브 파일 상세 정보 쿼리에서 <code>ai_summary</code> 컬럼을 SELECT 했으나, 로컬 DB 테이블에 해당 컬럼이 없어 SQL 에러 발생. 널가드(Null Guard) 부재로 프로세스 강제 종료(app crashed).</td>
|
|
<td>
|
|
1. <code>tb_data</code> 및 <code>_test_tb_data</code> 테이블에 <code>ai_summary TEXT</code> 컬럼을 추가하는 마이그레이션 적용.<br>
|
|
2. 초기화 스키마 파일(<code>ver4_init_schema.sql</code>) 동기화.<br>
|
|
3. <code>exports.getDataInfo</code> 컨트롤러에 <code>try-catch</code> 예외 예방 코드를 주입하여 서버 다운 방어.
|
|
</td>
|
|
</tr>
|
|
<!-- 8 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">8</td>
|
|
<td><span class="date-badge">2026-06-10 20:00</span></td>
|
|
<td>
|
|
<strong>서버 무한 재시작 방지</strong><br>
|
|
<span class="file-path">nodemon.json</span>
|
|
</td>
|
|
<td>winston 라이브러리가 <code>logs/</code> 폴더에 로그 파일을 계속 쓰거나 <code>views/</code> 폴더 내 리소스 로딩 시 nodemon이 파일 변경을 감지하고 서버를 무한 리스타트하여 웹소켓 끊김 등을 유발.</td>
|
|
<td>프로젝트 루트 경로에 <code>nodemon.json</code> 파일을 추가하여 <code>logs/*</code>, <code>views/*</code>, <code>node_modules/*</code> 폴더를 nodemon의 감시 대상(Watch) 목록에서 완전히 제외 처리.</td>
|
|
</tr>
|
|
<!-- 7 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">7</td>
|
|
<td><span class="date-badge">2026-06-10 19:50</span></td>
|
|
<td>
|
|
<strong>로딩 멈춤 방어 코드</strong><br>
|
|
<span class="file-path">pageRenderer.js</span>
|
|
</td>
|
|
<td>아카이브 렌더링을 위한 <code>getTreeObject</code> API 요청 중, 서버 에러나 이전 304 캐시 물림이 터졌을 때 프론트엔드가 크래시되어 로딩바(<code>.init-progress</code>)가 꺼지지 않고 화면이 영원히 멈추는 에러.</td>
|
|
<td><code>getTreeObject</code> API 호출 및 후속 렌더링 과정을 <code>try-catch</code> 구문으로 격리하여, 데이터 통신 오류나 변수 참조 에러가 나더라도 무조건 <code>closeInitProgress()</code>가 실행되어 로딩을 닫도록 방어.</td>
|
|
</tr>
|
|
<!-- 6 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">6</td>
|
|
<td><span class="date-badge">2026-06-10 19:40</span></td>
|
|
<td>
|
|
<strong>304 API 캐싱 방지</strong><br>
|
|
<span class="file-path">app.js</span>
|
|
</td>
|
|
<td>백엔드가 서버 복구 이전에 브라우저에 임시 전송했던 에러 응답(undefined)이 브라우저의 304 Not Modified 캐시에 물려, 서버 수정 이후에도 에러가 화면에 재발생하는 현상.</td>
|
|
<td><code>app.js</code>에 캐시 무효화 헤더 미들웨어를 주입하여, 정적 파일(.js, .css)을 제외한 모든 동적 API GET 요청 시 <code>Cache-Control: no-store</code>를 강제 반환하도록 설정.</td>
|
|
</tr>
|
|
<!-- 5 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">5</td>
|
|
<td><span class="date-badge">2026-06-10 19:10</span></td>
|
|
<td>
|
|
<strong>클릭 로그 서버 다운</strong><br>
|
|
<span class="file-path">archiveController.js</span><br>
|
|
<span class="file-path">tb_click_log 테이블</span>
|
|
</td>
|
|
<td>유저의 썸네일 보기 등의 클릭 이력을 누적하는 <code>_test_tb_click_log</code> 테이블의 스키마가 실제 백엔드가 시도하려는 컬럼 구조와 달라 SQL 에러 발생. 미처리 에러가 winston 예외 제어기에 걸려 노드 프로세스 다운.</td>
|
|
<td>
|
|
1. <code>_test_tb_click_log</code> 및 <code>tb_click_log</code> 테이블을 드롭하고 쿼리에 맞는 컬럼 구조(<code>activity</code>, <code>user_ip</code>, <code>path_arr</code> 등)로 전면 재생성.<br>
|
|
2. <code>mgmtFunc_addClickLog</code> 컨트롤러에 <code>try-catch</code>와 결과 null 가드를 주입하여 SQL 에러 시에도 서버가 꺼지지 않도록 방어.
|
|
</td>
|
|
</tr>
|
|
<!-- 4 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">4</td>
|
|
<td><span class="date-badge">2026-06-10 18:30</span></td>
|
|
<td>
|
|
<strong>다운로드 큐 에러</strong><br>
|
|
<span class="file-path">tb_download_folder</span><br>
|
|
<span class="file-path">archiveController.js</span>
|
|
</td>
|
|
<td>압축 폴더 이력을 로드하는 <code>getMyDownloadList</code> 쿼리 수행 시 로컬 DB에 <code>path</code>, <code>name</code> 컬럼이 누락되어 SQL 에러 발생. 백엔드 catch 문에 응답 코드가 없어 브라우저 요청이 Pending으로 영구 대기함.</td>
|
|
<td>
|
|
1. `tb_download_folder` 테이블에 누락된 <code>path TEXT</code>, <code>name TEXT</code> 컬럼 생성 및 초기화 스키마 동기화.<br>
|
|
2. `getMyDownloadList` catch 블록 내에 500 에러 응답 처리를 추가하여 영구 Pending 현상 차단.
|
|
</td>
|
|
</tr>
|
|
<!-- 3 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">3</td>
|
|
<td><span class="date-badge">2026-06-10 17:40</span></td>
|
|
<td>
|
|
<strong>로컬 스토리지 업로드 오류</strong><br>
|
|
<span class="file-path">onPremiseClient.js</span>
|
|
</td>
|
|
<td>MinIO/S3 규격은 대문자 및 언더스코어(<code>_</code>)가 섞인 버킷명을 거부하나, 프로젝트 ID(예: `PM_TEST_01`)를 버킷명으로 직접 사용해 presigned URL 업로드 요청 시 <code>InvalidBucketName</code> 에러로 업로드 실패.</td>
|
|
<td><code>onPremiseClient.js</code> 내 S3 Client 객체에 미들웨어를 주입하여, 로컬 스토리지에 요청되는 모든 버킷명을 <strong>자동 소문자 및 하이픈 형태(예: `pm-test-01`)로 실시간 강제 변환</strong>되도록 우회 처리.</td>
|
|
</tr>
|
|
<!-- 2 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">2</td>
|
|
<td><span class="date-badge">2026-06-10 16:50</span></td>
|
|
<td>
|
|
<strong>감사 로그 삽입 오류</strong><br>
|
|
<span class="file-path">archiveController.js</span>
|
|
</td>
|
|
<td>폴더/파일 조작 감사 기록 시, pg array 컬럼(<code>path_arr</code> 등)에 바인딩할 파라미터를 <code>JSON.stringify</code> 문자열로 전달하여 <code>malformed array literal</code> 오류로 서버가 리로드 및 강제 종료됨.</td>
|
|
<td><code>JSON.stringify</code> 호출부를 전부 제거하고, 순수 자바스크립트 Array(배열) 객체를 pg 모듈에 다이렉트 전달하여 드라이버가 자동으로 포스트그레스 규격 배열 문자열로 매핑 바인딩하도록 수정.</td>
|
|
</tr>
|
|
<!-- 1 -->
|
|
<tr>
|
|
<td style="text-align: center; font-weight: 600;">1</td>
|
|
<td><span class="date-badge">2026-06-10 16:00</span></td>
|
|
<td>
|
|
<strong>아카이브 용량 계산 지연</strong><br>
|
|
<span class="file-path">tb_overview</span>
|
|
</td>
|
|
<td><code>getFolderSize</code> 호출 시 <code>tb_overview</code>의 <code>data_size</code> 컬럼을 JSON 배열로 간주하고 JSON 변환 쿼리를 돌렸으나, 로컬 DB 스키마에는 <code>BIGINT</code> 타입으로 생성되어 있어 형변환 에러 및 화면 무한 로딩 유발.</td>
|
|
<td><code>data_size</code> 컬럼의 형식을 <code>TEXT</code> 타입으로 교체하고 기본값으로 <code>'[0]'</code>(JSON 배열 문자열)을 설정하는 마이그레이션 적용 및 스키마 파일 동기화.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</body>
|
|
</html>
|