- 등록 화면 = 공용 카카오 지도(마우스 설정 따름 · 일반/위성) 누름 · 끌기로 기준점 하나 · 주소 글 + 출처 - 사업 지역 = 주소의 「시군구 읍면」 채움 · 손으로 고친 값은 안 덮음 - 서버 = 기준점 필수(경위도 범위) · 주소는 서버가 VWorld 로 다시 찾아 저장 · 설계속도 칸 안 씀(B05 기본 20) - 새 길 GET /api/map/address — 지번 먼저(산 번지) · region · 출처 VWorld · B08 한 줄 주소 그대로 - DB 024 = projects 기준점 칸 셋 추가 · PLAN 설계속도 비움 · 옛 PLAN 기준점 = 지점 가운데(024_plan_site_fill.py · 적용 완료) - 시험 528 = 설계속도 단언을 기준점 단언으로 · 새 지킴 시험 591_1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
116 lines
4.1 KiB
Python
116 lines
4.1 KiB
Python
"""종류별 프로젝트 행 만들기 — D 예정노선 · E 안정성평가(요구 345).
|
|
|
|
임도설계(ROAD)는 B02 그대로. 저장소 경로는 B02 함수를 씀 · 초기 폴더는 종류 단계만
|
|
(B 양식 복사 · B0x 빈 폴더 없음 · D 는 지형 배치 B04_PreProcess 더함).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Any
|
|
from uuid import uuid4
|
|
|
|
from B02_ProjRegister.B02_ProjRegister_Repository import _build_project_storage
|
|
from common_util.common_util_audit import record_audit
|
|
from common_util.common_util_storage import get_project_stage_path
|
|
from common_util.common_util_workflow_state import initialize_project_stages
|
|
from config.config_db import get_db_pool
|
|
|
|
KIND_STAGE_DIRS = {
|
|
"PLAN": ("D02_PlanBase", "D03_PlanAnalysis", "D04_PlanConfirm", "B04_PreProcess"),
|
|
"STABILITY": (
|
|
"E02_StabGround",
|
|
"E03_StabSection",
|
|
"E04_Stab3D",
|
|
"E05_StabReport",
|
|
"E06_StabRock",
|
|
"E07_StabArea",
|
|
),
|
|
}
|
|
|
|
|
|
def init_kind_storage(project_root: Path, kind: str) -> None:
|
|
"""종류 단계 폴더만 — B 양식 · B0x 빈 폴더 · workflow · manifest 없음."""
|
|
for stage_dir in KIND_STAGE_DIRS[kind]:
|
|
get_project_stage_path(str(project_root), stage_dir)
|
|
|
|
|
|
async def create_kind_project(
|
|
*,
|
|
request: Any | None,
|
|
user_id: int,
|
|
company_id: int,
|
|
kind: str,
|
|
name: str,
|
|
region: str | None,
|
|
road_type: str | None,
|
|
project_year: int | None,
|
|
project_year_end: int | None = None,
|
|
site: tuple[float, float, str | None] | None = None,
|
|
route_start_m: float | None = None,
|
|
route_end_m: float | None = None,
|
|
source_project_id: str | None = None,
|
|
) -> str:
|
|
"""projects 행 + 참여자 + 종류별 단계 + 저장소 폴더 → 새 project_id.
|
|
|
|
site = 예정노선 기준점(경도, 위도, 주소 · 591-1) · 설계속도 칸은 비워 둠(B05 기본).
|
|
"""
|
|
project_id = str(uuid4())
|
|
storage_path, project_root = _build_project_storage(company_id, user_id, project_id)
|
|
now = datetime.utcnow()
|
|
|
|
async with get_db_pool().acquire() as connection, connection.cursor() as cursor:
|
|
try:
|
|
await connection.begin()
|
|
await cursor.execute(
|
|
"""
|
|
INSERT INTO projects (
|
|
id, user_id, company_id, name, region, road_type, project_kind,
|
|
project_year, project_year_end, site_lon, site_lat, site_address,
|
|
route_start_m, route_end_m, status, crs_epsg, storage_path,
|
|
source_project_id, source_copied_at, created_at, updated_at
|
|
)
|
|
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 'NEW', 5178, %s,
|
|
%s, %s, %s, %s)
|
|
""",
|
|
(
|
|
project_id,
|
|
user_id,
|
|
company_id,
|
|
name,
|
|
region,
|
|
road_type,
|
|
kind,
|
|
project_year,
|
|
project_year_end,
|
|
*(site or (None, None, None)),
|
|
route_start_m,
|
|
route_end_m,
|
|
storage_path,
|
|
source_project_id,
|
|
now if source_project_id else None,
|
|
now,
|
|
now,
|
|
),
|
|
)
|
|
await cursor.execute(
|
|
"INSERT IGNORE INTO project_members (project_id, user_id) VALUES (%s, %s)",
|
|
(project_id, user_id),
|
|
)
|
|
await initialize_project_stages(cursor, project_id, kind)
|
|
await record_audit(
|
|
cursor,
|
|
actor_id=user_id,
|
|
action="PROJECT_CREATE",
|
|
resource_type="project",
|
|
resource_ref=project_id,
|
|
request=request,
|
|
)
|
|
init_kind_storage(project_root, kind)
|
|
await connection.commit()
|
|
except Exception:
|
|
await connection.rollback()
|
|
raise
|
|
return project_id
|