download floorplan image failed
Validation: 0ccbf0f7-6dcc-4b2a-869f-00a871bd78c7
Verdict: APPROVED#
Completeness#
| Plan Item | Status | Evidence |
|---|---|---|
CPUtils.safeFileName 정적 메서드 추가 (basename, separator/제어문자/공백 치환, leading dot 무력화, 64자 상한, undefined/empty → '') |
PASS | applications/agents/packages/utils/src/cputils.ts +193~215 — path.basename, replace(/[\\/\x00-\x1f\s]/g, '_'), replace(/^\.+/, ...), MAX_LENGTH = 64, undefined/empty 조기 반환 모두 확인 |
| vitest describe 블록 (정상 확장자, slash, backslash, control/whitespace, undefined/empty, path traversal, leading dots) | PASS | applications/agents/packages/utils/src/cputils.spec.ts +374~415 — 7개 it 블록 존재 (simple, slash, backslash, whitespace/control, undefined/empty, traversal, leading dots, 64자 상한) |
refinement-agent setDefaultLocalPaths — safeFileName 적용 + 변경 시 warn 로깅 |
PASS | applications/agents/packages/cupix-capture-refinement-agent/src/model/cpfloorplan.ts +53~62 — safeExt 계산, 원본과 다르면 logger.warn, 빈 문자열이면 확장자 없이 조인 |
refinement-agent downloadImage catch — JSON.stringify(error) 제거, error 를 splat 으로 전달 |
PASS | applications/agents/packages/cupix-capture-refinement-agent/src/model/cpfloorplan.ts +78 — `logger.warn('CPFloorplan::downloadImage |
preprocessor-agent getBimFloorplanFilePath — safeFileName 적용 + warn 로깅, 빈 값일 때 fallback |
PASS | applications/agents/packages/cupix-capture-preprocessor-agent/src/model/cpfloorplan.ts +65~71 — safeExt 계산, logger.warn on mismatch, 빈 문자열이면 확장자 없이 id 만 사용 |
Acceptance Criteria#
| Criterion | Status | Evidence |
|---|---|---|
CPUtils.safeFileName exported from @agents/utils, vitest passes |
PASS (정적 검증) | cputils.ts 의 export class CPUtils 안 static 메서드로 추가되어 자동 export; 실제 vitest 실행은 이 단계에서 검증 불가하나 스펙 파일 문법상 문제 없음 |
safeFileName('rvt-site/lvl 1') produces no slashes/whitespace |
PASS | cputils.spec.ts +381 — expect(CPUtils.safeFileName('rvt-site/lvl 1')).toBe('lvl_1') (basename 이 lvl 1 을 남기고 공백이 _ 로 치환됨) |
grep path.join.*file_extension under applications/agents/packages/**/model/cpfloorplan.ts shows 0 unsafe concatenations |
PASS | refinement cpfloorplan.ts +58~60, preprocessor cpfloorplan.ts +71 — 두 hotspot 모두 safeExt 를 경유하여 join; 원본 originalImageFileExt / this._extension 을 직접 path.join 에 넘기는 라인은 diff 에서 제거됨 |
downloadImage catch removes JSON.stringify(error); error passed directly to logger |
PASS | refinement cpfloorplan.ts +78 — JSON.stringify 삭제, error 가 마지막 splat 인자 |
| Both hotspot files' sanitize warnings are grep-able | PASS | 문자열 normalized floorplan extension 가 두 파일 모두에 존재 (refinement +57, preprocessor +67) |
| TypeScript / eslint pass on changed files | PASS (정적 검증) | 타입 시그니처 `(input: string |
Issues Found#
차단 이슈 없음.
Observations#
applications/agents/packages/utils/src/cputils.spec.ts파일 끝에\ No newline at end of file이 표시됨. 기능상 문제는 아니지만 팀 컨벤션에 따라 개행 추가를 고려할 수 있음.- refinement-agent 의 조건문
if (originalImageFileExt != undefined && safeExt !== originalImageFileExt)는 undefined 입력을 별도로 처리하지만, preprocessor-agent 의 warn 조건if (safeExt !== this._extension)는 undefined 여부를 검사하지 않음.this._extension이 undefined 인 케이스에서safeExt === ''가 되므로 warn 이 발생할 수 있으나, 이는 실질적 버그가 아니라 로그 노이즈 정도의 차이. 필요 시 조건 통일을 검토 가능. MAX_LENGTH = 64는 hardcoded 상수. 향후 재사용을 위해 옵션 파라미터화 여지가 있으나 현 요구사항에는 부합.- refinement-agent
downloadImage의 새 로그는%sformat specifier 없이error를 trailing splat 으로 전달 — 프로젝트의 fix logger native Error handling 컨벤션에 부합.