diff --git a/B03_FileInput/B03_FileInput_Router.py b/B03_FileInput/B03_FileInput_Router.py index 2af94831..76956605 100644 --- a/B03_FileInput/B03_FileInput_Router.py +++ b/B03_FileInput/B03_FileInput_Router.py @@ -22,6 +22,7 @@ from B03_FileInput.B03_FileInput_Repository import ( get_project_storage_relative_path, list_incomplete_upload_sessions, list_project_input_files, + supersede_previous_input_files, ) # 분리 전 이 파일에 있던 이름은 그대로 다시 내보낸다 — 옛 이름을 참조하는 @@ -112,6 +113,7 @@ from common_util.common_util_storage import resolve_stored_project_path from common_util.common_util_workflow import load_project_workflow from common_util.common_util_workflow_state import ( get_workflow_state, + is_analysis_running, ) from config.config_db import get_db_pool from config.config_system import ( @@ -199,6 +201,14 @@ async def upload_project_files( async with pool.acquire() as connection: stored_path = await get_project_storage_relative_path(connection, project_id) project_root = Path(resolve_stored_project_path(stored_path)) + # 분석이 도는 중이면 새 자료를 받지 않는다 — 청크·임시배치 경로와 같은 가드다 + # (2026-09-08). 이 갈래만 빠져 있어 분석 2개가 같은 산출물 경로에서 부딪혔다. + async with connection.cursor(aiomysql.DictCursor) as cursor: + if await is_analysis_running(cursor, str(project_id)): + return JSONResponse( + status_code=409, + content={"status": "error", "message": _ANALYSIS_RUNNING_MESSAGE}, + ) await connection.begin() try: @@ -229,6 +239,14 @@ async def upload_project_files( crs_epsg=int(crs_epsg) if crs_epsg is not None else None, metadata=metadata, ) + # 같은 이름의 옛 행은 내려 둔다 — 청크 경로와 같은 처리다(2026-09-08). + # 이 갈래만 빠져 있어 같은 파일이 두 줄로 활성으로 남았다. + await supersede_previous_input_files( + connection, + project_id, + descriptor.original_filename, + input_file_id, + ) results.append( UploadedFileResult( input_file_id=input_file_id,