Files

9.9 KiB
Raw Permalink Blame History

Phase 1 코드 리뷰·QA — 2026-07-29

1. 리뷰 정보

항목 내용
리뷰 대상 Phase 1 / 공통 API·인증·file/crop 기반
기준 commit 또는 working tree dd30e36323543e8f60e9983326503653e8001f12; 리뷰 시작 시 tracked diff 36개, 전체 변경 169개
리뷰 일자 2026-07-29
리뷰어 Codex
기준 문서 prd.md, api-contract.openapi.json, plan-task.md
리뷰 상태 판정 완료

2. 리뷰 목적과 범위

목적

  • AUTH-001~013, FILE-001~015, 공통 API envelope와 crop 계약을 현재 구현과 대조한다.
  • 기존 review-phase-0-1.md에서 수정 완료된 항목은 보존하고 새 회귀만 판정한다.

포함 범위

  • 코드: src/shared/api, src/shared/lib/crop-image.ts, src/shared/ui/image-crop-dialog.tsx, 인증 저장소
  • 테스트: 공통 API 인증·오류, crop 계산·Dialog
  • 문서: Phase 1 Task·Gate와 PRD 인증/file 기준
  • 수동 검증: 코드 계산과 keyboard/pointer control 정적 대조

제외 범위

  • resource별 form과 multipart serializer, 실제 모바일 pinch 기기 QA

3. 판정 기준

심각도 기준
Blocker 보안·데이터 손실 또는 핵심 흐름 불능
High 확정 요구사항·계약 위반 또는 주요 회귀
Medium 제한 조건의 기능·접근성·복구 문제
Low 비핵심 UX·문서 정합성

상태는 확정/오탐/보류/수정 완료를 사용했다.

4. 검토한 근거

문서와 코드

  • 요구사항: AUTH-005, FILE-012, PRD 10.4
  • 코드: src/shared/api/client.ts:92, src/shared/api/client.ts:102, src/shared/api/client.ts:122, src/shared/lib/crop-image.ts:67, src/shared/lib/crop-image.ts:69, src/shared/ui/image-crop-dialog.tsx:38, src/shared/ui/image-crop-dialog.tsx:154
  • 테스트: src/shared/api/__tests__/client-auth.test.ts, src/shared/lib/crop-image.test.ts, src/shared/ui/__tests__/image-crop-dialog.test.tsx

실행 환경

OS: macOS 26.0
Node: v24.12.0
npm: 11.7.0
API mode: unit stub/MSW

실행한 검증

명령 또는 검증 결과 핵심 증거
npm run test:run -- src/shared/lib/crop-image.test.ts src/shared/ui/__tests__/image-crop-dialog.test.tsx src/shared/api/__tests__/client-auth.test.ts src/shared/api/__tests__/client.test.ts 성공 4 files / 27 tests passed
node crop 계산 실패 재현 600px 원본, zoom 1.5에서 source crop 400px, output 600px, 1.5배 확대
코드 경로 대조 실패 재현 401 처리가 정상 오류 envelope parse 뒤에만 존재

5. 발견 사항 요약

ID 심각도 상태 제목 소유 Task 후속 goal
REV-P1-011 High 수정 완료 비정상 envelope·JSON인 401은 session을 제거하지 않는다 P1-T2 P1-R6
REV-P1-012 High 수정 완료 zoom crop이 선택 영역보다 큰 결과를 만들어 no-upscale을 위반한다 P1-T5 P1-R7
REV-P1-013 Medium 수정 완료 crop Dialog에 pinch/zoom 입력이 없다 P1-T5 P1-R7

6. 발견 사항 상세

REV-P1-011 — 비정상 401에서 인증 만료 처리가 누락된다

  • 심각도: High
  • 상태: 수정 완료
  • 관련 요구사항: AUTH-005
  • 관련 계약: 보호 요청의 HTTP 401
  • 소유 Task: 신규 P1-R6

관찰 내용

response.json() 실패와 envelope schema 실패는 즉시 공통 ApiError를 던진다. session clear와 login 이동은 정상 오류 envelope가 parse된 뒤의 !apiResponse.success 분기에서만 실행된다.

재현 또는 검증 절차

  1. 인증이 필요한 요청에 session을 저장한다.
  2. server가 body 없는 401, non-JSON 401 또는 malformed envelope 401을 반환하게 한다.
  3. 현재 결과는 status 401 오류만 발생하고 session clear/redirect callback은 0회다.
  4. 요구 결과는 body 형태와 무관하게 보호 요청 401에서 1회 session clear와 login 이동이다.

영향

만료·무효 token이 브라우저 session에 남고 사용자가 보호 화면에서 반복 실패할 수 있다.

권장 조치

응답 body parse 전에 HTTP status 기반 인증 만료를 공통 처리하되 동시 401 burst 1회 규칙을 유지하고 malformed/empty 401 회귀 test를 추가한다.

판정 기록

  • 2026-07-29 — 코드의 모든 401 경로를 대조해 확정.
  • 2026-07-30 — P1-R6에서 HTTP status 기반 인증 만료 처리를 body parse 전에 수행하도록 수정하고 malformed JSON, empty body, schema mismatch 401 회귀를 추가해 수정 완료로 판정.

REV-P1-012 — zoom crop 결과가 선택 원본 영역을 확대한다

  • 심각도: High
  • 상태: 수정 완료
  • 관련 요구사항: FILE-012
  • 관련 계약: resource별 noUpscale=true
  • 소유 Task: 신규 P1-R7

관찰 내용

출력 크기는 항상 zoom=1인 crop 영역으로 계산하지만 실제 source 영역은 현재 zoom으로 축소된다. 600×600 원본을 1.5배 확대하면 source는 400×400인데 output은 600×600이다.

재현 또는 검증 절차

  1. 600×600 이미지와 1:1, maxWidth 800, noUpscale 정책을 연다.
  2. zoom을 1.5로 바꾸고 적용한다.
  3. calculateCropSourceRect는 400×400, Dialog는 output 600×600을 전달한다.
  4. 요구 결과는 output이 선택 source crop의 pixel 크기를 넘지 않는 것이다.

영향

Character·Audio·Series·Community JPEG/PNG crop이 확대되어 품질이 저하되고 파일 계약을 위반한다.

권장 조치

output size 계산에 현재 zoom의 source rect를 사용하고 zoom 경계별 실제 canvas draw test를 추가한다.

판정 기록

  • 2026-07-29 — 계산 결과 scale=1.5로 확정.
  • 2026-07-30 — P1-R7에서 CropOutputSizeRequest.zoom을 반영해 zoom 1.5의 600×600 source crop output을 400×400으로 제한했고, focused/broad Vitest와 typecheck로 수정 완료 판정.

REV-P1-013 — crop Dialog가 pinch/zoom을 지원하지 않는다

  • 심각도: Medium
  • 상태: 수정 완료
  • 관련 요구사항: PRD 10.4
  • 관련 계약: 없음
  • 소유 Task: 신규 P1-R7

관찰 내용

range, 버튼/keyboard zoom과 단일 pointer drag는 있으나 두 pointer 거리 또는 gesture를 처리하는 pinch 입력 경로가 없다.

영향

tablet/mobile touch 사용자가 명시된 pinch/zoom 방식으로 crop을 조작할 수 없다.

권장 조치

기존 range/keyboard 대안을 유지한 채 두 pointer pinch를 최소 구현하고 pointer 회귀 test와 실제 touch QA 항목을 추가한다.

판정 기록

  • 2026-07-29 — pointer handler와 테스트 전체 검색에서 pinch 경로 0건으로 확정.
  • 2026-07-30 — P1-R7에서 native pointer map/ref 기반 two-pointer pinch zoom을 추가하고 pointerup/pointercancel/pointerleave cleanup을 연결했다. Dialog 회귀 test로 pinch zoom 1.5, 기존 drag/range/keyboard 경로를 확인해 수정 완료 판정.

7. 확정 항목의 plan·goal 전환

  • REV-P1-011P1-R6
  • REV-P1-012~013P1-R7

8. 리뷰 종료 판정

판정 항목 결과 근거
리뷰 범위 전체 확인 충족 API 401·crop code/test 대조
후보 항목 판정 완료 충족 3건 모두 확정
확정 항목 plan 반영 충족 P1-R6, P1-R7
보류 항목 담당·재개 조건 해당 없음 보류 없음
검증 명령과 결과 기록 충족 §4

최종 결론: 확정 항목 수정 완료.

남은 항목: 없음.

9. 수정 후 검증 기록

  • 2026-07-30 P1-R6 — RED npm run test:run -- src/shared/api/__tests__/client-auth.test.ts src/shared/api/__tests__/client.test.ts에서 malformed JSON, empty body, schema mismatch 401이 clearSession 0회로 3건 실패했다. GREEN 같은 command는 2 files / 21 tests passed. LSP diagnostics는 src/shared/api/client.ts, src/shared/api/__tests__/client-auth.test.ts 모두 오류 0건이었다. Auth/session focused regression npm run test:run -- src/features/auth/tests/auth-session.test.tsx src/features/auth/tests/login-page.test.tsx src/app/App.test.tsx src/app/App.protected-auth.test.tsx는 3 files / 24 tests passed. Broad npm run test:run -- src/features/auth src/appREV-P10-001/P10-R1의 stale fallback assertion 6건으로 실패해 기존 Phase 10 후속 범위로 유지한다.
  • 2026-07-30 P1-R7 — RED npm run test:run -- src/shared/lib/crop-image.test.ts src/shared/ui/__tests__/image-crop-dialog.test.tsx에서 zoom 1.5 output 600×600과 pinch 미지원으로 2 failed / 9 passed를 확인했다. 1차 review blocker 보강 RED는 210:297 zoom 1.8 output 236×334의 source height 1px 초과와 touch-action: none 누락으로 2 failed / 11 passed였고, tiny source 0×0 붕괴 RED는 npm run test:run -- src/shared/lib/crop-image.test.ts 1 failed / 6 passed였다. 2차 review blocker 보강 RED는 aspect 2 tiny source 1×0 붕괴로 npm run test:run -- src/shared/lib/crop-image.test.ts 1 failed / 6 passed였다. 3차 review blocker 보강 RED는 free aspect tiny source 1×2 output이 source height를 초과해 npm run test:run -- src/shared/lib/crop-image.test.ts 2 failed / 5 passed였다. GREEN focused는 2 files / 14 tests passed로 zoom 1.5 output 400×400, 210:297 zoom 1.8 output 236×333, tiny source 1×1, aspect 2 tiny source 1×1, free aspect tiny source 1×1, two-pointer pinch zoom 1.5와 preview touch-action: none을 확인했다. Broad crop regression은 23 files / 119 tests passed였다. Surface E2E npm run e2e:mock -- tests/e2e/series.spec.ts --project=chromium은 7 tests passed로 실제 브라우저의 Series 생성 crop Dialog open/apply 경로를 확인했다. npm run typecheck, npm run lint는 exit 0이고, src/shared/ui, tests/e2e LSP diagnostics는 오류 0건이었다. 실제 tablet touch 장비 QA는 수행하지 못해 릴리스 QA 항목으로 유지한다.