fix(playwright): resolve browser dependencies without sudo & cleanup unused files
All checks were successful
Deploy Web Application / deploy (push) Successful in 6s
All checks were successful
Deploy Web Application / deploy (push) Successful in 6s
- Copy necessary shared libraries (libnss, libasound, libsoftokn, etc.) from docker to libs/ to support headless chromium execution on host - Update server and crawler configuration to support custom DB_PORT (3307) - Remove unused databases, lockfiles, standalone helper scripts, and documentation files as requested
This commit is contained in:
2
.env
2
.env
@@ -4,3 +4,5 @@ DB_HOST=localhost
|
|||||||
DB_USER=root
|
DB_USER=root
|
||||||
DB_PASSWORD=45278434
|
DB_PASSWORD=45278434
|
||||||
DB_NAME=PM_proto
|
DB_NAME=PM_proto
|
||||||
|
DB_PORT=3307
|
||||||
|
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
# 📊 시스템 운영 자산 가치 분석 보고 (Sabermetrics Report)
|
|
||||||
|
|
||||||
본 보고서는 프로젝트 관리 시스템 내에서 수집된 활동 로그 및 자산 데이터를 통계적/AI 기법으로 분석하여, 각 프로젝트의 운영 활력과 조직 기여도를 정량화한 지표를 정의합니다.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. 운영 활력 지수 (AVI, Activity Vitality Index)
|
|
||||||
프로젝트가 현재 얼마나 건강하게 가동되고 있는지를 나타내는 **'디지털 자산 생존 지표'**입니다.
|
|
||||||
|
|
||||||
### 1.1 산출 공식
|
|
||||||
$$AVI = e^{-\lambda \times Stagnant\_Days} \times Quality \times 100$$
|
|
||||||
|
|
||||||
### 1.2 3대 핵심 변수 상세 설명
|
|
||||||
|
|
||||||
#### ① 지수 감쇄 모델 ($e^{-\lambda \times t}$) : "가치의 시한폭탄"
|
|
||||||
자산은 관리하지 않으면 시간이 흐를수록 가치가 기하급수적으로 소멸한다는 **'정보 휘발성'** 원리를 반영합니다.
|
|
||||||
* **Stagnant Days (정체 일수)**: 마지막 유효 활동 로그 기록일로부터 오늘까지 경과된 날짜입니다.
|
|
||||||
* **특징**: 정체 초기에는 점수가 빠르게 하락하다가, 시간이 지날수록 하락 폭이 둔화되며 0에 수렴합니다. 이는 관리가 중단된 직후의 정보 망실 위험이 가장 크다는 실무적 경험을 반영한 것입니다.
|
|
||||||
|
|
||||||
#### ② 위험 가속 계수 ($\lambda$) : "대형 자산의 높은 관리 비용"
|
|
||||||
모든 프로젝트는 자산 규모에 따라 '늙어가는 속도'가 다릅니다.
|
|
||||||
* **공식**: $\lambda = 0.04 + \log_{10}(Files + 1) \times 0.008$
|
|
||||||
* **비즈니스 로직**: 파일이 많은 대형 프로젝트일수록 관리 부재 시 조직에 미치는 타격이 큽니다. 따라서 대형 프로젝트일수록 $\lambda$ 값이 커지며, 소형 프로젝트보다 **훨씬 빠른 속도로 AVI가 하락**하도록 설계되었습니다. (대형 프로젝트는 더 자주 관리해야 점수가 유지됨)
|
|
||||||
|
|
||||||
#### ③ 활동 품질 가중치 ($Quality$) : "행정과 실무의 구분"
|
|
||||||
단순히 접속하거나 로그가 찍혔다고 해서 활력이 100% 회복되지 않습니다. AI가 로그 키워드를 분석하여 활동의 **'진정성'**을 평가합니다.
|
|
||||||
* **High (1.0)**: **성과물 중심 활동** (파일 업로드, 수정, 등록, 업데이트 등)
|
|
||||||
* **Medium (0.7)**: **구조적 유지 활동** (폴더 생성, 삭제, 이동 등)
|
|
||||||
* **Low (0.4)**: **단순 행정 활동** (권한 변경, 메일 확인, 참가자 추가 등)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. 자산 가치 기여도 (VCI, Value Contribution Index)
|
|
||||||
야구의 **WAR(Wins Above Replacement)** 개념을 도입하여, 전체 포트폴리오 평균 대비 개별 프로젝트가 조직 가치에 얼마나 기여하는지 산출합니다.
|
|
||||||
|
|
||||||
### 2.1 산출 공식
|
|
||||||
$$VCI = (Individual\_AVI - Portfolio\_Avg\_AVI) \times Asset\_Weight$$
|
|
||||||
* **Asset Weight (파일 규모 가중치)**: $max(0.2, \frac{Individual\_Files}{Portfolio\_Avg\_Files})$
|
|
||||||
|
|
||||||
### 2.2 지표의 의미: "평균(0.0)을 기준으로 한 상대 평가"
|
|
||||||
* **0.0 (평균)**: 조직 내 평균적인 관리 수준과 규모를 가진 표준 프로젝트.
|
|
||||||
* **(+) 점수**: 평균 이상의 활력으로 조직의 디지털 자산 가치를 증대시키는 프로젝트.
|
|
||||||
* **(-) 점수**: 평균 이하의 방치로 인해 조직에 잠재적 기회비용 손실을 입히는 리스크 프로젝트.
|
|
||||||
* **상대 가중치**: 조직의 평균 파일 수보다 큰 프로젝트가 방치될 때 마이너스 점수가 더 가파르게 하락하여 **'우선 관리 대상'**을 명확히 식별합니다.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. 강력한 예외 처리 (Hard Rules)
|
|
||||||
|
|
||||||
데이터의 신뢰도를 확보하기 위해 다음과 같은 **'사망 판정'** 규칙이 적용됩니다.
|
|
||||||
1. **자동 삭제 패널티**: 최근 로그가 시스템에 의한 '폴더자동삭제'인 경우, AVI는 즉시 **0.1%**로 고정됩니다. (관리 포기 상태)
|
|
||||||
2. **자산 부재 패널티 (ECV)**: 파일 개수가 0개인 경우 운영 일관성(OCI)은 **0.0점**이며, 파일 10개 미만은 최종 가중치에 **50% 패널티**를 적용하여 '껍데기 프로젝트'를 걸러냅니다.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. 발표 및 분석 가이드 (Executive Summary)
|
|
||||||
|
|
||||||
* **AVI가 낮은 프로젝트**: "데이터가 낡아가고 있으니 즉시 최신 성과물을 업데이트하십시오."
|
|
||||||
* **VCI가 음수(-)인 대형 프로젝트**: "조직에서 가장 중요한 자산임에도 불구하고 평균 이하로 방치되고 있습니다. **최우선 관리 대상**입니다."
|
|
||||||
* **OCI가 낮은 프로젝트**: "활동은 있으나 불규칙합니다. 관리의 지속성을 확보하여 운영 리듬을 찾으십시오."
|
|
||||||
34
PLAN.md
34
PLAN.md
@@ -1,34 +0,0 @@
|
|||||||
# 데이터 분석 관리자 페이지 기획안
|
|
||||||
|
|
||||||
## 1. 프로젝트 개요
|
|
||||||
본 프로젝트는 데이터 분석 프로세스 및 프로젝트 리소스를 통합 관리하기 위한 관리자 대시보드입니다. 사용자 인터랙션 관리부터 시스템 로그, 리소스 현황을 한눈에 파악하는 것을 목표로 합니다.
|
|
||||||
|
|
||||||
## 2. 주요 기능 상세
|
|
||||||
|
|
||||||
### ① 메일 관리 및 요구사항 시스템 (Mail & Inquiry Management) - [완료]
|
|
||||||
- **UI/UX 고도화**: 리스트 영역 너비 확장(400px) 및 시각적 가독성 개선
|
|
||||||
- **검색 및 필터링**: 키워드 및 기간별 메일 검색 기능 구현
|
|
||||||
- **동적 연동**: 리스트 클릭 시 메일 본문 실시간 업데이트 구현
|
|
||||||
- **메일 관리**: 개별 삭제 및 체크박스를 활용한 대량 삭제 기능 추가
|
|
||||||
- **탭 시스템**: 수신/발신/임시/휴지통별 데이터 분류 및 동적 렌더링 적용
|
|
||||||
|
|
||||||
### ② 로그 관리 (Log Management)
|
|
||||||
- **최근 로그**: 실시간으로 발생하는 시스템 및 분석 작업 로그 출력
|
|
||||||
- **전체 로그**: 날짜별, 프로젝트별 필터링을 통한 로그 기록 조회 및 내보내기
|
|
||||||
|
|
||||||
### ③ 파일 관리 (File Management)
|
|
||||||
- 프로젝트별 데이터셋, 분석 결과물 파일 개수 및 용량 통계
|
|
||||||
- 파일 확장자별 구성 비율(CSV, JSON, Python 등) 시각화 지표 제공
|
|
||||||
|
|
||||||
### ④ 인원 관리 (Personnel Management)
|
|
||||||
- 프로젝트 참여 인원 현황 조회
|
|
||||||
- 사용자별 권한(관리자, 분석가, 뷰어) 부여 및 수정 기능
|
|
||||||
|
|
||||||
### ③ 공지사항 (Notice & Patch Notes)
|
|
||||||
- 분석 모델 업데이트, 시스템 점검, 패치 내역 공유
|
|
||||||
- 사용자 대상 공지사항 작성 및 게시판 관리
|
|
||||||
|
|
||||||
## 3. UI/UX 가이드라인
|
|
||||||
- **Layout**: 좌측 내비게이션 바(Sidebar) + 상단 헤더(Header) + 중앙 컨텐츠 영역
|
|
||||||
- **Theme**: 신뢰감을 주는 Dark Blue / White 톤의 깨끗한 디자인
|
|
||||||
- **Responsiveness**: 다양한 해상도에 대응하는 반응형 레이아웃 구성
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
import pymysql
|
|
||||||
import re
|
|
||||||
from collections import Counter
|
|
||||||
|
|
||||||
def get_db_connection():
|
|
||||||
return pymysql.connect(
|
|
||||||
host='localhost',
|
|
||||||
user='root',
|
|
||||||
password='45278434',
|
|
||||||
database='pm_proto_test',
|
|
||||||
charset='utf8mb4',
|
|
||||||
cursorclass=pymysql.cursors.DictCursor
|
|
||||||
)
|
|
||||||
|
|
||||||
def analyze_logs():
|
|
||||||
conn = get_db_connection()
|
|
||||||
try:
|
|
||||||
with conn.cursor() as cursor:
|
|
||||||
cursor.execute("SELECT DISTINCT recent_log FROM projects_history WHERE recent_log IS NOT NULL AND recent_log != ''")
|
|
||||||
rows = cursor.fetchall()
|
|
||||||
|
|
||||||
logs = [r['recent_log'] for r in rows]
|
|
||||||
|
|
||||||
output = []
|
|
||||||
output.append("[Raw Log Samples]")
|
|
||||||
for log in logs[:20]:
|
|
||||||
output.append(f"- {log}")
|
|
||||||
|
|
||||||
patterns = []
|
|
||||||
for log in logs:
|
|
||||||
p = re.sub(r'\d{2,4}\.\d{2}\.\d{2}', '[DATE]', log)
|
|
||||||
p = re.sub(r'\d+', '[NUM]', p)
|
|
||||||
patterns.append(p)
|
|
||||||
|
|
||||||
output.append("\n[Log Patterns Frequency]")
|
|
||||||
pattern_counts = Counter(patterns).most_common(20)
|
|
||||||
for p, count in pattern_counts:
|
|
||||||
output.append(f"({count}) {p}")
|
|
||||||
|
|
||||||
with open("log_analysis_result.txt", "w", encoding="utf-8") as f:
|
|
||||||
f.write("\n".join(output))
|
|
||||||
print("Analysis complete. Result saved to log_analysis_result.txt")
|
|
||||||
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
analyze_logs()
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import pymysql
|
|
||||||
import os
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
def show_tables():
|
|
||||||
conn = pymysql.connect(
|
|
||||||
host=os.getenv('DB_HOST', 'localhost'),
|
|
||||||
user=os.getenv('DB_USER', 'root'),
|
|
||||||
password=os.getenv('DB_PASSWORD', '45278434'),
|
|
||||||
database='PM_proto_test',
|
|
||||||
charset='utf8mb4',
|
|
||||||
cursorclass=pymysql.cursors.DictCursor
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
with conn.cursor() as cursor:
|
|
||||||
cursor.execute("SHOW TABLES")
|
|
||||||
tables = cursor.fetchall()
|
|
||||||
print("Tables in PM_proto_test:")
|
|
||||||
for t in tables:
|
|
||||||
print(f" - {list(t.values())[0]}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error occurred: {e}")
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
show_tables()
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import pymysql
|
|
||||||
import os
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
def clear_project_history():
|
|
||||||
conn = pymysql.connect(
|
|
||||||
host=os.getenv('DB_HOST', 'localhost'),
|
|
||||||
user=os.getenv('DB_USER', 'root'),
|
|
||||||
password=os.getenv('DB_PASSWORD', '45278434'),
|
|
||||||
database='PM_proto_test',
|
|
||||||
charset='utf8mb4',
|
|
||||||
cursorclass=pymysql.cursors.DictCursor
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
with conn.cursor() as cursor:
|
|
||||||
# 테이블의 모든 데이터를 삭제
|
|
||||||
print("Cleaning projects_history table in PM_proto_test...")
|
|
||||||
cursor.execute("DELETE FROM projects_history")
|
|
||||||
conn.commit()
|
|
||||||
print("Successfully cleared all records from projects_history.")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error occurred: {e}")
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
clear_project_history()
|
|
||||||
45
clone_db.py
45
clone_db.py
@@ -1,45 +0,0 @@
|
|||||||
import pymysql
|
|
||||||
import os
|
|
||||||
|
|
||||||
def clone_database():
|
|
||||||
try:
|
|
||||||
connection = pymysql.connect(
|
|
||||||
host=os.getenv('DB_HOST', 'localhost'),
|
|
||||||
user=os.getenv('DB_USER', 'root'),
|
|
||||||
password=os.getenv('DB_PASSWORD', '45278434'),
|
|
||||||
charset='utf8mb4',
|
|
||||||
cursorclass=pymysql.cursors.DictCursor
|
|
||||||
)
|
|
||||||
|
|
||||||
with connection.cursor() as cursor:
|
|
||||||
# 1. Create test database
|
|
||||||
cursor.execute("CREATE DATABASE IF NOT EXISTS PM_proto_test")
|
|
||||||
print("Database PM_proto_test created or already exists.")
|
|
||||||
|
|
||||||
# 2. Get all tables from source database
|
|
||||||
cursor.execute("SHOW TABLES FROM PM_proto")
|
|
||||||
tables = cursor.fetchall()
|
|
||||||
|
|
||||||
for table_row in tables:
|
|
||||||
table_name = list(table_row.values())[0]
|
|
||||||
|
|
||||||
# 3. Drop existing table in test DB if exists
|
|
||||||
cursor.execute(f"DROP TABLE IF EXISTS PM_proto_test.{table_name}")
|
|
||||||
|
|
||||||
# 4. Clone schema and data
|
|
||||||
# Note: CREATE TABLE ... LIKE doesn't copy data, and CREATE TABLE ... AS SELECT doesn't copy indexes.
|
|
||||||
# So we use LIKE first, then INSERT INTO ... SELECT *
|
|
||||||
cursor.execute(f"CREATE TABLE PM_proto_test.{table_name} LIKE PM_proto.{table_name}")
|
|
||||||
cursor.execute(f"INSERT INTO PM_proto_test.{table_name} SELECT * FROM PM_proto.{table_name}")
|
|
||||||
print(f"Table {table_name} cloned.")
|
|
||||||
|
|
||||||
connection.commit()
|
|
||||||
print("Database cloning completed successfully.")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error during database cloning: {e}")
|
|
||||||
finally:
|
|
||||||
if 'connection' in locals():
|
|
||||||
connection.close()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
clone_database()
|
|
||||||
@@ -21,6 +21,7 @@ def get_db_connection():
|
|||||||
"""MySQL 데이터베이스 연결을 반환 (환경변수 기반)"""
|
"""MySQL 데이터베이스 연결을 반환 (환경변수 기반)"""
|
||||||
return pymysql.connect(
|
return pymysql.connect(
|
||||||
host=os.getenv('DB_HOST', 'localhost'),
|
host=os.getenv('DB_HOST', 'localhost'),
|
||||||
|
port=int(os.getenv('DB_PORT', 3306)),
|
||||||
user=os.getenv('DB_USER', 'root'),
|
user=os.getenv('DB_USER', 'root'),
|
||||||
password=os.getenv('DB_PASSWORD', '45278434'),
|
password=os.getenv('DB_PASSWORD', '45278434'),
|
||||||
database=os.getenv('DB_NAME', 'PM_proto'),
|
database=os.getenv('DB_NAME', 'PM_proto'),
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ def get_db_connection():
|
|||||||
"""MySQL 데이터베이스(TEST) 연결을 반환"""
|
"""MySQL 데이터베이스(TEST) 연결을 반환"""
|
||||||
return pymysql.connect(
|
return pymysql.connect(
|
||||||
host=os.getenv('DB_HOST', 'localhost'),
|
host=os.getenv('DB_HOST', 'localhost'),
|
||||||
|
port=int(os.getenv('DB_PORT', 3306)),
|
||||||
user=os.getenv('DB_USER', 'root'),
|
user=os.getenv('DB_USER', 'root'),
|
||||||
password=os.getenv('DB_PASSWORD', '45278434'),
|
password=os.getenv('DB_PASSWORD', '45278434'),
|
||||||
database='PM_proto_test', # 테스트용 DB 고정
|
database='PM_proto_test', # 테스트용 DB 고정
|
||||||
|
|||||||
1
libs/libasound.so.2
Symbolic link
1
libs/libasound.so.2
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
libasound.so.2.0.0
|
||||||
BIN
libs/libasound.so.2.0.0
Normal file
BIN
libs/libasound.so.2.0.0
Normal file
Binary file not shown.
BIN
libs/libfreebl3.chk
Normal file
BIN
libs/libfreebl3.chk
Normal file
Binary file not shown.
BIN
libs/libfreebl3.so
Normal file
BIN
libs/libfreebl3.so
Normal file
Binary file not shown.
BIN
libs/libfreeblpriv3.chk
Normal file
BIN
libs/libfreeblpriv3.chk
Normal file
Binary file not shown.
BIN
libs/libfreeblpriv3.so
Normal file
BIN
libs/libfreeblpriv3.so
Normal file
Binary file not shown.
BIN
libs/libnspr4.so
Normal file
BIN
libs/libnspr4.so
Normal file
Binary file not shown.
BIN
libs/libnss3.so
Normal file
BIN
libs/libnss3.so
Normal file
Binary file not shown.
BIN
libs/libnss_compat.so.2
Normal file
BIN
libs/libnss_compat.so.2
Normal file
Binary file not shown.
BIN
libs/libnss_dns.so.2
Normal file
BIN
libs/libnss_dns.so.2
Normal file
Binary file not shown.
BIN
libs/libnss_files.so.2
Normal file
BIN
libs/libnss_files.so.2
Normal file
Binary file not shown.
BIN
libs/libnss_hesiod.so.2
Normal file
BIN
libs/libnss_hesiod.so.2
Normal file
Binary file not shown.
BIN
libs/libnss_systemd.so.2
Normal file
BIN
libs/libnss_systemd.so.2
Normal file
Binary file not shown.
BIN
libs/libnssckbi.so
Normal file
BIN
libs/libnssckbi.so
Normal file
Binary file not shown.
BIN
libs/libnssdbm3.chk
Normal file
BIN
libs/libnssdbm3.chk
Normal file
Binary file not shown.
BIN
libs/libnssdbm3.so
Normal file
BIN
libs/libnssdbm3.so
Normal file
Binary file not shown.
BIN
libs/libnssutil3.so
Normal file
BIN
libs/libnssutil3.so
Normal file
Binary file not shown.
BIN
libs/libplc4.so
Normal file
BIN
libs/libplc4.so
Normal file
Binary file not shown.
BIN
libs/libplds4.so
Normal file
BIN
libs/libplds4.so
Normal file
Binary file not shown.
BIN
libs/libsmime3.so
Normal file
BIN
libs/libsmime3.so
Normal file
Binary file not shown.
BIN
libs/libsoftokn3.chk
Normal file
BIN
libs/libsoftokn3.chk
Normal file
Binary file not shown.
BIN
libs/libsoftokn3.so
Normal file
BIN
libs/libsoftokn3.so
Normal file
Binary file not shown.
6
package-lock.json
generated
6
package-lock.json
generated
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "AICodeTest",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {}
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import asyncio
|
import asyncio
|
||||||
import pymysql
|
import pymysql
|
||||||
|
from dotenv import load_dotenv
|
||||||
from fastapi import FastAPI, Request
|
from fastapi import FastAPI, Request
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.responses import StreamingResponse, FileResponse
|
from fastapi.responses import StreamingResponse, FileResponse
|
||||||
@@ -16,6 +17,7 @@ from project_service import ProjectService
|
|||||||
from analysis_service import AnalysisService
|
from analysis_service import AnalysisService
|
||||||
|
|
||||||
# --- 환경 설정 ---
|
# --- 환경 설정 ---
|
||||||
|
load_dotenv()
|
||||||
os.environ["PYTHONIOENCODING"] = "utf-8"
|
os.environ["PYTHONIOENCODING"] = "utf-8"
|
||||||
TESSDATA_PREFIX = os.getenv("TESSDATA_PREFIX", r"C:\Users\User\AppData\Local\Programs\Tesseract-OCR\tessdata")
|
TESSDATA_PREFIX = os.getenv("TESSDATA_PREFIX", r"C:\Users\User\AppData\Local\Programs\Tesseract-OCR\tessdata")
|
||||||
os.environ["TESSDATA_PREFIX"] = TESSDATA_PREFIX
|
os.environ["TESSDATA_PREFIX"] = TESSDATA_PREFIX
|
||||||
@@ -41,6 +43,7 @@ def get_db_connection():
|
|||||||
"""MySQL 데이터베이스 연결을 반환"""
|
"""MySQL 데이터베이스 연결을 반환"""
|
||||||
return pymysql.connect(
|
return pymysql.connect(
|
||||||
host=os.getenv('DB_HOST', 'localhost'),
|
host=os.getenv('DB_HOST', 'localhost'),
|
||||||
|
port=int(os.getenv('DB_PORT', 3306)),
|
||||||
user=os.getenv('DB_USER', 'root'),
|
user=os.getenv('DB_USER', 'root'),
|
||||||
password=os.getenv('DB_PASSWORD', '45278434'),
|
password=os.getenv('DB_PASSWORD', '45278434'),
|
||||||
database=os.getenv('DB_NAME', 'PM_proto'),
|
database=os.getenv('DB_NAME', 'PM_proto'),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import asyncio
|
import asyncio
|
||||||
import pymysql
|
import pymysql
|
||||||
|
from dotenv import load_dotenv
|
||||||
from fastapi import FastAPI, Request
|
from fastapi import FastAPI, Request
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.responses import StreamingResponse, FileResponse
|
from fastapi.responses import StreamingResponse, FileResponse
|
||||||
@@ -16,6 +17,7 @@ from project_service import ProjectService
|
|||||||
from analysis_service import AnalysisService
|
from analysis_service import AnalysisService
|
||||||
|
|
||||||
# --- 환경 설정 ---
|
# --- 환경 설정 ---
|
||||||
|
load_dotenv()
|
||||||
os.environ["PYTHONIOENCODING"] = "utf-8"
|
os.environ["PYTHONIOENCODING"] = "utf-8"
|
||||||
TESSDATA_PREFIX = os.getenv("TESSDATA_PREFIX", r"C:\Users\User\AppData\Local\Programs\Tesseract-OCR\tessdata")
|
TESSDATA_PREFIX = os.getenv("TESSDATA_PREFIX", r"C:\Users\User\AppData\Local\Programs\Tesseract-OCR\tessdata")
|
||||||
os.environ["TESSDATA_PREFIX"] = TESSDATA_PREFIX
|
os.environ["TESSDATA_PREFIX"] = TESSDATA_PREFIX
|
||||||
@@ -41,6 +43,7 @@ def get_db_connection():
|
|||||||
"""MySQL 데이터베이스(TEST) 연결을 반환"""
|
"""MySQL 데이터베이스(TEST) 연결을 반환"""
|
||||||
return pymysql.connect(
|
return pymysql.connect(
|
||||||
host=os.getenv('DB_HOST', 'localhost'),
|
host=os.getenv('DB_HOST', 'localhost'),
|
||||||
|
port=int(os.getenv('DB_PORT', 3306)),
|
||||||
user=os.getenv('DB_USER', 'root'),
|
user=os.getenv('DB_USER', 'root'),
|
||||||
password=os.getenv('DB_PASSWORD', '45278434'),
|
password=os.getenv('DB_PASSWORD', '45278434'),
|
||||||
database='PM_proto_test', # 테스트용 DB로 고정
|
database='PM_proto_test', # 테스트용 DB로 고정
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
import pymysql
|
|
||||||
from analysis_service import AnalysisService
|
|
||||||
|
|
||||||
def verify_analysis():
|
|
||||||
conn = pymysql.connect(
|
|
||||||
host='localhost',
|
|
||||||
user='root',
|
|
||||||
password='45278434',
|
|
||||||
database='pm_proto_test',
|
|
||||||
charset='utf8mb4',
|
|
||||||
cursorclass=pymysql.cursors.DictCursor
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
with conn.cursor() as cursor:
|
|
||||||
results = AnalysisService.get_p_zsr_analysis_logic(cursor)
|
|
||||||
print(f"Total Projects Analyzed: {len(results)}")
|
|
||||||
print("\n[Sample Project Analysis Result]")
|
|
||||||
for res in results[:5]:
|
|
||||||
print(f"Project: {res['project_nm']}")
|
|
||||||
print(f" - Log Quality Score (Semantic): {res['log_quality']}")
|
|
||||||
print(f" - AVI Score (p_war): {res['p_war']}")
|
|
||||||
print(f" - OCI Score: {res['oci_score']}")
|
|
||||||
print("-" * 30)
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
verify_analysis()
|
|
||||||
Reference in New Issue
Block a user