Commit Graph
171 Commits
Author SHA1 Message Date
eomsangdonandClaude Opus 5 99248440c6 feat(B08): 기초잡석 물량·용수 축 (확정 3차 ②④) — 옹벽 묶음 다섯 조각이 다 참
기초잡석(②)
- 두께 0.2m(사용자 확정). 폭은 버림 폭과 같아(KCS 34 50 05) **버림 × 두께 비**로 나옴
  ⇒ 관측 원단위로 오는 옹벽에도 값이 섬(버림 0.15㎥/m ⇒ 잡석 0.30㎥/m)
- destination `unit_price` — 운반·부설·다짐 품이 붙는 공종이라 자재총괄에 안 섞임
- 인계에 FP-12-25 줄로 섬. 묶음 구조물(옹벽)은 조각이 이미 세므로 건너뜀
- 두께는 설정 `rubble_base_thickness_m` 로 화면에서 바꿀 수 있음

용수 축(④)
- 품셈 9-13 의 18구분을 토질 × 육상/용수 × 심도로 골라 자식 코드로 내려감
- ⚠ 기본 「육상」은 **통상값이고 사용자 확정이 아님** — 그 사실을 줄 사유에 적음
- 3m 초과 칸은 원문에 없어 상위 코드 + 사유

- 설정 신설: rubble_base_thickness_m(0.2) · structure_trench_water(육상)
- tmp/tests 신설 test_b08_rubble_base.py(7건) + 터파기 시험 6건 추가

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 06:21:05 +09:00
eomsangdon 8eed1f7b4a Merge remote-tracking branch 'origin/main_laptop_1' into main_desktop_1 2026-09-08 23:17:25 +09:00
eomsangdonandClaude Opus 5 df6d33c462 feat(B06): 구조물 잔토에 터파기 토질을 이어받아 사토 갈래(ea/rr/br)를 채움
B08 이 구조물터파기에서 이미 판정한 토질(`design.ground_type`, 품셈 9-13 3구분)을
잔토 측점값에 함께 실어 준다. **새 근거를 만드는 것이 아니라 이어받는 것**이라
두 자리가 같은 판정을 쓴다(두 벌로 짜면 갈린다).

- `structure_spoil_points[].ground_type` (soil→ea · ripping_rock→rr · blasting_rock→br).
  옛 이름(`ground`)·라벨(`ground_label`)도 함께 받는다.
- ⚠ **섞여서 못 고른 구조물은 `null`** 로 오고 그 몫은 갈래 없이 담겨
  `ground_unknown_m3` 로 드러난다 — 임의로 토사로 몰지 않는다.
- ⚠ 한계는 그대로 넘어온다: 「터파기 깊이가 암반 경계선보다 깊은지」는 안 본다
  (터파기 토질에 이미 있던 한계이고 새로 생기는 것이 아니다).

시험 8건(갈래별로 담김·못 고른 몫은 「모름」으로 남음 포함).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 23:15:08 +09:00
eomsangdonandClaude Opus 5 221eb23e46 feat(B06): 사토 잔량에 「지반 모르는 몫」을 값으로 냄
B08 이 사토 운반을 덤프 단가로 가르려면 토사/암 갈래가 필요하다. 잔량에는 이미
`ea/rr/br` 이 실려 있으나(절토에서 남은 흙이라 구성비를 안다), **구조물 잔토로 생긴
몫만은 근거가 없다**(어느 지반에서 파낸 흙인지 판정하지 않는다).

- `ground_unknown_m3 = volume − (ea+rr+br)` 을 잔량마다 함께 낸다.
- ⚠ 안 내면 받는 쪽이 **0 으로 눅여 토사로 세기 쉽다** — 그래서 값으로 드러낸다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 23:10:40 +09:00
eomsangdon c70f79cbc3 Merge remote-tracking branch 'origin/main_laptop_1' into main_desktop_1 2026-09-08 23:05:26 +09:00
eomsangdonandClaude Opus 5 759343e384 fix(B08): 사토 운반 줄 신설 — 유토곡선이 낸 사토를 아무도 실어 내지 않았음
- 운반 줄이 띠(bands)·이동(transfers)에서만 만들어져 사토는 잔량(residuals)으로 남아
  어디에도 안 실렸음. 그래서 구조물 잔토 126.63㎥ 를 얹어도 덤프가 안 늘었고,
  채집석 공제도 사토를 줄이는 값이라 끝까지 금액에 안 나타났음
- 실무에는 서는 줄(울진 대흥 1공구 토적집계 D32 사토 1,281㎥)
- 운반표에 `spoil`(물량·거리·근거)을 실어 인계가 「사토 운반」 한 줄을 세움
- 물량은 유토곡선 결과 그대로 — 공제·가산이 끝난 값이라 여기서 또 만지지 않음.
  자연방토는 실어 내지 않으므로 뺌
- 거리는 설계 입력 `spoil_site_distance_m` 신설 — 안 정했으면 막고 사유
  (품셈이 정하는 값이 아니라 임의 거리가 그대로 금액이 됨)
- 지반 갈래는 유토곡선이 안분하지 않아 갈래 없이 한 줄, 그 사실을 근거에
- tmp/tests/test_b08_spoil_haul.py 신설(6건)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 23:05:15 +09:00
eomsangdonandClaude Opus 5 12c8d14ee1 fix(B06): 「잔토를 더하고 → 공제를 뺀다」 순서로 못 박음
두 창 저장분에서 **공제가 한 톨도 안 빠졌다**(`deducted 0`). 두 노선 다 원래 사토가 0
(전 구간 토취)이라, 공제가 잔토 가산보다 **먼저** 돌아 뺄 대상이 없었다.

- 유토곡선의 사토는 「현장에 남는 흙 총량」이고 출처를 안 가린다 — 공제는 그 총량에서
  빼는 것이라 **잔토가 담긴 뒤라야** 뺄 대상이 있다.
- ⚠ 모자라면 `collected_stone_deducted_m3` 가 작게 나와 「덜 뺐다」가 값으로 드러난다 —
  그 장치는 그대로 살려 뒀다.
- ⚠ 토취는 계속 안 건드린다. 「채집석을 캐 가면 성토에 쓸 흙이 줄어 토취가 는다」는
  갈래가 있으나 근거가 없다 — 그 여지를 주석에 적어 뒀다.

시험 7건(순서 시험 추가: 잔토 100 더한 뒤 공제 40 이 실제로 빠짐).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 23:03:50 +09:00
eomsangdonandClaude Opus 5 7e41c94be7 feat(B06): 담을 사토가 없으면 사토를 새로 세워 구조물 잔토를 담음 (확정 ㉰)
사토가 0 인 노선(전 구간 토취)에서는 잔토를 더할 자리가 없어 **물량이 그냥 사라졌다**.
파낸 흙은 어디로든 가므로 그것이 가장 나쁘다.

- 담을 사토 잔량이 없으면 **그 측점에 사토를 새로 세워** 담는다. 물량이 보존되고
  운반비가 붙는다(금액이 느는 방향 — 안전측).
- ⚠ 토취를 줄이는 길(㉯)은 「그 잔토를 성토재로 쓸 수 있다」는 근거가 있어야 한다.
  구조물 터파기 흙은 암이 섞일 수 있고 우리가 그 판정을 안 하므로, **근거 없이 금액을
  내리지 않는다.** 확정되면 이 함수 한 곳만 바꾸면 된다 — 그 문장을 주석에 남겼다.
- 새로 세운 사토는 자연방토 0 · 지반유형 안분 0 — 실어 내는 흙이고 지반을 모른다.
- 측점별 잔토를 Node 진입점까지 이어 붙임(빠져 있어 총량 갈래로 떨어지고 있었다).

실측(route 184): 사토 0 → **12.88㎥**, 잔량이 **측점 5m 자리에 섬**(전에는 노선 전체 구간).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 22:50:43 +09:00
eomsangdonandClaude Opus 5 abf586108c fix(B06): 구조물 몫(공제·잔토)이 실제로 흐르게 — 부르는 자리 둘이 인자를 안 넘기고 있었음
통로는 났는데 `_mass_haul_context()` 를 **인자 없이** 불러 값이 늘 `None` 이었다
(`Router_HaulPlan.py:64` · `Server_Calc_Prebuild.py:170`). 오늘 세 번째로 나온
「받는 곳은 있는데 넣는 곳이 없던」 자리다.

- `haul_inputs_for()` 로 B08 의 `project_haul_inputs` 를 받아 두 자리 모두에 넘긴다.
  ⚠ 여기서 다시 세지 않는다 — 두 값 다 B08 전개에서 나온다(CLAUDE.md 5장).
- 측점별 잔토(`structure_spoil_points`)를 받으면 **그 자리 잔량에 얹는다** —
  총량 비례로 흩으면 운반거리가 틀린다. 총량만 오면 종전대로 비례 분배(차선).
- 저장 payload 에 받은 값·실제로 먹은 값 넷을 남긴다 — 「값이 흐르는지」를 저장분에서
  바로 가릴 수 있어야 한다.

실측(route 184): 공제 0(구입이라 채집 없음) · 구조물 잔토 12.875㎥ 가 **실제로 전달됨**.
⚠ 그 노선은 사토가 0(전 구간 토취)이라 더할 잔량이 없어 `added=0` — 아래 물음 참조.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 22:44:50 +09:00
eomsangdon 3dda55e588 Merge remote-tracking branch 'origin/main_laptop_1' into main_desktop_1 2026-09-08 22:34:36 +09:00
eomsangdonandClaude Opus 5 3ac616fb5b feat(B06): 구조물 잔토를 사토에 더하는 통로 신설 — 공제와 짝이 되는 자리
데스크탑 메인이 구조물 터파기·되메우기·잔토를 인계에 실었는데, **잔토 126.625㎥ 가
어디에도 안 실렸다**. 사토로 실어 내는 몫이라 유토곡선이 세야 겹치지 않는다.

    구조물 잔토는 사토에 한 번만 더한다.
    B08 은 소요량(structure_spoil_m3, ㎥ 양수)을 내기만 하고,
    더하는 자리는 유토곡선의 사토뿐이다.

- ⚠ **잔량 하나하나를 늘린다** — 총량만 늘리면 사토는 늘고 운반이 안 는다(공제 때와 같은 자리).
- ⚠ 나누는 법: 지금은 총량 하나만 오므로 **남은 사토 잔량 크기에 비례**해 나눈다.
  한 곳에 몰면 운반거리가 틀린다. 측점별 값이 오면 이 함수만 고치면 된다.
- ⚠ 자연방토·지반유형 안분은 안 건드린다 — 실어 내는 흙이고, 어느 지반에서 나온지 모른다.
- `null`(아직 안 옴) ≠ `0`(없음), 받은 값과 **실제로 더한 값**을 따로 싣는다.

시험 5건(더해짐·잔량 동반 증가·자연방토 불변·토취 불변·공제와 함께 와도 한 번씩).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 22:33:21 +09:00
eomsangdonandClaude Opus 5 9c811c4d20 fix(B06): 구조물을 놓아도 횡단도에 안 보이던 것 — 빈 초안이 저장분을 지우고 있었음
「구조물을 놓아도 횡단도에 아무것도 안 보인다」가 창 둘에서 같은 증상이었다.
화면에 표식을 심어 재 보니 **브라우저 쪽 단면에 `revetment` 자체가 없었다**.

- 원인: `withDraftWalls` 가 미저장 초안 목록이 **빈 배열**일 때도 「초안 있음」으로 읽고
  **서버 저장분(`revetment`)을 통째로 지운 뒤** 아무것도 안 얹었다.
  ⇒ `!drafts || !drafts.length` 로 고쳤다 — 빈 목록도 「초안 없음」이다.
- 초안 경로가 `foundation` 을 안 실어 터파기가 안 그려지던 것도 함께 고침
  (`WallSpec.foundation` 추가, 거울 시험도 같이 갱신).
- 겹침 방지 가드를 **좁혔다** — 링크가 있기만 하면 막던 것을, 그 링크의 벽이
  **이 카드에 실제로 설 때만** 막게 했다(`culvertWallsStandAt`). 관이 아홉·열하나인
  노선에서는 링크가 거의 모든 측점을 덮어 독립 벽 경로가 통째로 죽어 있었다.

화면 확인: 벽 터파기 「기초유 · 폭 1.62m · 깊이 0.50m (수직)」, 관 터파기 Φ1000 1.80m ·
Φ800 1.60m, 그려진 선 전부 좌우 변이 수직.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 22:16:24 +09:00
eomsangdon 86b0438c7a Merge remote-tracking branch 'origin/main_laptop_1' into main_desktop_1 2026-09-08 21:50:42 +09:00
eomsangdonandClaude Opus 5 ae52ba7699 feat(B05·B06): 터파기 축을 관에도 · 독립 벽까지 잇고, 계수·강도 칸 신설
- `pipe.revet_foundation`(기슭막이 기초) 신설 — **유입·유출 한 칸**. 한 공사에서 한쪽만
  기초유로 하는 일이 드물어 폼을 둘로 안 늘렸다. 실무가 갈라 쓰면 그때 나눌 것.
- 독립 기슭막이·돌쌓기 갈래도 이음: 구조물 정본 `foundation` → `RevetmentSpec` →
  `RevetmentLayout.foundation` → 터파기 그림. ⚠ 이름을 저장 칸과 **같은 글자**로 뒀다.
- ⑨ `stone_coeff_basis`(품셈/실무 관행) · ⑩ `fill_concrete_mpa`(180/210) 칸 신설.
  ⚠ **기본값 없음** — 「비어 있음 = 아직 안 정함」이고 기본값(⑨ 품셈 · ⑩ 210)은 계산 쪽이 갖는다.
- 저장 왕복 확인: PUT 200 → 되읽기에서 "실무 관행"·"180"·"기초유" 그대로.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 21:48:54 +09:00
eomsangdonandClaude Opus 5 bec7e841e0 feat(B06): 횡단도에 터파기 선 — 관은 법정 표값 폭, 벽은 실무 정본 수직
사용자 확정 ④ 「터파기가 횡단도에서 표현이 안 된다 → 교본·실무문서로 구현 →
노티스 → 사용자가 선택」.

- 관: 관 위에서 관 바닥까지 **표값 폭**으로 수직(KCS 44 40 10 그림 3.2-1).
  표에 없는 관경이면 **안 그린다** — 폭을 지어내지 않는다.
- 벽: 벽 바닥선 아래로 **수직**(정본 식에 기울기 항 없음). 폭 = 바닥폭 + 여유 0.2,
  깊이 = 기초유 0.5 / 기초버림 0.1.
- ⚠ `foundation` 이 비어 있으면 **안 그린다** — 고르기 전에는 근거가 없다.
- 말풍선에 **근거의 급을 갈라** 적는다: 관은 「법정 표」, 벽은 「품셈에 규정이 없어
  실무 관행으로 정한 값」.
- 파선(`.b06-chart__excavation`)으로 구조물보다 먼저 그려 벽 밑에 깔린다.

화면 확인: 관 터파기 5개소, Φ1000 → 1.80m · Φ800 → 1.60m (표값 그대로).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 21:35:24 +09:00
eomsangdon 09a5eee338 Merge remote-tracking branch 'origin/main_laptop_1' into main_desktop_1 2026-09-08 21:31:38 +09:00
eomsangdonandClaude Opus 5 d175c6e457 feat(공용): 터파기 단면 — 관은 법정 표, 벽은 실무 정본 식 + 「기초유/기초버림」 칸
사용자 확정 ④ 「터파기를 횡단도에서 표현 → 노티스 → 사용자가 선택」의 밑감.
근거의 급이 달라 갈라 둔다.

- 관: `KCS 44 40 10 배수관 §3.2(4) 그림 3.2-1` 표 그대로(Ø800→1.6 · 1000→1.8 ·
  1200→2.1 · 1500→2.5 m). ⚠ 관경+2b 로 계산하지 않는다 — 표가 관 두께·여유를 담고 있다.
  표에 없는 관경은 `None` — 지어내지 않는다.
- 벽: 법정 근거 없음(교본은 「설계도서 지시」까지). 실무 정본 xls 7탭 식 —
  기초 0.5×0.9(기초버림이면 0.1×0.7) + H×(평균두께+0.2). ⚠ **비탈 없음(수직)**.
- 레지스트리에 「기초」 칸(기초유/기초버림) 신설 — 정본 탭 제목 그대로. 그림·물량이 같은 축.
- 파이썬·TS 짝 + 거울 시험. 실무 수치(H=1·2·3 → 1.48·2.51·3.54)와 맞는지도 잠금.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 21:29:39 +09:00
eomsangdonandClaude Opus 5 b6bc9b9a54 feat(B08): 층따기 길이 칸 — 면적 × 길이로 ㎥ 를 냄 (확정 2차 ①)
 사용자 확정 2차 ① — 「㎡ 유지. 부피는 **사용자가 지정한 길이값을 곱해** 쓴다」.
그러면 품셈 ㎥ 단가를 그대로 쓸 수 있어 **단위 불일치가 풀림**(2,124만원 자리).

- 설정 `quantity.bench_cut_depth_m` 신설. [저장]으로도 넣을 수 있게 요청 모양에 칸을 두고,
  「안 정함」으로 되돌릴 수 있게 nullable 목록에도 넣음.
- 인계 줄: 길이가 있으면 **면적 × 길이 = ㎥** 로 내고, 규격 칸에 「면적 13,696.75㎡ ×
  길이 0.5m」로 **어디서 온 값인지** 남김.
- ⚠ **면적을 없애지 않음** — 횡단도 하단 표가 면적을 씀. ㎥ 를 덧붙이는 것.
- ⚠ **길이 기본값을 임의로 박지 않음** — 없으면 종전처럼 막고 사유를 냄
  (교본 「층따기 높이·폭은 **설계도서에 명시**」라 설계 입력임).
- 매핑 밑수를 ㎥ 로 되돌리고 그 까닭을 적음(공식이 체적 기준).

실측 — 길이 0.5m 를 넣으면 13,696.75㎡ → **6,848.375㎥** 로 서고 in_bill True.
안 넣으면 0 · input_missing · 「길이를 넣으면 면적 × 길이로 물량이 섭니다」.

시험 748 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 21:23:12 +09:00
eomsangdonandClaude Opus 5 e29f55782e feat(공용): 구조물 자리의 성토/절토 판정 한 벌 + 전면 기울기 범위 안내
품셈 표준경사 표가 높이 × 메/찰 × **성토/절토** 로 갈리는데 성절토만 없었다.
새 입력을 만들지 않고 이미 저장되는 두 값으로 가린다 —
`design.section_mode` + 구조물 `options.side`.

- `common_util_structure_face_role.structure_face_role()` — ("성토"|"절토"|None, 까닭 문구).
  ⚠ 못 가르면 **None**. 성토로 눅이지 않는다 — 받는 쪽이 근거 없음을 알아야 한다.
  예외 하나: `both_cut` + 「자동(성토 쪽)」은 세울 성토면이 없어 근거 없음.
  판정을 두 벌로 짜면 그 예외에서 갈리므로 여기 하나만 둔다(CLAUDE.md 5장).
  파이썬 단독 — 읽는 쪽이 B08 뿐이다. 화면이 쓰게 되면 그때 TS 짝·거울 시험을 붙일 것.
- 전면 기울기 칸: 표 범위(0.20~0.50) 밖이면 **막지 않고 알리기만** 한다.
  실무 도면이 S0.7·S0.8 을 쓴다 — 막으면 실물이 안 들어간다.

시험 14건(네 단면유형 × 좌/우 여덟 · 자동 셋 · 모르는 값 · 옛 영문 표기 · 문구).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 20:21:12 +09:00
eomsangdon c8b76bf529 Merge remote-tracking branch 'origin/main_desktop_1' into main_laptop_1 2026-09-08 19:23:54 +09:00
eomsangdonandClaude Opus 5 6a7c339f8a feat(B06): 측구터파기 단면적을 토사/암으로 가름 — 새 입력 없이 암반 경계선으로
별표2 Ⅰ.1.나.(5) 「측구터파기 단면적」이 횡단도 표의 법정 칸인데 한 값뿐이라
「측구 토사 / 측구 암석」 두 칸이 반만 채워졌다.

- 가르는 근거는 **절토 분리와 같은 것**(지반 유형 + 암반 경계선). 새 입력을 만들지 않았다.
- 측구 상단에서 암반 경계선까지의 깊이로 공칭 도형(사다리꼴·L형)을 가로로 가른다.
- ⚠ 근거가 없으면 **나누지 않는다.** 사유를 `ditch_split_basis` 로 함께 냄:
  rock_boundary / soil_ground / rock_ground_no_boundary / no_ditch.
- 기존 `ditch_area_m2` 는 **합계로 그대로** 두고 갈래를 덧붙였다 — B08 이 순서대로 옮겨 갈 수 있게.
- 파이썬·TS 짝을 함께 고침. 거울 테스트 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 19:22:58 +09:00
eomsangdon 5cf722021f Merge remote-tracking branch 'origin/main_laptop_1' into main_desktop_1 2026-09-08 19:19:11 +09:00
eomsangdonandClaude Opus 5 f60fb9c355 feat(B06): 채집석 공제를 사토에서 빼는 통로 신설
네 창 합의 문구 그대로 못 박음:

    채집석 공제는 사토에서 한 번만 뺀다.
    B08 은 소요량(collected_stone_deduction_m3, ㎥ 양수)을 내기만 하고 공제하지 않으며,
    빼는 자리는 유토곡선의 사토뿐이다 —
    실어 내는 몫(spoil_m3 − natural_spoil_m3)에서 먼저 빼고 모자라면 자연방토에서 뺀다.

- `computeHaulPlan` 이 공제를 받아 **잔량 하나하나**를 줄인다 — 총량만 줄이면 사토
  balloon·운반거리가 안 따라간다. 지반유형 안분도 같은 비율로 줄인다.
- ⚠ `null`(아직 안 옴)과 `0`(공제 없음)을 가른다. 결과에 받은 값과 실제로 뺀 값을 함께 싣는다.
- 서버 진입점·파이썬 context 를 통로로 이어 둠. B08 이 값을 내면 실어 주기만 하면 됨.

시험 3건(공제 반영·잔량 동반 감소·사토 초과 시 사토까지만·자연방토는 나중) 을
TS 를 실제로 돌려 확인.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 19:15:27 +09:00
eomsangdonandClaude Opus 5 42cd2b8fdd feat(B08): 부대시설 다섯 줄을 산출에 추가 (사용자 확정 ⑬)
법이 요구하는데 우리가 안 내던 줄들임 — 국가지점번호판·안내판·차단기·가설창고·수방자재.

⚠ 개소를 **지어내지 않음.** 임도규정 제26조제5항이 「500미터 마다 설치·관리하되
**필요시 거리를 조정**할 수 있으며」라 하고 기점 포함·종점 잔여·갈림길 중복을 원문이
정하지 않음 ⇒ `연장÷500` 을 산식으로 쓰지 않고 설정 `ancillary_counts` 로 **개소를 받음**.

⚠ 사유를 **갈라 적음** — 「품셈에 그 이름의 공종이 없음」과 「개소 미입력」은 다음에 할 일이
다름. 법정 의무인 둘(번호판 제26조5항 · 안내판 제26조6항)은 그 사실을 사유에 적어
화면에서 왜 채워야 하는지 보이게 함. 차단기는 교본에만 있어 「법정」이라 적지 않음.

⚠ 다섯 중 **품셈에 공종이 있는 것은 가설창고(FP-11-01) 하나뿐**(마스터 전수 확인).
나머지 넷은 금액이 못 서지만 **줄은 세움** — 빼면 빠진 줄을 아무도 못 봄.
개소를 안 넣어도 줄이 서고 사유가 함께 감(준비공 표 · 인계 양쪽).

시험 749 통과(새 6건 포함).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 19:07:41 +09:00
eomsangdonandClaude Opus 5 86437ce753 feat(B06): 층따기 밑수를 횡단 설계에서 냄 — 성토부 아래 원지반 지표면 길이
사용자 확정(2026-09-09): 층따기 단위는 ㎡. 대신 그 면적이 B06 설계에서 나와야 한다.

- `_bench_cut_length`: 성토(diff<0) 구간에서 원지반 횡단기울기가 **1:4 보다 급한**
  조각만 골라 지표면을 따라간 길이(빗변)를 더한다. 절·성토 경계는 영교점까지만 센다.
  근거는 별표2·교본 6장 4절, 지식DB 성토_비탈면 §4 [구현].
- 결과에 `bench_cut_length_m` 을 실어 B08 이 측점 사이를 평균단면적법으로 이어 ㎡ 를 낸다.
  ⚠ 여기서 ㎥ 로 바꾸지 않는다 — 단의 높이·폭은 설계도서 값이라 지어낼 수 없다.
- 파이썬·TS 짝을 함께 고침(`common_util_cross_design_areas.ts`). 거울 테스트 통과.
- ⚠ 성토 비탈면 길이가 아니라 **원지반 표면**을 센다 — 층따기 대상 면이 그쪽이다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 19:06:53 +09:00
eomsangdonandClaude Opus 5 d14cd46f51 feat(수량): 구조물 연장에 **겹침을 지운 구간 목록**을 함께 냄
B08 창 요청(2026-09-08) — 연장(m)만 내면 산출근거에 **「어디부터 어디까지」**를 못 적음.
실무 내역은 「산마루측구 40m」 한 줄이라 없어도 서지만, 있으면 검산이 쉬워짐.

`_merge` 가 길이 대신 **합친 구간 목록**을 돌려주게 하고, 행에 `spans`
(`[{start_m, end_m}, …]`)를 실음. **길이는 그 목록의 합**이라 둘이 갈릴 수 없음.

⚠ 겹침은 **합쳐서** 냄 — 데스크탑 실측: 산마루측구 둘(80~120 · 100~140)이 **60.0m**
로 합쳐져 내역서에 감(단순 합 80.0m). 구조물별로 셌으면 **20m 를 더 셀** 자리였음.
그 규칙이 이 함수 한 벌에만 있어야 하는 까닭이기도 함(측구 제외·관 소관 제외도 같음).

시험 5건 — 안 겹치면 그대로 · 겹치면 합침(그 실측 그대로) · 맞닿은 두 구간은 하나 ·
품은 구간은 사라짐 · **행의 길이가 구간 합과 같은지**. 전체 513 passed · 17 skipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 10:26:03 +09:00
eomsangdonandClaude Opus 5 8555e693ac fix(B06): 관 길이를 **소유 측점에만** 싣게 — 같은 관을 두 번 셀 뻔한 자리
`pipe_length_m` 을 넣고 실화면 [저장]으로 확인하다 드러남 — **관 9개인데 값이 10곳**에 실렸음.
까닭은 `attach_culvert_sets` 가 세트를 **폭의 절반까지 옆 측점에도** 붙이기 때문임(3D·카드가
이어 그리려고). 그 자리에 길이를 실으면 수량이 **같은 관을 두 번** 셈.

- 스펙에 **놓인 누가거리(`chainage_m`)** 를 함께 얹음 — 파이썬 `attach_culvert_sets` ·
  TS `attachCulvertSets` **둘 다**(한쪽만 얹으면 세트 거울 시험이 깨짐. 실제로 깨져서 알았음).
- 길이는 그 값과 측점이 같을 때만 실음.
- 옛 값 정리 — 이미 실려 있던 이웃 측점 4곳(260.0·800.0·900.0·980.0)에서 지웠음.
  **파생값이라 병합만으로는 안 지워짐**(merge 는 키를 얹기만 함).

⚠ **따로 드러난 것 — 관 3개(439.55·620.43·720.37)는 측점 행 자체가 없음.** 그 관들은 횡단
설계도 수량도 통째로 빠져 있음. 별건으로 조사할 것(계획서에 적음).

실측 결과 — 관 길이가 실린 측점 **6곳**(85.05→10.0 · 258.12→11.0 · 534.49→9.0 · 804.30→9.0 ·
901.24→10.0 · 984.18→10.0m). 나머지 셋이 위 별건임.

시험 7건(소유 측점 판정 한 건 추가) · 전체 507 passed · 17 skipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 09:36:23 +09:00
eomsangdonandClaude Opus 5 618b6cf4c5 feat(dev): 확정 없이 다음으로 — 개발 전용 잠금 해제 (신규 파일만, 1/2)
공용 파일 두 걸음 규칙 — 이 커밋은 신규 파일뿐이고 main.py 등록은 다음 커밋.
먼저 push 해야 다른 창이 등록 줄만 받고 파일이 없어 죽는 일이 없음.

까닭 — 단계마다 [확정]을 해야 다음 페이지가 열려서, 상세 설계를 확정하기
전에는 B08·B09 를 볼 수 없음. 오늘 화면 검증이 그 자리에서 두 번 막혔음.

⚠ 계산을 대신 돌리지 않음 — 잠금만 품
- 바꾸는 것은 project_workflow_stages.state 한 칸뿐
- 확정은 전 측점을 다시 계산해 정본에 쓰는 것이라, 흉내 내면
  「확정 안 했는데 확정된 값」이 생겨 막힌 것보다 나쁨
- 값이 없으면 B08 이 「미확보」로 뜨는 것이 정상

⚠ 문은 서버가 정본 — ENVIRONMENT 가 개발이 아니면 세 입구 모두 403
  (화면에서 단추를 숨겨도 API 가 열려 있으면 소용없음)

되돌리기 — 푼 단계의 이전 상태를 message 에 DEV_UNLOCK:<옛상태> 로 적어 두고
DELETE 가 그대로 복원. 그 표시가 없는 단계(진짜 확정)는 안 건드림.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 06:39:05 +09:00
eomsangdonandClaude Opus 5 ae431bb17d feat(B08): 규준틀 개소 · 목재틀 갈래 · 표토 두께 칸
㉓. ㉒ 에서 원문을 찾아 닫힌 셋을 구현.

- **비탈 규준틀 개소** — 품셈 11-2 [주]① 「비탈길이 10m 이상 20m마다 설치」.
  사면표의 측점별 사면길이·거리로 셈. ⚠ 「10m 이상」은 비탈길이 조건이고
  「20m마다」는 노선 거리 간격이라 둘을 안 섞음. 재료량은 [주]④ 「설계수량」이라
  개소만 내고 재료는 미확보로 둠.
- **수평 규준틀**은 11-3 [주]① 이 「중심점 성토고 5m 이상」인데 성토고가 사면표에
  없어 0 으로 때우지 않고 미확보로 둠.
- **목재틀흙막이 갈래** — 품셈 13-13-1 [주]③ 이 재료 구성으로 가름.
  임도 흙막이는 「보통구조 상(통나무 기슭막이)」로 잠정 판정. ⚠ 잠정임을 근거
  문구에 드러내고 「상등구조를 쓰면 8.760 → 16.975 인/㎥ 로 약 1.9배」를 함께 적음.
  갈래표는 데이터 파일(`resources/data_timber/`)이라 줄만 더하면 늘어남.
  ⚠ 밑수 1㎥ 는 구조물 체적이 아니라 **목재 채적**임을 데이터에 명시 — 그래야
  「1㎥에 건축목공 17인」이 말이 되는지 판단됨.
- **표토제거 두께** — 9-15 [주]② 가 「T : 표토두께(m)」로 공식의 입력 변수로 둠.
  품셈이 정하는 값이 아니므로 설계 입력 칸(`quantity.topsoil_thickness_m`)으로 냄.
  ⚠ 기본값 없음 · 미입력이면 물량 안 냄(0 으로 때우지 않음). 대상 면적은 참고로 보임.

검증 — 준비공 16건 통과, 전체 642 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 04:42:04 +09:00
eomsangdonandClaude Opus 5 24fc6ec090 feat(B08): 화면에 안 보이던 확정 대기 셋을 드러냄
목록에만 있고 화면에 없으면 사용자는 그것이 잠정인 줄도 모름. 셋 다
「지금 어떤 값으로 돌고 있는지 + 왜 잠정인지」를 함께 보임.

- 콘크리트 타설 방식을 좌측 패널 칸으로 냄. ⚠ 금액에 바로 걸리는 값이라
  기본값으로 돌고 있으면 「기본값 「레디믹스트」로 계산 중 — 아직 안 정한 값」
  안내를 띄움. 설정 기본을 None 으로 바꿔 「안 정함」과 「일부러 레디믹스트를
  고른 것」을 가름 — 값을 미리 넣으면 그 구별이 사라짐. 되돌리기도 됨.
- 물구멍 근거에 잠정값을 적음 — 「관 Ø 미정(법 3~6㎝ / 실무 Ø50) ·
  간격 2.0㎡당 1개소(법 2~3㎡당 1개소 이상)」. 「미확정」만으로는 무엇을
  정해야 하는지 모름.
- 준비공의 벌목 줄에 공종 미확정 사유와 후보를 함께 적음(수확베기·단목베기·
  위험목 베기 중 어느 것인지 원본이 말하지 않음).

검증 — 전체 580 passed, tsc 오류 0. 화면에서 셋 다 뜨는 것과 타설 방식
저장·되돌리기까지 확인 후 검증으로 바꾼 값은 원래대로 복원.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 01:14:34 +09:00
eomsangdonandClaude Opus 5 c12b1027f7 feat(B08): 콘크리트 타설 갈래 — 철근 유무 자동 판정
조율 창 판정 반영. 타설 공종은 타설 방식 × 구조물 종류로 갈림.

- **구조물 종류는 자동 판정** — 원단위 성분에 철근이 있으면 철근구조물.
  사람이 고르는 값이 아님. 옹벽 관측 원단위의 D13·D16 에서 그대로 나옴.
- **타설 방식은 설계 판단**이라 프로젝트 설정(`quantity.concrete_placing_method`)이
  고르고 기본은 레디믹스트(FP-12-01-01). 잠정이며 사용자 확정 대기.
  모르는 방식이면 기본으로 떨어지되 그 사실을 알림.
- 옹벽 묶음의 타설 코드를 `FP-12-01-01#철근구조물` 로 좁힘.
- ⚠ 묶음 넷 중 `FP-12-03`·`FP-12-25` 는 B09 일위대가가 아직 안 섬.
  `composite_not_ready` 로 함께 알림 — 지금 세우면 절반짜리가 됨.

검증 — 인계 48건 통과, 전체 578 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 01:03:55 +09:00
eomsangdonandClaude Opus 5 c7d917864c feat(B08): 암 시공법 칸 · 관급구분 표 입력 · 산출 크기 요약
- 암 시공법(ripping/blasting)을 갈래 비율 칸 아래에 붙임. 갈래 이름만으로는
  품셈 공종(암절취 FP-09-04 / 발파암 FP-09-05)을 못 고르던 자리. 기본은
  「안 정함」이고, 안 정하면 인계에서 사유와 함께 드러남. 비율 미입력 상태의
  「암」 한 줄에도 칸을 냄.
- 관급/사급은 표 안에서 줄마다 고름. 관급 줄에만 설치주체가 열리고 사급으로
  되돌리면 잠기며 비워짐. 만진 줄은 표시가 남음.
- 산출 요약(최소·중앙·최대)을 원단위·자재총괄·인계에 붙임. 단위별로 갈라 냄 —
  값이 있기만 하면 시험이 못 잡는 자릿수 어긋남을 사람이 훑게 하는 장치.

화면에서 걸려 고친 것 둘
- 관급을 골라도 설치주체 칸이 잠긴 채 남던 것. 고른 즉시 열고 닫게 함.
- 한 번 고른 시공법을 되돌릴 길이 없던 것. 설정 저장이 병합이라 빈 값을 보내도
  옛 값이 남았음. `save_section(replace_keys=…)` 로 되돌릴 수 있어야 하는 칸만
  통째로 갈아 끼움. 나머지는 그대로 병합.

앞 커밋에서 온 타입 오류 2건도 고침 (`slopeColumnCount` 미사용,
`variant: "outlined"` 는 없는 값). 앞선 확인에서 npx 가 엉뚱한 패키지를 실행해
「오류 없음」으로 잘못 봤음 — tsc 는 config/node_modules 것으로 부를 것.

검증 — 새 시험 5건 + 인계 28건 통과, 전체 509 passed. tsc 오류 0.
화면 실조작으로 시공법 저장·되돌리기, 관급/설치주체 저장·되돌리기 확인 후
검증으로 바꾼 값은 원래대로 복원.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 00:18:00 +09:00
eomsangdonandClaude Opus 5 6a487fc6e3 feat(B08): 자재총괄 — 할증이 붙는 유일한 자리
구조물 원단위의 `destination == "material"` 성분만 모아 자재별 합산 후
할증률을 한 번만 적용. 열은 순수량·할증률·합계 + 관급구분·설치주체·비고이며
금액은 없음(B09 경계).

- 할증률은 코드가 아니라 데이터 — `resources/data_material_surcharge/`
  (품셈 1-3-1 재료 할증률 19종 + sha256 매니페스트). 실무 관측값은
  `observed_practice` 로 분리(법대로 원칙).
- 표에 없는 자재는 0 % 로 넘기지 않고 「할증률 미확보」로 표시.
  이름 조회는 정확 일치 — 부분일치면 `막자갈` 이 `자갈` 할증을 뭄.
- 이중계상 방어 ㉠ — 앞 단계 `surcharge_applied` 깃발을 실제로 읽어 경고.
  자재총괄 응답은 `True`, 원단위표는 `False` 로 어느 쪽 값인지 명시.
- 관급/사급 이름은 B09 와 동일(`owner_supplied`/`contractor_supplied`).
  관급 줄에만 설치 주체(`install_by`)를 붙이고, 미지정은 기본값으로
  때우지 않고 드러냄 — 안전관리비 대상액이 「도급자설치 관급금액」이라서임.
- 라우터 `GET /quantity/material-summary` 신설, 화면에 「구조물 원단위」·
  「자재총괄」 탭 추가. `design_owner` 가 붙은 타입(측구)은 중복 계상 방지로 제외.

검증 — 전용 테스트 23건 통과, 전체 회귀 473 passed(기존 B05 깨짐 1건 제외).
공용 브라우저 실조작으로 탭 5장·머리글·값 4줄·미확보 안내 확인.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 23:43:46 +09:00
eomsangdonandClaude Opus 5 9badcbf80e feat(B08): 토공집계표·운반 가중평균 엔진 + 프로젝트 설정 자리
일감 4·5 의 엔진 덩어리. PLAN 8-11·8-3·8-7.

프로젝트 설정 (common_util/common_util_project_settings.py)
  자리 = <project_root>/project_settings.json, 루트의 project_manifest.json 옆.
  매니페스트 stages 는 단계 산출물 목록이고 설정은 두 페이지가 함께 읽는
  프로젝트 값이라 단계 폴더에 넣으면 주인이 애매해짐.
  구획 quantity(B08) · estimation(B09) — 남의 구획은 읽기만.
  ⚠ 경계를 코드로 막음 — save_section() 이 이름 붙은 한 구획만 갈아 끼우고
  통째로 쓰는 함수를 두지 않음. 두 페이지가 같은 파일을 쓰므로 통째로 덮으면
  상대 값이 사라짐(오늘 main.py 에서 같은 모양의 사고를 이미 겪음).
  ⚠ *_override 기본은 None — 「안 정했으면 config 정본을 씀」. 기본값을 복사해
  넣으면 정본이 바뀌어도 옛 프로젝트가 안 따라옴.
  ⚠ dataset_versions 는 기록이지 정본이 아님 — 되살릴 때 쓰는 정본은 프로젝트
  스냅샷이고 어긋나면 스냅샷이 이김.
  estimation.rate_dataset 은 「연도」가 아니라 판을 가리킴 — 제비율은 연중에도
  개정됨(현행판 2026-04-13). B09 확정 반영.

토공집계표 (열 = 구분·공종·규격·단위·계·비고, 거창 실무 시트 그대로)
  ⚠ 암 갈래 개수를 코드에 안 박음 — 울진 2 · 거창 5 · BOM 1 로 공사마다 다름.
  프로젝트 설정의 세트를 받아 그만큼 줄을 냄. 비율이 아직 없으면 지어내지 않고
  「암」 한 줄로 냄. 비율 합이 100 이 아니어도 준 비율끼리 안분해 총량 보존.
  ⚠ 반영률 기본 100 % — 실무 관측 80/50/80 은 참고이지 기본값 아님(법대로).
  바꾼 경우에만 비고에 「80 % 반영」이 남음 — 누가 정한 값인지 보이게.

운반 가중평균 ((운반수단 x 지반유형)별 1줄)
  실무 울진이 도자 토사/암 · 덤프 토사/암 4줄을 올림. 가중평균 = Σ(토량x거리)/Σ토량
  으로 단순평균이 아님. 개별 구간은 근거로 함께 냄 — 어느 구간이 그 평균을
  만들었는지 되짚게.
  입력은 이미 있는 HaulPlan — 띠·장거리이동에 equipment·haul_distance_m·
  지반유형별 물량(ea/rr/br)이 다 있어 다시 세지 않음.
  ⚠ 무대(free_haul)는 in_bill=False — 품셈 1-2-7 로 품에 포함이고 인력운반 10-6
  도 「소운반 20m 초과분」이라 붙일 단가가 없음. 값은 내되 내역 줄만 뺌 —
  「무대+도자+덤프 = 총 운반토량」 검산에 씀.

검증 — 28건 통과 (토공집계·설정 19 + 운반 9).
  가중평균이 단순평균과 다름을 못 박음(도자 토사 600@40+400@50 → 44m, 45 아님).
  울진2·거창5 두 세트가 같은 코드로 서는 것, 무대가 내역 줄이 아닌 것,
  구획을 따로 저장해도 상대 값이 안 지워지는 것을 각각 시험함.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 20:54:23 +09:00
eomsangdonandClaude Opus 5 33aa07f782 docs(B06): cut_slope_segments 는 지금 읽는 곳이 없음을 코드에 명시
데스크탑 창이 「법정 경사 검사가 빈 값을 볼 수 있다」고 알려 와 확인함. **검사 자체가 없어
문제 없음** — 별표2 검사는 오늘 폐기됐고(`cc428d7e`, 암질을 횡단도에서 안 고르기로 사용자
확정), 지금 이 값을 읽는 코드는 **한 곳도 없음**(계산해 내보내기만 함).

같이 확인한 사실 — 저장분에도 안 들어감. 실측(공용 DB) `cross_sections.data.design` **33키**에
`cut_slope_segments` 없음(같은 자리에 `cut_area_m2` 는 있음). 저장되는 것은 화면이 보낸
**설계 지정값**이라 엔진 출력 전체가 아님.

그런데 주석 셋이 아직 「법정 경사 검사가 읽는다」로 남아 있어 **다음 사람이 저장분에서 읽으면
된다고 오해**할 자리였음. 그 셋을 고쳐 ① 지금 읽는 곳 없음 ② 저장분에도 없음 ③ 남겨 두는
까닭은 소단 기하가 이 셈 위에 서 있어서 ④ **되살릴 때는 저장분에서 읽지 말고 계산해서 쓸 것**
을 적음. 코드는 한 줄도 안 바뀜(주석만).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 20:29:25 +09:00
eomsangdonandClaude Opus 5 80db17d463 fix(소단): 제자리 무릎이 되풀이돼 화면이 멈추던 것 — 앞으로 갈 때만 무릎 인정
**실사고(2026-09-07)** — 사용자 공용 브라우저에서 **소단을 한 건 놓자 화면이 25분 넘게 멈춤**
(렌더러가 1.4코어를 계속 태움). 서버(파이썬)로 같은 측점을 돌리면 0.01초에 끝나 **서버는
멀쩡**했고 화면만 물렸음.

**원인** — `cut_profile_points` 의 무릎(암 경계 교차) 가지에서 **제자리 뒤집기**.
암 경계선의 기울기가 **암 경사와 토사 경사 사이**면
· 토사로 바꾸면 다음 걸음이 경계 **아래** → 「다시 암」
· 암으로 바꾸면 다음 걸음이 경계 **위** → 「다시 토사」
가 되고, 이때 보간 비율 `share` 가 0 이라 `knee_dist == dist` — **한 걸음도 안 나감.**
`while dist < limit` 이 끝나지 않음. `multi_knee` 는 **소단이 있으면 항상 참**이라 소단이 지뢰였음.

**고침 둘**(파이썬·TS **같은 모양**)
1. **앞으로 나아가는 무릎만 인정** — 직전 무릎 자리를 들고 있다가 같은 자리(1e-9 이내)면
   뒤집지 않고 한 걸음 감. **첫 무릎은 종전대로 인정**되므로 `multi_knee=False`(소단 없는
   경로)는 한 비트도 안 바뀜 — 그쪽은 첫 뒤집기 뒤 가지 자체가 닫힘.
2. **걸음 수 상한 40,000**(정상 최대 4,000의 10배). 넘으면 **조용히 자르지 않고 경고**를 남김 —
   조용히 자르면 절토선이 짧아진 채 값이 나가 또 조용히 틀림(25 지적).

**시험 5건**(`tmp/tests/test_berm_knee_progress.py`) — 경계 기울기를 두 경사 사이에 둔 재현으로
① 8초 안에 끝나는지 ② 거리가 뒤로 안 가는지 ③ 소단 없는 경로가 종전 그대로인지
④ 두 파일이 같은 규칙을 쓰는지 ⑤ **TS 를 실제로 돌려 파이썬과 꼭짓점 수·끝점이 같은지**.
고치기 전에는 ①이 무한 대기였음. 전체 **491 passed · 17 skipped**, `tsc --noEmit` 통과.

버그를 낸 창(25)과 확인하고 진행함 — 겹치는 작업 없음.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 19:57:44 +09:00
eomsangdonandClaude Opus 5 4774eb3efb docs(소단): 모듈 설명 첫 줄의 기본 기울기 2° → 0° 정정
아래 항목 설명은 0° 로 고쳐져 있었는데 머리말만 2° 로 남아 서로 어긋났음.
값 자체는 이미 0 이라 동작 변화 없음.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 18:16:10 +09:00
eomsangdon 29559b2b5e Merge remote-tracking branch 'origin/main_laptop_1' into sub_laptop_1
# Conflicts:
#	B06_Section/B06_Section_Api_Types.ts
2026-09-07 18:09:36 +09:00
eomsangdon 77a614ecf9 Merge remote-tracking branch 'origin/main_desktop_1' into sub_laptop_1 2026-09-07 18:08:34 +09:00
eomsangdonandClaude Opus 5 674d4ef14a fix(토공): 도자 운반 한계거리 70m → 60m 확정
근거 — 실무 오솔길 EARTH.DAT 헤더 6개 공사지가 전부 `20.0 / 60.0`
(거창·장수·진안·봉화·영월 본선·지선). 산림과임업기술 5장 「다. 공사수량의
산출」도 「도저운반성토 60m 이하 / 덤프운반성토 60m 초과(건설표준품셈
참조)」로 규정. 70m 는 Aislo 단독값이었음(2026-08-02 잠정 확정).

- config_system_design.py — EARTHWORK_HAUL_EQUIPMENT_LIMITS_M 의 dozer
  경계와 주석의 확정 이력·근거 갱신. 정의처가 이 상수 한 곳이라 다른 코드
  변경 없음.
- common_util_mass_haul_balance.ts — 경계현 설명 주석의 70m 표기 정정.

검증 — 백엔드 재시작 뒤 공용 브라우저에서 실제 API 호출,
sections/context 의 dozer.max_distance_m = 60 확인. 회귀 369 passed
(실패 3건은 haul 미참조 기존 깨짐).

지식DB 미결 No.21 해소 — 목록 정리는 위키 AI 몫.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 18:08:18 +09:00
eomsangdonandClaude Opus 5 6b9c115baa feat(B06): 절토 경사를 사용자가 넣게 — 카드에 암 절토각(°), 전체는 표준 설정
사용자 지시(2026-09-07): 「대신 경고부분은 삭제해주고 대신 각도를 사용자가 넣을수 있게 반영.
전체 공통으로 변경하는 경우에는 기본값 지정으로 하면 되지만 횡단도 하나만 변경하는 폼은
가져야함 / 개별 횡단도에는 암 절토 각도의 개별 수정 가능해야함」

**화면** — 암 측점 카드 아래에 「암 절토 68.2° ↺」 칸이 섬. 값을 넣으면 그 측점만 사면이
새 경사로 다시 그려지고 절토량도 따라 바뀜. ↺ 는 표준값으로 되돌림. 전체를 바꾸는 자리는
종전대로 좌측 [표준 횡단면 설정]임.

**계산에 넣는 자리는 한 곳씩** — 파이썬 `compute_cross_design(cut_slope_ratio=…)` ·
TS `computeCrossDesign({cutSlopeRatio})` 의 **그룹을 만든 바로 뒤**에서 경사비만 갈아 끼움.
부르는 쪽 9곳에서 표준값을 측점마다 복제하는 방식은 안 씀(한 곳만 빠져도 값이 조용히
사라지는 실패군). 기하·소단 코드는 한 줄도 안 건드림 — 25 확인대로 소단이 그 값을 읽어
서므로 **위치·개수가 새 경사를 저절로 따라옴**.

⚠ **경사는 나르는 값이 아니라 기하 입력임** — 계산 뒤에 키만 베껴 붙이면 설계선은 옛 경사로
그려지고 숫자만 새것이 됨(소단에서 겪은 자리). 그래서 재계산 세 경로(포장 강제·세월교 하강·
선형 재계산)와 브라우저 재계산·서버 프리뷰 **모두 계산 인자로** 넘김.

**되돌리기는 0 을 남김** — 세션에서 지우기만 하면 정본에 남은 옛 사용자 값이 되살아나
표준으로 못 돌아감. 0 = 「표준값을 씀」.

값의 길 — 세션 `cutslope`(등록표 한 줄) → 카드 입력 → [저장]·[확정]에서 `cross_patches`
(`design.cut_slope_ratio_user`) → 정본. `USER_TOUCHED_KEYS` 양쪽에 넣어 **표준을 바꿔도
개별로 고친 측점은 그대로** 둠(사용자 원문 끝줄).

시험 — 새 7건(넣은 경사가 실제로 그려짐 · 무릎 위 토사 경사는 그대로 · 0 은 되돌림 ·
재계산에도 남음 · **계산 전에 넘어감** · 각도↔경사비 · 칸은 암 측점에만),
거울 시험에 「암 절토 경사를 측점에서 바꿈」 한 갈래 추가, 7-3 회귀 한 줄 추가.
전체 **483 passed · 17 skipped**.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 17:52:06 +09:00
eomsangdonandClaude Opus 5 7833b9e677 feat(구조물): 소단을 「구조물 배치」로 옮김 — C군 사면안정 신설 (계획서 3-9, 사용자 재확정)
사용자 확정(2026-09-07) — 소단은 좌측 별도 폼이 아니라 **다른 옹벽·기슭막이와 같은 자리**
(구조물 배치)에서 놓는 것으로 바뀜. 기하는 그대로 두고 **입구만 옮겼음.**

· 레지스트리에 **C군(사면안정) 「소단」** 신설. 옵션은 다른 C군 구간형과 같은 꼴 —
  길이·기준측점 전·후 + 폭·간격(사면길이)·안쪽 기울기.
· ⚠ **소단은 C군 구간형이지만 벽이 아님** — 기슭막이 제원 자리에 얹히지 않게 파이썬·TS
  양쪽 벽 필터에서 뺐음. 안 뺐으면 소단을 놓는 순간 「독립 기슭막이」로 그려졌을 것임.
· 구조물 목록이 바뀌면 소단 구간을 세션 사본(`berm`)으로 펴고, 달라졌을 때만 재계산함.
  계산 계통(브라우저·서버·`USER_TOUCHED_KEYS`·옹벽 의무 판정)은 **한 줄도 안 바꿨음**.
· ④에서 만든 좌측 별도 「소단」 패널은 걷어냈음(모듈 삭제).

**안쪽 기울기 기본값 2° → 0°** (사용자 재확정). 기울이는 것은 실무이나 법령·교본 근거가
없어 기본으로 넣지 않고 폼에서 받음. 주석·지식DB 방침도 그에 맞춰 고침.

**소단측구**(B군 종단배수)도 같은 꼴로 옵션을 붙였음 — 소단 위에 놓이는 시설이라 폭·간격이
소단을 따르고, 기울기만 **사면 쪽**(소단과 반대). 소단이 실제로 서면서
`PENDING_TYPE_IDS` 빈 칸이 풀려 연장 수량이 다른 구조물과 같은 길로 나옴.

자체검증 — 「근거 없는 기본값 금지」 시험에 두 타입 12개 기본값을 근거와 함께 등재.
소단측구 연장 시험을 「빈 칸」에서 「연장 100m」로 뒤집음. 전체 544 passed · 18 skipped.
TS 타입 검사·ruff 통과. 화면 확인은 다음 단계.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 17:29:50 +09:00
eomsangdonandClaude Opus 5 c7770b7529 fix(횡단): 옹벽 의무 판정이 소단을 실제로 보게 함 — 부호·쪼개짐 두 곳 (계획서 3-9 ⑥)
앞 커밋으로는 화면 값이 안 바뀌어 실화면에서 두 가지를 더 찾았음.

① **TS 결과에 소단을 안 실었음** — 파이썬만 되싣고 브라우저 판을 빠뜨렸음.
   판정(`fillSlopeLengths`)은 브라우저에서 도는데 `design.berm` 이 없어 종전 식으로 갔음.

② **소단을 폭으로 찾으면 못 찾음** — 설계선 꼭짓점에는 지반 샘플(0.5m 격자)이 섞여 있어
   폭 0.5m 짜리 소단이 **두 도막으로 쪼개짐**(실측: 평탄부 0개). 게다가 설계선은 오프셋
   오름차순이라 **우측(음수) 성토면은 같은 소단이 `-기울기`로 나와** 부호를 그대로 대면
   역시 못 찾음.
   ⇒ **기울기로 가름.** 소단은 2°(0.035), 성토는 1:1.2~2.0(0.5~0.83)이라 성토 기울기의
   절반만 잡아도 확실히 갈림. 쪼개져도 부호가 뒤집혀도 걸림.

실화면 확인(8001·5174, `stale:false`) — 측점 2820.0m, 성토사면이 긴 자리:
· 소단 없음 → **≥32.54m** (옹벽·석축 의무 대상)
· 폭 0.5m·3m마다 놓음 → **≥3.00m** (5m 이내 — 의무 해소). 3.00m 은 소단 간격 그대로임
· 옆 측점(2840.0m, 안 놓음) → **≥32.54m 그대로**

**소단 없는 측점은 값이 안 바뀜 — 272측점 전수 대조, 달라진 곳 0.**
구조로도 보장됨(`design.berm` 이 없으면 종전 식을 그대로 탐).

전체 542 passed · 18 skipped. TS 타입 검사 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 16:59:48 +09:00
eomsangdonandClaude Opus 5 db4f17fb1c feat(횡단): 성토면 소단 + 옹벽 의무 판정을 「소단 사이 구간별 최대」로 (계획서 3-9 ⑥)
한 묶음으로 처리했음 — 화면에 5m 판정이 틀린 채 서 있는 시간이 없게.

성토 사면 꼭짓점 짝 신설(`fill_profile_points` · `fillProfilePoints`). 절토와 달리
경사가 하나뿐이라 무릎이 없고, 소단 규칙은 같음. 설계선·지반 교차·꼭짓점 목록이 모두
그 선을 봄.

⚠ **옹벽 의무 판정을 함께 고쳤음** — 「성토사면 길이 5m 이내, 넘으면 옹벽·석축 의무」
(`성토_비탈면.md` §2)를 재는 `fillSlopeLengths` 가 **「성토선은 1:n 직선」을 전제로
수평거리 × 기울기**로 재고 있었음(주석에도 그 전제가 적혀 있었음). 소단이 들어가면 그
전제가 깨져 값이 틀림.

고침 — 소단이 있으면 설계선을 걸어가며 **소단으로 끊긴 한 도막**의 최대 길이를 잼.
· 전체를 한 줄로 재면 소단을 넣어도 5m 를 넘어 **의무가 사라지지 않음**
· 실효 경사로 재면 완만해져 **의무가 사라진 것처럼** 보임
둘 다 틀리므로 「끊긴 한 도막」이 맞는 기준임.

**소단이 없는 측점은 종전 식을 그대로 탐** — `design.berm` 이 없으면 예전 계산 그대로라
값이 한 톨도 안 바뀜(구조로 보장). 화면 전후 대조는 다음 단계에서 냄.

자체검증 — 새 시험 2건(성토면에 계단이 서고 같은 거리에서 덜 내려감 · 소단이 없으면
성토선이 곧은 한 줄). 전체 542 passed · 18 skipped. TS 타입 검사·ruff 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 16:38:33 +09:00
eomsangdonandClaude Opus 5 4e7a4bf787 fix(횡단): 사면 구간 재료를 **그린 경사비**로 가름 — 「토사 경사인데 암」 라벨 없앰
다른 창이 전 측점을 돌려 찾은 것(용화 5601e828 · route 169, 63측점 124구간).
`material: "rock"` 인데 경사비가 1.0(토사)인 구간이 **13개** 나왔음.

까닭 — 재료를 **암반 경계선을 다시 재서** 붙였음. 그런데 무릎을 지난 뒤에도 경계선은
지반을 따라 계속 오르므로, 토사 경사로 그린 구간이 경계 아래로 **되돌아가 있는** 일이
흔함. 그것을 경계로 재면 그린 것과 라벨이 어긋남.

고침 — 재료는 **그 구간을 실제로 그린 경사비**를 따라 붙임(암 경사비에 가까우면 암,
토사 경사비에 가까우면 토사). 두 경사비가 같으면(2단 절토 아님) None.

영향 — 별표2 경사 판정이 갈리던 자리임. 13개가 「암인데 너무 완만」 위반으로 잘못 뜰 수
있었음. 토사 구간 50개는 종전대로 위반 0.

자체검증 — 새 시험 1건: 지반이 가파른 암 지반에서 모든 구간의 재료가 그 경사비와 맞는지
확인(어긋나면 실패). 거울 시험도 통과. 전체 542 passed · 18 skipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 16:25:46 +09:00
eomsangdonandClaude Opus 5 061d550e55 feat(횡단): 소단을 미리보기·재계산에 실어 화면에 계단이 서게 함 (계획서 3-9)
계단이 값에만 있던 것을 화면까지 연결함.

배선 — 세션 열쇠 `berm`(측점키 → 폭·간격·기울기)을 등록표에 두고,
`readBermSession` 으로 읽어 ① 브라우저 재계산(`refreshCrossDesigns`)과
② 서버 미리보기(`cross-design/preview` 의 `berms`) 양쪽에 실음.
암 경계선 오프셋과 같은 길이라 「계획선을 고치면 계단이 사라지는」 일이 없음.

실화면 확인(8001·5174, `/api/health` `stale:false`) — 측점 4120.0m 에 소단을 놓고
계획고를 한 칸 올렸다 내려 전 구간 재계산을 태움.
· 폭 0.5m · 간격 3.0m → 절토 6.84 → 8.10㎡ (토사 2.42→3.24 · 암 4.42→4.86)
· 폭 1.0m · 간격 2.0m → 절토 6.84 → 12.96㎡, 횡단도에 **계단이 눈으로 보임**
· 소단을 안 놓은 옆 측점(4100.0m)은 3.77㎡ 그대로 — 놓은 곳만 달라짐
· 되돌린 뒤 6.84㎡ 로 복귀. [저장]·[확정] 안 눌렀으므로 정본은 그대로.

`cut_slope_segments` 신설 — 절토 사면을 경사 구간별로 쪼갠 목록(파이썬·TS 짝).
법정 경사 검사가 읽을 값임(다른 창 요청). 소단이 서면 사면 전체를 하나로 재는
「실효 경사」가 완만해져 **위반이 사라진 것처럼** 보이므로(폭 1.0·간격 2 이면 설계 1:1 이
실효 1:1.71), 검사는 소단을 뺀 구간 자체를 봐야 함. 실측 — 소단을 놓아도 구간별 경사비는
1.0 그대로 나옴. 평탄부(소단)와 지반 만난 뒤 구간은 싣지 않음.

자체검증 — 거울 시험에 사면 구간 대조를 더해 파이썬·TS 일치 확인.
전체 539 passed · 18 skipped. TS 타입 검사 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 15:28:16 +09:00
eomsangdonandClaude Opus 5 5a6617f278 fix(횡단): 소단이 암 경계 아래로 되돌아가면 다시 암 경사로 그림 (계획서 3-9)
배분 창 지적으로 확인한 자리 — 미룰 수 없는 쪽이었음.

무엇이 문제였나 — 소단은 평탄한데 암 경계선은 지반을 따라 올라감. 지반이 1:1 이면
폭 0.5m 소단 하나를 지나는 동안 경계는 0.5m 오르고 소단은 2°(0.017m)만 오름. 그래서
설계선이 경계 아래로 **되돌아 들어가는 일이 흔함**. 무릎을 한 번만 꺾는 종전 규칙으로는
그 구간을 **암인데 토사 경사로** 그려 절토가 조용히 커짐 — 경고도 안 뜸.

고침 — `multi_knee` 를 둬서 경계를 오갈 때마다 꺾게 함. **소단이 있을 때만** 켬.
소단이 없을 때 켜면 지금 측점들의 설계가 같이 바뀌기 때문임(실측: 물결 경계 0.0016m).
기본값은 거짓이라 소단을 안 쓰는 프로젝트는 그대로임.

자체검증
- 새 시험 1건 — 경계를 뚫고 올라갔다가 소단마다 뒤처져 되돌아 들어가는 지형에서
  한 번만 꺾는 결과와 갈리고, 되돌아 들어간 구간이 암 경사(가파름)라 같은 거리에서
  더 높이 올라가는 것을 확인.
- 거울 시험에 되돌아 들어가는 경우를 한 줄 더해 파이썬·TS 일치 확인(12건).
- 전체 539 passed · 18 skipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 14:58:18 +09:00
eomsangdonandClaude Opus 5 e43ad18f97 feat(횡단): 절토 사면에 소단(계단) 기하를 넣음 — 파이썬·TS 짝 (계획서 3-9)
사용자 확정(2026-09-07)에 따라 소단을 **자동 적용하지 않고 사용자가 놓는 것**으로 만듦.
이 커밋은 그 기하 한 벌이고, 화면 폼은 다음 단계임.

새 짝 모듈 `common_util_cross_berm.py` · `.ts` — 절토 사면 꼭짓점을 만듦.
암 경계 무릎과 소단이 한 목록에 함께 들어가고, `breakpoints` 가 그 꼭짓점을 설계선에
실어 도면·면적·유토곡선·3D 가 계단을 그대로 봄.

기본값 폭 0.5m · 간격(사면길이) 3.0m · 안쪽 기울기 2°.
· 폭·간격은 별표2 범위(사면길이 2~3m마다 · 폭 50~100㎝) 안에서 가장 적게 파는 조합임.
  기본값은 되돌리기 쉬운 쪽이어야 함 — 더 넣는 것은 폼에서 한 번이지만 이미 판 것을
  되돌리면 전 측점을 다시 계산해야 함. 실효 경사로도 그러함(경사 1:1 기준)
  폭 0.5·간격 3 → 1:1.24 / 폭 1.0·간격 3 → 1:1.47 / 폭 1.0·간격 2 → 1:1.71.
· 기울기 2°는 사용자 확정값이고 법령·교본 근거가 없어 지식DB 에 적지 않음(사용자 지시).

무릎은 종전대로 **한 번만** 꺾음. 여러 번 꺾게 풀면 소단이 없는 지금 측점 설계도 같이
바뀌므로 별건으로 미룸(실측: 물결 경계에서 0.0016m 차이, 경계를 다시 만나면 구조가 달라짐).

자체검증
- 거울 시험 10건 `tmp/tests/test_cross_berm_mirror.py` — 소단 켠 5경우 포함해 파이썬·TS
  꼭짓점이 1e-9 안에서 일치. 간격이 수평이 아니라 사면길이 기준인 것, 평탄부가 2° 기운 것,
  소단이 없으면 옛 무릎 방식과 완전히 같은 것까지 확인.
- 면적 시험 6건 `tmp/tests/test_cross_berm_area.py` — 절토 55.115 → 78.785㎡(기본값),
  폭·간격이 물량에 단조로 반영, 소단 모서리가 설계선에 실림, 소단을 안 주면 설계선까지 동일.
- ⚠ 어림식 두 번을 시험이 잡아냄. 「늘어난 면적 = 폭 × 그 위 높이」는 틀림(11.797 vs
  7.770㎡) — 설계선이 밀리면 지반과 만나는 점도 함께 밀려 절토가 더 길어짐. 「폭만큼 밀림」도
  틀림 — 참값은 「그 아래 소단 개수 × 폭」임. 시험은 그 참값으로 잼.
- 기존 거울 시험(`test_b06_cross_design_mirror.py`) 10건 그대로 통과 — 리팩터가 값을
  안 바꿨다는 증거임. 전체 537 passed · 18 skipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 14:54:18 +09:00
eomsangdonandClaude Opus 5 7769db3639 feat(구조물): 측구는 「횡단 설계에서 관리」로 표시하고, B군 연장(m) 집계를 만듦 (계획서 3-6)
사용자 결정 두 가지를 반영함(2026-09-07).

① 측구(옆도랑) — 목록에 두되 표시만.
레지스트리에 `design_owner` 를 새로 두고 측구에 「횡단 설계」를 적음. 구조물 배치 폼에서
그 종류를 고르면 「횡단 설계에서 관리 — 여기서 넣어도 제원·수량은 그쪽 값을 씁니다.」가
뜸. `managed_by` 와 달리 저장은 그대로 되므로 배치는 계속 가능함.

까닭 — 횡단 설계가 측구 켬/끔·형식·터파기 단면적(`ditch_area_m2`)을 파이썬·TS 짝으로
이미 셈함. 구조물로 또 세면 같은 것을 두 번 계상함.

목록 항목에 안 붙이고 폼에 붙인 것은 「한 항목 = [측점][이름]만」이 2026-08-18 사용자
지시이기 때문임.

② B군 수량 1단계 — 구조물 정본에서 시설별 연장(m)을 냄.
`common_util_structure_lengths.py` 하나. B군 수량 단위가 전부 m 이라 단면 기하가 필요
없음(맹암거 12-10 · L형 측구 12-9-1 · 산마루측구 12-9-2). 수량서 양식에 안 묶이므로
B08 을 실무 xlsx 양식으로 다시 짜도 그대로 씀.

빼는 것 셋 — 관 정본 소관(`managed_by`), 횡단 소관(`design_owner`), 그리고 소단측구
(놓일 소단이 아직 없음 — 계획서 3-9 뒤에 채움).

겹친 구간은 합쳐서 셈함. 같은 시설을 겹치게 두 번 넣으면 단순 합이 그 구간을 두 번
세기 때문임. 원래 합(`raw_length_m`)도 함께 내보내 겹침이 숨지 않게 함.

자체검증
- 새 시험 7건 `tmp/tests/test_structure_lengths.py` — 종류별 합산 / 겹침 제거(80m 인데
  단순 합 110m) / 측구 제외 / 소단측구 제외 / 배관 제외 / 구간 없는 항목은 스키마가 막음
  / 빈 프로젝트.
- 화면 확인(8001·5174, `/api/health` `stale:false`) — 구조물군 B → 종류 측구 선택 시
  안내가 254×44px 로 뜨고 문구가 맞음. 리셋으로 폼 되돌림.
- 전체 521 passed · 18 skipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 13:39:42 +09:00
eomsangdonandClaude Opus 5 e2d329d35f fix(배수유역): 지문이 달라도 같은 노선이면 관 지점을 그대로 씀 (계획서 0-7 곁가지 ③)
같은 노선인데 지문이 늘 어긋나 관 지점이 매번 투영 이월을 탔음.

까닭 — 같은 노선을 두 파일이 다른 자릿수로 담고 있음.
`planned_route.csv` 는 소수 4자리(`208403.2001`), `route_main.geojson` 은 소수 3자리
(`208403.2`)로 csv 를 mm 반올림한 사본임. 좌표 차는 최대 0.5mm 뿐인데, 지문이
`f"{x:.2f}"` 로 0.01m 자리에서 끊는 탓에 그 0.5mm 가 `.xx5` 경계를 넘는 정점마다
글자가 바뀜 — 169개 중 16개가 그랬음.

경계에서 자르는 방식은 저장 자릿수가 또 바뀌면 다시 흔들리므로, 글자 일치 대신
**허용오차**로 가름. 저장된 관을 지금 노선에 투영해 **재 보기만** 하고
(`max_projection_shift`, 값은 안 고침), 최대 어긋남이 0.05m 이하면 같은 노선으로 보고
저장분을 그대로 돌려줌.

허용오차 0.05m 근거 — 실측 어긋남이 최대 0.0053m 이라 다섯 배 이상 여유이고,
사람이 노선을 실제로 고치면 관은 m 단위로 밀리므로 「같다」로 볼 위험이 없음.

투영 이월 가지는 그대로 둠 — 대신 그 가지가 실제로 돌면 WARNING 을 찍게 함.
한동안 0 인 것을 확인한 뒤에야 지울 수 있음(먼저 지우면 관이 통째로 사라짐).

자체검증
- 새 시험 3건 `tmp/tests/test_pipe_route_tolerance.py` — mm 반올림 사본은 같은 노선으로
  판정되고 누가거리가 한 값도 안 움직임 / 중간을 3m 민 노선은 안 걸림 / 허용오차 범위.
- 기존 `test_pipe_point_projection.py` 2건 그대로 통과(±0.7m 잔물결 노선은 여전히 투영).
- 저장된 실제 3개 프로젝트 전후 대조 — 셋 다 「다름 → 투영」이 「같음 → 저장분 그대로」로
  바뀜. 화면 값 변화는 최대 0.0053m · 0.0009m · 0.0005m.
- 전체 514 passed · 18 skipped.

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