Files
Aislo/B02_ProjRegister/B02_ProjRegister_Router.py
T
eomsangdonandClaude Opus 5 4e4bfa2354 feat(B02/B03/B04/B05): 계획노선 사용 범위 · 절단 여유 3m · 배수유역도 줌·측점 표기
- 계획노선 사용 범위: B02 등록에 시작·종료 누가거리 두 칸 추가, B01 수정 모달에서도
  변경. projects.route_start_m·route_end_m 신설(015_route_range.sql).
  load_design_route 가 범위 절단 → 서피스 트림 순서로 적용. 시작 >= 종료는 화면·서버
  양쪽에서 차단. 비우면 전 구간으로 종전과 같음.
- 서피스 절단 여유 기본값 30m → 3m (SURFACE_ROUTE_EDGE_TRIM_M).
- B04 지도·B05 배수유역도 줌 상한을 「화면 폭 20m」 기준으로 계산(고정 8배·16배 폐지).
  4배를 넘으면 배경 그림 흐림 보간 해제.
- 계획선 위 측점 눈금·번호 표기(측점번호+잔여거리). 관 마커와 겹치면 반대쪽으로 밀고,
  되꺾임 구간에서 라벨이 겹치면 건너뜀. 그리기 코드는 두 화면 공용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 19:08:11 +09:00

70 lines
2.5 KiB
Python

"""B02_ProjRegister FastAPI 라우터."""
from typing import Any
from fastapi import APIRouter, Depends, HTTPException
from B01_Dashboard.B01_Dashboard_Repository_Members import check_project_refs
from common_util.common_util_auth import require_company
from .B02_ProjRegister_Repository import create_project
from .B02_ProjRegister_Schema import CreateProjectRequest, CreateProjectResponse
router = APIRouter(prefix="/api/b02", tags=["B02_ProjRegister"])
@router.post("/project", response_model=CreateProjectResponse)
async def post_project(
payload: CreateProjectRequest,
session: dict[str, Any] = Depends(require_company),
) -> CreateProjectResponse:
"""신규 프로젝트를 생성한다."""
company_id = session.get("company_id")
if company_id is None:
raise HTTPException(status_code=403, detail="회사 연결이 필요합니다.")
title_block = payload.model_dump(
include={
"client_org",
"project_number",
"work_amount",
"design_date",
"pm_user_id",
"field_lead_user_id",
"designer_user_id",
"logo_asset_id",
"route_start_m",
"route_end_m",
}
)
# 시작이 종료보다 뒤면 남는 구간이 없다 — 저장 전에 막는다 (2026-09-04 사용자 지시).
start_m, end_m = payload.route_start_m, payload.route_end_m
if start_m is not None and end_m is not None and start_m >= end_m:
raise HTTPException(
status_code=400,
detail="노선 시작 누가거리는 종료 누가거리보다 작아야 합니다.",
)
# 담당자·로고는 같은 회사 것만 (B01 프로젝트 수정과 같은 규칙).
await check_project_refs(int(company_id), title_block)
try:
result = await create_project(
user_id=int(session["user_id"]),
company_id=int(company_id),
name=payload.name.strip(),
region=payload.region.strip(),
road_type=payload.road_type,
project_year=payload.project_year,
estimated_length_m=payload.estimated_length_m,
memo=payload.memo.strip() if payload.memo else None,
title_block=title_block,
)
return CreateProjectResponse(**result)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
except Exception as exc:
raise HTTPException(
status_code=500, detail="프로젝트 생성 처리 중 오류가 발생했습니다."
) from exc