diff --git a/.env b/.env new file mode 100644 index 0000000..bd7a495 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +DB_HOST=172.16.8.151 +DB_PORT=3306 +DB_USER=itam_admin +DB_PASS=itam1234 +DB_NAME=itam +PORT=3000 \ No newline at end of file diff --git a/PC_사양_개선_기획서.html b/PC_사양_개선_기획서.html new file mode 100644 index 0000000..ded45ee --- /dev/null +++ b/PC_사양_개선_기획서.html @@ -0,0 +1,379 @@ + + + + + + PC 사양 대시보드 시각화 개선 기획서 + + + + + + + +
+
+
기획 명세서 / Product Specification
+

PC 사양 대시보드 시각화 개선 기획서

+
+ 기획부서: IT자산관리 태스크포스(TF) + 최종 수정일: 2026. 05. 28 + 문서 버전: v1.1 (실제 엑셀 데이터 반영) +
+
+ + +
+

기획 개요 및 목적

+

본 기획은 법인별/직무별 PC 자산 사양 현황의 시각적 피로도를 낮추고 데이터 전달력을 고도화하기 위한 개선 작업을 목적으로 합니다. 기존 대시보드 레이아웃의 비정형 비율을 재정립하고, 평균 점수와 권장 점수의 비교 방식을 '다중 막대' 형태에서 '혼합형(막대 + 꺾은선) 차트'로 변경하여 대조 직관성을 극대화합니다.

+
+ + +
+

주요 개선 내역

+ +
+

① 가족사별 PC 사양 현황 레이아웃 고도화

+
    +
  • 가로 비율 정밀 제어 (1:2): 평균 점수 리스트와 막대그래프의 가로 폭 비율을 1 : 2로 엄격하게 고정하여 반응형 레이아웃 환경에서도 깨짐 없는 균형미를 제공합니다.
  • +
  • 가독성 개선: 가족사 텍스트 크기를 0.95rem, 평균 사양 점수 텍스트 크기를 1.05rem으로 키우고 세로 행간 여백을 확보해 가시성을 향상시켰습니다.
  • +
+
+ +
+

② 직무별 PC 사양 평균 및 권장 점수 혼합 시각화

+
    +
  • 혼합형 차트(Mixed Chart) 구성: 직무별 PC 사양 평균 점수는 막대(Bar) 그래프로, 권장 PC 사양 점수는 그 위를 관통하는 선(Line) 그래프로 표현합니다.
  • +
  • 레이어 정렬 우선순위 적용: 차트 정의 시 권장 점수선(Line)이 평균 점수막대(Bar) 뒤에 가리지 않고 항상 맨 앞에 위치하도록 렌더링 우선순위(order 속성)를 명확히 지정합니다.
  • +
  • 정렬 원복: 수동 정렬을 지양하고, 직무별 실제 평균 PC 사양 점수가 높은 순으로 자동 내림차순 정렬되도록 하여 가장 자연스러운 시각화를 구축합니다.
  • +
+
+
+ + +
+

직무별 평균 및 권장 사양 점수 스펙

+

실제 PC 자산 데이터(CPU 및 RAM 점수 연산 결과)와 관리자의 권장 기준선이 아래 명시된 대소 조건 관계를 완벽히 만족하도록 더미 데이터 및 초기 권장 스펙 기준을 재정의했습니다.

+ +
+ 대소 관계 정렬 순서 (실제 평균 점수 기준):
+ AI 개발자 ➔ 편집 디자이너 ➔ 3D 디자이너 ➔ UXUI 디자이너 ➔ 3D 개발자 ➔ 프로그램 개발자 ➔ BIM모델러 ➔ 엔지니어 ➔ 웹 개발자 ➔ 기획자 순서로 실제 평균 점수 순위가 자동 정렬되어 시각화됩니다. (감리원은 실제 자산 데이터 부재로 비교군에서 제외) +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
정렬 순위직무명실제 평균 사양 점수 (Bar)기본 권장 사양 점수 (기준)대소 관계 평가
1AI 개발자88.0 점95 점미달 (교체 요망)
2편집 디자이너80.2 점75 점권장 스펙 충족
33D 디자이너78.4 점90 점미달 (교체 요망)
4UXUI 디자이너72.7 점70 점권장 스펙 충족
53D 개발자67.8 점90 점미달 (교체 요망)
6프로그램 개발자67.3 점80 점미달 (교체 요망)
7BIM모델러62.1 점75 점미달 (교체 요망)
8엔지니어42.9 점60 점미달 (교체 요망)
9웹 개발자39.2 점75 점미달 (교체 요망)
10기획자38.6 점50 점미달 (교체 요망)
11감리원-40.0 점데이터 없음
+
+
+ + +
+

기술 구현 세부 사양

+
+

차트 렌더링 옵션 (Chart.js v4.x+)

+

평균 PC 사양 점수를 보여주는 데이터셋과 권장 PC 사양 점수를 보여주는 데이터셋을 하나의 Canvas 엘리먼트에 그리되, 레이어 겹침과 시인성을 확보하기 위해 다음 세부 옵션을 바인딩합니다.

+
    +
  • Average Dataset: type: 'bar', order: 2, backgroundColor: '#6366F1'
  • +
  • Recommended Dataset: type: 'line', order: 1, borderColor: '#10B981', borderWidth: 3, pointRadius: 4, fill: false
  • +
  • 정렬 로직: Object.keys(jobScores).sort((a, b) => jobScores[b].avg - jobScores[a].avg)
  • +
+
+
+ + +
+ + diff --git a/PC_사양_적정성_분석_기획서.html b/PC_사양_적정성_분석_기획서.html new file mode 100644 index 0000000..60a01be --- /dev/null +++ b/PC_사양_적정성_분석_기획서.html @@ -0,0 +1,429 @@ + + + + + + PC 사양 적정성 분석 기획서 (GPU 반영) + + + + + + +
+ + +
+
기능 명세서 v3.0 — 100점 감점제 반영
+

PC 사양 적정성 분석 기획서
+ + 100점 만점 감점 방식 · 성능 감점 기준 · 실제 업무 효율성 평가 (CPU / RAM / GPU / 연식) + +

+
+
분석 지표CPU + RAM + GPU + 연식 (감점법)
+
최대 점수100점 (만점)
+
적정성 판별 기준직무별 목표 사양 대비 편차
+
최종 수정일2026. 05. 31
+
+
+ + +
+

1개요 — 100점 만점 감점형 성능 점수 체계

+

+ v3.0부터 PC 사양 점수는 100점 만점 기준 감점제로 산출됩니다. + 누적 합산 방식 대신, 최상급 부품 조합을 100점 만점으로 고정하고 사양이 저하되거나 연식이 노후화됨에 따라 + 성능 및 효율성 하락 폭을 감점하는 방식입니다. 이는 실제 업무 환경에서 PC 노후도에 따른 + 체감 생산성 저하를 훨씬 직관적이고 현실적으로 드러냅니다. +

+ +
+
① 기본 100점 만점
+
+
② CPU 등급/세대 감점
+
+
③ RAM 용량 감점
+
+
④ GPU 등급 감점
+
+
⑤ 연식 노후 감점
+
+
⑥ 최종 실질 성능 점수
+
+ +
+// ─── 최종 PC 사양 점수 (100점 만점, 최소 10점 보존) ─── +totalScore = max(10, 100 - (cpuDeduction + genDeduction + ramDeduction + gpuDeduction + ageDeduction)) +
+
+ + +
+

2CPU 사양 감점 기준

+

CPU 감점은 등급 감점(최대 -30점)세대 노후 감점(최대 -15점)의 합산입니다.

+ +
+// [CPU 등급 감점] +i9 / Ryzen 9 → 0점 감점 +i7 / Ryzen 7 → -5점 감점 +i5 / Ryzen 5 → -15점 감점 +i3 / Ryzen 3 → -25점 감점 +기타 → -30점 감점 + +// [CPU 세대 노후 감점] +최신 세대 (Intel 12~14세대, Ryzen 5000~7000시리즈 이상) → 0점 감점 +과도기 세대 (Intel 10~11세대, Ryzen 3000시리즈) → -5점 감점 +구형 세대 (Intel 8~9세대, Ryzen 1000~2000시리즈) → -10점 감점 +노후 세대 (Intel 7세대 이하, 구형 AMD) → -15점 감점 +
+ +

CPU 조합별 감점 예시

+
+ + + + + + + + + + + +
모델세대 구분등급감점세대감점CPU 감점 합계
i9-13900K최신 세대000점 (감점 없음)
i7-14700K최신 세대-50-5점
i7-1360P최신 세대 (노트북)-50-5점
i5-12400최신 세대-150-15점
i7-9700구형 세대-5-10-15점
i5-8500구형 세대-15-10-25점
i7-7700노후 세대-5-15-20점
+
+
+ + +
+

3RAM 용량 감점 기준

+

메모리 용량 부족에 따른 멀티태스킹 제약 및 병목 현상을 반영해 최대 -25점까지 감점합니다.

+
+ + + + + + + + +
RAM 용량감점 점수영향도평가
32GB 이상0점 (감점 없음)대용량 3D 및 개발 작업 원활최적
16GB-10점 감점일반 사무용 및 가벼운 멀티태스킹 적합보통
8GB-20점 감점브라우저 탭 다수 실행 시 물리 메모리 부족주의
8GB 미만-25점 감점기본 OS 구동 외 심각한 메모리 병목부족
+
+
+ + +
+

4GPU 성능 감점 기준

+

+ 3D 렌더링 및 고급 연산 처리 능력을 기준으로 외장 및 내장 GPU를 분류해 최대 -25점까지 감점합니다. + GPU 정보가 감지되지 않거나 없는 경우 기본적으로 내장 그래픽 수준인 -25점을 감점합니다. +

+ +
+ + + + + + + + +
등급제품군 구분대표 모델감점 점수적합 작업
S최상위 외장 GPURTX 4070~4090, RTX A4000~A60000점 (감점 없음)3D 그래픽, AI 연산, VR
A메인스트림 외장 GPURTX 3060~3070, RTX 2060, RTX A2000-5점 감점중급 개발, CAD 설계
B엔트리 외장 GPUGTX 1660, GTX 1060, RX 6600-15점 감점기본 CAD, 그래픽 보조
C내장 그래픽 및 기타Intel Iris Xe, UHD Graphics, Vega, GPU 없음-25점 감점오피스 사무, 문서 작업
+
+
+ + +
+

5감점법 종합 점수 계산 실사례

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
모델명CPU 사양 (감점)RAM 사양 (감점)GPU 사양 (감점)연식 (감점)감점 총합최종 점수
HP ZBook Fury 16Ryzen 9 7900X (0)64GB (0)NVIDIA RTX A2000 (-5)2년차 (-6)-1189점
Dell Precision 5680i9-13900K (0)64GB (0)NVIDIA RTX 4070 (0)2년차 (-6)-694점
LG Gram 17 Proi7-14700K (-5)32GB (0)NVIDIA RTX 4060 (-5)1년차 (-3)-1387점
LG Gram 16i7-1360P (-5)16GB (-10)Intel Iris Xe (-25)3년차 (-9)-4951점
Samsung Galaxy Book 3i5-1340P (-15)16GB (-10)Intel Iris Xe (-25)3년차 (-9)-5941점
HP EliteBook 840Ryzen 5 5600X (-15)16GB (-10)AMD Radeon Vega (-25)4년차 (-12)-6238점
HP ProDesk 400 G5i3-8100 (-35)8GB (-20)Intel UHD 630 (-25)5년 이상 (-15)-9510점(보존)
+
+
+ + +
+

6직무별 평균 및 권장 점수 기준 (100점 만점 감점형)

+

100점 만점 감점형 점수 체계를 실제 PC 데이터에 대입하여 산출된 각 직무별 평균 및 권장 목표 점수 기준선입니다.

+
+ + + + + + + + + + + + + + + + + +
정렬직무실제 데이터 평균 (감점 반영)기본 권장 점수 (목표)규칙
1AI 개발자88.0점95점최고
2편집 디자이너80.2점75점최고
33D 디자이너78.4점90점최고
4UXUI 디자이너72.7점70점고성능
53D 개발자67.8점90점최고
6프로그램 개발자67.3점80점고성능
7BIM모델러62.1점75점최고
8엔지니어42.9점60점고성능
9웹 개발자39.2점75점고성능
10기획자38.6점50점중간
11감리원-40점기본
+
+
+
📌 대소 관계 조건 충족 확인
+ AI 개발자(88.0) > 편집 디자이너(80.2) > 3D 디자이너(78.4) > UXUI 디자이너(72.7) > 3D 개발자(67.8) > 프로그램 개발자(67.3) > BIM모델러(62.1) > 엔지니어(42.9) > 웹 개발자(39.2) > 기획자(38.6) ✅ +
+
+ + +
+

7적정성 판별 기준

+

직무 내 실제 평균 점수를 기준으로 편차율을 산출하여 3단계로 판별합니다.

+
+avgScore = 해당 직무 소속 PC 점수들의 산술 평균 + +IF 개인 실질 점수 < avgScore × 0.80"사양 부족" (직무 평균 20% 이상 미달) +IF 개인 실질 점수 > avgScore × 1.30"오버스펙" (직무 평균 30% 이상 초과) +ELSE → "적정" +
+
+ + + + + + + +
판별 결과조건권장 조치
사양 부족실질 점수 < 직무 평균 × 0.8교체 또는 성능 업그레이드 우선 검토
적정직무 평균 × 0.8 ≤ 실질 점수 ≤ 직무 평균 × 1.3현행 업무 효율 유지
오버스펙실질 점수 > 직무 평균 × 1.3과스펙 장비 회수 또는 필요 부서 재배치
+
+
+ + +
+

8점수 신뢰도 및 한계 분석

+ +

✅ 신뢰 가능한 부분

+
+
    +
  • 3요소 합산으로 실제 성능 근접도 향상: CPU·RAM·GPU를 모두 반영함으로써 단순 CPU 점수 대비 실체감 성능과의 상관관계가 크게 개선되었습니다.
  • +
  • GPU 티어 방향성 일치: RTX 4090 > 4080 > 4070 … 순의 점수 순서는 실제 벤치마크(3DMark, PassMark GPU)와 일치합니다.
  • +
  • 내장/외장 구분 명확: 내장 그래픽(5~15점)과 독립 GPU(18점~)의 점수 구간이 명확히 분리되어 사양 격차를 직관적으로 반영합니다.
  • +
  • 직무별 상대 비교 합리성 유지: GPU 점수 추가 후에도 직무 내 평균 기준 편차율 판별 방식이 그대로 유지됩니다.
  • +
+
+ +

⚠️ 여전히 남아있는 한계점

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
한계 항목내용영향도
노트북 TDP 미반영i7-1360P (노트북 28W)와 i7-13700K (데스크탑 125W)는 같은 세대지만 실제 성능 차이가 큽니다. 현재는 동일 점수가 부여됩니다.중간
SSD 유형 미반영NVMe SSD와 HDD의 체감 속도 차이는 크지만 점수에 포함되지 않습니다.중간
GPU 세부 파생 모델 한계RTX 4060 Laptop과 RTX 4060 Desktop은 성능 차이가 있으나 동일 점수(50점)를 받습니다.중간
GPU 세대 보정 미적용CPU와 달리 GPU는 세대 보정 없이 모델명 매핑 방식만 사용됩니다. 향후 세대별 보정을 검토할 수 있습니다.낮음
실측 벤치마크 미연동3DMark / PassMark GPU 실측값이 아닌 모델명 파싱 추정치입니다.중간
+
+ +
+
💡 종합 신뢰도 평가
+ GPU 점수 반영 후 특히 디자이너·개발자와 같은 그래픽 집약적 직무의 적정성 판별 정확도가 대폭 향상되었습니다. + 다만 노트북 TDP, SSD 유형 등 추가 변수를 향후 보완하면 신뢰도를 더 끌어올릴 수 있습니다. + 현 시점에서 본 점수 체계는 "절대적 성능 수치"가 아닌 "조직 내 직무별 상대 비교 도구"로 활용하는 것이 가장 적합합니다. +
+
+ + +
+

9향후 개선 로드맵

+
+ + + + + + + + + + +
우선순위항목기대 효과난이도
완료GPU 점수 반영 (v2.0)그래픽 직무 신뢰도 대폭 향상
권장SSD 유형별 점수 추가 (NVMe/SATA/HDD)실체감 체감 속도 반영
권장노트북/데스크탑 TDP 보정모바일 CPU 과대평가 방지
선택PassMark / 3DMark 실측 DB 내장 연동추정치 → 실측값 전환
선택직무별 항목 가중치 커스터마이징조직 특성 맞춤 정밀 점수화
선택RMM 에이전트 실시간 자원 점유율 연동실사용 기반 교체 우선순위 추천
+
+
+ + + +
+ + diff --git a/PLAN_ASSET_HISTORY.md b/PLAN_ASSET_HISTORY.md new file mode 100644 index 0000000..a9f1065 --- /dev/null +++ b/PLAN_ASSET_HISTORY.md @@ -0,0 +1,60 @@ +# 자산 이력 누적 관리 시스템 (Cumulative Asset History System) 구현 계획 + +본 문서는 자산의 라이프사이클(조직, 사용자, 용도, 상태 변동)을 체계적으로 추적하고 누적 관리하기 위한 기술적 설계 및 단계별 구현 계획을 담고 있습니다. + +## 1. 목적 +- 자산 정보 수정 시 중요 변경 사항을 자동으로 감지하여 이력(Log)화 +- 과거부터 현재까지의 변동 사항을 타임라인 형태로 시각화하여 자산 흐름 파악 +- 데이터 정합성을 위해 서버 측에서 변경 전/후 스냅샷 비교 방식 채택 + +## 2. 관리 대상 이력 (Watch Fields) +다음 항목의 변경이 발생할 경우 이력을 자동 생성합니다. +1. **조직 변동**: `current_dept` (현 사용조직) ↔ `previous_dept` 업데이트 포함 +2. **사용자 변동**: `user_current` (현 사용자) ↔ `previous_user` 업데이트 포함 +3. **용도 변경**: `asset_type`, `current_role` (예: 개인PC -> 공용PC) +4. **상태 변경**: `hw_status` (예: 운영 -> 수리, 재고 -> 폐기 등) + +## 3. 기술 설계 (Technical Design) + +### A. 데이터베이스 (DB) +- **대상 테이블**: `asset_history` +- **컬럼 구조 활용 및 보완**: + - `asset_id`: 대상 자산 식별자 + - `event_type`: 변경 유형 (DEPT_CHANGE, USER_CHANGE, ROLE_CHANGE, STATUS_CHANGE) + - `details`: "상태 변경: 운영 -> 수리" 와 같이 읽기 쉬운 문자열 저장 + - `cost`: 관련 비용 발생 시 기록 (수리비 등) + - `log_user`: 변경을 수행한 작업자 + - `log_date`: 변경 발생 일시 + +### B. 백엔드 (Server-side Logic) +- **위치**: `server.js` 의 `POST /api/asset/:category/save` 엔드포인트 +- **동작 흐름**: + 1. **Snapshot**: 인서트/업데이트 수행 전, 기존 DB의 데이터를 `SELECT`하여 메모리에 저장. + 2. **Comparison**: 요청된 신규 데이터와 기존 데이터를 필드별로 대조. + 3. **Auto-logging**: 변경점이 발견되면 `asset_history` 테이블에 즉시 인서트. + 4. **Transaction**: 모든 로그 생성이 자산 저장과 하나의 트랜잭션으로 묶여야 함. + +### C. 프론트엔드 (UI/UX) +- **위치**: `HWModal.ts` 우측 `modal-history-area` +- **개선 사항**: + - `renderHistory()` 함수를 고도화하여 이벤트 타입별 아이콘/컬러 적용. + - "이전 값 ➔ 이후 값" 형태의 직관적인 레이아웃 도입. + - 스크롤을 통한 무제한 누적 이력 조회 지원. + +## 4. 단계별 구현 로직 + +### 1단계: 서버 로직 고도화 +- `server.js`에 비교 함수(`compareAndLog`) 구현. +- 각 자산 카테고리별 저장 로직에 비교 로직 삽입. + +### 2단계: DB 데이터 마이그레이션 (필요시) +- 기존 자산의 `current_dept` 등을 `previous_dept`로 밀어내는 로직 점검. + +### 3단계: UI 타임라인 렌더링 개선 +- `modal.css`에 이력 전용 스타일(이벤트 뱃지 등) 추가. +- `HWModal.ts`에서 최신 로그를 실시간으로 다시 불러오는 로직 확인. + +## 5. 검증 계획 +- **자동 감지 테스트**: 상태 변경 후 저장 시 우측 이력에 즉시 한 줄이 추가되는지 확인. +- **다중 변경 테스트**: 조직과 사용자를 동시에 변경했을 때 두 개의 로그가 생성되는지 확인. +- **데이터 무결성**: 수정을 취소하거나 저장 실패 시 로그가 남지 않는지(Transaction) 확인. diff --git a/SampleData_PC.xlsx b/SampleData_PC.xlsx new file mode 100644 index 0000000..0c52785 Binary files /dev/null and b/SampleData_PC.xlsx differ diff --git a/SampleData_SVR.xlsx b/SampleData_SVR.xlsx new file mode 100644 index 0000000..e137431 Binary files /dev/null and b/SampleData_SVR.xlsx differ diff --git a/backup_db.js b/backup_db.js new file mode 100644 index 0000000..2687b14 --- /dev/null +++ b/backup_db.js @@ -0,0 +1,59 @@ +import mysql from 'mysql2/promise'; +import dotenv from 'dotenv'; +import * as xlsx from 'xlsx'; +import fs from 'fs'; + +dotenv.config(); + +const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env; + +async function backup() { + const connection = await mysql.createConnection({ + host: DB_HOST, + user: DB_USER, + password: DB_PASS, + database: DB_NAME, + port: parseInt(DB_PORT || '3306') + }); + + console.log('🚀 Starting Database Backup Process...'); + + const tables = [ + 'asset_pc', 'asset_server', 'asset_storage', 'asset_remote', + 'asset_equipment', 'asset_office_supplies', 'asset_survey', 'asset_vip' + ]; + + const wb = xlsx.utils.book_new(); + + for (const table of tables) { + try { + // 1. Create table backup + await connection.query(`DROP TABLE IF EXISTS ${table}_backup`); + await connection.query(`CREATE TABLE ${table}_backup AS SELECT * FROM ${table}`); + console.log(`✅ Table backup created: ${table} -> ${table}_backup`); + + // 2. Fetch data for Excel + const [rows] = await connection.query(`SELECT * FROM ${table}`); + if (rows.length > 0) { + const ws = xlsx.utils.json_to_sheet(rows); + // Sheet names max length is 31 chars + const sheetName = table.substring(0, 31); + xlsx.utils.book_append_sheet(wb, ws, sheetName); + } + } catch (e) { + console.warn(`⚠️ Skipped ${table}: ${e.message}`); + } + } + + // 3. Write Excel file + const fileName = 'backupDB_20260608.xlsx'; + xlsx.writeFile(wb, fileName); + console.log(`✅ Excel data exported successfully to ${fileName}`); + + await connection.end(); +} + +backup().catch(err => { + console.error('❌ Backup Failed:', err); + process.exit(1); +}); diff --git a/check_logs.js b/check_logs.js new file mode 100644 index 0000000..d14cdb7 --- /dev/null +++ b/check_logs.js @@ -0,0 +1,28 @@ +import mysql from 'mysql2/promise'; +import dotenv from 'dotenv'; + +dotenv.config(); + +const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env; + +async function checkRecentLogs() { + const connection = await mysql.createConnection({ + host: DB_HOST, + user: DB_USER, + password: DB_PASS, + database: DB_NAME, + port: parseInt(DB_PORT || '3306') + }); + + console.log('--- Recent History Logs ---'); + const [rows] = await connection.query('SELECT * FROM asset_history ORDER BY created_at DESC LIMIT 5'); + console.log(JSON.stringify(rows, null, 2)); + + console.log('\n--- Recent Core Data (to check current_dept) ---'); + const [coreRows] = await connection.query('SELECT id, asset_code, current_dept, previous_dept FROM asset_core ORDER BY updated_at DESC LIMIT 5'); + console.log(JSON.stringify(coreRows, null, 2)); + + await connection.end(); +} + +checkRecentLogs().catch(console.error); diff --git a/check_network.js b/check_network.js new file mode 100644 index 0000000..85228d4 --- /dev/null +++ b/check_network.js @@ -0,0 +1,29 @@ +import mysql from 'mysql2/promise'; +import dotenv from 'dotenv'; + +dotenv.config(); + +const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env; + +async function checkRemote() { + const connection = await mysql.createConnection({ + host: DB_HOST, + user: DB_USER, + password: DB_PASS, + database: DB_NAME, + port: parseInt(DB_PORT || '3306') + }); + + console.log('--- Checking asset_remote table ---'); + + const [columns] = await connection.query('DESCRIBE asset_remote'); + const cols = columns.map(c => c.Field); + console.log('Columns in asset_remote:', cols.join(', ')); + + const [count] = await connection.query('SELECT COUNT(*) as count FROM asset_remote WHERE remote_tool IS NOT NULL OR remote_id IS NOT NULL'); + console.log(`Rows with remote info (tool or id): ${count[0].count}`); + + await connection.end(); +} + +checkRemote().catch(console.error); diff --git a/drop_legacy.js b/drop_legacy.js new file mode 100644 index 0000000..c4b6ad5 --- /dev/null +++ b/drop_legacy.js @@ -0,0 +1,44 @@ +import mysql from 'mysql2/promise'; +import dotenv from 'dotenv'; + +dotenv.config(); + +const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env; + +async function dropLegacyTables() { + const connection = await mysql.createConnection({ + host: DB_HOST, + user: DB_USER, + password: DB_PASS, + database: DB_NAME, + port: parseInt(DB_PORT || '3306') + }); + + console.log('🧹 Starting cleanup of obsolete legacy backup tables...'); + + const tablesToDrop = [ + 'asset_pc', 'asset_pc_backup', + 'asset_server', 'asset_server_backup', + 'asset_storage', 'asset_storage_backup', + 'asset_remote_backup', // IMPORTANT: DO NOT drop asset_remote! + 'asset_equipment', 'asset_equipment_backup', + 'asset_office_supplies', 'asset_office_supplies_backup', + 'asset_survey', 'asset_survey_backup', + 'asset_vip', 'asset_vip_backup', + 'asset_pc_parts' + ]; + + for (const table of tablesToDrop) { + try { + await connection.query(`DROP TABLE IF EXISTS ${table}`); + console.log(`✅ Dropped table: ${table}`); + } catch (err) { + console.warn(`⚠️ Failed to drop table ${table}: ${err.message}`); + } + } + + console.log('🎉 Cleanup complete. Database is now lean and mean.'); + await connection.end(); +} + +dropLegacyTables().catch(console.error); diff --git a/index.html b/index.html index ab990f8..9b2c65a 100644 --- a/index.html +++ b/index.html @@ -19,36 +19,6 @@ - -
-
- - - -
-
-