feat(B03): 입력 화면을 계획노선/지형 두 컨테이너로 나누고 파일마다 카드를 준다
노선 파일이 다섯이면 카드도 다섯이어야 어느 것이 왔는지 보인다(사용자 지시). 세트를 슬롯 하나에 몰아 담던 companions 구조를 걷어내고, 슬롯 하나가 파일 하나를 갖는 기존 구조로 되돌렸다 - 업로드 루프도 원래대로다. - 왼쪽 컨테이너 계획노선 자료: csv(.csv/.shp) shx dbf cpg route_prj - 오른쪽 컨테이너 지형 자료(LAS): las_laz prj(지형 좌표계) tfw tif + LAS 없는 설계 토글 - .prj만 확장자로 안 갈린다 - 노선 도형과 basename이 같으면 노선 좌표계 카드, 아니면 지형 카드(planSlotAssignments). 재접속 현황은 저장 경로(input/shp/)로 가른다. - 재접속 현황 응답에 relative_path 추가. - 필수 판정이 노선 PRJ를 route_prj로 따로 센다 - 지형 PRJ 없이 통과하던 구멍을 막았다. - 형제 카드(shx/dbf/route_prj)는 노선 도형이 shapefile일 때만 필수 - 확장자 줄의 "선택" 꼬리표가 실시간으로 붙고 떨어진다. - 카드가 좁아져 한글 제목이 글자 단위로 접히던 것을 word-break: keep-all과 헤더 flex-wrap으로 고쳤다. 화면 검증(공용 브라우저): 실물 7파일을 한 번에 떨어뜨려 배정 실측 - route.prj는 노선 좌표계 카드, terrain.prj는 지형 카드로 갈렸고 카드 제목 9개 모두 한 줄. tmp/tests/test_route_shapefile_input.py 9개 통과, tsc --noEmit 통과. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -69,11 +69,15 @@ async def get_project_input_readiness(
|
||||
|
||||
계획노선은 CSV 또는 shapefile이다. 둘 다 있으면 shapefile을 고른다 —
|
||||
`find_planned_route_file()`의 우선순위와 같아야 WF1 입력과 실제 판독 대상이 갈리지 않는다.
|
||||
|
||||
PRJ는 노선용·지형용 두 장이 온다. DB `file_type`은 둘 다 `prj`라 그대로 세면 노선
|
||||
PRJ 하나로 필수가 채워진다 — 프로젝트 좌표계를 정하는 것은 **지형 PRJ**이므로,
|
||||
노선 세트 폴더(`input/shp/`)에 있는 PRJ는 `route_prj`로 갈라 센다(2026-08-31).
|
||||
"""
|
||||
async with connection.cursor(aiomysql.DictCursor) as cursor:
|
||||
await cursor.execute(
|
||||
"""
|
||||
SELECT id, LOWER(file_type) AS file_type
|
||||
SELECT id, LOWER(file_type) AS file_type, raw_file_path
|
||||
FROM input_files
|
||||
WHERE project_id = %s AND status IN ('UPLOADED', 'PROCESSED')
|
||||
ORDER BY id DESC
|
||||
@@ -82,7 +86,14 @@ async def get_project_input_readiness(
|
||||
)
|
||||
rows = await cursor.fetchall()
|
||||
|
||||
file_types = {str(row["file_type"]) for row in rows if row.get("file_type")}
|
||||
file_types: set[str] = set()
|
||||
for row in rows:
|
||||
file_type = str(row.get("file_type") or "")
|
||||
if not file_type:
|
||||
continue
|
||||
if file_type == "prj" and "/input/shp/" in str(row.get("raw_file_path") or ""):
|
||||
file_type = "route_prj"
|
||||
file_types.add(file_type)
|
||||
point_cloud_id = next(
|
||||
(int(row["id"]) for row in rows if str(row.get("file_type") or "") in {"las", "laz"}),
|
||||
None,
|
||||
@@ -316,7 +327,7 @@ async def list_project_input_files(
|
||||
await cursor.execute(
|
||||
"""
|
||||
SELECT f.id, f.file_type, f.original_filename, f.file_size_mb, f.status,
|
||||
f.upload_at
|
||||
f.upload_at, f.raw_file_path
|
||||
FROM input_files f
|
||||
INNER JOIN (
|
||||
SELECT MAX(id) AS id
|
||||
|
||||
Reference in New Issue
Block a user