fix(B03): 파일 교체 후 다시 업로드할 수 있게 — 끝난 카드 [파일 선택] + 확정 대기 관문
- 완료 카드에서도 [파일 선택]을 보임. 올리는 중에만 감춤. 교체 확인 모달과 교체 업로드 규칙은 이미 있던 것을 그대로 씀. - 업로드 관문이 전처리 1단계 IN_PROGRESS 를 무조건 「분석 중」으로 읽어, 자동 확정이 보류된 프로젝트는 영영 새 자료를 받지 못했음. 전처리 진행 파일이 awaiting_confirmation·completed·failed 로 끝나 있으면 받도록 고침. 실제로 도는 중(analyzing)이면 그대로 막음. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -699,8 +699,9 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.b03-file__card--uploading .b03-file__card-select,
|
||||
.b03-file__card--completed .b03-file__card-select {
|
||||
/* 올리는 중에만 [파일 선택]을 감춘다. 끝난 카드에도 남겨 두어야 파일 하나를 갈아
|
||||
끼우고 [파일 업로드]로 다시 돌릴 수 있다(2026-09-04 사용자 지시). */
|
||||
.b03-file__card--uploading .b03-file__card-select {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -260,7 +260,41 @@ async def is_analysis_running(cursor: aiomysql.DictCursor, project_id: str) -> b
|
||||
if not row:
|
||||
return False
|
||||
state = row["state"] if isinstance(row, dict) else row[0]
|
||||
return str(state) == "IN_PROGRESS"
|
||||
if str(state) != "IN_PROGRESS":
|
||||
return False
|
||||
# 자동 확정이 보류되면 1단계는 사용자가 B04에서 모델을 고를 때까지 IN_PROGRESS 로
|
||||
# 남는다 — 계산은 이미 끝난 상태다. 그 사이에도 새 자료는 받아야 한다
|
||||
# (2026-09-04 사용자 지시 — 같은 프로젝트로 전처리를 되풀이 시험).
|
||||
return not await _surface_run_settled(cursor, project_id)
|
||||
|
||||
|
||||
# 계산이 끝나 사용자의 다음 조작을 기다리는 진행 단계 — 도는 중이 아니다.
|
||||
_SETTLED_SURFACE_STAGES = frozenset({"awaiting_confirmation", "completed", "failed"})
|
||||
|
||||
|
||||
async def _surface_run_settled(cursor: aiomysql.DictCursor, project_id: str) -> bool:
|
||||
"""전처리 진행 파일이 「끝났음」으로 적혀 있는가. 파일이 없으면 판단하지 않는다."""
|
||||
from pathlib import Path
|
||||
|
||||
from B04_PreProcess.B04_PreProcess_Router_Progress import read_surface_progress
|
||||
from common_util.common_util_storage import resolve_stored_project_path
|
||||
|
||||
await cursor.execute(
|
||||
"SELECT storage_path FROM projects WHERE id = %s AND deleted_at IS NULL",
|
||||
(project_id,),
|
||||
)
|
||||
row = await cursor.fetchone()
|
||||
if not row:
|
||||
return False
|
||||
storage_path = row["storage_path"] if isinstance(row, dict) else row[0]
|
||||
if not storage_path:
|
||||
return False
|
||||
try:
|
||||
progress = read_surface_progress(Path(resolve_stored_project_path(str(storage_path))))
|
||||
except (OSError, ValueError):
|
||||
return False
|
||||
stage = str((progress or {}).get("current_stage") or "")
|
||||
return stage in _SETTLED_SURFACE_STAGES
|
||||
|
||||
|
||||
async def reset_stages_after_input_change(cursor: aiomysql.DictCursor, project_id: str) -> None:
|
||||
|
||||
Reference in New Issue
Block a user