feat(B03): 재접속 업로드 현황(10) + B05·B06 자동 설계 체인(9)
10. 재접속 현황·완료 표시·재업로드 경고:
- GET /projects/{id}/upload-overview 신설 — 완료 파일 목록(input_files 정본),
중단 청크 세션(진행률), 필수 파일·WF1 분석 완료 여부
- 진입 시 서버 정본으로 슬롯 카드 표시(serverUploaded), localStorage는 보조로 강등
- 파일 재선택 전에도 중단 세션 이어올리기 안내 배너
- 전체 완료 배지 + 완료 슬롯 재업로드 시 교체 확인 모달(승인 시에만 진행)
- 필수 슬롯 검증: 서버 업로드분 있으면 충족 — 단일 파일 교체 업로드 허용
9. 자동 설계 체인 연장 (B03_FileInput_Service_Chain.py):
- WF1 자동 확정 후 같은 백그라운드 태스크에서 ① 계획노선 CSV 기반 B05 기본 경로
계산(solve) ② 경로 확정(stage 2) ③ B06 기본 횡단 설계 확정(stage 3)까지 진행
- 수동 이력 보호: 프로젝트에 경로가 이미 있으면 건너뜀
- 단계별 실패 격리: 실패 단계에서 멈추고 로그·workflow 상태로만 기록
- AUTO_DESIGN_CHAIN_ENABLED config 플래그(기본 True)
typecheck·ruff·B03 unittest(7건) 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -290,3 +290,51 @@ async def mark_upload_session_failed(
|
||||
""",
|
||||
(session_id,),
|
||||
)
|
||||
|
||||
|
||||
async def list_project_input_files(
|
||||
connection: aiomysql.Connection,
|
||||
project_id: UUID,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""업로드 완료된 입력 파일 목록(재접속 현황 표시용) — 서버가 정본이다.
|
||||
|
||||
같은 파일명을 다시 올리면 새 레코드가 쌓이므로 파일명별 최신 것만 남긴다.
|
||||
"""
|
||||
async with connection.cursor(aiomysql.DictCursor) as cursor:
|
||||
await cursor.execute(
|
||||
"""
|
||||
SELECT f.id, f.file_type, f.original_filename, f.file_size_mb, f.status,
|
||||
f.created_at
|
||||
FROM input_files f
|
||||
INNER JOIN (
|
||||
SELECT MAX(id) AS id
|
||||
FROM input_files
|
||||
WHERE project_id = %s AND status IN ('UPLOADED', 'PROCESSED')
|
||||
GROUP BY original_filename
|
||||
) latest ON latest.id = f.id
|
||||
ORDER BY f.id ASC
|
||||
""",
|
||||
(str(project_id),),
|
||||
)
|
||||
rows = await cursor.fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
|
||||
async def list_incomplete_upload_sessions(
|
||||
connection: aiomysql.Connection,
|
||||
project_id: UUID,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""중단된(미완료) 청크 업로드 세션 목록 — 재접속 시 이어올리기 안내용."""
|
||||
async with connection.cursor(aiomysql.DictCursor) as cursor:
|
||||
await cursor.execute(
|
||||
"""
|
||||
SELECT id, original_filename, file_size_bytes, chunk_size_bytes,
|
||||
total_chunks, completed_chunks, updated_at
|
||||
FROM upload_sessions
|
||||
WHERE project_id = %s AND status = 'in_progress'
|
||||
ORDER BY updated_at DESC
|
||||
""",
|
||||
(str(project_id),),
|
||||
)
|
||||
rows = await cursor.fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
Reference in New Issue
Block a user