diff --git a/.env.localhost b/.env.localhost index 3b355869..3532ed1f 100644 --- a/.env.localhost +++ b/.env.localhost @@ -33,4 +33,5 @@ NEXT_PUBLIC_AWS_S3_BASE_URL="//files.hanasys.jp" S3_PROFILE="dev" #logging -NEXT_PUBLIC_ENABLE_LOGGING=false +# [debug auto-capture 2026-05-06] true 로 켜면 debugCapture 가 debug/*.json/*.log 로 자동 저장. +NEXT_PUBLIC_ENABLE_LOGGING=true diff --git a/.gitignore b/.gitignore index a235b0ff..317a0dab 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,9 @@ npm-debug.log* yarn-debug.log* yarn-error.log* +# [debug auto-capture 2026-05-06] debugCapture 산출물 / dev 서버 stdout +debug/ +dev.log # local env files .env*.local diff --git a/package.json b/package.json index 676d8f4f..1f96d08c 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,9 @@ "private": true, "scripts": { "dev": "env-cmd -f .env.localhost next dev", + "dev:log": "env-cmd -f .env.localhost next dev 2>&1 | tee dev.log", + "dev:local-api": "NEXT_PUBLIC_API_SERVER_PATH=http://localhost:8080 env-cmd --no-override -f .env.localhost next dev", + "dev:log:local-api": "NEXT_PUBLIC_API_SERVER_PATH=http://localhost:8080 env-cmd --no-override -f .env.localhost next dev 2>&1 | tee dev.log", "local:dev": "env-cmd -f .env.local.dev next dev", "build": "env-cmd -f .env.production next build", "build:dev": "env-cmd -f .env.development next build", diff --git a/src/util/skeleton-utils.js b/src/util/skeleton-utils.js index 7ade81e8..5a3e89d1 100644 --- a/src/util/skeleton-utils.js +++ b/src/util/skeleton-utils.js @@ -3464,19 +3464,27 @@ export function ensureCounterClockwiseLines(lines) { if (!lines || lines.length < 3) return [...(lines || [])]; // 1. 모든 점을 연결 그래프로 구성 + // [graph drift fix 2026-05-06] + // 좌표 0.1 단위 round 로 부동소수점 drift 흡수 (caller `_keyOfEdge` 정책과 통일). + // raw 좌표 그대로 키를 만들면 drift (e.g. 100.0 vs 100.0000001) 로 같은 점이 다른 노드가 되어 + // graph 가 끊어짐 → traversal 중도 break → 결과 길이 < 입력 길이 → sortRoofLines 인덱스 어긋남 + // (간헐 발생, 사용자가 다시 그리면 정상화되던 증상의 근본 원인). + const _r = (v) => Math.round(v * 10) / 10; const graph = new Map(); // 각 점에서 연결된 점들을 저장 lines.forEach(line => { - const p1 = `${line.x1},${line.y1}`; - const p2 = `${line.x2},${line.y2}`; + const x1r = _r(line.x1), y1r = _r(line.y1); + const x2r = _r(line.x2), y2r = _r(line.y2); + const p1 = `${x1r},${y1r}`; + const p2 = `${x2r},${y2r}`; if (!graph.has(p1)) graph.set(p1, []); if (!graph.has(p2)) graph.set(p2, []); - // 양방향 연결 - graph.get(p1).push({ x: line.x2, y: line.y2, line }); - graph.get(p2).push({ x: line.x1, y: line.y1, line }); + // 양방향 연결 (이웃 좌표도 rounded — 후속 `${n.x},${n.y}` 키가 graph 키와 일치) + graph.get(p1).push({ x: x2r, y: y2r, line }); + graph.get(p2).push({ x: x1r, y: y1r, line }); }); // 2. 왼쪽 상단 점 찾기 @@ -3524,8 +3532,10 @@ export function ensureCounterClockwiseLines(lines) { }, nextPoints[0]); // 라인 추가 (방향 유지) + // [graph drift fix 2026-05-06] line.x1/y1 은 raw, next.x/y 는 rounded → 0.05 (round 절반) 임계 approx 비교. + // 정확비교 시 raw vs rounded 불일치로 isReversed 가 항상 true 가 될 위험 차단. const line = next.line; - const isReversed = (line.x1 !== next.x || line.y1 !== next.y); + const isReversed = (Math.abs(line.x1 - next.x) > 0.05 || Math.abs(line.y1 - next.y) > 0.05); result.push({ ...line,