- `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>
7.2 KiB
B07 표지 도면 템플릿 신설
원본: docs/raw/PLAN.md의 「B08 CAD 후속 › 도각(A1 템플릿)이 설계를 방해한다 › 표지 템플릿 신설」.
커밋 44fbe480 (feat/b07-cover-template, push 완료). 값 배선·서명은 다음 판으로 남아 PLAN.md에 있다.
근거 자료: 실무 설계도면 원본 1쪽
resources/knowledge/original/실무문서/25년 산불진화임도(기번8)(울진소광)/1. 설계원본/01-도면/산불임도-울진 금강송 소광리.pdf
(A3 가로 420×297mm, 18쪽). 사용자가 지목한 용화 폴더에는 PDF가 없어 이 자료로 대체했다.
표지 텍스트는 전부 아웃라인(패스)이라 extract_text() 로는 안 읽히고, pymupdf
get_drawings() 로 잉크 bbox를 mm 단위 실측했다.
실측 배치 (A3, 좌하단 원점 mm):
| 요소 | y | 잉크높이 | x | 정렬 |
|---|---|---|---|---|
| 상단 굵은 가로선 | 283.4~284.7 | 1.3 | 26.3~401.9 | 폭 375.6 |
연도·기번 (2025년 (기번8)) |
271.4~279.7 | 8.3 | 31.2~ | 좌 |
대제목 (2025년 산불진화임도사업 설계도) |
221.4~235.0 | 13.6 | ~397.0 | 우 |
− 위 치 : … |
181.3~188.5 | 7.2 | 271.0~ | 좌 |
− 사 업 량 : 0.60km |
169.6~176.5 | 6.9 | 271.0~ | 좌 |
| 발주청 로고(이미지 1개) | 34.8~55.0 | 20.2 | 299.5~320.1 | — |
시행청명 (울진국유림관리소) |
40.2~48.9 | 8.7 | ~394.7 | 우 |
| 하단 굵은 가로선 | 12.4~13.4 | 1.0 | 26.3~401.9 | 폭 375.6 |
도각이 없다 — 좌우 세로 테두리도 없고 상·하 굵은 가로선 두 줄뿐. 사용자가 고른 "도각 없는 전면 디자인"이 실무 그대로임이 확인됐다.
A1(840×594)이 A3의 정확히 2배이므로 좌표를 X = -5.05 + 2x, Y = -5.04 + 2y 로
옮긴다(오프셋은 00_template_A1.json 의 재단 표식 원점 (-5.05,-5.04)~(834.95,588.96)).
같은 종이 좌표계를 쓰므로 도각 도면과 나란히 놓인다.
설계 판단
- 굵은 가로선은
lineWidth로 못 낸다 —screenCanvas.drawController.ts:261이 캔버스context.lineWidth에 그대로 넣어 화면 픽셀이라 확대해도 안 두꺼워진다. 실치수 두께는Hatch(style:"solid") 채움 사각형으로 낸다 (B07_DesignDetail_Engine_Cad_Basin.py:186배지 원판과 같은 수법). - 그래서
frame_entities()를 재사용하지 않는다 —_transform_entity()가 다루는 좌표 키가startPoint·endPoint·basePoint·point·center뿐이라Hatch의points배열을 변환하지 못한다. 표지는 A1 실치수 고정이라 애초에 변환이 필요 없으므로, id·레이어만 찍어 내보내는 전용 함수를 쓴다. 공용 함수는 건드리지 않는다. - 발주청 로고는 넣지 않는다 — 백엔드가
Image엔티티를 만들 줄 모른다 (B07_DesignDetail/*.py에"Image"0회). 로고 자리를 비우고 시행청명을 우측정렬로 둔다. 이미지 통로는 다음 판(서명·메타 배선)에서 뚫는다. - 텍스트 세로 기준은 글자 중간이다 (
drawTextScreen이textBaseline='middle'). 실측 잉크 bbox의 중점을basePoint.y로 쓰고,fontSize는 잉크높이÷0.72 (한글 글립이 em 박스에서 차지하는 대략 비율).
체크리스트
resources/template_2dDrawing/00_template_cover.json신설 (2026-08-31). A1 실치수 표지, 엔티티 14개 — 재단 표식Point4 · 띠Hatch3 · 글자Text7. 플레이스홀더{{연도기번}}{{공사명}}{{위치}}{{사업량}}{{시행청}}. ({{연도기번}}을 한 칸으로 둔 이유:"{{연도}} ({{기번}})"로 쪼개면 기번이 비었을 때2026년 ()이 남는다. 조합은 배선 판에서 백엔드가 한다.) 생성 스크립트는tmp/build_cover_template.py— 실측값·환산식이 주석에 남아 있다.- 글자 크기는 잉크 높이가 아니라 폭으로 잡았다 (1차 시안에서 드러난 결함). 실무 원본은 장평이 좁은 CAD 글꼴이라 같은 높이에서 폭이 30%쯤 좁다. 잉크 높이를 그대로 옮기니(높이÷0.72) 우리 sans-serif 에서 위치값이 종이 밖으로 44mm 넘치고 라벨과 값이 겹쳤다. 실측 문자열 폭을 em(한글 1.0 · 숫자 0.55 · 공백 0.3)으로 나눠 되돌린 값으로 바꿨다 — 대제목 38→30, 연도기번 23→17, 개요 19→14, 시행청 24→18. 정보 블록도 왼쪽으로 옮겼다(라벨 x 536.95→464.9, 값 x 606.95→580).
- 붙임표를 U+2212(−)에서 보통 하이픈으로 바꿨다 — 글꼴에 따라 두부(□)로 깨졌다.
- 그래서 위 「설계 판단」의
fontSize = 잉크높이÷0.72는 폐기된 방침이다.
B07_DesignDetail_Engine_Cad_Cover.py신설 (2026-08-31) —build_cover_drawing(). 템플릿을 실치수 그대로 싣고 id·FRAME_LAYER_ID만 찍는다.kind:"cover"배선 (2026-08-31) —B07_DesignDetail_Schema.pyLiteral 2곳,B07_DesignDetail_Api_Fetch.ts2곳,B07_DesignDetail_UI_Page.tsDRAWING_GROUPS({ label: "표지" }→kind: "cover"),B07_DesignDetail_Router_Support.pyCOVER_ID신설 + 목록 등록 + 빌드 분기 + 확정 캐시 kind 매핑.B07_DesignDetail_Router.py는 손대지 않았다 — 표지는 원본 자료를 안 쓴다.- 자체검증 (2026-08-31, 백엔드 재시작 후 공용 브라우저).
- 단위 시험
tmp/tests/test_cover_template.py6건 통과 — 종이 840×594mm 정확, 띠 3개가solidHatch 이고 두께 0.5~3mm, 도면이 잠금b08-frame단일 레이어, 플레이스홀더 치환(값 없으면 빈칸),lru_cache템플릿 오염 없음(앞 도면 값이 다음 도면에 새지 않는다). 스위트 전체는 304 passed / 11 failed — 실패 11건 중 10건은 기존 실패(B05 구조물· B06 포장·B07 유역도 정보표, 이번 변경과 무관), 1건은 내 시험 코드 오타로 고쳤다. - API(
GET /api/projects/{id}/design-drawings): 목록에{"id":"cover","kind":"cover","label":"표지"}가 들어온다. - API(
.../design-drawings/cover):format 7, 엔티티 14 (Point 4·Hatch 3·Text 7), 레이어도각(잠금)하나, bbox[-5.05, -5.04, 834.95, 588.96]= 정확히 A1. - 화면(
906·907·909): 사이드 패널 맨 위 표지가 활성으로 뜨고, 누르면 CAD 에 엔티티 14개 전부b08-frame,Ctrl+A선택 0개(잠금 도각 규칙 준수). 스크린샷tmp/browser/shots/909_cover_final.png. - 넘침 재검산(값을 실제 문자열로 채웠을 때): 가장 긴 위치값
울진군 금강송면 소광리 산29 외이 x 580.0780.2 로 종이 한계 798.75 안, 라벨은 464.9537.8 로 값 시작(580)과 42mm 떨어진다. 제목은 344.9~789.0. 미리보기 렌더러는tmp/preview_cover.py(검증용, 배포 코드 아님).
- 단위 시험
커밋: feat/b07-cover-template · 44fbe480 (push 완료).
다음 판으로 넘긴 것 (2026-08-31 사용자 확정 순서: "표지 템플릿을 먼저 하고, 다음
서명 메타 배선으로 다음판으로 넘기자"): 값 배선(공사명·위치·사업량·시행청), 서명·직인,
B02 등록 칸 추가, 백엔드 Image/SVG 통로.