Files
Aislo/B02_ProjRegister/B02_ProjRegister_Router.py
T
eomsangdonandClaude Opus 5 ac983cf0e1 feat(B02): 등록 폼에 표제란 8칸 반영
사용자 지시(2026-09-02) — 프로젝트 등록에서도 수정 모달과 같은 항목 수신.

- 시행청·연도기번·사업량·설계일자·과업책임자·분야별책임자·설계자·회사 로고 8칸 추가.
  담당자는 select + 「신규 등록…」(관리자만), 로고는 회사 대표 로고가 기본값
- 담당자·자산 회사 경계 검사를 check_project_refs(company_id, data) 로 옮겨 B01 수정과 공용
- GET /admin/members 문턱을 require_company 로 — 일반 사용자도 담당자 선택 필요.
  _scope_company 가 남의 회사를 막고 쓰기는 관리자 그대로
- fix: road_type 스키마가 옛 값(branch·stream)을 받고 화면 선택지 work 를 막아
  「작업임도」 등록이 422 로 떨어지던 것 수정 — ^(main|fire|work)$
- 검증(5174 실조작): 등록 칸 14개로 수정 모달과 동일, 등록된 행에 8칸 그대로 저장
  (road_type=work, logo_asset_id=1, designer=3), 해당 프로젝트 표제란 12칸 전부 채워짐.
  pytest 151 passed (신규 test_b02_register_schema.py 8건)

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

61 lines
2.1 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",
}
)
# 담당자·로고는 같은 회사 것만 (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