feat: 크롤러 부서 정보 수집 추가 및 대시보드 데이터 정확도 개선

- getData API 가로채기 기능을 통한 부서(department) 자동 수집 구현
- 파일 0개 기준의 "데이터 없음" 분류 로직 최적화 (LEFT JOIN 적용)
- 관리자 권한 인증 모달 스타일 복구 및 UI 정밀 조정
- 중복 등록 프로젝트(sm-25-032-phlinfra) DB 정리 및 테스트 파일 삭제
This commit is contained in:
2026-03-11 17:52:12 +09:00
parent 9f06857bea
commit 600c54c1f0
7 changed files with 178 additions and 81 deletions

View File

@@ -102,8 +102,8 @@ async def get_project_data(date: str = None):
SELECT m.project_nm, m.short_nm, m.department, m.master,
h.recent_log, h.file_count, m.continent, m.country
FROM projects_master m
JOIN projects_history h ON m.project_id = h.project_id
WHERE h.crawl_date = %s ORDER BY m.project_id ASC
LEFT JOIN projects_history h ON m.project_id = h.project_id AND h.crawl_date = %s
ORDER BY m.project_id ASC
"""
cursor.execute(sql, (target_date,))
rows = cursor.fetchall()
@@ -130,6 +130,8 @@ async def get_project_activity(date: str = None):
target_date_val = datetime.strptime(date.replace(".", "-"), "%Y-%m-%d").date()
target_date_dt = datetime.combine(target_date_val, datetime.min.time())
# 아코디언 리스트와 동일하게 마스터의 모든 프로젝트를 가져오되, 해당 날짜의 히스토리를 매칭
sql = """
SELECT m.project_id, m.project_nm, m.short_nm, h.recent_log, h.file_count
FROM projects_master m
@@ -142,12 +144,27 @@ async def get_project_activity(date: str = None):
for r in rows:
log, files = r['recent_log'], r['file_count']
status, days = "unknown", 999
if log and log != "데이터 없음" and files and files > 0:
# 파일 수 정수 변환 (데이터가 없거나 0이면 0)
file_val = int(files) if files else 0
has_log = log and log != "데이터 없음" and log != "X"
if file_val == 0:
# [핵심] 파일이 0개면 무조건 "데이터 없음"
status = "unknown"
elif has_log:
# 로그 날짜가 있는 경우 정밀 분석
match = re.search(r'(\d{4})\.(\d{2})\.(\d{2})', log)
if match:
diff = (target_date_dt - datetime.strptime(match.group(0), "%Y.%m.%d")).days
status = "active" if diff <= 7 else "warning" if diff <= 14 else "stale"
days = diff
else:
status = "stale"
else:
# 파일은 있지만 로그가 없는 경우
status = "stale"
analysis["summary"][status] += 1
analysis["details"].append({"name": r['short_nm'] or r['project_nm'], "status": status, "days_ago": days})
return analysis