refactor: SQL 쿼리 관리 모듈화 및 메일 관리 UI/UX 고도화

This commit is contained in:
2026-03-17 14:27:25 +09:00
parent 74f11d3bd4
commit d0b33edea8
22 changed files with 851 additions and 1324 deletions

View File

@@ -13,6 +13,7 @@ from fastapi.templating import Jinja2Templates
from analyze import analyze_file_content
from crawler_service import run_crawler_service, crawl_stop_event
from sql_queries import InquiryQueries, DashboardQueries
# --- 환경 설정 ---
os.environ["PYTHONIOENCODING"] = "utf-8"
@@ -87,7 +88,7 @@ async def get_inquiries(pm_type: str = None, category: str = None, status: str =
try:
with get_db_connection() as conn:
with conn.cursor() as cursor:
sql = "SELECT * FROM inquiries WHERE 1=1"
sql = InquiryQueries.SELECT_BASE
params = []
if pm_type:
sql += " AND pm_type = %s"
@@ -102,7 +103,7 @@ async def get_inquiries(pm_type: str = None, category: str = None, status: str =
sql += " AND (content LIKE %s OR author LIKE %s OR project_nm LIKE %s)"
params.extend([f"%{keyword}%", f"%{keyword}%", f"%{keyword}%"])
sql += " ORDER BY no DESC"
sql += f" {InquiryQueries.ORDER_BY_DESC}"
cursor.execute(sql, params)
return cursor.fetchall()
except Exception as e:
@@ -113,7 +114,7 @@ async def get_inquiry_detail(id: int):
try:
with get_db_connection() as conn:
with conn.cursor() as cursor:
cursor.execute("SELECT * FROM inquiries WHERE id = %s", (id,))
cursor.execute(InquiryQueries.SELECT_BY_ID, (id,))
return cursor.fetchone()
except Exception as e:
return {"error": str(e)}
@@ -123,13 +124,8 @@ async def update_inquiry_reply(id: int, req: InquiryReplyRequest):
try:
with get_db_connection() as conn:
with conn.cursor() as cursor:
handled_date = datetime.now().strftime("%Y. %m. %d")
sql = """
UPDATE inquiries
SET reply = %s, status = %s, handler = %s, handled_date = %s
WHERE id = %s
"""
cursor.execute(sql, (req.reply, req.status, req.handler, handled_date, id))
handled_date = datetime.now().strftime("%Y.%m.%d")
cursor.execute(InquiryQueries.UPDATE_REPLY, (req.reply, req.status, req.handler, handled_date, id))
conn.commit()
return {"success": True}
except Exception as e:
@@ -140,12 +136,7 @@ async def delete_inquiry_reply(id: int):
try:
with get_db_connection() as conn:
with conn.cursor() as cursor:
sql = """
UPDATE inquiries
SET reply = '', status = '미확인', handled_date = ''
WHERE id = %s
"""
cursor.execute(sql, (id,))
cursor.execute(InquiryQueries.DELETE_REPLY, (id,))
conn.commit()
return {"success": True}
except Exception as e:
@@ -158,7 +149,7 @@ async def get_available_dates():
try:
with get_db_connection() as conn:
with conn.cursor() as cursor:
cursor.execute("SELECT DISTINCT crawl_date FROM projects_history ORDER BY crawl_date DESC")
cursor.execute(DashboardQueries.GET_AVAILABLE_DATES)
rows = cursor.fetchall()
return [row['crawl_date'].strftime("%Y.%m.%d") for row in rows if row['crawl_date']]
except Exception as e:
@@ -172,20 +163,13 @@ async def get_project_data(date: str = None):
with get_db_connection() as conn:
with conn.cursor() as cursor:
if not target_date:
cursor.execute("SELECT MAX(crawl_date) as last_date FROM projects_history")
cursor.execute(DashboardQueries.GET_LAST_CRAWL_DATE)
res = cursor.fetchone()
target_date = res['last_date']
if not target_date: return {"projects": []}
sql = """
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
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,))
cursor.execute(DashboardQueries.GET_PROJECT_LIST, (target_date,))
rows = cursor.fetchall()
projects = []
@@ -203,7 +187,7 @@ async def get_project_activity(date: str = None):
with get_db_connection() as conn:
with conn.cursor() as cursor:
if not date or date == "-":
cursor.execute("SELECT MAX(crawl_date) as last_date FROM projects_history")
cursor.execute(DashboardQueries.GET_LAST_CRAWL_DATE)
res = cursor.fetchone()
target_date_val = res['last_date'] if res['last_date'] else datetime.now().date()
else:
@@ -212,12 +196,7 @@ async def get_project_activity(date: str = None):
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
LEFT JOIN projects_history h ON m.project_id = h.project_id AND h.crawl_date = %s
"""
cursor.execute(sql, (target_date_val,))
cursor.execute(DashboardQueries.GET_PROJECT_LIST_FOR_ANALYSIS, (target_date_val,))
rows = cursor.fetchall()
analysis = {"summary": {"active": 0, "warning": 0, "stale": 0, "unknown": 0}, "details": []}