diff --git a/docs/PDF 도면 외벽선 자동작성 - 코드베이스 현황 분석.html b/docs/PDF 도면 외벽선 자동작성 - 코드베이스 현황 분석.html new file mode 100644 index 00000000..e0568d65 --- /dev/null +++ b/docs/PDF 도면 외벽선 자동작성 - 코드베이스 현황 분석.html @@ -0,0 +1,408 @@ + + + + + +PDF 도면 → 외벽선 자동작성 · 코드베이스 현황 분석 + + + +
+ +
+
코드베이스 현황 분석 리포트
+

PDF 도면 → 외벽선 자동작성 기능

+

배치면 초기설정 단계에서 PDF 도면을 업로드하면 AI(Gemini)가 외벽선을 추출해 캔버스에 그려주는 기능의 구현 현황

+
+ Q.CAST Front · Next.js 14 · Fabric.js 5.5.2 + branch feature/pv-btob + ● 이미 구현됨 · 현재 활성 + 분석일 2026-05-29 +
+
+ + +
+

핵심 결론 (TL;DR)

+

요청하신 “PDF 도면 업로드 → AI 분석 → 외벽선 자동 그리기” 기능은 새로 만들 필요가 없습니다. 이미 완전히 구현되어 동작 중입니다.

+

커밋 849f7a1d(2026-05-20)에서 Google Gemini 기반으로 전체 구현 → f8641079에서 일시 비활성화 → 현재 HEAD 0187b234에서 다시 활성화되어 있습니다.

+

따라서 이번 작업의 실제 성격은 “신규 개발”이 아니라 “기존 구현의 검증 · 정합성 보완 · 품질 개선”입니다. 아래에서 구현 위치, 데이터 흐름, 그리고 보강이 필요한 갭/리스크를 정리합니다.

+
+ + +

01한눈에 보기

+
+
+
AI 엔진
+
Gemini
+
gemini-3.1-pro-preview · @google/generative-ai ^0.24.1
+
+
+
진입점 (UI)
+
배치면 초기설정 모달
+
치수 입력방법 라디오에 “도면 파일 업로드” 옵션 추가
+
+
+
서버 처리
+
Next.js API Route
+
POST /api/gemini/floor-plan · 분석 후 파일 즉시 폐기
+
+
+
캔버스 반영
+
외벽선 + WALL 폴리곤
+
QLine(outerLine) + QPolygon(WALL) 생성
+
+
+
좌표 단위
+
mm → canvas
+
10mm = 1 canvas unit, 이후 화면 맞춤 스케일
+
+
+
다국어
+
ko / ja 완비
+
각 30개 pdf.import.* / ...size.pdf.*
+
+
+ + +

02구현 타임라인 (git 이력)

+ + + +

03전체 데이터 흐름 (실제 구현)

+
+
[클라이언트 · PlacementShapeSetting.jsx]
+  배치면 초기설정 모달 열기
+        │
+        ▼  "도면 파일 업로드" 라디오 선택 (INPUT_MODE.PDF)
+  파일 선택  handlePdfFileChange()       # MIME=application/pdf, ≤20MB 검증
+        │
+        ▼  [저장] 버튼 → handleSaveBtn() → analyzePdfAndApply()
+  FormData(file, unitHint=mm, pageMode, facadePages?, floorPages?)
+        │
+        ▼  POST
+[서버 · /api/gemini/floor-plan/route.js]
+  ① MIME / 20MB 재검증
+  ② GoogleAIFileManager.uploadFile()  ──→ Gemini File API 업로드
+  ③ waitForFileActive()                  # PROCESSING→ACTIVE, 60s 타임아웃
+  ④ model.generateContent()           # responseSchema 강제, temperature 0.1
+  ⑤ validateOuterline()                  # 정점 3~500개, 면적≠0 검증
+  ⑥ finally: deleteFile()             # 성공/실패 무관 Gemini 파일 폐기
+        │
+        ▼  { outerline:[{x,y}…], unit:'mm', scale, confidence, notes }
+[클라이언트 · usePdfImport.js]  applyOuterline()
+  ⑦ toCanvasUnits()        mm ÷ 10 → canvas unit
+  ⑧ 중복점 필터            인접거리 < 0.5 제거
+  ⑨ fitAndCenter()         캔버스 60% / 최대 1500 내로 스케일 + 중앙정렬
+  ⑩ ensureCounterClockwise()   CCW 정규화
+  ⑪ [기존 외벽선 존재 시]  useSwal confirm "덮어쓰시겠습니까?"
+  ⑫ clearExistingCanvasState() → setOuterLinePoints() (Recoil)
+  ⑬ drawOuterLines()       QLine(name='outerLine') 생성
+  ⑭ addPolygonByLines()    QPolygon(name=WALL) 생성
+  ⑮ canvas.renderAll()
+        │
+        ▼  roofSizeSet='1'(복시도)로 저장 → setSelectedMenu('outline')
+   외벽선 메뉴로 자동 전환 (수동 입력 흐름과 동일 지점에 합류)
+
+ + +

04구성요소별 상세

+ +

① 서버 라우트 — src/app/api/gemini/floor-plan/route.js

+ + +

② 캔버스 반영 훅 — src/hooks/pdf-import/usePdfImport.js

+ + +

③ UI 통합 — src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx

+ + +

④ 의존성 · 환경변수 · 로케일

+ + + +

05계획서 대비 실제 구현 차이

+

구현 과정에서 초기 계획(docs/…구현 계획.md)과 달라진 설계 결정들입니다. 대부분 더 나은 통합 방향으로 수렴했습니다.

+ + + + + + + + + + + + +
항목계획서실제 구현 (HEAD)평가
UI 진입점floor-plan 상단 툴바 + 신규 PDF 아이콘배치면 초기설정 모달의 치수 입력방법 라디오 옵션변경 기존 흐름과 자연스럽게 통합
업로드 모달별도 PdfImportModal.jsx (상태머신)없음 — PlacementShapeSetting에 통합변경 모달 중첩 회피
메뉴 등록menuAtompdf-import 항목미등록 (툴바 방식 폐기로 불필요)정합
페이지 지정(없음)전체/지정 + 입면도·평면도 페이지 입력추가 분석 속도·정확도 개선
config 매핑config.*.js에 GEMINI 추가미적용 — route가 process.env 직접 사용상이 아래 리스크 R3 참조
자기교차 검증turf 로 self-intersection 검출미구현 — 정점수·면적만 검증, 나머지는 프롬프트+CCW 의존미구현 리스크 R2
거대 폴리곤Douglas–Peucker 단순화 or 거부500 정점 초과 시 거부만 (단순화 없음)미구현
파일 폐기finally에서 삭제 보장동일 구현정합
+ + +

06갭 · 리스크 · 보완 권장

+

기능은 동작하지만, “외벽선을 도면 그대로 정확히” 재현하려는 목표 관점에서 다음 항목들의 검증/보완을 권장합니다.

+ +
+

R1 · 실측 치수가 캔버스에 보존되지 않을 수 있음HIGH

+

fitAndCenter()가 외벽선을 캔버스 60%(≈840 canvas unit, 약 8.4m)에 맞춰 추가 스케일링합니다. 도면이 그보다 크면 scale < 1이 곱해져 실제 치수 ↔ 캔버스 길이 정합이 깨집니다. 수동 입력 흐름은 실측/10을 그대로 좌표로 쓰므로, PDF 경로만 길이가 달라질 위험이 있습니다.

+

권장: 일반 주택(외곽 8.4m 초과 흔함) 기준으로 실측 비율을 보존하는 변환으로 재검토. 화면 맞춤이 필요하면 좌표 자체가 아니라 canvas viewport zoom/pan으로 처리하거나, 그리드 축척과 동일한 mm/unit 비율을 강제할 것.

+
+ +
+

R2 · 자기교차(self-intersection) 폴리곤 통과 가능MID

+

서버 validateOuterline()은 정점수·면적만 본다. 자기교차는 Gemini 프롬프트 지침과 CCW 정규화에만 의존한다. 꼬인 폴리곤이 들어오면 QPolygonsortedPointLessEightPoint 정렬과 충돌해 형상이 깨질 수 있다.

+

권장: 계획서대로 turf(또는 경량 segment-intersection)로 서버/클라이언트에서 자기교차 거부. SizeSetting의 0-area 가드 정신과 일관되게 처리.

+
+ +
+

R3 · 지붕면(ROOF) 자동 생성 부재 — 안내 문구와 동작 갭MID

+

로케일 …pdf.file.info는 “외벽선과 지붕형상이 함께 생성”된다고 안내하지만, usePdfImport외벽선(QLine) + WALL 폴리곤까지만 만든다. 수동 흐름의 ccwCheck → RoofShapeSetting 자동 오픈 → drawRoofPolygon 단계가 PDF 경로에선 호출되지 않아 지붕면은 수동 작성이 필요하다.

+

권장: ①요청 목표(외벽선 그리기)만 보면 충족이므로 문구를 동작에 맞게 정정하거나, ②PDF 적용 후 기존 useRoofShapeSetting 자산을 재사용해 지붕 자동화를 확장. (요청 범위 명확화 필요)

+
+ +
+

R4 · GEMINI 키의 config 우회 — 컨벤션 관점LOW

+

CLAUDE.md는 “feature code에서 env 직접 읽지 말고 src/config에서 import”를 규정한다. route는 process.env를 직접 읽는다. 다만 서버 시크릿은 클라이언트 config로 노출하면 안 되므로 서버 라우트에서의 직접 사용은 정당화 가능한 회색지대다.

+

권장: 현행 유지 가능. 일관성을 원하면 서버 전용 config 헬퍼로 묶되 클라이언트 번들 유입이 없도록 주의.

+
+ +
+

R5 · 비결정적 분석 · 검증 자동화 부재LOW

+

프로젝트에 테스트 러너가 없고(CLAUDE.md), Gemini 출력은 비결정적이다. 회귀 검증은 수동 의존. 분석 소요(최대 60s 타임아웃)에 비해 진행률 UX가 약하다.

+

권장: 좌표 변환부(toCanvasUnits/fitAndCenter/ensureCounterClockwise)는 순수 함수이므로 단위 테스트로 분리 검증 가능. 분석 중 스피너/단계 표시 추가 검토.

+
+ + +

07파일 인벤토리

+ + + + + + + + + + + +
경로구분역할 / 핵심 라인
src/app/api/gemini/floor-plan/route.js신규Gemini 분석 서버 라우트 · POST(L111) · validate(L64) · finally 폐기(L202)
src/hooks/pdf-import/usePdfImport.js신규좌표 변환·캔버스 반영 · applyOuterline(L104) · drawOuterLines(L89)
src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx수정UI 통합 · INPUT_MODE(L34) · analyzePdfAndApply(L144) · UI(L486-591)
package.json수정@google/generative-ai ^0.24.1 (L23)
.env.{development,local.dev,localhost,production}수정GEMINI_API_KEY · GEMINI_MODEL
src/locales/ko.json · ja.json수정pdf.import.* / …size.pdf.* (각 30개)
docs/PDF Gemini 평면도 분석 기능 구현 계획.md / .html문서초기 설계 문서 (2026-05-18)
+ +
+ 신규 파일 + 수정 파일 + 문서/참고 +
+ + +

08다음 단계 제안

+

“새 기능 개발”이 아니라 기존 구현의 검증·보완으로 방향을 잡는 것을 권합니다. 우선순위 순:

+ +

실제 코드 보완에 착수하기 전, 위 R1·R3는 제품 의사결정이 필요하므로 먼저 합의하는 것을 권합니다. 합의되면 brainstorming → 구현 → 검증 순으로 진행하겠습니다.

+ + + +
+ +