feat(roof-shape): Gemini 출력 정규화 normalizeRoofShape 추가

[작업내용] :
- raw 지붕형상 출력 → RoofShapeDescriptor(type/ridge/flows/confidence?) 정규화
- 어휘 밖 type/ridge 는 ''(매처 결측 관대), flows 는 어휘만 소문자화·중복제거
- 모두 비면 null, direction 비산출(매처 미사용)
- route.js 배선은 다음 task

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
sangwook yoo 2026-06-24 14:43:04 +09:00
parent 4ebe02186f
commit 3f8ead0a3e

View File

@ -126,3 +126,25 @@ export const matchRoofShapePattern = (descriptor) => {
return candidate.shapeNum return candidate.shapeNum
} }
// Gemini 자유 출력(raw) → 매처 strict 어휘로 정규화한 RoofShapeDescriptor | null.
// 어휘 밖 type/ridge 는 ''(매처가 결측 관대), flows 는 ROOF_FLOW 어휘만 소문자화·중복제거.
// type·ridge·flows 가 모두 비면 null. direction 은 산출하지 않는다(매처 미사용).
export const normalizeRoofShape = (raw) => {
if (!raw || typeof raw !== 'object') return null
const norm = (value) => (typeof value === 'string' ? value.trim().toLowerCase() : '')
const TYPE_VALUES = Object.values(ROOF_SHAPE_TYPE)
const RIDGE_VALUES = Object.values(ROOF_RIDGE)
const FLOW_VALUES = Object.values(ROOF_FLOW)
const type = TYPE_VALUES.includes(norm(raw.type)) ? norm(raw.type) : ''
const ridge = RIDGE_VALUES.includes(norm(raw.ridge)) ? norm(raw.ridge) : ''
const flows = Array.isArray(raw.flows) ? [...new Set(raw.flows.map(norm).filter((flow) => FLOW_VALUES.includes(flow)))] : []
if (!type && !ridge && flows.length === 0) return null
const result = { type, ridge, flows }
if (typeof raw.confidence === 'number') result.confidence = raw.confidence
return result
}