21 KiB
커뮤니티 댓글 직접 답글 구현 계획
| 문서 항목 | 내용 |
|---|---|
| 상태 | 구현 완료 |
| 작성일 | 2026-08-06 |
| 요구사항 기준 | prd.md |
| API 기준 | api-contract.md |
| 현재 Phase | Phase 1 완료 |
| 현재 활성 Goal | 없음 |
목표
활성 커뮤니티 게시글의 답글 0개 원댓글에서도 기존 답글 form을 열어 첫 답글과 여러 직접 답글을 작성할 수 있게 한다.
현재 상태
| Phase | 상태 | 완료 Task | 활성/다음 Goal | 차단 또는 남은 조건 |
|---|---|---|---|---|
| 1 | 완료 | 4/4 |
없음 | 완료 |
- Community 답글 GET·POST, form, 여러 직접 답글 조회·작성·재조회 흐름은 이미 구현돼 있다.
- 답글이 하나 이상인 Community root에는
답글 보기와 추가 작성 form이 제공된다. replyCount === 0인 활성 Community root에도답글 작성진입과 기존 답글 form이 제공된다.P1-T1구현과 test는 완료됐고,P1-R1에서 E2E fixture 검증 결함 후보를 실제 mock 실행 경로와 대조해 오탐으로 판정했다.- 최종 커밋 감사에서 위 문장의 기존 표현이 실제 완료 상태와 충돌해
CCR-REV-P1-002로 확정됐고P1-R2에서 정정했다.
범위의 포함·제외
포함
- 활성 Community root의
replyCount === 0일 때답글 작성버튼 표시 - 기존 답글 영역, form, GET·POST와 mutation 상태 재사용
- 같은 원댓글에 첫 답글과 여러 직접 답글 작성
- Community 첫 답글과 Audio·비활성·reply row 경계 회귀 test
- 기존 Comments Chromium mock E2E와 정적 검증
제외
- 새 endpoint, DTO, component, state library 또는 dependency
- form 상시 노출, reply-of-reply, payload 정책 변경
- 기존 답글 수정·삭제·pagination 리팩터링
- Audio 전용
languageCode의 Community payload 추가 - optimistic update와 답글 전체 선조회
기술적 제약
- React·TypeScript strict, Vitest·React Testing Library와 기존 Playwright 구성을 사용한다.
- api-contract.md의 기존 GET·POST만 사용한다.
CommentThread,CommentItem,CommentForm의 현재 책임 경계를 유지한다.CommentItem의 기존replyActionLabel,CommentThread.toggleReplies()와 reply state를 재사용한다.- 공통 조건 한 곳에서 Audio와 Community의 첫 답글 진입을 일치시키며 target별 분기를 추가하지 않는다.
- RED → GREEN → REFACTOR 순서와 최소 변경을 지킨다.
Phase 1. 커뮤니티 직접 답글 진입 구현·검증
Phase 결과: 관리자가 활성 Community의 답글 0개 원댓글에서 첫 답글을 작성하고 같은 원댓글에 여러 직접 답글을 추가하며, 기존 Audio·읽기 전용·2단계 경계가 유지된다.
선행조건: CCR-001~006과 기존 Community 댓글 GET·POST 계약 확정.
Phase 완료 조건: P1-T1, P1-R1, P1-R2, P1-GATE 완료와 Progress 기록.
Task 1.1 커뮤니티 첫 답글 진입
Goal 실행 P1-T1: Community의 답글 0개 원댓글에 기존 답글 영역을 여는
답글 작성 action을 추가하고 직접 답글 작성 흐름을 검증한다.
- 시작 조건: prd.md의
CCR-001~006, api-contract.md. - 완료 증거: TDD 체크박스, focused·회귀·E2E·정적 검증과 Progress 기록.
- 범위 밖: API·mock·schema 변경, 새 UI 구조, 관련 없는 Comments 리팩터링.
Files:
- Modify:
src/features/comments/components/CommentThread.tsx - Modify:
src/features/comments/tests/comment-thread.test.tsx - Modify:
tests/e2e/comments.spec.ts - Test:
src/features/comments/tests/comment-thread.test.tsx,tests/e2e/comments.spec.ts
Interfaces:
- Consumes:
CommentRecord.replyCount,canMutate,expandedRootIds,toggleReplies(),CommentForm, CommunitycreateComment()overload. - Produces: 활성 Audio·Community 원댓글에 공통 적용되는 첫 답글 action 노출 조건.
TDD 절차:
- RED: 실패 테스트 작성/실패 확인 —
comment-thread.test.tsx에 CommunityreplyCount=0root의답글 작성노출, 클릭 후 form,parentIdPOST와languageCode미전송을 검증하고npm run test:run -- src/features/comments/tests/comment-thread.test.tsx가 버튼 부재로 실패하는지 확인한다. - GREEN: 최소 구현/통과 확인 —
CommentThread.tsx의 기존 optional action label 조건에서 Audio 전용 제한만 제거하고 같은 명령이 exit 0인지 확인한다. - REFACTOR: 정리/회귀 확인 — 추가 helper·component 없이 조건을 읽기 쉬운 최소 표현으로 유지하고 focused test와
npm run test:run -- src/features/comments가 모두 exit 0인지 확인한다. - 기존 Community mock E2E에 답글 0개 root의 첫 답글 작성과 같은 root에 추가 직접 답글 작성 journey를 검증한다.
- 검증 결과를 Progress에 기록한다.
검증 기준:
- 실행 명령:
npm run test:run -- src/features/comments/tests/comment-thread.test.tsx;npm run test:run -- src/features/comments;npm run e2e:mock -- tests/e2e/comments.spec.ts --project=chromium;npm run typecheck;npm run lint. - 기대 결과: 모든 명령 exit 0, Community 첫 답글 POST 1회 이상,
parentId는 원댓글 ID, Community body의languageCode0건, reply row의 답글 action 0건, 기존 Audio·Comments 회귀 실패 0건. - 수동 확인: 활성 Community Sheet에서 답글 0개 root의
답글 작성→ form 노출 → 첫 답글 등록 → 같은 root 추가 답글 등록을 확인한다. 비활성 workspace와 reply row에는 작성 진입이 없어야 한다.
완료 조건
P1-T1의 모든 TDD·검증 체크박스가 완료됐다.CCR-001~006이 구현 또는 검증 증거에 연결됐다.- API·mock·schema와 범위 밖 파일 변경이 없다.
Task 1.R1 Community E2E fixture 검증
Goal 실행 P1-R1: CCR-REV-P1-001의 E2E fixture 분류 오류 후보가 실제
mock E2E 실행 경로에 영향을 주는지 검증하고 판정한다.
- 시작 조건:
P1-T1완료,CCR-REV-P1-001확정. - 완료 증거: 실제 mock 요청 소유권 확인, 후보를 구분하는 E2E assertion, Chromium·Comments 회귀·정적 검증과 Progress 기록.
- 범위 밖: 애플리케이션 mock handler·store, API·schema, production 댓글 동작 변경.
Files:
- Modify:
tests/e2e/comments.spec.ts - Test:
tests/e2e/comments.spec.ts
TDD 예외 사유: 리뷰 후보를 구분하는 assertion이 기존 mock E2E에서도 통과해 production 또는 fixture 수정이 필요하지 않은 오탐으로 판정됐다. 실패하는 구현 변경이 없으므로 RED → GREEN 대신 실제 요청 소유권과 기존 동작을 대체 검증했다.
- root
2102의 초기 reply region에 root 댓글이 없고, 첫·두 번째 답글이 region에 표시되며 중첩 action이 없는 assertion을 추가했다. - 기존
comments-test-support.ts를 유지한 상태에서 Chromium E2E3/3통과를 두 번 확인했다. VITE_API_MODE=mock의 Browser MSW Service Worker가 mock 요청을 처리하며page.routefixture 후보가 실제 실행 경로를 소유하지 않음을 확인했다.- fixture 변경을 폐기하고 Comments 회귀·typecheck·lint·
git diff --check를 통과했다. - 검증 결과와
CCR-REV-P1-001오탐 판정을 Progress에 기록했다.
검증 기준:
- 실행 명령:
npm run e2e:mock -- tests/e2e/comments.spec.ts --project=chromium;npm run test:run -- src/features/comments;npm run typecheck;npm run lint;git diff --check. - 기대 결과: 기존 fixture를 변경하지 않고 모든 명령 exit 0, Chromium
3/3, 첫·추가 답글이 root2102region에만 표시된다. - 수동 확인: 기존
P1-GATE의 Community 첫·추가 답글 browser QA 결과와 mock E2E의 동일 동작을 대조한다.
Task 1.R2 완료 문서 현재 상태 정합성 복구
Goal 실행 P1-R2: CCR-REV-P1-002의 미구현 문장을 실제 완료 상태로
정정하고 기존 Progress와 결정 기록을 보존한다.
- 연결 리뷰: 최종 커밋 감사 —
CCR-REV-P1-002 - 시작 조건:
CCR-REV-P1-002확정, 완료된P1-T1,P1-R1,P1-GATE. - 완료 증거: 현재 상태 문장 정정, 아래 체크박스·문서 검증 통과, review 수정 완료 기록과 Progress 누적.
- 범위 밖: 애플리케이션 코드·test·API Contract, 기존 Progress·Decision Log 삭제 또는 덮어쓰기.
Files:
- Modify:
docs/20260806_커뮤니티댓글답글/plan-task.md - Modify:
docs/20260806_커뮤니티댓글답글/reviews/phase1-final-commit-audit.md - Test: 없음 — 애플리케이션 동작을 변경하지 않는 문서 정합성 수정이다.
Interfaces:
- Consumes:
CCR-REV-P1-002,CCR-001, 완료된P1-T1·P1-GATE검증 증거. - Produces: 실제 구현과 일치하는 plan 현재 상태와 수정 완료 review 기록.
TDD 예외 사유: 애플리케이션 코드·동작을 바꾸지 않는 문서 정정이므로 실패 unit test를 추가하지 않는다.
대체 검증 방법: stale 미구현 marker 부재, 완료 상태 문장·review 상태·상호 링크 존재와 Markdown diff를 명령으로 확인한다.
replyCount === 0인 Community root의 현재 상태를 실제 구현 완료 내용으로 정정한다.CCR-REV-P1-002의 상태와 리뷰 종료 판정을수정 완료로 갱신한다.- 기존 Progress와 Decision Log를 보존하고
P1-R2기록을 누적한다. - 문서 marker·link·diff 검증 결과를 Progress와 review에 기록한다.
검증 기준:
- 실행 명령:
! sed -n '17,28p' docs/20260806_커뮤니티댓글답글/plan-task.md | rg -n '첫 답글 작성 진입만 없다';sed -n '17,28p' docs/20260806_커뮤니티댓글답글/plan-task.md | rg -n 'replyCount === 0.*답글 작성.*제공';rg -n 'CCR-REV-P1-002.*수정 완료' docs/20260806_커뮤니티댓글답글/reviews/phase1-final-commit-audit.md;test -f docs/20260806_커뮤니티댓글답글/reviews/phase1-final-commit-audit.md;git diff --check. - 기대 결과: 모든 명령 exit 0, stale 미구현 marker 0건, 완료 상태·review 수정 완료 marker와 링크 각 1건 이상, whitespace 오류 0건.
- 수동 확인: 없음 — 제품 동작을 바꾸지 않으며 문서의 정확한 marker와 link를 명령으로 판정한다.
검증 방법
Phase 1 Gate
Goal 실행 P1-GATE: 커뮤니티 첫·추가 직접 답글 journey와 Comments 공통
경계를 최종 판정한다.
- 시작 조건:
P1-T1완료. - 완료 증거: 아래 명령·수동 확인 통과와 Progress 기록.
- 범위 밖: test 완화, timeout 상향과 관련 없는 수정.
실행 명령:
npm run test:run -- src/features/comments
npm run e2e:mock -- tests/e2e/comments.spec.ts --project=chromium
npm run typecheck
npm run lint
git diff --check
기대 결과: 모든 명령 exit 0, CCR-001~006 위반 0건.
수동 확인: 활성·비활성 Community와 활성 Audio에서 action 노출 경계를 대조한다. Community Sheet를 1280px·320px와 200% zoom에서 열어 수평 overflow 없이 첫·추가 답글을 작성하고 keyboard-only로 form에 진입한다.
실행 순서와 의존성
P1-T1REDP1-T1GREENP1-T1REFACTOR·회귀P1-GATE- 최종 커밋 감사에서 확정된
CCR-REV-P1-002를P1-R2로 전환 P1-R2문서 정정·검증과 review 수정 완료 처리
- 동시에 하나의 미완료 goal만 운용한다.
- 사용자가 goal 실행을 요청하기 전에는 goal을 생성하지 않는다.
변경 금지 항목
- 기존 OpenAPI, API client, request schema, mock handler·store 변경
- 새 dependency, state library, component 또는 speculative abstraction
- 답글의 답글, optimistic update와 form 상시 노출
- Audio payload와 기존 수정·삭제·pagination 동작 변경
- 실패 test 삭제·skip, timeout 상향으로 Gate 통과
- 기존 Progress와 결정 기록 삭제·덮어쓰기
의사결정 및 중단 규칙
replyCount === 0,canMutate === true인 Audio·Community 원댓글에만답글 작성을 표시한다.replyCount > 0또는 펼친 원댓글은 기존답글 보기label을 유지한다.- reply row에는
onShowReplies를 전달하지 않으며 3단계 작성 경로를 만들지 않는다. - API 응답이나 오류가 api-contract.md와 다르면 추정 수정하지 않고 외부 의존으로 기록한다.
- 범위가 바뀌면 코드보다 PRD Decision Log와 이 계획을 먼저 갱신한다.
Progress
2026-08-06 요구사항·설계
- 무엇을: 활성 Community 원댓글의 첫 답글 진입, 여러 직접 답글과 2단계 제한을 요구사항·API 재사용 계약·단일 구현 Task로 정리했다.
- 왜: Community 답글 조회·작성 흐름은 이미 있으나
replyCount === 0이면 진입 action이 없어 첫 답글만 작성할 수 없다. - 어떻게: 선행 Audio 답글 문서, 프로젝트 OpenAPI,
CommentThread, request schema, mock handler·store, unit·E2E를 대조했다. 기존 공통 흐름을 재사용할 수 있어 새 API·컴포넌트·mock을 계획에서 제외했다. 애플리케이션 코드와 test는 변경하지 않았다.
2026-08-06 P1-T1 커뮤니티 첫 답글 진입
- 무엇을: 활성 Community의
replyCount=0원댓글에도 기존답글 작성action을 노출하고, 같은 원댓글에 첫 번째와 두 번째 직접 답글을 작성하는 단위·Chromium E2E를 추가했다. reply row의 중첩 답글 action 부재와 Community payload의languageCode미전송도 검증했다. - 왜: 기존 공통 GET·POST·form·재조회 흐름은 완성돼 있었지만 action label 조건이 Audio target만 허용해 Community 첫 답글 진입이 막혀 있었다.
- 어떻게: RED에서
npm run test:run -- src/features/comments/tests/comment-thread.test.tsx를 실행해AI 루트 댓글 답글 작성버튼 부재로1 failed, 7 passed를 확인했다. GREEN에서CommentThread.tsx의 Audio 전용 조건만 제거한 뒤 focused test8/8을 통과했다. REFACTOR·회귀로npm run test:run -- src/features/comments는15/15,npm run e2e:mock -- tests/e2e/comments.spec.ts --project=chromium은3/3,npm run typecheck와npm run lint는 exit 0이었다. API·schema·mock·dependency는 변경하지 않았다.
2026-08-06 P1-R1 E2E fixture 후보 판정
- 무엇을:
CCR-REV-P1-001이 지적한 단일replyRootIdfixture가 mock E2E의 root2102답글을 오분류하는지 검증했다. - 왜: 코드만 보면
comments-test-support.ts가 root2101만 replies로 처리하지만, 실제 mock E2E가 이 fixture를 사용하는지 확인하지 않으면 오탐 수정으로 범위를 확장할 수 있다. - 어떻게: 기존 fixture를 유지한 상태에서
2102초기 reply region에 root 댓글 0건, 첫·두 번째 답글 표시, dialog 내 각 1건, 중첩 action 0건을 추가하고 Chromium E2E3/3통과를 두 번 확인했다.playwright.config.ts의VITE_API_MODE=mock과src/shared/mocks/browser.ts의setupWorker(...)를 대조해 Browser MSW가 Service Worker에서 요청을 처리하며page.route가 해당 요청을 소유하지 않음을 확인했다. fixture 변경은 폐기했고CCR-REV-P1-001을 오탐으로 판정했다.
2026-08-06 P1-GATE Phase 1 최종 검증
- 무엇을: Community 첫·추가 직접 답글, 2단계·권한 경계, Comments 회귀와 반응형·keyboard·CJK 품질을 최종 판정했다.
- 왜: 코드와 자동 test 통과만으로는 실제 Sheet의 keyboard 진입, 320px·200% zoom, 한국어 줄바꿈과 reviewer 차단 해소를 증명할 수 없다.
- 어떻게:
npm run test:run -- src/features/comments는15/15,npm run e2e:mock -- tests/e2e/comments.spec.ts --project=chromium은3/3,npm run typecheck,npm run lint,npm run build:dev,git diff --check는 exit 0이었다. 실제 Chromium에서 첫·두 번째 답글, input 초기화, 중첩 action 0건, keyboard-only 진입과 1280px·320px·200% zoom의 수평 overflow 0건을 확인했다. 독립 goal·코드 품질·보안·컨텍스트·기능·visual/CJK 리뷰는 최종 PASS였고 Phase 1 리뷰에 근거를 기록했다.
2026-08-06 P1-R2 완료 문서 현재 상태 정합성 복구
- 무엇을:
CCR-REV-P1-002를P1-R2로 전환한 뒤replyCount === 0인 활성 Community root의 현재 상태를 실제 구현 완료 내용으로 정정하고 최종 커밋 감사 상태를 수정 완료로 갱신했다. - 왜: plan의 완료 상태·코드·test와 반대인 구현 전 문장 때문에 후속 작업자가 첫 답글 진입을 미구현으로 오인할 수 있었다.
- 어떻게: stale 현재 상태 marker 부재, 완료 상태 문장 존재, review 파일과 수정 완료 marker 존재를
rg·test -f로 확인하고 trailing whitespace 검사와git diff --check를 실행해 모두 exit 0을 확인했다. 애플리케이션 코드·test·API Contract는 변경하지 않았다.
2026-08-06 P1-R2 후 기능 회귀 감사
- 무엇을: 문서 정정 뒤 Community 첫·추가 직접 답글과 Comments 공통 회귀, 정적 품질과 development build를 다시 확인했다.
- 왜: 문서 전용 변경임을 diff로 확인하고 최종 완료 상태가 기존 기능 검증 증거와 계속 일치하는지 판정하기 위해서다.
- 어떻게:
npm run test:run -- src/features/comments는15/15, 샌드박스 밖에서 실행한npm run e2e:mock -- tests/e2e/comments.spec.ts --project=chromium은3/3,npm run typecheck,npm run lint,npm run build:dev,git diff --check는 모두 exit 0이었다. build의 기존 500kB chunk warning 외 실패는 없었다.
Decision Log
| 날짜 | 결정 | 근거 | 영향 |
|---|---|---|---|
| 2026-08-06 | Audio와 동일한 답글 작성 진입을 활성 Community 원댓글에도 적용한다. |
사용자 요청 | CCR-001~003, P1-T1 |
| 2026-08-06 | 한 원댓글에 여러 직접 답글을 허용하고 reply-of-reply는 제외한다. | 사용자 요청 | CCR-004~005, P1-T1, P1-GATE |
| 2026-08-06 | 기존 공통 UI와 Community GET·POST를 재사용하고 API·mock·schema는 변경하지 않는다. | OpenAPI와 코드 확인 | CCR-002~006, P1-T1 |
| 2026-08-06 | 구현은 공통 action 조건의 Audio 전용 제한 제거와 기존 test 보강으로 제한한다. | CommentThread 흐름 확인과 최소 변경 원칙 |
P1-T1 Files·Interfaces |
| 2026-08-06 | E2E 전용 route fixture가 특정 root만 replies로 처리하는 결함을 P1-R1에서 수정한다. |
최종 코드 품질·컨텍스트 리뷰에서 2102 답글이 roots에 저장돼 E2E가 오탐 통과함을 확인 |
CCR-REV-P1-001, P1-R1, P1-GATE |
| 2026-08-06 | 정정: CCR-REV-P1-001은 mock mode에서 Browser MSW가 요청을 소유해 E2E route fixture 분기가 실행되지 않으므로 오탐이다. fixture를 변경하지 않는다. |
기존 fixture 상태에서 2102 빈 reply·첫·추가 답글 assertion과 Chromium 3/3 통과, VITE_API_MODE=mock·setupWorker(...) 확인 |
CCR-REV-P1-001, P1-R1, P1-GATE |
| 2026-08-06 | 최종 커밋 감사에서 확정된 stale 현재 상태 문장을 문서 전용 회귀 Task로 수정한다. | CCR-REV-P1-002의 plan·코드·test 불일치 |
P1-R2 |
| 2026-08-06 | P1-R2에서 현재 상태 문장을 실제 구현과 일치시키고 review를 수정 완료 처리한다. |
문서 marker·link·diff 검증 통과 | CCR-REV-P1-002, P1-R2 |
발견된 문제
- 수정 완료: 답글 0개 Community root의 첫 답글 작성 진입을
P1-T1에서 구현하고P1-GATE에서 검증했다. - 확정: E2E 전용 fixture가
replyRootId하나만 replies로 분류해 다른 root의 직접 답글을 roots에 저장한다. (CCR-REV-P1-001,P1-R1에서 수정 예정) - 오탐:
CCR-REV-P1-001— mock mode에서는 Browser MSW가 요청을 처리해 해당 E2E route fixture 분기가 실행되지 않으며, 기존 fixture 상태에서 root2102의 빈 reply·첫·추가 답글 journey가 통과한다. - 확정: 완료된 현재 상태에 첫 답글 진입이 없다는 구현 전 문장이 남아 있다. (
CCR-REV-P1-002,P1-R2진행 중) - 수정 완료:
CCR-REV-P1-002의 stale 현재 상태 문장을 실제 구현 완료 내용으로 정정하고 문서 검증을 통과했다. (P1-R2) - 외부 차단: 없음.
최종 보고 형식
- 완료 Goal ID
- 변경한 파일과 최소 구현 내용
- RED·GREEN·REFACTOR 및 Gate 명령과 실제 결과
- 실행하지 못한 수동·server 검증과 이유
- 남은 위험 또는 열린 질문