Files

15 KiB

Phase 0 프로젝트 기반 코드 리뷰·QA

1. 리뷰 정보

항목 내용
리뷰 대상 Phase 0 / 프로젝트 기반, 환경 설정, 기본 Gate
기준 commit 또는 working tree dd30e36323543e8f60e9983326503653e8001f12, 2026-07-31 종합 재점검 당시 사용자 변경을 포함한 current working tree
리뷰 일자 2026-07-31
리뷰어 Codex
기준 문서 prd.md, api-contract.openapi.json 2.3.0, plan-task.md
리뷰 상태 판정 완료, 회귀 수정 완료

2. 리뷰 목적과 범위

목적

  • Phase 0의 환경별 API origin, 실행 명령, 기본 품질 Gate가 현재 구현과 일치하는지 확인한다.
  • 완료 기록과 현재 working tree의 코드·테스트·문서가 같은 기준을 사용하는지 검증한다.

포함 범위

  • 코드·설정: .env*, src/shared/config, Vite·Vitest·Playwright 설정
  • 테스트: 전체 unit, mock/server Playwright Gate, typecheck, lint, build
  • 문서: PRD 공통 API 원칙, P0-*, README와 환경 가이드
  • 수동 검증: 환경 파일과 실제 요청 intercept origin 정적 대조

제외 범위

  • 외부 개발 API에 대한 실제 ADMIN 계정 로그인과 운영 데이터 검증
  • 발견 사항의 코드·테스트 수정

3. 판정 기준

심각도 기준
Blocker 보안·데이터 손실 위험, 핵심 흐름 불능, 완료 판정을 무효화하는 문제
High 확정 요구사항·API Contract 위반 또는 주요 회귀
Medium 제한된 조건의 기능·접근성·복구 문제
Low 비핵심 UX 또는 문서 정합성 문제

상태는 후보, 확정, 오탐, 보류, 수정 완료를 사용한다.

4. 검토한 근거

문서와 코드

  • 요구사항: PRD §4, §6, §13, §14
  • 계획: P0-T1~P0-GATE
  • 설정: .env.development:1, .env.production:1
  • 문서: README.md:21-22, docs/agent-guide/environment.md:3-4
  • 테스트: tests/e2e/auth.spec.ts:3, accessibility-shell.spec.ts:4, server-mode-boundary.spec.ts:4, error-mapping.spec.ts:12, comments-test-support.ts:3

실행 환경

OS: macOS 26.0 (Build 25A354)
Node: v24.12.0
npm: 11.7.0
Browser: Playwright Chromium, Mobile Chrome
환경 변수: VITE_API_MODE=mock/server, VITE_API_BASE_URL(값은 저장소 공개 설정만 대조)

실행한 검증

명령 또는 수동 검증 결과 핵심 증거
npm run typecheck 성공 exit 0
npm run lint 성공 exit 0
npm run test:run 성공 72 files, 354 tests passed
npm run build 성공 exit 0, 253 modules transformed
npm run e2e:mock 실패 201 passed, 22 skipped, 5 failed; 4개 프로젝트의 error-mapping이 과거 origin으로 요청해 500 수신
npm run e2e:mock -- tests/e2e/series.spec.ts --project=webkit --grep "desktop and tablet Series management flow remains available at 768px" 성공 1 passed; 전체 실행의 단일 timeout은 재현되지 않음
npm run e2e 실패 12 passed, 24 failed; auth·shell·server boundary가 현재 앱 origin을 intercept하지 못함
jq operation/status 집계 및 component schema $ref 차집합 검증 성공 두 명령 모두 exit 0; 25 paths, 37 operations, status 전부 implemented, 누락 schema ref 없음

OpenAPI 검증은 다음 명령으로 실행했다.

jq '[.paths[] | to_entries[] | select(.key | IN("get", "put", "post", "delete", "patch", "head", "options", "trace")) | .value] as $operations | {openapi, version: .info.version, paths: (.paths | length), operations: ($operations | length), statuses: ([$operations[]."x-implementation-status"] | unique)}' docs/20260725_AI캐릭터관리자웹/api-contract.openapi.json
jq -e '((([.. | objects | .["$ref"]? // empty | select(startswith("#/components/schemas/")) | split("/")[-1]] | unique) - (.components.schemas | keys)) | length) == 0' docs/20260725_AI캐릭터관리자웹/api-contract.openapi.json

5. 발견 사항 요약

ID 심각도 상태 제목 소유 Task 후속 goal
REV-P0-004 High 수정 완료 API origin 변경이 문서와 Playwright route에 반영되지 않아 브라우저 Gate가 실패한다 P0-R2 P0-R2

6. 발견 사항 상세

REV-P0-004 — API origin 변경이 문서와 Playwright route에 반영되지 않아 브라우저 Gate가 실패한다

  • 심각도: High
  • 상태: 수정 완료
  • 관련 요구사항: PRD §4, §6.2, §13, §14
  • 관련 계약: 모든 OpenAPI operation의 server-mode 요청 경계
  • 소유 Task: 신규 P0-R2

관찰 내용

현재 개발·운영 환경 파일은 각각 https://test-api.sodalive.net, https://api.sodalive.net을 사용한다. README, 환경 가이드와 다섯 Playwright 지원 파일은 과거 test-character-admin/character-admin origin을 사용한다. 앱 요청과 테스트 route가 서로 다른 origin을 바라보므로 mock 오류 매핑과 server auth·shell·retry 검증이 실제 요청을 가로채지 못한다.

근거

  • 코드: .env.development:1, .env.production:1
  • 테스트: tests/e2e/auth.spec.ts:3, accessibility-shell.spec.ts:4, server-mode-boundary.spec.ts:4, error-mapping.spec.ts:12, comments-test-support.ts:3
  • 문서: README.md:21-22, docs/agent-guide/environment.md:3-4
  • 자동화: mock Gate 4개 동일 error-mapping 실패, server Gate 24개 실패

재현 또는 검증 절차

  1. 현재 .env.development를 유지한다.
  2. npm run e2e:mock을 실행한다.
  3. 과거 origin 요청이 MSW handler와 일치하지 않아 기대한 401 대신 500이 반환되는 것을 확인한다.
  4. npm run e2e를 실행해 로그인·shell·server retry route가 현재 요청을 intercept해야 하지만 24개 test가 실패하는 것을 확인한다.

영향

브라우저 Gate가 제품 회귀와 무관하게 실패하고, server-mode 인증·오류 경계 및 Comments 연동을 올바른 origin에서 검증하지 못한다. README를 따르는 개발자도 잘못된 서버 주소를 사용하게 된다.

권장 조치

공개 환경 파일을 단일 기준으로 README·환경 가이드·Playwright route/probe를 동기화하고, 과거 host 검색과 mock/server focused test를 회귀 증거로 추가한다.

판정 기록

  • 2026-07-30 — 설정·문서·테스트 문자열 대조와 두 브라우저 Gate의 반복 실패로 확정.
  • 2026-07-30 — P0-R2에서 E2E API origin helper와 문서 현재값을 정렬하고 focused/full Gate 분할 검증으로 수정 완료 판정.

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

  • REV-P0-004plan-task.md 신규 P0-R2
  • goal objective: [P0-R2] API origin 단일 기준을 문서와 모든 Playwright route/probe에 동기화하고 mock/server Gate 회귀를 방지한다.

8. 리뷰 종료 판정

판정 항목 결과 근거
리뷰 범위 전체 확인 충족 설정·문서·정적·자동 Gate 확인
후보 항목 판정 완료 충족 1건 확정
확정 항목 plan 반영 충족 P0-R2 완료
보류 항목의 담당·재개 조건 기록 해당 없음 보류 없음
검증 명령과 결과 기록 충족 §4에 실제 결과 기록

최종 결론: 확정 발견 사항 수정 완료.

남은 항목: 없음.

9. 수정 후 검증 기록

  • 2026-07-30 — P0-R2 RED: npm run e2e:mock -- tests/e2e/error-mapping.spec.ts는 4 failed / 4 passed로 과거 origin unhandled 500을 재현했고, npm run e2e -- tests/e2e/server-mode-boundary.spec.ts --project=chromium은 2 failed / 2 passed로 stale route/probe 실패를 재현했다.
  • 2026-07-30 — tests/e2e/api-base-url.ts를 추가해 E2E route/probe가 .env.developmentVITE_API_BASE_URL을 읽게 하고, README와 환경 가이드를 https://test-api.sodalive.net / https://api.sodalive.net로 정렬했다.
  • 2026-07-30 — GREEN focused: npm run e2e:mock -- tests/e2e/error-mapping.spec.ts 8 passed, npm run e2e -- tests/e2e/server-mode-boundary.spec.ts --project=chromium 4 passed, npm run e2e -- tests/e2e/comments.spec.ts --project=chromium 3 passed.
  • 2026-07-30 — Gate: npm run e2e 36 passed. npm run e2e:mock 단일 실행은 900초 제한으로 188/228 진행 중 timeout됐으나, 같은 allowlist를 project별로 분할해 chromium 57 passed, webkit 49 passed / 8 skipped, mobile-chrome 52 passed / 5 skipped, mobile-safari 48 passed / 9 skipped로 전체 mock matrix를 확인했다.
  • 2026-07-30 — 정적 검증: rg -n 'test-character-admin|character-admin\.sodalive\.net' README.md docs/agent-guide tests/e2e no matches, npm run typecheck, npm run lint, npm run build 모두 exit 0, tests/e2e LSP diagnostics 오류 0건.

10. 2차 점검 결과 — 2026-07-30

  • npm ci, npm run typecheck, npm run lint, npm run build가 모두 exit 0이었다.
  • 전체 unit은 72 files / 358 tests, server allowlist E2E는 36 tests, mock Chromium matrix는 57 tests가 통과했다.
  • Phase 0 신규 발견은 없으며 REV-P0-004 수정 완료 상태가 유지된다.

11. 2026-07-31 재점검

  • 기준: commit dd30e36323543e8f60e9983326503653e8001f12, 재점검 시작 시 working tree 변경 220개. 기존 사용자 변경은 수정하지 않고 현재 tree를 검토했다.
  • 검증: npm run typecheck, npm run lint, npm run build는 exit 0, npm run test:run은 72 files / 360 tests passed, npm run e2e는 36 passed였다.
  • 계약·구성 판정: package scripts, 환경 mode 경계, build와 server allowlist에서 Phase 0 신규 결함은 확인되지 않았다. REV-P0-004는 수정 완료 상태를 유지한다.
  • 교차 Phase: 당시 Mobile Safari 간헐 실패 후보는 이후 지원 project 축소로 현재 Task에서 제외했다.
  • 신규 Task: 없음.

12. 최종 Phase별 점검 — 2026-07-31

  • 검토 범위: package scripts, TypeScript·ESLint·production build, server/mock mode 실행 경계, 현재 Playwright project 구성을 P0 Gate와 재대조했다.
  • 실행 증거: npm run typecheck, npm run lint, npm run build exit 0. server E2E는 샌드박스의 최초 listen EPERM을 제품 실패와 분리한 뒤 승인된 로컬 실행에서 18/18 통과했다.
  • 판정: 현재 지원 project인 Chromium·Mobile Chrome 기준 기반 설정과 server allowlist에서 확정 신규 발견 사항 없음.
  • 남은 위험: 실제 개발 API의 가용성·운영 배포 환경은 이 Phase 자동 검증 범위 밖이다.
  • 신규 Task: 없음.

13. 종합 재점검 — 2026-07-31

REV-P0-005 — 문서 디렉터리의 .DS_Store가 version control index에 포함됨

항목 내용
심각도 Low
상태 수정 완료
관련 요구사항·계약 Phase 0 재현 가능한 프로젝트 기반과 저장소 문서 유지보수; API 계약 영향 없음
소유 Task P0-R3
근거 git ls-files 'docs/20260725_AI캐릭터관리자웹/.DS_Store'가 해당 binary entry를 반환하고 .gitignore에는 .DS_Store 규칙이 없다.

재현 또는 검증 절차

  1. git ls-files | rg '(^|/)\.DS_Store$'를 실행한다.
  2. docs/20260725_AI캐릭터관리자웹/.DS_Store가 출력되는지 확인한다.
  3. rg -n '^\.DS_Store$' .gitignore가 no matches인지 확인한다.

영향과 권장 조치

운영체제별 binary metadata가 문서 변경에 섞여 불필요한 diff와 충돌을 만들 수 있다. 해당 entry만 제거하고 저장소 전역 ignore 규칙을 추가한다. 다른 사용자 파일이나 문서 내용은 정리하지 않는다.

판정 기록

  • 2026-07-31 — 현재 index와 ignore 규칙을 정적으로 대조해 확정.
  • 2026-07-31 — 애플리케이션 코드는 수정하지 않고 plan-task.md 신규 P0-R3로 전환.
  • 2026-07-31 — P0-R3에서 .DS_Store를 index와 working tree에서 제거하고 저장소 ignore 규칙을 추가해 수정 완료 판정.

Phase 0 결론

  • 자동 검증: npm run typecheck, npm run lint, npm run build:dev, npm run build:prod 모두 exit 0. 두 build는 기존 500kB 초과 chunk warning만 출력했다.
  • 판정: runtime·환경 mode·script의 신규 결함은 없다. Low 1건은 P0-R3에서 수정 완료됐다.
  • 남은 위험: 실제 배포 환경과 개발 API 가용성은 자동 검증 범위 밖이다.

P0-R3 수정 후 검증 — 2026-07-31

  • 무엇을: 문서 디렉터리의 .DS_Store staged entry를 제거하고 저장소 ignore 규칙을 추가했다.
  • 왜: 운영체제별 binary metadata가 문서 변경과 충돌에 섞이지 않게 하기 위해서다.
  • 검증: git ls-files | rg '(^|/)\.DS_Store$'git status --short --untracked-files=all | rg '\.DS_Store'는 no matches, rg -n '^\.DS_Store$' .gitignore7:.DS_Store, git diff --check -- .gitignore docs/20260725_AI캐릭터관리자웹은 exit 0이었다.

14. 요청 기준 재리뷰 — 2026-07-31

  • 기준: commit dd30e36323543e8f60e9983326503653e8001f12와 사용자 변경을 포함한 current working tree.
  • 검증: typecheck, lint, build:dev, build:prod exit 0, server-mode Chromium·WebKit·Mobile Chrome·Mobile Safari smoke/auth/boundary 36 passed. 두 build는 기존 500kB 초과 chunk warning만 표시했다.
  • 판정: Phase 0 runtime·환경·build 소유의 신규 기능 결함은 없다. 전체 unit 실패는 P9-R7의 mock E2E script 문서·test 정합성으로 REV-P9-008에 귀속한다.
  • 문서 교차 항목: 상단 리뷰 상태가 완료된 P0-R3와 어긋나는 문제는 REV-P10-008/P10-R7에서 과거 기록을 보존한 채 정리한다.
  • 신규 Phase 0 Task: 없음.

15. 최종 재검증 — 2026-07-31

  • 검토 범위: package script, server/mock mode, 환경 변수, 개발·운영 build와 browser project 구성을 다시 확인했다.
  • 실행 증거: npm run test:run 78 files / 394 tests, npm run e2e 36 tests, npm run e2e:mock 186 passed / 22 skipped가 통과했다. typecheck, lint, build:dev, build:prod, staged/unstaged diff check도 exit 0이었다.
  • 판정: Phase 0 소유의 확정 신규 발견 사항 없음. build의 502.94kB chunk warning은 PRD·plan에 hard limit가 없어 이번 Task로 전환하지 않는다.
  • 남은 위험: 실제 배포 환경과 개발 API 가용성은 자동 검증 범위 밖이다.
  • 신규 Phase 0 Task: 없음.

16. 2026-07-31 문서 기준 재리뷰

  • 검토 범위: package.json, Vite/Vitest/Playwright 설정, server/mock 명령, 환경 mode 경계, build 산출물과 P0·P9 Gate 기록을 PRD·plan에 대조했다.
  • 실행 증거: npm run typecheck, npm run lint, npm run build:dev, npm run build:prod exit 0, server E2E 4 projects / 36 passed. build는 기존 503.04kB chunk warning만 표시했다. 전체 unit은 79 files / 397 tests 중 5 failed / 392 passed였고, 기반 코드가 아닌 integration harness 비결정성 REV-P9-009/P9-R9로 분리했다.
  • 판정: Phase 0 runtime·실행 스크립트·환경 mode 소유의 확정 신규 발견 사항 없음. 후보·오탐·보류 0건, 신규 Phase 0 Task 없음.
  • 남은 위험: 503.04kB warning은 문서 hard limit가 없어 Task로 전환하지 않았다. 실제 배포 환경과 개발 API 가용성은 자동 범위 밖이다.