- `docs/` 를 .gitignore 에서 빼 git 추적 대상으로 전환 (위키·완료 이력·검증 기록) - `docs/raw/PLAN.md` · `docs/raw/OWNERS.md` 를 저장소 최상위로 이동 후 .gitignore 에 등록 — 창끼리 공유하되 저장소에는 안 올리는 장부 - 살아 있는 경로 참조 7개 파일 정정 (아카이브 107건은 그때 사실이라 그대로 둠) - graphify 날짜별 산출물(`docs/wiki/graphify-out/20*/`) 제외 — `graphify update` 가 다시 만듦 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
698 lines
53 KiB
Markdown
698 lines
53 KiB
Markdown
# 일하는 법 · 검증 함정 — 겪은 것에서 (2026-09-07 ~ 09)
|
||
|
||
> **상시계획서 `PLAN.md` 「참고」에서 옮긴 원문임. 줄이지 않았음.**
|
||
> 옮긴 까닭 — 계획서의 「참고」는 **코드 작업 중 필요한 기준표·확정사항만** 두기로 되어 있는데
|
||
> 여기 든 것은 기준표가 아니라 **일하는 법**임(2026-09-09 사용자 지시 「반영」).
|
||
> **다음 세션이 계획서보다 먼저 읽을 것.** 계획서 「참고」에는 이 파일 링크만 남겼음.
|
||
>
|
||
> 든 것 — 일하는 법 열둘 · 좁은 폭 화면 깨짐 · vite 캐시 · 공용 이름 바꾸기 ·
|
||
> [저장]과 횡단 재계산 · 공용 브라우저 조작 주의 셋 · 검증 함정 모음.
|
||
|
||
### ⚠⚠ 일하는 법 넷 — 2026-09-07 두 창이 겪은 것에서 (다음 세션이 먼저 읽을 것)
|
||
|
||
이 절의 값어치는 **같은 사고를 다시 겪지 않는 것**이다. 넷 다 하루에 여러 번 나왔다.
|
||
|
||
#### ㉠ 「숫자가 늘어난 것」은 좋아진 신호가 아니다
|
||
|
||
배분율 표 25건이 살아났으나 그게 **10 % 짜리**였고, 2단 표 165줄이 늘었으나 상당수가
|
||
오독이었다. **늘어난 뒤에는 반드시 최대·중앙값과 손대조를 볼 것.**
|
||
(그래서 산출 요약에 최소·중앙·최대를 붙였다 — 8-22 ③.)
|
||
|
||
#### ㉡ 넓은 규칙이 정상 값을 지운다 — 하루에 **여덟 번** (두 창에서 넷씩)
|
||
|
||
① 배합 검사가 `막자갈`을 오탐 ② 자원 필터가 정상 자원 70/745 를 지움 ③ 비율 지시를
|
||
먼저 봐 강관동바리 소요량표가 참조로 넘어감 ④ 머리글 필터가 등급 글자(상·중·하)를 지움
|
||
⑤ 「당」을 느슨히 잡아 `(무한궤도,0.7㎥)` 를 밑수로 읽음 ⑥ 식 칸 집계가 비고 설명문까지
|
||
걸어 93 → 31 로 좁힘 ⑦ 「값 못 읽은 줄」 판정이 **값이 없는 게 당연한 머리 줄**까지 세어
|
||
28 → 12 ⑧ 표 안 긁기가 비고의 「10㎡」를 그 표의 밑수로 물어 옴.
|
||
|
||
⑨ **`REFERENCE_MARKS` 의 「단 위」 하나가 공종 41건을 참조로 버림** — 그 안에
|
||
**돌쌓기(장비) 13-4-5·13-4-2**(우리 매핑이 매일 쓰는 코드)가 있었다. 규모가 가장 컸다.
|
||
⑩ 자간 공백 이름 세기가 「단 위」·「모 래」까지 걸어 101 → 20 으로 좁힘.
|
||
|
||
**⚠ ⑦ 은 이 병을 다섯 번 잡아 놓고 새로 하나 만든 것**이다. 원인은 **짝 시험을 그 자리에
|
||
같이 안 둔 것**. 세기 전에 **「이건 세면 안 된다」 쪽 표본을 먼저 정해 둘 것.**
|
||
|
||
**⚠ ⑨ 의 진단이 이 절의 처방이다** — 그 표지의 원래 겨냥(품셈 1-2-2 「단위 표준」)은
|
||
**chapter 규칙이 이미 거르고 있었다.** 즉 **넓기만 하고 얻는 것이 없었다.**
|
||
**⇒ 넓은 규칙을 만나면 그것이 실제로 무엇을 **더** 잡는지 세어 볼 것 — 다른 규칙과 겹치면
|
||
얻는 것 없이 잃기만 한다.** 규칙을 지울 근거는 「안 잡히는 것」이 아니라 **「이미 다른 규칙이
|
||
잡고 있는 것」**이다.
|
||
|
||
**⚠ 정규화는 값을 살리지만 잘못된 줄도 함께 살린다** (2026-09-07 서브 창 실례).
|
||
기종 이름 공백을 지워 빠졌던 장비 몫을 살렸더니, **같은 표의 버킷계수 `K` 를 소요량으로 읽어**
|
||
시간당 사용료가 이중이 될 뻔했다. **살리는 규칙에도 짝 시험을 둘 것.**
|
||
|
||
**⇒ 규칙을 새로 둘 때마다 「걸려야 한다」와 「걸리면 안 된다」 짝 시험을 함께 둘 것.**
|
||
**⇒ 값을 지우는 규칙은 좁게, 표시만 하는 깃발은 넓게.** 깃발은 넓어도 값이 안 사라진다
|
||
(`partial_ratio` 를 몫 유무로 넓게 잡은 판단이 그것).
|
||
|
||
#### ㉢ 검사가 도는 줄 알았는데 안 돌고 있었다 — 하루에 네 번
|
||
|
||
① 가드를 만들어 두고 안 부름 ② 지문 장치가 원판 지문을 봐서 안 움직임
|
||
③ `npx tsc` 가 **엉뚱한 패키지를 실행**(이 저장소는
|
||
`node ./config/node_modules/typescript/bin/tsc --noEmit` 로 부를 것)
|
||
④ 사방공에 **없는 `type_id`** 를 적어 영영 안 걸릴 뻔함.
|
||
|
||
**⇒ 새 검사·장치는 일부러 깨뜨려 보고 실제로 잡히는지 확인할 것.**
|
||
**⇒ 이름으로 무언가를 알아보는 코드는 정본(레지스트리·마스터)과 대조하는 시험을 둘 것.**
|
||
|
||
#### ㉤ ⚠ **먼저 원문부터 뒤진다** — 「관측값인 줄 알았는데 법이었다」가 **여덟 번**
|
||
|
||
여덟 다 「실무 관측값을 쓰자」·「사용자에게 물어야 한다」로 시작했다가 **품셈 원문에 이미
|
||
정해져 있는 것**을 찾았다. 뒤 여섯은 **2026-09-08 재조사에서 네 창이 동시에** 건졌다.
|
||
|
||
| 물음 | 처음 생각 | 원문 |
|
||
|---|---|---|
|
||
| 거푸집을 몇 번 쓰나 | 관측값 병용 | **품셈 1-7-1** — 「3회 … 옹벽, 파라펫트, 날개벽」 |
|
||
| 철근 갈래가 무엇인가 | 사용자에게 물음 | **품셈 12-3 [주]①** — 「보통: 수문, 반중력식 옹벽 및 교대」 |
|
||
| 덤프 t↔㎥ 환산 γt | 지식DB 에 없음 | **품셈 10-12-1 [주]②** — 토사 1.9 · 암 2.4 t/㎥ |
|
||
| 공구손료 밑수·제잡비와의 관계 | 두 문서가 어긋남 | **건설품셈 1-2-6** — 「명시된 것은 그것을 계상, 명시 안 된 것만 별도」·「인력품의 3%까지」 |
|
||
| 야면석 개수·중량 원단위 | 실무값밖에 없음 | **품셈 13-4** 「돌쌓기의 개수 및 중량의 표준」 — 0.575 / 0.88 / 1.10 |
|
||
| 물빼기 구멍 간격·지름 | 사용자에게 물음 | **품셈 13-4-4 [주]④⑤⑦** — 2~3㎡ 마다 Ø3~6㎝ · 모르터 0.009 |
|
||
| 돌쌓기 **전면 기울기** | 사용자에게 물음 | **품셈 13-4-4 「표준경사」 표** — 직고×메찰×성절토 20칸 |
|
||
| 돌쌓기 **뒷길이** 규격 | 우리 표 네 칸이 전부 | **품셈 13-4-4 「뒷길이 표준」 표** — 일곱 규격, 높이별 |
|
||
|
||
**⇒ 「이건 관측값밖에 없다」·「이건 사용자가 정할 값이다」로 넘어가기 전에 품셈 원문
|
||
본문(표가 아니라 **표 앞뒤 [주]·안내 줄**)을 먼저 볼 것.** 밑수도 같은 자리였다 —
|
||
표 안이 아니라 표 바로 위 본문에 있었다.
|
||
|
||
**⇒ 「지식DB 전수 확인: 없음」은 원문까지 안 보면 절반만 본 것이다** (2026-09-08 넷으로 굳음).
|
||
지식DB 는 **요약·후보 가이드**라 원문의 [주]·부속 표가 옮겨지지 않은 자리가 많다.
|
||
**조사 보고에 「원문 어디까지 봤나」를 함께 적을 것** — 파일명·줄번호가 없으면 「안 본 것」으로 친다.
|
||
|
||
**⇒ 원문에 표가 있으면 물음이 「값」에서 「축」으로 바뀐다.** 전면 기울기가 그랬다 —
|
||
높이·메찰·성절토를 우리가 이미 아니까 **값은 자동으로 정해지고**, 남은 물음은
|
||
「품셈 축(높이·성절토)과 교본 축(시설 종류) 중 어느 쪽이냐」 하나였다.
|
||
|
||
**⇒ 판정할 수 있는 것을 사람에게 물으면 그것이 곧 미결이 된다.** 물음 목록이 길어질수록
|
||
사용자가 답할 수 있는 물음이 묻힌다. 실제로 「철근 갈래 전체」를 물으려던 것이 원문 확인 뒤
|
||
**「캔틸레버식 옹벽 하나」로 좁아졌다.**
|
||
|
||
#### ㉪ ⚠ 계약이 바뀌면 시험부터 의심할 것 — 이틀에 **열두 번**
|
||
|
||
**2026-09-08 네 번** (덧곱 · 구조물 한 줄 · 사방공 이름 · 뒷길이 접기)
|
||
**2026-09-09 여덟 번** — 사용자 확정을 붙일 때마다 **옛 시험이 옛 계약을 지키고 있었음**:
|
||
```
|
||
버림 콘크리트 「없음」을 못 박은 둘 (구조물 한 줄 · 큰돌쌓기 성분 집합)
|
||
층따기 「막힌다」를 못 박은 둘
|
||
기울기 「늘 1:0.3」을 못 박은 셋 (실무 시트 대조 시험 포함)
|
||
stone_supply 기본값을 「근거 없음」으로 잡은 둘 ← 근거를 적어 예외로 뺌
|
||
```
|
||
⇒ **사용자 확정이 오면 「어느 시험이 옛 계약을 지키고 있나」를 먼저 찾을 것.**
|
||
⚠ **검사를 눅이지 말 것** — 근거를 문장으로 적어 **예외로 빼는 것**과, 검사 자체를 약하게 만드는 것은 다름.
|
||
|
||
**옛 시험이 틀린 계약을 못 박고 지키고 있던 자리.** 실물:
|
||
```python
|
||
def test_표에_없는_뒷길이는_덮는_칸으로_접을것():
|
||
assert _back_length({"back_len_cm": "25"}) == 35
|
||
assert _back_length({"back_len_cm": "75"}) == 60
|
||
```
|
||
**「접는 것」이 옳다고 시험이 지키고 있었음.** 그런데 **접을 까닭이 아예 없었음** — 품셈이
|
||
일곱 규격(25·30·35·45·55·60·75)을 다 주는데 **우리 표가 네 칸만 들고 있었을 뿐**임
|
||
(실무 라이브러리가 네 칸만 옮겨 적은 것을 그대로 받았음).
|
||
|
||
⇒ **시험이 있다는 것이 「맞다」는 뜻이 아님.** 값이 나오면 아무 시험도 안 잡음(㉣ 과 한 벌).
|
||
|
||
**곁들여 같은 자리에서 나온 것 둘**
|
||
- ⚠ **원문이 「-」인 칸에 0 줄을 만들지 말 것** — 25㎝ 고임돌이 **0.0 으로 서고 있었음**.
|
||
**0 은 「없음」과 구별이 안 되고** 받는 쪽이 「값이 0 인 자재」로 읽음. 줄을 빼고 사유를 낼 것.
|
||
- ⚠ **고른 갈래의 빈 칸은 빈 칸으로 덮을 것** — `None` 이라고 안 덮었더니
|
||
**「야면석 75㎝」에 종전 값(깬돌 0.25)이 조용히 섰음.**
|
||
|
||
#### ㉦ ⚠ 저장 제원의 키 이름과 엔진이 읽는 키 이름을 대조할 것
|
||
|
||
레지스트리는 `back_len_cm` 인데 엔진이 `stone_back_length_cm` 을 읽고 있어 **저장값이
|
||
영영 안 닿고 늘 기본 45㎝ 로 돌았다.** 사용자가 뒷길이 75 를 골라도 45 계수가 붙었다.
|
||
|
||
**⇒ 오늘 잡은 「조용히 틀린 값」 가운데 사용자가 고른 값이 직접 버려진 첫 사례다.**
|
||
앞의 것들은 우리가 원문을 잘못 읽은 것이었는데 이건 **사용자 입력이 무시된** 것이라
|
||
성격이 더 나쁘다.
|
||
|
||
**⇒ 「이름으로 알아보는 코드는 정본과 대조하라」(㉢)의 데이터 키 판이다.** 대조를 시험으로
|
||
둔다(`test_b08_option_keys.py`). **「칸이 아예 없는 것」과 「이름이 어긋난 것」은 다른 것**이라
|
||
가려 적는다 — 앞은 「칸이 생기면 받는다」이고 뒤는 **버그**다.
|
||
|
||
#### ㉥ 폴더 튐은 「내 것이 없어진 것처럼 보이는」 착시까지 만든다
|
||
|
||
2026-09-07 두 창이 한 저장소에서 일하며 **폴더 튐이 네 번** 났다. 그중 하나는 상대 창이
|
||
**남의 폴더 파일을 읽으며 「내 코드가 사라졌다」**고 판단한 것이었고, 자기 폴더에서는 멀쩡했다.
|
||
|
||
**⇒ 「내 변경이 사라졌다」고 느끼는 순간 먼저 현재 폴더부터 확인할 것.** 그 상태에서
|
||
「복구」에 손대면 **없어지지 않은 것을 되살리려다 멀쩡한 것을 덮는** 진짜 사고가 된다.
|
||
**⇒ push 전에 `git status` 로 남의 파일이 섞였는지 볼 것**(OWNERS 규칙 2). 남의 파일이
|
||
보이면 **경로를 지정해 커밋**하고 자동 스크립트를 쓰지 말 것 — 폴백이 주워 담는다.
|
||
|
||
#### ㉣ 「값이 있기는 하니 안 보이는」 것이 가장 위험하다
|
||
|
||
씨앗뿜어붙이기 합계 68.8원 · 측구터파기가 인력 10 % 몫만 · 운반 표가 [확정] 뒤 0줄 ·
|
||
부분 성공한 표가 엉뚱한 직종에 붙음. **부분 성공이 완전 실패보다 위험하다** —
|
||
실패는 눈에 띄고 부분 성공은 안 띈다.
|
||
|
||
**⇒ 「0 이 아님」이 아니라 「크기가 말이 되나」로 잴 것.**
|
||
|
||
**⚠ 그 반대 짝도 있다 — 「값이 맞는데 이상해 보이는」 경우.** 반영률이 전부 100 % 라
|
||
성토면다짐과 층따기가 같은 수로 나온 것을 「곱하기가 빠졌다」로 오진한 일이 있었다
|
||
(두 계열이 같은 사면 면적에서 나오므로 원래 같다).
|
||
**⇒ 「두 값이 같다」를 만나면 코드보다 설정·입력을 먼저 읽을 것.**
|
||
|
||
#### ㉧ 양쪽 근거가 다 있으면 **한쪽으로 몰아 보고하지 말 것** (2026-09-08)
|
||
|
||
교차검토에서 「제잡비 3% 의 밑수에 굴착기 조종원 노임이 들어가는가」가 나왔음.
|
||
산림품셈 13-6-2 [주]③ 은 「**노무비의 합계액**」이라고만 하고 그게 무엇인지 정의를 안 함.
|
||
근거가 양쪽에 다 있었음 —
|
||
|
||
| 쪽 | 근거 |
|
||
|---|---|
|
||
| 사람 품만 | 건설품셈 제8장이 같은 「제잡비율」을 **「직접노무비」로 못 박음**. 기계를 밑수에 넣을 때는 **「노무비, 기계손료 및 운전경비의 합」이라 따로 적음** |
|
||
| 노무비 계정 전체 | 우리 원가 체계에서 「노무비」와 「직접노무비」는 **다른 말**이고, 중기 운전사 노임도 같은 노임표에서 옴 |
|
||
|
||
한쪽만 실어 보냈으면 받는 창이 그대로 받았을 것임. **양쪽을 나란히 놓자 조율 창이
|
||
자기 앞 판정을 뒤집었음**(「사람 품만」으로 확정, 미결 ㉮ 로도 올림).
|
||
|
||
**⇒ 판단은 받는 쪽이 함. 반대 근거가 없으면 판단 자체가 안 됨.**
|
||
**⇒ 문구가 갈리는 자리는 「같은 규정이 다른 데서는 어떻게 쓰였나」를 볼 것** — 이 건은
|
||
**「넣을 땐 넣는다고 쓴다」**가 갈랐음.
|
||
**⇒ 그리고 그 조항이 무엇을 사는 값인지 읽을 것** — 제잡비는 「콘크리트 버켓 손료·다짐기계
|
||
손료」, 즉 **본 자원에 안 선 잔 기계**임. 그 표에 굴착기는 이미 본 자원으로 서 있으므로
|
||
잔 기계를 **그 굴착기 조종원 노임에 비례**시키는 것은 뜻이 어긋남.
|
||
|
||
**⚠ 이 자리는 어떤 시험도 안 잡았음** — 값이 나오고 자원 넷이 원문과 정확히 맞았음.
|
||
**손대조로 차액을 역산**해서야 밑수가 드러났음(㉣ 「크기가 말이 되나」의 한 단 아래).
|
||
|
||
**⇒ 그리고 「없다」를 확정하기 전에 「어디에 없나」를 볼 것** (2026-09-08 ㉗).
|
||
품셈에 없다는 것이 **답이 없다는 뜻은 아님.** 같은 날 둘이 그랬음 —
|
||
**지장목제거**는 품셈에 공종이 없을 뿐 **수량은 법령이 요구하고 실무가 같은 산식으로 세고 있었음**,
|
||
**입목 본수**는 조사값이 아니라 **우리 저장소가 재료(원본 LAS·다중 리턴)를 이미 갖고 있었음**.
|
||
**⇒ 찾을 자리는 셋임 — 품셈 · 다른 문서(법령·교본·실무) · 우리가 이미 가진 것.**
|
||
|
||
**⇒ 값이 움직였는데 코드 diff 에 없으면 **남의 창을 먼저 볼 것** (2026-09-08).
|
||
**DB 는 원격 공용 서버 한 대**(`dsm.chemifactory.com`)라 네 환경이 같은 자료를 쓴다.
|
||
어느 창이든 [확정]·[저장]을 부르면 나머지 셋의 값이 그 자리에서 바뀐다 — 코드를 하나도
|
||
안 건드려도 바뀐다. 실제로 성토가 +1.14 % 움직였고 원인은 랩탑의 실화면 검증이었다.
|
||
⚠ `cross_sections` 표에 **시각 칸이 없어** 언제·누가 바꿨는지 DB 로는 못 짚는다.
|
||
짚는 순서는 ① 커밋 diff 로 코드 배제 ② 서버 로그로 내 창 배제 ③ DB 재계산으로 「후」 값 확인
|
||
④ 파일 mtime 으로 시각 잡기. **되받기 전후로 `tmp/snapshot_b08.py` 를 떠 두면 대조가 된다.**
|
||
|
||
#### ㉩ ⚠ md 에 없으면 원본(pdf·xlsx)을 열어 볼 것 (2026-09-08)
|
||
|
||
**변환본이 원본을 못 따라가는 자리가 있음.** 「돌쌓기 표준도 그림이 저장소에 없다」고 판단해
|
||
원본 확보를 요청하려 했는데, **PDF 원본(173쪽)이 이미 저장소에 있었음.** md 로 옮길 때
|
||
**그림 폴더를 안 받아 둔 것**이었고, PDF 에서 그대로 뽑아 넣으니 끝났음.
|
||
|
||
- 오늘 같은 계열이 셋임 — **표가 코드를 못 따라감**(8-25 화면 칸이 낡음) ·
|
||
**내 출력이 실물을 못 따라감**(옵션 넷만 골라 찍고 「빠졌다」로 오해) ·
|
||
**변환본이 원본을 못 따라감**(이번).
|
||
- ⇒ **「없다」를 말하기 전에 원본 형식(pdf·xlsx·las)을 한 번 볼 것.** 특히 **그림·서식·병합셀**은
|
||
텍스트 변환에서 빠지기 쉬움.
|
||
|
||
#### ㉨ ⚠ 「사유」 칸에는 왜 막혔나만 — 설명은 비고로 (2026-09-08, 하루에 **세 번**)
|
||
|
||
**받는 쪽은 사유 칸을 「상태」로 읽는다.** 설명을 거기 적으면 그 줄이 통째로 막힌 것이 된다.
|
||
|
||
- **겹침 설명을 `blocked_reason` 에 넣었더니** B09 가 「막힌 줄」로 읽어 금액을 안 붙였음.
|
||
- **`blocked_kind: None`** — 「다른 표에서 이미 섬」은 막힌 것이 아니라 **여기서 세면 안 되는 줄**임.
|
||
막힘으로 보내면 받는 쪽이 「만들어야 할 것」에 얹어 **결국 이중계상으로 감.**
|
||
- **사유를 뭉뚱그리면 할 일이 갈리지 않음** — 「일위대가 없음」 하나로는
|
||
「아직 안 만든 것」과 「성분이 빠져 못 세운 것」이 구분되지 않음. 앞엣것은 우리가 만들면 되고
|
||
뒤엣것은 **참조 대상을 이어야** 풀림. 사유를 갈라 적으니 다음 일감이 바로 보였음.
|
||
|
||
**⇒ 사유 칸은 「왜 막혔나」만. 설명·계산 경위는 비고로. 그리고 사유를 갈라 적을 것.**
|
||
|
||
#### ㉫ ⚠⚠ **법이 두 동작을 묶은 자리 — 앞 동작만 세고 있지 않은지** (2026-09-09, 하루에 **두 번**)
|
||
|
||
**막힘 목록에도 없고 어떤 검사에도 안 걸리는 자리임.** 줄이 서 있고 값도 맞으니
|
||
**「없는 줄」을 아무도 못 봄.** 오늘 둘 다 별표2 원문을 읽다가 나왔음.
|
||
|
||
```
|
||
표토 별표2 「표토는 전량 **제거한 후** … 최고 홍수위보다 높은 장소로 **운반하고 쌓아두어야**」
|
||
우리 — 표토제거(9-15) 한 줄만. **운반·적치가 없었음**
|
||
|
||
뿌리 품셈 9-20 가. 「벌개·제근 → 뿌리다듬기 → **적재** → **운반**」 (시공 과정 표준)
|
||
별표2 「입목…과 **그 뿌리**, 표토는 전량 제거한 후 … 운반하고 쌓아두어야」
|
||
우리 — 「제근·뿌리다듬기」 한 줄뿐. **적재·운반이 없었음**
|
||
```
|
||
|
||
**⇒ 어떻게 찾나** — 원문에서 **동사가 둘 이상 이어진 문장**을 볼 것.
|
||
`제거한 **후** … 운반하고 쌓아두어야` · `~하고 ~하여야` · `→ 로 이어진 과정 표준`.
|
||
**앞 동작에 우리 줄이 있으면, 뒤 동작에도 줄이 있어야 함.**
|
||
|
||
**⇒ 찾은 뒤 지킬 것 셋**
|
||
- **물량을 다시 세지 말 것** — 뒤 동작의 밑수는 **앞 동작의 물량 그대로**임(표토 운반 = 표토 제거량).
|
||
다시 세면 이중계상.
|
||
- **앞이 안 서면 뒤도 안 섬** — 밑수가 그 줄이므로 함께 막히게 할 것.
|
||
- **법 문구를 사유에 실을 것** — 화면에서 **왜 이 줄을 세는지**가 보여야 함.
|
||
|
||
⚠ **품셈에 그 공종이 없을 수 있음**(뿌리 운반이 그랬음 — 10장 어디에 붙는지 원문이 안 말함).
|
||
그때도 **줄은 세우고 코드만 비울 것.** 지어내지 말고 사유로. → 아래 ㉬.
|
||
|
||
#### ㉬ ⚠ **「수량은 서는데 품셈에 공종이 없는 줄」은 한 물음임 — 모아서 한 번에 물을 것** (2026-09-09)
|
||
|
||
따로 만나면 매번 새 물음처럼 보이나 **답은 하나임.**
|
||
|
||
```
|
||
뿌리 운반 9-20 가. 가 과정으로 두었는데 붙을 공종이 10장에 없음
|
||
도수로·절토사면 배수로 「수로」 전수 검색에 셋뿐 — 그 셋에 없음
|
||
지장목제거 수량은 서는데 단가 공종이 없음
|
||
부대시설 넷 국가지점번호판·안내판·차단기·수방자재 — 개소를 넣어도 단가 없음
|
||
```
|
||
|
||
**⇒ 선례가 답을 정해 둠 — 확정 8-4** 「편책은 바자얽기(5-15)를 **빌려 쓰지 않음. 일위대가를 따로
|
||
만들어 연결**」. 즉 **품셈에 없으면 우리가 만들어 잇는다**가 사용자 방침임.
|
||
⚠ **빌려 쓸 후보가 있어도 답이 「만들라」일 수 있음** — 편책이 그랬음. **후보 유무로 미리 가르지 말 것.**
|
||
|
||
**⇒ 물을 때는 한 표로** — `공종명 | 수량은 서나 | 빌려 쓸 후보 | 없으면 새로 만들 성분`.
|
||
넷을 따로 물으면 사용자가 네 번 답해야 하고, 그 사이 창마다 다르게 처리함.
|
||
|
||
#### ㉭ ⚠⚠ **대조표를 인용하기 전에 「그것이 언제 것인지」부터 볼 것** (2026-09-09, 한 건이 **세 번** 뒤집힘)
|
||
|
||
**오늘 가장 비싼 헛걸음임.** 구조물 터파기 한 줄을 두고 조율 창·데스크탑 메인·랩탑 보조가
|
||
**세 바퀴**를 돌았고, **뿌리는 「오전에 뜬 대조표를 오후에 그대로 인용한 것」** 하나였음.
|
||
|
||
```
|
||
대조표(오전) 「우리 2.30」 = 2.0 × (0.95 + 0.2) ← 옛 두께식 · 기초 몫 없던 때
|
||
그 사이 바뀐 것 확정 ② 두께 → 뒷길이 기반 (`8141eb34`)
|
||
확정 3차 → 기초유/기초버림 축, 기초 몫 0.45·0.07 이 붙음 (`b4ae32d1`·`759343e3`)
|
||
실제(오후) H=2.0 · 두께 0.83 · 기초유 → **2.510** = 실무 정본 2.51 과 자릿수까지 같음
|
||
```
|
||
|
||
**⇒ 그 낡은 2.30 하나가 만든 잘못된 결론 셋**
|
||
```
|
||
1. 「우리가 6.6배 과다 — 955만원을 줄일까요」 ← 사용자에게 갈 뻔한 틀린 물음
|
||
2. 「기초 몫 0.45 를 빠뜨렸다」 ← 이미 들어 있었음
|
||
3. 「화면 0.5 와 수량 H 가 다른 말을 한다」 ← 셋이 같은 말을 하고 있었음
|
||
```
|
||
|
||
**⇒ 지킬 것**
|
||
- **대조표·실측표를 인용할 때 날짜와 커밋을 함께 적을 것.** 「오늘」은 날짜가 아님 — 하루에 두 번 바뀜.
|
||
- **금액이 걸린 인용은 그 자리에서 다시 재 볼 것.** 재는 데 몇 분, 헛걸음은 세 창 몇 시간.
|
||
- **표를 만들 때 머리에 「잰 시각 + 그때 커밋」을 박아 둘 것.** 표가 스스로 낡았다고 말하게.
|
||
- ⚠ **이 병은 「값이 틀린 것」이 아니라 「값이 옛것인 것」이라 어떤 검사에도 안 걸림.**
|
||
시험도 통과하고 숫자도 맞음 — **그때는** 맞았기 때문.
|
||
|
||
**⇒ 곁들여 나온 것** — 그럴듯하게 맞아떨어지는 설명이 **같은 건에서 두 번** 틀렸음
|
||
(`0.7 × 0.5 = 0.35` · 「H × 평균두께」 모양 일치). **딱 맞아떨어질수록 곱셈을 해 볼 것.** → ㉧
|
||
|
||
**⇒ 같은 집안 하나 더 — 「잘라서 인용한 자리」를 「없는 자리」로 읽지 말 것** (2026-09-09).
|
||
규준틀 사유를 **44자로 잘라** 보고하다 **「아무 표시가 없다」**로 냈음. 실제로는 그 뒤에
|
||
「재료량은 품셈 11-2 [주]④ 「설계수량에 따른다」라 미확보」가 **적혀 있었음.**
|
||
⇒ **길이를 줄여 인용할 때는 「…(잘림)」을 붙일 것.** 안 붙이면 **자기가 자른 자리를 사실로 읽음.**
|
||
⇒ 그리고 **「아무도 말 안 함」과 「이쪽만 말 안 함」은 다름** — 보내는 쪽이 이미 말하고 있을 수 있음.
|
||
|
||
#### ㉮ ⚠⚠ **시험이 「지금 동작」을 베껴 적으면 버그를 잠근다** (2026-09-09, 실물 한 건)
|
||
|
||
**제근 단가가 두 배로 서 있던 것을 시험이 「맞다」고 지키고 있었음.**
|
||
```
|
||
있던 시험 「제근은 보통인부 줄이 **둘**이다」
|
||
실제 그 둘이 곧 이중계상 — 품셈은 「0.2㎥를 쓰면 이 값 **또는** 0.7㎥를 쓰면 저 값」
|
||
⇒ 시험이 버그를 계약으로 못 박아, 고치려 하면 **시험이 먼저 막아섬**
|
||
```
|
||
|
||
**⇒ 어떻게 생기나** — 시험을 쓸 때 **원문을 안 보고 지금 출력을 베껴** 적으면 이렇게 됨.
|
||
「돌려 보니 둘이 나오네」 → 「둘이어야 한다」. 그 순간 **틀린 값이 정본이 됨.**
|
||
|
||
**⇒ 지킬 것**
|
||
- **시험의 기대값은 「돌려 본 결과」가 아니라 「원문」에서 올 것.** 기대값 옆에 **근거를 한 줄** 적을 것
|
||
(품셈 절 번호·실무 시트 셀 좌표). 근거를 못 적겠으면 **그 시험은 아직 쓰면 안 되는 것**임.
|
||
- **개수를 세는 시험**(「줄이 둘이다」·「성분이 N개다」)이 가장 위험함 — 값이 아니라 **모양**을 잠그는데
|
||
모양이 틀렸을 때 그것을 알려 줄 것이 없음.
|
||
- **뒤집을 때는 「왜 뒤집혔는지」를 그 시험 설명에 남길 것.** 안 남기면 다음 사람이 되돌림.
|
||
|
||
⚠ **㉪(계약이 바뀌면 시험부터 의심할 것)과 다른 병임.** ㉪는 **시험이 낡은 것**이고,
|
||
이것은 **시험이 처음부터 틀린 것**임. 낡은 시험은 계약이 바뀔 때 깨져서 드러나는데,
|
||
**처음부터 틀린 시험은 영영 안 깨짐** — 지키는 대상이 실제로 그렇게 돌고 있으므로.
|
||
|
||
#### ㉯ ⚠ **검산은 「어디까지 쟀는지」를 함께 적을 것** (2026-09-09)
|
||
|
||
뒤채움 두께가 품셈 범위 안에 드는지 재면서 **H 4.0m 까지만 재고 「세 자리 다 범위 안」**으로 냈음.
|
||
그물을 시험으로 옮겨 **H 6.0 까지** 늘리자 **4.0~4.5 사이에서 범위 밖으로 나감**이 바로 걸렸음.
|
||
```
|
||
우리 두께 직고에 0.30/m 로 **계속** 붙음 (확정 ② 실무 정본 식)
|
||
품셈 표 하부 두께가 **1.40m 에서 멈춤** ([주]⑨ 직고 7m 칸 상한)
|
||
⇒ 높이 축의 기울기가 다름. 어느 쪽도 상대를 틀렸다고 못 함 — **갈리는 자리를 값으로 남길 것**
|
||
```
|
||
**⇒ 「범위 안이다」는 잰 범위 안에서만 참임.** 시험 이름·주석에 **잰 구간**을 박을 것.
|
||
**⇒ 그리고 범위 검산은 등호로 바꾸지 말 것** — 밖으로 나가면 「틀림」이 아니라 **「봐야 함」**임.
|
||
우리 식이 맞을 수도 있음.
|
||
|
||
#### ㉰ ⚠⚠ **표를 읽을 때 칸을 이어 붙이면 「원문에 없는 값」이 만들어진다** (2026-09-09)
|
||
|
||
**앞 칸의 숫자 + 뒤 칸의 단위가 붙어, 원문 어디에도 없는 밑수가 섰음.**
|
||
```
|
||
품셈 13-2-4 … 0.28 | **0.36** / **㎥당** | 0.60 … ⇒ 「0.36㎥당」 (0.36 은 뒷길이 60 의 ㎡당 값)
|
||
품셈 5-19-2 15 | **30**(표토두께 ㎝) / **㎥ 당** | … ⇒ 「30㎥당」 (30 은 두께)
|
||
```
|
||
⚠ **잘못된 값이 아니라 「없는 값」임.** 그리고 **두 숫자 다 그 표 안에 실재**해서
|
||
**그럴듯함 — 어떤 검사에도 안 걸림.**
|
||
|
||
**⇒ 지킬 것**
|
||
- **표를 훑을 때 「칸 하나 안에서만」 볼 것.** 셀을 죽 이어 붙여 정규식을 걸면 이 병이 남.
|
||
「100㎥당」처럼 **한 칸에 다 든 것**만 인정.
|
||
- **밑수가 늘어난 것은 좋아진 신호가 아님** — 이 건에서 밑수 확보가 **182 → 180 으로 줄어든 것이
|
||
개선**이었음(없는 값 둘이 빠지고 넷이 「미확보」로 정직해짐). → ㉠
|
||
- **잡은 실례를 그대로 재는 시험을 남길 것.** 그래야 다음에 정규식을 넓힐 때 걸림.
|
||
|
||
⚠ **같은 날 잡은 「인」 오독과 다른 병임** — 「인」은 **잘못된 단위**(원문에 있는 글자를 잘못 읽음),
|
||
이것은 **없는 숫자**(원문에 없는 조합을 만들어 냄). **고치는 자리도 다름.**
|
||
|
||
#### ㉱ ⚠⚠ **코드 추적으로만 낸 「원인」은 자료를 재 보기 전까지 가설임** (2026-09-09, 하루를 돌아감)
|
||
|
||
계획서 3-14 에 **「원인 찾음(코드 추적)」**이라 적어 두었는데 **자료를 안 재 봤고, 재 보니 틀렸음.**
|
||
```
|
||
적어 둔 원인 「관을 나중에 놓으면 그 측점이 안 생긴다」 — 측점 생성 호출부를 따라가 낸 결론
|
||
실제 측점 440.0 · 620.0 · 720.0 · 900.0 이 **이미 있었고 구조물 이름표까지 달고 있었음**
|
||
진짜 원인 관 자리와 측점 자리가 **최대 0.5m 어긋나는 것이 설계**(정수 미터 격자로 스냅)인데
|
||
**붙이는 쪽이 0.02m 로만 봐서** 안 붙었음
|
||
```
|
||
|
||
**⇒ 그 틀린 원인이 하루 동안 판단 셋을 끌고 다녔음**
|
||
```
|
||
1. 「B06 자리」로 넘겨 B08·B09 가 손을 못 댐
|
||
2. 조율 창이 **「0.05 와 0.5 를 맞추지 말라」**고 지시 — **좁은 쪽이 스냅을 모르는 것**이 진짜 문제였음
|
||
3. [측점 만들기] 단추를 **주 해법**으로 잡음 (실제로는 0개짜리 예외 처리였음)
|
||
```
|
||
|
||
**⇒ 지킬 것**
|
||
- **「원인」이라 적을 때 어떻게 알았는지를 함께 적을 것** — `코드 추적` / `실측` / `원문`.
|
||
**추적만으로 낸 것은 「가설」이라 쓸 것.**
|
||
- **가설을 남에게 넘기기 전에 한 번 잴 것.** 이 건은 **「그 측점이 정말 없는가」를 한 번 조회**하면
|
||
끝날 일이었음.
|
||
- **남이 넘겨준 진단을 그대로 이어받아 지시하지 말 것** — 조율 창이 그 위에 지시 둘을 얹었고
|
||
**둘 다 틀렸음.**
|
||
|
||
⚠ **㉭(대조표가 낡음)과 다른 병임.** 그건 **한때 맞았던 값**이 낡은 것이고,
|
||
이것은 **처음부터 안 재 본 것**임. 낡은 값은 날짜로 걸러지지만 **안 잰 것은 걸러지지 않음.**
|
||
|
||
#### ㉲ ⚠⚠ **「막혔다」고 말하기 전에 차단 표시를 볼 것 — 화면 문구는 근거가 아님** (2026-09-09, 하루에 **두 번**)
|
||
|
||
**주의 문구를 차단으로 읽어 두 번 헛돌았음.**
|
||
```
|
||
아침 겹침 설명을 `blocked_reason` 에 넣었더니 **B09 가 「막힌 줄」로 읽어 금액을 안 붙였음**
|
||
⇒ 비고 칸으로 옮기고 막힘은 **진짜 막힐 때만** 넣게 고침
|
||
밤 「관종을 안 정해 기본값(파형강관)으로 섰습니다」를 **조율 창과 B09 창이 「막는 사유」로 읽음**
|
||
실제 `blocked_kind` 는 **공종코드를 못 찾을 때만** 섬(`if code is None`).
|
||
기본값 파형강관은 코드가 있어 **줄도 서고 금액도 섬** — 그것은 `kind_note`(주의)였음
|
||
⇒ 「칸을 만들라」는 지시가 두 창에 나갔고 **칸은 이미 있었음**
|
||
```
|
||
|
||
**⇒ 지킬 것**
|
||
- **차단 여부의 근거는 `blocked_kind` 하나임.** 사유 글자·주의 문구·「미정」이라는 말은 근거가 아님.
|
||
- **막힘을 보고할 때 `blocked_kind` 값을 함께 적을 것.** 「막혔음」만 적으면 받는 쪽이 문구를 읽음.
|
||
- **화면에서도 「주의」와 「차단」을 갈라 보일 것** — 같은 자리에 뜨면 사람도 코드도 헷갈림.
|
||
- ⚠ **남이 옮겨 준 사유 문구를 그대로 판단 근거로 쓰지 말 것.** 두 번 다 **문구를 옮긴 창과 받은 창이
|
||
함께 틀렸음.** → ㉱
|
||
|
||
⚠ **㉨(「사유」 칸에는 왜 막혔나만)의 반대쪽 얼굴임.** 그건 **쓰는 쪽** 규칙이고 이것은 **읽는 쪽** 규칙임.
|
||
사유 칸에 설명을 섞으면 읽는 쪽이 막힘으로 읽고, 읽는 쪽이 표시를 안 보면 안 막힌 것을 막혔다고 함.
|
||
|
||
#### ㉳ ⭐⭐ **예외는 「git 밖 시험 목록」이 아니라 「정본 스키마」에 적을 것** (2026-09-09)
|
||
|
||
**칸은 건너가는데 까닭은 안 건너감** — 그래서 **같은 판인데 창마다 시험 결과가 다름.**
|
||
```
|
||
정본 등록부 B05_Profile_Structure_Types.json git **안** ⇒ 다른 창에 감
|
||
정책 시험 tmp/tests/…_registry_policy.py git **밖**(CLAUDE.md 4장) ⇒ **안 감**
|
||
⇒ 칸을 열고 시험의 예외 목록에 까닭을 적으면 **칸만 건너가고 까닭은 안 건너감**
|
||
⇒ 연 창은 통과, 받은 창은 실패. **둘 다 맞는 상태인데 서로 틀렸다고 함**
|
||
```
|
||
|
||
**⇒ 고침 — 「예외」를 목록에서 스키마로 옮길 것.** 실제로 세운 두 갈래:
|
||
```
|
||
empty_means 「비워 두는 것이 뜻인 칸」 — 비면 계산 쪽이 기준값으로 돌고 그 사실이 화면에 뜸.
|
||
값을 넣으면 그 값이 이김. **까닭 한 줄을 값 옆에** 적음
|
||
default_basis 기본값이 **도메인 확정값이 아닐 때** 그 뜻(「다단 없음」·「안 더함」).
|
||
법정·확정 수치면 **비워 둠** — 비어 있는 것이 「확정값」이라는 뜻
|
||
```
|
||
⇒ 시험은 **목록을 읽지 않고 그 칸을 읽음.** 까닭이 한 낱말이면 잡는 시험도 함께 둘 것
|
||
(빈 문구로 통과하는 것을 막음).
|
||
|
||
**⇒ 규칙 한 줄 — 등록부에 칸을 열 때 예외 목록을 고치지 말고 까닭을 값 옆에 적을 것.**
|
||
|
||
⚠ **다만 구조를 고쳐도 「옮기는 일」은 남음** (2026-09-09 그날 저녁 실측).
|
||
스키마를 고치면 **그 스키마를 읽는 시험 파일도 바뀌는데**, 그 파일이 `tmp/tests`(git 밖)라
|
||
**여전히 안 건너감.** 실제로 한 창이 스키마를 고친 뒤 다른 창이 **옛 시험으로 2건 실패**했음.
|
||
```
|
||
⇒ 스키마를 고쳤으면 **그 시험 파일 내용을 메시지로 보내** 각 창이 자기 폴더에 놓을 것
|
||
⚠ 남의 폴더에 직접 쓰지 말 것 — 보내고, 받는 쪽이 놓음
|
||
⇒ 「내 창은 통과인데 저쪽은 실패」가 보이면 먼저 **시험 파일 판을 맞출 것**
|
||
```
|
||
|
||
흙깎기 장비 이름이 표에 없고 **[주]① 이 지정**
|
||
기초잡석 운반 표에 「덤프트럭(15ton)」 줄만 있고 시간이 빔 — **10-12 가 거리로 냄**(같은 15ton)
|
||
커플링밴드 표 「EA | (빈칸) | 필요시적용」 — **[주]① 「1EA/6m 이며 필요시 별도 산정」**
|
||
```
|
||
**⇒ 빈 칸을 만나면 그 표의 [주]·비고·앞뒤 절 참조를 먼저 훑을 것.** 셋 다 **표만 보면 「없음」**이었고
|
||
**[주]를 보면 있었음.**
|
||
|
||
**⇒ 사유 문구를 갈라 쓸 것 — 다음 사람이 볼 때 뜻이 아주 다름**
|
||
```
|
||
「원문에 값이 없음」 ⇒ 영영 막힌 것으로 읽힘. **지어내지 말라는 뜻**
|
||
「[주]에 있음 — 조건이 붙음」 ⇒ 조건만 정하면 서는 것
|
||
「다른 절이 냄 — 거리/규격 필요」 ⇒ 그 값이 오면 저절로 섬
|
||
```
|
||
⚠ 셋을 뭉쳐 「값 없음」으로 적으면 **사용자가 없는 것을 정하러 감.** → ㉲
|
||
|
||
⚠ **㉢(밑수 단위가 표 밖)과 같은 집안이나 다른 것임** — 그건 **단위**가 표 밖에 있는 것이고
|
||
이것은 **값 자체**가 표 밖에 있는 것임. 둘 다 「표만 읽는 코드」가 못 잡음.
|
||
|
||
#### ㉵ ⚠⚠ **`0` 과 「없음」을 같은 것으로 두지 말 것** (2026-09-09, 하루에 **세 번**)
|
||
|
||
```
|
||
표토 대상 면적이 **0 ㎡** 인데 **0 ㎥ 를 「값 있음」으로** 냄
|
||
⇒ 받는 쪽이 「표토가 없는 노선」으로 읽음. 두께 미입력은 막고 있었는데 면적 0 만 통과
|
||
사토장 구조물을 지웠는데 **설계 결과가 0.0 을 늘 실어** 횡단도·면적표에 계속 남아 있었음
|
||
⇒ 「칸이 있는 것」과 「값이 있는 것」이 달랐음
|
||
말풍선 폭을 이분법으로 찾아 남은 **0.0063㎥** 에 「⚠ 못 담음」 경고가 늘 떴음
|
||
⇒ 표시 자릿수에서 안 보이는 몫을 「남았다」고 말했음
|
||
```
|
||
|
||
**⇒ 세 가지 다 「0 이라는 값」이 거짓말을 한 것임.** 값이 없어서가 아니라 **있어서** 안 걸림.
|
||
|
||
**⇒ 지킬 것**
|
||
- **「없음」은 `None`(빈 값)으로 낼 것.** `0` 은 **「재 보니 0 이었다」**는 뜻으로만 쓸 것.
|
||
- **얹는 코드를 쓰면 지우는 길도 함께 쓸 것.** 사토장이 그 자리였음 — 얹기만 하고 안 지워
|
||
**구조물을 없앤 뒤에도 값이 남았음.** 시험은 「놓았을 때」만 보고 「지웠을 때」를 안 봤음.
|
||
- **경고는 사람이 보는 자릿수로 판정할 것.** 0.0063 처럼 화면에 안 보이는 몫을 경고하면
|
||
**경고 전체가 믿을 것이 못 됨.**
|
||
|
||
⚠ **셋 다 시험은 통과했고 화면에서 잡혔음.** 「있다」와 「돈다」의 그 자리임 — **지우는 길·빈 자료·
|
||
표시 자릿수는 시험이 잘 안 훑는 세 곳**임.
|
||
|
||
### ⚠ 좁은 폭에서 화면이 깨지면 볼 자리 셋 (2026-09-09 B03 업로드 현황에서 셋이 한꺼번에)
|
||
|
||
셋 다 **넓은 화면에서는 안 보이다가 창을 줄이면 터짐.** 다른 페이지도 같은 짜임이면 같이 깨짐.
|
||
|
||
- **`minmax(260px, 1fr)` 는 「260보다 좁아질 수 없다」는 뜻** — 컨테이너가 그보다 좁아지면
|
||
**격자가 컨테이너를 뚫음.** ⇒ `minmax(min(260px, 100%), 1fr)` 로 적을 것.
|
||
- **접는 분기가 아예 없는 2열** — `repeat(2, minmax(0,1fr))` 는 좁아져도 2열을 고집해
|
||
열마다 카드 하나도 못 담음. ⇒ `repeat(auto-fit, minmax(min(360px,100%), 1fr))`.
|
||
- **flex 자식의 `min-width: 0` 누락** — 기본값이 `auto` 라 **내용보다 안 줄어듦.**
|
||
안쪽 격자가 넘치면 **페이지 몸통이 통째로 가로로 밀림.**
|
||
|
||
**판정은 눈이 아니라 숫자로** — 폭을 여러 개(1400·1000·760·620·480) 돌며
|
||
`scrollWidth − clientWidth` 가 0 인지 볼 것. 창이 눈에 안 따라와도 **뷰포트 폭만 바꾸면
|
||
레이아웃은 다시 계산되므로 측정은 됨.**
|
||
|
||
**⚠ 같은 짜임이 다른 화면에도 있음 — 훑은 목록** (2026-09-09, 아직 안 고침)
|
||
|
||
```
|
||
㉡ 접는 분기 없는 고정 2열 — 아홉 곳 (B03 에서 깨진 것과 같은 짜임)
|
||
B01_Dashboard_UI_Style.css:22 · :134 · :166
|
||
B02_ProjRegister_UI_Style.css:18 ← 등록 폼, 사용자가 자주 봄
|
||
B05_Profile_UI_Style.css:303 · :338 · :436
|
||
B05_Profile_UI_Style_Structures.css:157
|
||
B06_Section_UI_Style.css:286
|
||
B06_Section_UI_Style_Cross_Controls.css:314
|
||
B07_DesignDetail_UI_Style.css:55 (1fr 1fr)
|
||
⚠ B05·B06 은 좌측 패널 안이라 폭이 원래 좁음 — B03 보다 먼저 깨질 수 있음
|
||
㉢ min-width:0 누락 — 62 곳. 전부가 문제는 아니고 ㉡ 와 겹치는 자리부터 볼 것
|
||
㉠ minmax(고정px) — B01_Dashboard_UI_Style.css:231 한 곳뿐(150px 라 위험 낮음)
|
||
㉣ @media 가 아예 없는 화면 — B05_* · B06_* · B08_* · B09_*
|
||
⇒ 좁은 폭 대응을 안 한 화면이 넷임
|
||
```
|
||
**고칠 순서 제안** — ① B02 등록 폼 ② B05·B06 좌측 패널 2열 ③ 나머지.
|
||
|
||
### ⚠ **`reload()` 만으로는 vite 가 옛 모듈을 물고 있을 수 있음 — 캐시부터 비울 것** (2026-09-09)
|
||
|
||
지침이 「페이지·공용 코드는 `page.reload()` 한 번(vite dev)」이라 적고 있으나 **그것으로 안 걷힌 자리**가 나왔음. **한 증상을 두고 세 창이 차례로 헛짚었음.**
|
||
```
|
||
증상 벽 터파기가 화면에 0건 (관 터파기는 뜸)
|
||
헛짚음 ① 「그리기 가드가 먹는다」 ② 「초안 경로에서만 그려진다」 ③ 「백엔드 재시작을 안 했다」
|
||
실측 백엔드 stale:false · API 상세에 revetment.foundation="기초유" **이미 옴** · 화면만 옛것
|
||
답 CDP Network.clearBrowserCache + sessionStorage.clear + reload → **바로 뜸**
|
||
```
|
||
⇒ **TS 를 고쳤는데 화면이 옛것 같으면 「캐시부터」.** `page.goto`·`reload` 만으로는 부족할 수 있음.
|
||
⚠ **브라우저 창은 재시작하지 말 것** — 캐시 비우기로 끝남(지침 4장 그대로).
|
||
|
||
### ⚠ 공용 이름을 **갈거나 지울 때는 창들에 먼저 알릴 것** (2026-09-09, 하루에 세 번)
|
||
|
||
**값을 한 벌로 두어도 이름이 바뀌면 깨진다.** 「공용 상수를 직접 읽으니 저절로 따라온다」가
|
||
**반만 맞는 말**임 — 값은 따라오고 **이름은 안 따라옴.**
|
||
```
|
||
① BLANK_DRAWINGS·BLANK_LABELS 를 걷어냄 → 남의 tmp/tests 가 수집 단계에서 터져 **267건이 통째로 멈춤**
|
||
② tmp/tests 는 git 밖 → 병합에 안 실림. **지운 쪽이 알리는 것 말고 길이 없음**
|
||
③ 두께 상수 이름 셋을 갈이 → 남의 표준도 그림이 KeyError 로 **죽음**
|
||
thickness_base_m·_top_coeff·_bottom_coeff → _top_add_m·_slope_per_m·_height_base_m
|
||
```
|
||
⇒ **새로 넣는 것은 안전함. 갈거나 지우는 것만 알리면 됨.**
|
||
⇒ 셋 다 **실화면·실행에서만** 드러났음 — 코드만 봐서는 안 잡힘.
|
||
|
||
### ⚠ **[저장]은 횡단 설계를 다시 계산하지 않음 — 새 키를 넣었으면 「재생성」을 돌릴 것** (2026-09-09)
|
||
|
||
**설계 엔진에 키를 새로 넣었는데 저장분에 안 들어오는 자리.** 하루를 「값이 0 이다」로 보냄.
|
||
```
|
||
[저장] 편집을 적용하고 Node 로 **구조물 면적·유토곡선만** 다시 냄(_recompute_stored_designs)
|
||
⇒ 저장분이 **옛 34키 그대로** — 새 키(bench_cut_length_m 등)가 안 들어감
|
||
재생성 파이썬 설계 엔진이 **전 측점을 새로 냄** ⇒ design 키가 **38개**로 늘어남
|
||
```
|
||
**세 창에 돌린 절차 (순서를 지킬 것)**
|
||
```
|
||
① git sync
|
||
② npm run build:server-calc ⚠ 번들은 git 밖 — 창마다 각자 해야 함
|
||
③ 백엔드 재시작 ⚠ @lru_cache 가 옛 등록부·config 를 물고 있음
|
||
④ B06 열고 카드가 다 뜰 때까지 기다림
|
||
⑤ POST /api/projects/{pid}/sections/{routeId}/regenerate
|
||
body {"cross_half_width_m": <지금 쓰는 반폭>}
|
||
(routeId·반폭은 GET /api/projects/{pid}/sections/context 의 route_id·defaults)
|
||
⑥ 확인: GET …/sections/{routeId}/detail → **design 키 38개**
|
||
```
|
||
⚠ **[확정]은 필요 없음** — 저장·재생성만으로 정본이 섬.
|
||
⚠ **추정치를 그대로 쓰지 말 것** — 같은 노선에서 추정 12,931㎡ → 실측 **13,699.7㎡ (+6%)** 로 갈렸음.
|
||
|
||
### ⚠ 창 크기를 바꿀 때 `page.set_viewport_size` 를 부르지 말 것 — `resize(w, h)` (2026-09-09)
|
||
|
||
**그 한 줄이 화면을 그 크기에 박아** 사용자가 창을 끌어도 안 따라옴. `Emulation.
|
||
clearDeviceMetricsOverride` 로도 안 풀림(Playwright 가 다시 걺) — **드라이버 재시작 말고는
|
||
푸는 길이 없음.** 데스크탑이 그렇게 하루를 그 상태로 보냈고, **랩탑이 멀쩡했던 것은
|
||
그 호출을 안 썼기 때문**이지 배율·인자 차이가 아니었음.
|
||
|
||
- 드라이버에 **`resize(w, h)`** 를 넣었음 — CDP `Browser.setWindowBounds` 로 **창 자체**를 바꿔
|
||
화면이 따라옴. `page.set_viewport_size` 는 이제 **막힘 문구와 함께 거부**됨.
|
||
- ⚠ **`.claude/` 는 git 밖이라 커밋으로 안 건너감** — 시놀로지 동기화에 기대거나 창마다 붙여야 함.
|
||
붙었는지는 `grep -n "def resize" .claude/browser_driver.py` 로 확인.
|
||
- **화면이 안 따라와도 폭 측정은 됨** — 뷰포트 폭만 바꾸면 레이아웃은 다시 계산되므로
|
||
`scrollWidth − clientWidth` 로 재는 검증은 그대로 유효함. 눈으로 보는 확인만 뒤로 미룰 것.
|
||
|
||
### ⚠ 브라우저 명령 파일은 **다른 이름으로 쓴 뒤 `mv` 로 넣을 것** (2026-09-09, 하루에 두 번)
|
||
|
||
`tmp/browser/cmd/` 에 파일을 **직접 쓰면 드라이버(1초 폴링)가 쓰는 도중에 집어감.**
|
||
**실행은 되고 `OK` 도 뜨는데 내용이 비어 아무 일도 안 일어남** — driver.log 에도 안 남음.
|
||
⇒ **딴 이름으로 다 쓴 다음 `mv` 로 옮길 것.** 「도는 척만 하는 검사」와 같은 계열이라 특히 나쁨(㉢).
|
||
|
||
### 공용 브라우저가 로그인 화면에서 멈췄을 때 (2026-09-08 — 두 창이 같은 자리에서 막힘)
|
||
|
||
**튕기면 서버가 아니라 쿠키를 의심할 것.** 세션은 DB 표(`sessions`)라 **서버 재시작으로 안 지워진다.**
|
||
날아가는 것은 브라우저 쿠키 쪽이다(새 프로필·만료·캐시 비우기에 함께).
|
||
쿠키는 포트를 안 가려 **8000·5173 중 한 번만 로그인하면 둘 다 붙는다.**
|
||
|
||
**되살리는 법** — 자격증명은 `tmp/aislo_cred.json`(git 밖, 사용자가 유지 — **지우지 말 것**).
|
||
없으면 **짐작하지 말고 사용자에게 요청**할 것. 명령 파일에서:
|
||
|
||
```python
|
||
import json
|
||
cred = json.load(open("tmp/aislo_cred.json", encoding="utf-8"))
|
||
api = page.context.request # ⚠ 브라우저 컨텍스트의 요청 — 쿠키를 공유한다
|
||
if api.get("http://localhost:8000/api/auth/session").status != 200:
|
||
api.post("http://localhost:8000/api/auth/login/request", data=cred)
|
||
log(api.get("http://localhost:8000/api/auth/session").status) # 200 이어야 함
|
||
```
|
||
|
||
⚠ **`page.evaluate` 안에서 `fetch` 로 하지 말 것** — 로그인 화면이 그 사이 이동해
|
||
`Execution context was destroyed` 로 죽는다(2026-09-08 두 번 겪음). `page.context.request` 는
|
||
페이지 이동과 무관하다.
|
||
|
||
⚠ `dev_up.py`·`browser_driver.py` 에 **로그인 처리가 없는 것이 맞다** — 드라이버는 창만 띄우고
|
||
로그인은 **명령 파일 몫**이다. grep 해도 안 나온다.
|
||
|
||
⚠ **`shot()` 은 확장자를 붙일 것** — `shot("이름")` 은 `unsupported mime type ""` 로 죽는다.
|
||
`page.screenshot(path="tmp/browser/shots/이름.png")` 로 쓰는 편이 안전하다.
|
||
|
||
⚠ **값을 만지기 전에 「어느 프로젝트가 열려 있나」부터 볼 것** —
|
||
`localStorage['frd_current_project_id']`. 사용자 프로젝트(`5cff3920`)면 **읽기만** 한다.
|
||
|
||
### 검증 함정 모음 — 재기 전에 볼 것 (2026-09-07 정리)
|
||
|
||
끝난 절을 `plans/` 로 옮기며, **다시 걸리면 또 오진할 것들만** 여기로 건져 왔음.
|
||
괄호는 원래 절 번호(`docs/raw/plans/2026-09-07_plan_completed_items.md` 에 원문 있음).
|
||
|
||
- ⚠ **시험을 저장소 실물에 매지 말 것 — 만든 창에서만 통과함** (2026-09-09).
|
||
`test_prj_identify.py::test_compound_vertical_prj` 가 특정 프로젝트의
|
||
`…/input/prj/result.prj` 를 **실경로로 열어** epsg 를 확인하는데, **그 프로젝트가 지워지자**
|
||
두 PC 에서 `FileNotFoundError` 로 깨졌음. `tmp/tests` 는 git 밖이지만 시놀로지로 **파일은
|
||
건너오고 저장소 자료는 창마다 다름** — 그래서 **남의 PC 에서만 깨지는 시험**이 됨.
|
||
**⇒ 실물 파일이 필요하면 없을 때 `skip` 하게 가드를 붙일 것.** 같은 파일의 다른 넷은 이미
|
||
그렇게 돼 있었고 하나만 빠져 있었음. **깨진 것을 「병합이 망가뜨렸다」로 오진하기 쉬운 자리임.**
|
||
|
||
- **옛 코드로 도는 서버에 속지 말 것** — 속도·화면을 재기 전에 ① 백엔드를 확실히 재시작하고
|
||
② **그 수정의 로그나 새 응답 항목이 실제로 있는지** 먼저 볼 것. 하루에 두 번 속았고, 한 번은
|
||
응답에 새 항목이 아예 없는데 화면은 정상처럼 보였음(다른 값으로 세는 폴백). (0-12)
|
||
- **캐드(B07) 화면은 `npm run build` + 캐시 비우기** 를 해야 바뀜 — 안 하면 옛 화면을 봄. (4-4)
|
||
- **화면이 백지가 되면 옛 vite 프로세스를 먼저 볼 것** (2026-09-07 보조 창, 하루 세 번 겪음) —
|
||
증상: 해시 이동은 되는데 `document.body` 가 빈 문자열, 콘솔에 `ERR_CONNECTION_RESET`.
|
||
원인: 백엔드를 다시 띄우면 `main.py` 가 vite 를 새로 띄우는데 **옛 vite 가 남아** 탭이 죽은
|
||
소켓을 물고 있음(실측: 5174 를 쥔 node 하나 + 유령 둘). 캐시만 비워서는 안 살아남.
|
||
되살리는 순서 — ① `Get-NetTCPConnection -LocalPort <포트>` 로 주인 확인, 유령 node 정리
|
||
② 백엔드 재시작 ③ **`about:blank` → `http://localhost:<포트>/`(wait "load") → 그다음 해시**.
|
||
해시로 곧장 가면 계속 백지였고, 루트를 먼저 거치면 살아남.
|
||
- **조정창은 두 벌이고 조작이 갈려 있음** (2026-09-07 두 창이 각각 헛짚음) — 좌측 [횡단 조정]
|
||
dock 에는 **이동 십자(▲▼◀▶)·집수정 9키가 CSS 로 숨겨져** 있고(`_Style_Cross_Controls.css:244~`),
|
||
그 십자는 **도면 위에 뜨는 오버레이 창에만** 있음. 반대로 오버레이에는 값·형식 행이 숨겨져
|
||
있음(2026-08-29 「값은 좌측, 위치제어는 도면 위」). dock 에서 ◀ 를 찾으면 DOM 에는 있는데
|
||
`vis:false` 인 것이 **정상**임 — 결함으로 오해하지 말 것.
|
||
- **요소가 보이는지는 `offsetParent` 로 재지 말 것** (2026-09-07, 두 창이 같이 걸림) —
|
||
**고정 위치(`position: fixed`) 요소는 보이든 안 보이든 `offsetParent` 가 늘 `null`** 이라
|
||
「안 보인다」로 오판함. 크기로 잴 것 — `getBoundingClientRect()` 의 width/height, 또는
|
||
`offsetWidth || offsetHeight`. 둘 다 0 이면 실제로 안 그려진 것임.
|
||
- **UI 를 붙였으면 크기도 같이 잴 것** (2026-09-07) — 알약 레인을 종단 패널에 넣고 「알약이 뜬다」만
|
||
보고 넘겼다가, 잰 높이에서 레인 몫을 안 빼 되먹임이 생겨 **패널이 16,664px 로 부풀었음**.
|
||
그 상태에서는 카드·알약을 아예 못 눌러 다음 검증이 통째로 막혔음.
|
||
- **3D 클릭을 잴 때** — `__corridorScene.project()` 좌표는 DOM 이 덮고 있는지를 안 봄.
|
||
클릭 직전에 `document.elementFromPoint(x, y) === document.querySelector('canvas')` 를 확인하거나
|
||
종단 오버레이 핸들(`.ui-workflow-overlay__handle`)을 먼저 접을 것. 이걸 몰라 두 번 오진. (2-2)
|
||
- **조정창은 셋으로 쪼개져 있음 — 「단 수」는 어느 조정창에도 없음** (2026-09-07, 3-7 에서
|
||
한참 헤맴). ① **카드 위 조정창** = 이동 십자·집수정 9키 **전용** ② 좌측 **[횡단 조정] dock**
|
||
= 높이·길이·기준측점 전/후 ③ **단 수(추가 기슭막이)와 옵션(연동·경사)** 은 둘 다 아니고
|
||
**좌측 구조물 폼의 유입구/유출구 칸**(`.b05-structure__adjust-slot`)으로 옮겨 붙음.
|
||
카드 조정창 안에도 그 행의 DOM 은 있지만 CSS 로 `display:none` 이라 눌리지 않음 —
|
||
`innerText` 로만 보면 「있는데 왜 안 눌리지」로 헤매게 됨. **크기(rect)로 볼 것.**
|
||
- **B06 조정창을 볼 때 — 두 번 걸린 함정임(3-4 · 3-7).** `.b06-structure-panel` 은 **카드마다
|
||
하나씩** 있음(66~67개). 목록에서 `find` 로 아무거나 집으면 **다른 카드의 빈 패널**이 먼저 잡혀
|
||
크기 0 · `is-hidden` 으로 나옴. 2026-09-07 에는 이것 때문에 두 창이 「십자 단추가 안 그려진다 =
|
||
사용자도 벽을 못 옮긴다」로 잘못 결론냈다가 되물렀음(고른 벽의 카드에서 재니 조정창 124×185,
|
||
이동 행 107×86 으로 멀쩡했음). **반드시 그 카드 안의 것**(`card.querySelector`)을 볼 것.
|
||
또 **벽을 안 그리는 카드**를 고르면 굳히기 루프가 0회 도니
|
||
`card.querySelector('.b06-chart__culvert-revet-hit')` 로 먼저 거를 것.
|
||
- **화면 서버(vite)는 백엔드(`main.py`)의 자식임** (`main.py → npm → vite`, `.claude/dev_up.py:40`).
|
||
백엔드를 트리째 끄면 **화면 서버도 같이 죽고** 열려 있던 탭이 옛 모듈을 붙들어 **백지**가 됨.
|
||
재시작이 비싼 진짜 까닭은 서버가 아니라 이쪽임. 조작 전에 8000·5173(또는 8001·5174) **둘 다**
|
||
200 인지 볼 것. (옛 「7. 개발 환경」에서 건져 온 것)
|
||
- **로그인 세션은 DB 표**(`sessions`, `common_util/common_util_auth.py:115`)라 재시작으로 안 지워짐.
|
||
⚠ **그래도 브라우저 쪽 세션은 끊김** — 2026-09-08 데스크탑 두 창이 같은 자리에서 막혔음.
|
||
화면 검증 전에 `#/a06-login` 으로 튀는지 먼저 볼 것. (로그인하는 절차는 랩탑 창 확인 중)
|
||
- ⚠ **화면이 막혀도 엔진은 파이썬에서 직접 부를 수 있음** — 라우터가 인계를 함수로
|
||
부르므로(`from B08_Quantity… import get_handoff`) HTTP·로그인을 안 탐.
|
||
⚠ 다만 **`await init_db_pool()` 을 먼저 부를 것** — 안 부르면 예외가 응답 본문으로 나가
|
||
**빈 응답처럼 보이고 「자료가 없다」로 잘못 읽힘**(2026-09-08 실측). 그리고 **한 이벤트
|
||
루프 안에서** 다 끝낼 것(따로 돌리면 `Event loop is closed` 가 쏟아짐).
|
||
- ⚠ **되받기 전후로 인계 응답을 파일로 떠 둘 것** — 「합계가 221원 줄었다」를 짚을 때
|
||
**어느 줄이 얼마나 바뀌었는지**를 대조할 자료가 없으면 짐작이 됨(2026-09-08).
|
||
마침 화면 로그에 옛 수량이 남아 있어 짚었으나 그건 운이었음.
|
||
⚠ 다만 「재시작하면 다시 로그인해야 했다」는 기록이 있으므로 **다른 까닭이 있을 수 있음** —
|
||
실측은 안 해 봤음.
|
||
- 🔴 **횡단 카드를 확대·이동하면 그 측점의 면적이 달라질 수 있음** (2026-09-07 3-9 뒷정리에서
|
||
발견). 확대·이동은 그 측점의 **「표시 반폭」**(`display_half_width_m`)을 바꾸고(실측 12 → 27m),
|
||
**사면이 반폭 안에서 지반을 못 만나는 측점**은 잘린 만큼 면적이 달라짐(성토 **57.45 → 62.79㎡**).
|
||
세션 `crossw` 에 남으므로 **검증하러 확대하는 것만으로 수치가 흔들림.**
|
||
· 설계상 그런 자리는 `slope_unclosed` 경고가 이미 뜨므로 **결함이라기보다 「반폭이 좁으면 면적이
|
||
잘린다」는 성질**임. 다만 검증할 때는 **확대 전 반폭을 적어 두고 끝나면 되돌릴 것.**
|
||
- **화면 요소가 보이는지 `offsetParent` 로 재지 말 것** — 고정 위치 요소는 늘 `null` 이라 늘
|
||
안 보이는 것으로 나옴. `getBoundingClientRect()` 크기로 잴 것. (3-7)
|
||
- **단계바 `.ui-workflow-layout__step` 은 0번이 대시보드** — 종단설계는 3번. (2-7)
|
||
- **살아 있는 프로젝트에 검증용 `solve_route` 를 돌리지 말 것** — `route_main.geojson` 은 프로젝트당
|
||
한 벌이라 노선 행이 늘어도 파일은 덮임(실제로 덮였고 되돌렸음). (0-10)
|
||
- **이미 만든 프로젝트는 그대로임** — 노선이 폴리라인 기준이 되려면 새로 업로드해야 함. (0-10)
|
||
- **곡선 생략(내각 155°) 규칙을 쓰지 않기로 해 곡선 개수가 늘었음**(용화 13 → 26곳) —
|
||
평면 R 을 읽는 자리(3-1 확폭 · 2-6 구조물)는 그것을 감안할 것. (0-12)
|
||
- **3-5 물량 파급을 되돌릴 자리** — `Cross_Culvert_Geom.ts` 의 `extendTrimSlope` 위 주석.
|
||
사용자가 「그대로 둠」으로 확정했으므로 근거로만 남긴 것. (3-5)
|
||
- **확폭이 수량에 실리는 것은 B08 재작업 때** — `carriageway_width_m`(= 3.0 + 확폭)을 쓰면 됨. (3-1)
|