change(B03): 업로드/분석 알림 메일을 초기 설계 완료 시점 한 통으로 통합
같은 업로드 한 번에 업로드 완료 메일과 지표면 분석 완료 메일이 두 통 도착했다. 사용자가 실제로 화면을 볼 수 있는 시점은 초기 설계(B04 전처리 + B05 종단 + B06 횡단)까지 끝난 때 하나뿐이므로 그 시점에 통합 메일 한 통만 보낸다. - send_initial_analysis_complete_email 신설: 지표면 요약 + 노선 연장/측점 수 + 종단설계 화면 링크. 자동 체인 미실행/실패 시 전처리 요약만 싣고 안내 문구 전환 - run_auto_design_chain이 요약(route_id/length_m/cross_section_count) 반환 - WF1 서비스: 체인 실행 -> 통합 메일 순으로 재배치 - 업로드 직후 메일 발송 호출 제거(일반·청크 두 경로). 발송 함수는 프로젝트 생성 전 임시 보관함 안내용으로 남겨 두고 주석으로 용도 명시 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -52,11 +52,16 @@ def _planned_route_points_in_project_crs(project_root: Path) -> list[dict[str, f
|
||||
return [{"x": x, "y": y} for x, y in points]
|
||||
|
||||
|
||||
async def run_auto_design_chain(project_id: UUID, surface_model_id: int | None = None) -> None:
|
||||
async def run_auto_design_chain(
|
||||
project_id: UUID, surface_model_id: int | None = None
|
||||
) -> dict[str, Any] | None:
|
||||
"""B05 기본 경로 계산·확정 → B06 기본 횡단 설계 확정을 기본값으로 이어 실행한다.
|
||||
|
||||
WF1 자동 확정 직후 같은 백그라운드 태스크에서 호출된다. 어떤 단계가 실패해도
|
||||
예외를 밖으로 던지지 않는다 — 로그와 각 단계의 workflow 상태 기록으로 남긴다.
|
||||
|
||||
성공하면 초기 분석 완료 메일에 실을 요약(노선 id·연장·측점 수)을 돌려주고,
|
||||
건너뛰거나 실패하면 None을 돌려준다.
|
||||
"""
|
||||
from B03_FileInput.B03_FileInput_Repository import get_project_storage_relative_path
|
||||
from B05_Profile.B05_Profile_Repository import get_latest_route
|
||||
@@ -79,14 +84,14 @@ async def run_auto_design_chain(project_id: UUID, surface_model_id: int | None =
|
||||
project_id,
|
||||
existing.get("id"),
|
||||
)
|
||||
return
|
||||
return None
|
||||
|
||||
# 2) 계획노선 CSV → BP/EP/경유점. 없으면 자동 경로를 세울 근거가 없다.
|
||||
project_root = Path(resolve_stored_project_path(stored_path))
|
||||
points = _planned_route_points_in_project_crs(project_root)
|
||||
if not points:
|
||||
logger.warning("자동 설계 체인 중단(계획노선 CSV 없음): project_id=%s", project_id)
|
||||
return
|
||||
return None
|
||||
|
||||
# 3) B05 경로 계산 — WF1 자동 확정과 같은 config 기본값을 쓴다.
|
||||
defaults = surface_confirmation_defaults()
|
||||
@@ -109,7 +114,7 @@ async def run_auto_design_chain(project_id: UUID, surface_model_id: int | None =
|
||||
project_id,
|
||||
solve_result.status_code,
|
||||
)
|
||||
return
|
||||
return None
|
||||
route_id = int(solve_result.route_id)
|
||||
logger.info(
|
||||
"자동 설계 체인 B05 경로 계산 완료: project_id=%s route_id=%s length=%.1fm",
|
||||
@@ -127,7 +132,7 @@ async def run_auto_design_chain(project_id: UUID, surface_model_id: int | None =
|
||||
project_id,
|
||||
confirm_result.status_code,
|
||||
)
|
||||
return
|
||||
return None
|
||||
|
||||
# 5) B06 횡단 설계 확정 — 미지정 측점을 기본값으로 채워 저장. stage 3은
|
||||
# IN_PROGRESS(스텝바 노란 표시)로 남겨 사용자 검토·확정을 기다린다.
|
||||
@@ -141,12 +146,17 @@ async def run_auto_design_chain(project_id: UUID, surface_model_id: int | None =
|
||||
route_id,
|
||||
sections_result.status_code,
|
||||
)
|
||||
return
|
||||
return None
|
||||
logger.info(
|
||||
"자동 설계 체인 완료(B05·B06 기본값 확정): project_id=%s route_id=%s",
|
||||
project_id,
|
||||
route_id,
|
||||
)
|
||||
return {
|
||||
"route_id": route_id,
|
||||
"length_m": float(solve_result.total_length_m or 0.0),
|
||||
"cross_section_count": solve_result.cross_section_count,
|
||||
}
|
||||
except Exception:
|
||||
# 체인은 업로드·WF1 흐름의 부가 작업이다 — 어떤 예외도 밖으로 던지지 않는다.
|
||||
logger.exception("자동 설계 체인 실패: project_id=%s", project_id)
|
||||
|
||||
Reference in New Issue
Block a user