Chore/spec kit setup - #371
Conversation
- 운영 중인 피드 도메인을 사용자 관점으로 정형화 (신규 기능 정의 아님) - User Story 5건 (P1: 작성/관리·둘러보기, P2: 반응/저장·작성 보조, P3: 개인화 추천) - Functional Requirements 25건 (FR-001 ~ FR-025) - 측정 가능한 Success Criteria 7건, Edge Cases 8건, Assumptions 8건 - 노출 모드 선택 규칙 명문화: 개인화 > 팔로잉 우선 > 기본 (코드 클래스명 Personalized / FollowingPriority / Basic 병기) - 신고 누적 시 노출 정책 명문화: 즉시 숨김 → 검수 큐 → 복원/영구 숨김 (신고 트리거 자체는 별도 신고 도메인 PRD에서 정의) - 책 도메인, 알림, 신고 트리거는 명시적으로 범위 외 처리 - 헌법 v1.0.0의 "API 계약 안정성" 원칙 반영 (#336 컨텍스트)
- 운영 중인 팔로우 도메인을 사용자 관점으로 정형화 (신규 기능 정의 아님) - User Story 5건 (P1: 토글·관계 둘러보기, P2: 팔로잉 최근 피드·알림 트리거, P3: 동시성·재시도 일관성) - Functional Requirements 16건 (FR-001 ~ FR-016) - 측정 가능한 Success Criteria 7건, Edge Cases 8건, Assumptions 8건 - 재시도 한계 초과 시 사용자 경험 명문화: 자원 경합 비노출, 일반 안내만 (운영자/개발자는 내부 코드·로그로 식별) - 알림 트리거 발화 보증(팔로우 1회당 1건, 언팔로우는 미발화) - 차단/비공개 계정/알림 도메인/사용자 라이프사이클은 명시적 범위 외 - 헌법 v1.0.0의 "API 계약 안정성"·"성능 가드" 원칙 반영 (#335 follow count 이슈, #336 중복 에러코드 컨텍스트)
- 운영 중인 책 도메인을 사용자 관점으로 정형화 (신규 기능 정의 아님) - User Story 5건 (P1: 검색·상세·저장, P2: 방 생성용 책 선택·인기/모집 발견) - Functional Requirements 18건 (FR-001 ~ FR-018) - 측정 가능한 Success Criteria 7건, Edge Cases 8건, Assumptions 8건 - 외부 도서 데이터 소스(현재 Naver Book API)는 벤더 중립으로 다룸 - 인기 검색 책 산정 기준 명문화: 전날 책 상세 조회 호출 수 기준, 개인화 없음, 일 단위 경계 이후 갱신 (주의: 신호가 키워드 검색이 아닌 '상세 조회'라는 점) - 사용되지 않는 책 자동 정리(BookCleanUpService)의 안전 조건 명시 (현재 참조 중인 책이 사라지지 않아야 함) - 외부 데이터 일시 장애 시 사용자 경험은 팔로우 PRD와 동일 정책 (자원/외부 원인 비노출, "잠시 후 다시 시도" 일반 안내) - 방·피드·최근 검색어·메타 갱신 정책은 명시적 범위 외
…ain) - 운영 중인 RoomPost 도메인(기록·투표 한정)을 사용자 관점으로 정형화 - 오늘의 한마디(AttendanceCheck)는 사용자 정의에 따라 별도 도메인으로 명시적 범위 외 처리 - User Story 5건 (P1: 기록 작성·투표 만들기/참여·목록 조회, P2: 피드 핀·AI 독후감) - Functional Requirements 25건 (FR-001 ~ FR-025) - 측정 가능한 Success Criteria 7건, Edge Cases 9건, Assumptions 10건 - 총평 조건 차이 명문화: 기록은 책 마지막 페이지에서만, 투표는 책 진행률 80% 이상에서만 (코드 상 실제 차이) - 투표 참여 정합성: 한 사용자가 한 투표에 정확히 한 선택지, 항목 변경 시 카운트 이동, 진행 중 방에서만 참여 가능 - 방-게시글 소속 검증: 수정·삭제·핀 시 방 ID와 게시글 방 ID 일치 필수 - AI 사용량 한도 정책 명문화: 전역(모든 방 합산) 평생 누적 5회, 리셋 없음 기록 작성 횟수는 안내용 (한도 게이트 아님) - 방·책·피드·댓글/좋아요·신고·알림은 명시적 범위 외
- 운영 중인 방 도메인을 사용자 관점으로 정형화 (신규 기능 정의 아님) - User Story 6건 (P1: 방 생성·발견과 참여·내 방 관리, P2: 호스트 운영·방 안 컨텍스트·카테고리별 추천) - Functional Requirements 27건 (FR-001 ~ FR-027) - 측정 가능한 Success Criteria 7건, Edge Cases 9건, Assumptions 10건 - 방 라이프사이클 명문화: RECRUITING -> IN_PROGRESS -> EXPIRED IN_PROGRESS 전환은 호스트의 모집 마감, EXPIRED 전환은 종료일 기반 시간 트리거(스케줄)로 자동 수행 - 공개/비공개의 비밀번호 짝 검증, 카테고리 5종 사전 명시 - "인기 방" 산정 기준 명문화: 모집 중 방의 memberCount 내림차순 (충원율 아닌 절대 참여자 수, 개인화 없음) - 호스트 이탈 정책 명문화: 현재 정책상 호스트는 어떤 경로로도 방을 떠날 수 없음 (양도·방 폐쇄 기능 미제공) - 향후 도입 예정: 호스트 양도 + 호스트 단독 방 삭제 (도입 시 본 PRD 개정 트리거로 Assumptions에 명시) - 책 도메인은 외부 의존(#356), 방 안 활동은 RoomPost PRD(#357), 알림·신고는 별도 도메인
- 운영 중인 알림 도메인을 사용자 관점으로 정형화 (신규 기능 정의 아님) - User Story 5건 (P1: 알림 센터·읽음 라우팅·디바이스 토큰 등록·트리거 수신, P2: 디바이스별 수신 여부 토글) - Functional Requirements 21건 (FR-001 ~ FR-021) - 측정 가능한 Success Criteria 7건, Edge Cases 10건, Assumptions 11건 - 본 PRD의 본질: 트리거 수신 이후의 알림 동작 (트리거 발화 조건은 발화 도메인 PRD가 책임) - 알림 트리거 카탈로그 15종 명문화: FEED 6종(팔로우/피드 좋아요/댓글/답글/댓글 좋아요/팔로잉 새 피드), ROOM 9종(새 참여자/모집 조기 마감/활동 시작/기록·투표 시작/ 게시글 댓글·답글·좋아요/댓글 좋아요) - 디바이스 단위 수신 여부 토글 정책: 같은 사용자라도 디바이스별 독립 - 외부 푸시 채널(현재 FCM)은 벤더 중립 추상화 - 저장(알림 센터)과 전달(푸시)의 독립성 보장 (외부 장애 시에도 누적 손실 X) - 알림 보존 정책 명문화: 현재는 평생 누적·수동 삭제 미제공 향후 최근 N일 자동 삭제 도입 예정 (개정 트리거로 Assumptions에 명시) - 트리거 발화 도메인·댓글·좋아요·사용자 라이프사이클은 명시적 범위 외
- "팔로잉한 사용자가 새 피드를 작성함" 트리거를 본 도메인 책임으로 명시 (공개 피드 생성 성공 시 작성자의 팔로워들에게 발화, 비공개·수정·삭제는 미발화) - 좋아요·댓글로 인한 알림 트리거의 책임 분리 명확화 (좋아요 공통 도메인, 댓글 도메인 책임) - 알림 도메인 PRD(#359)의 트리거 카탈로그(FEED 6종)와 정합
- "새 기록 작성됨" 트리거: 기록 작성 성공 시 같은 방의 다른 참여자 (작성자 제외)에게 발화. 수정·삭제는 미발화 - "새 투표 시작됨" 트리거: 투표 생성 성공 시 같은 방의 다른 참여자 (작성자 제외)에게 발화. 참여·취소·항목 변경·수정·삭제는 미발화 (생성 1회당 1건) - 댓글·좋아요로 인한 알림 트리거 책임 분리 명확화 (댓글 도메인, 좋아요 공통 도메인 책임) - 알림 도메인 PRD(#359)의 트리거 카탈로그와 정합
- "새 참여자" 트리거: 방 참여 성공 시 호스트에게 발화. 참여 취소(나가기)는 미발화 (참여 1회당 1건) - "모집 조기 마감" 트리거: 호스트가 closeRoomRecruit으로 RECRUITING -> IN_PROGRESS 전환 시 호스트 제외 참여자에게 발화 - "활동 시작" 트리거: IN_PROGRESS 진입 시 참여자에게 발화 (조기 마감과 함께 발화될 수 있는 별개 트리거) - 알림 도메인 PRD(#359)의 트리거 카탈로그(ROOM 9종 중 3종)와 정합
[docs] 피드(Feed) 도메인 PRD 역설계 (specs/001-feed-features)
[docs] 팔로우(Follow) 도메인 PRD 역설계 (specs/002-follow-domain)
[docs] 책(Book) 도메인 PRD 역설계 (specs/003-book-domain)
[docs] 방 게시글(RoomPost) - 기록·투표 도메인 PRD 역설계
[docs] 방(Room) 도메인 PRD 역설계 (specs/005-room-domain)
[docs] 알림(Notification) 도메인 PRD 역설계 (specs/006-notification-domain)
Walkthrough피드, 팔로우, 책, RoomPost, 방, 알림 도메인의 PRD와 요구사항 체크리스트를 추가했다. 각 문서에는 사용자 시나리오, 기능 요구사항, 성공 기준, 엣지 케이스와 가정이 포함되며, Spec Kit 대상 디렉터리가 팔로우 도메인으로 변경됐다. Changes도메인 기능 명세
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Test Results498 tests 498 ✅ 50s ⏱️ Results for commit 7008460. |
There was a problem hiding this comment.
Actionable comments posted: 12
🧹 Nitpick comments (2)
specs/006-notification-domain/spec.md (2)
183-183: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win푸시 토큰 명칭과 벤더 중립 원칙을 일치시키세요.
specs/006-notification-domain/spec.md#L183-L183:FcmToken을PushToken또는DeviceToken으로 일반화하세요.specs/006-notification-domain/checklists/requirements.md#L9-L9: 일반화된 명칭을 기준으로 체크리스트의 벤더 중립성 검증을 유지하세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@specs/006-notification-domain/spec.md` at line 183, 벤더 종속적인 FcmToken 명칭을 PushToken 또는 DeviceToken 같은 일반화된 명칭으로 변경하고 관련 설명도 일관되게 갱신하세요. specs/006-notification-domain/spec.md 183-183에서는 일반화된 토큰 명칭을 적용하고, specs/006-notification-domain/checklists/requirements.md 9-9에서는 해당 명칭을 기준으로 벤더 중립성 검증을 유지하세요.
98-99: 🩺 Stability & Availability | 🔵 Trivial푸시 “전달”의 보장 수준과 장애 후 처리를 정의하세요.
Line 133은 외부 채널 장애를 허용하지만, 이 구간은 매 트리거마다 푸시가 전달되어야 한다고 단정합니다. “외부 채널에 수락됨”과 “디바이스에 도달함”을 구분하고, 재시도·실패 큐·재시도 멱등성의 기준을 정해야 테스트 가능한 계약이 됩니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@specs/006-notification-domain/spec.md` around lines 98 - 99, 알림 트리거 처리 규칙에서 푸시 “전달”을 디바이스 도달이 아닌 외부 푸시 채널의 수락으로 명확히 정의하고, 외부 채널 장애 시 재시도 정책과 실패 큐 적재 기준을 추가하세요. 동일 알림의 재시도가 중복 푸시를 만들지 않도록 알림 또는 전달 시도의 멱등성 키와 중복 처리 기준도 명시해 테스트 가능한 계약으로 만드세요.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@specs/001-feed-features/spec.md`:
- Around line 149-152: FR-014~FR-015의 비공개 피드 반응 규칙을 보완하여 작성자는 자신의 비공개 피드에 좋아요와
댓글을 작성할 수 있음을 명시하세요. 다른 사용자의 비공개 피드 반응은 계속 거부하도록 유지하고, 댓글 작성 권한을 담당하는 도메인 규칙도
명확히 기술하세요.
- Line 204: 새 피드 알림의 생성 주체를 Feed로 단일화하고, 공개 피드 생성 성공 시 Feed가 이벤트를 발행하도록 명시하세요.
Follow는 팔로잉 사용자 목록을 조회해 수신자만 제공하며 이벤트를 생성하지 않는 책임으로 정리하세요.
specs/001-feed-features/spec.md 204-204와 specs/006-notification-domain/spec.md
105-105의 `피드 + 팔로우` 설명을 동일한 생성자·수신자 책임 구분으로 수정하세요.
- Around line 184-185: Update SC-002 in specs/001-feed-features/spec.md:184-185
to define a reproducible measurement method and numeric latency threshold for
the first feed-list result, replacing the subjective “지연 없이” criterion. Update
SC-001 and SC-007 in specs/002-follow-domain/spec.md:160-166 with explicit
measurable values, test conditions, and pass/fail criteria so both success
criteria can be independently reproduced.
In `@specs/002-follow-domain/spec.md`:
- Around line 142-143: specs/002-follow-domain/spec.md:142-143의 팔로우 상태 전이 요구사항에
고유 이벤트 ID 생성과 재시도 시 동일 이벤트 ID를 사용하는 멱등 계약을 명시하세요.
specs/006-notification-domain/spec.md:174의 알림 처리 요구사항에는 이벤트 ID 기반 중복 제거와 중복 수신 시
동일 이벤트로 안전하게 처리하는 규칙을 추가하세요.
- Around line 90-95: 동시 토글에서 마지막 사용자 의도를 결정하는 공통 순서 계약이 정의되지 않았습니다.
specs/002-follow-domain/spec.md 90-95행의 Acceptance Scenarios에 클라이언트 시퀀스/버전 검증 또는
서버 직렬화와 오래된 요청 무시 규칙을 명시하여 요청 처리 순서와 최종 상태 판정 기준을 추가하세요.
specs/002-follow-domain/checklists/requirements.md 17-18행에서는 해당 계약이 명확히 정의될 때까지
“모호하지 않음” 항목을 완료로 표시하지 마세요.
In `@specs/003-book-domain/spec.md`:
- Around line 172-178: 정성적으로만 정의된 SC-001, SC-002, SC-007에 객관적인 수치·비율과 측정 기간을 추가해
독립적으로 합격 여부를 판단할 수 있게 하세요. specs/003-book-domain/spec.md 172-178의 각 성공 기준을
구체화하고, 그 변경에 맞춰 specs/003-book-domain/checklists/requirements.md 18의 “성공 기준이 측정
가능하다” 체크는 유지하세요.
- Around line 63-66: 저장 토글 요구사항의 3번 시나리오에 “마지막 사용자 의도”를 판정하는 기준을 명시하세요. 동시 요청 처리
시 클라이언트 순번·버전·명시적 선행 관계를 사용할지, 또는 서버가 인정한 선형화 순서를 마지막 요청으로 간주할지 정의하고,
FR-013·SC-003을 재현 가능한 테스트로 검증할 수 있도록 해당 규칙을 일관되게 적용하세요.
In `@specs/004-roompost-domain/checklists/requirements.md`:
- Line 27: Update the functional requirements checklist entry to cover FR-001
through FR-025, and verify that FR-025 is mapped to its corresponding User Story
acceptance scenario.
In `@specs/004-roompost-domain/spec.md`:
- Line 55: 투표 총평 생성 조건에서 사용하는 진행률의 주체와 계산 기준을 명시하세요. 작성자 또는 방 중 누구의 진행률인지, 기준이
되는 현재 페이지와 전체 페이지 값, 백분율 계산 및 반올림·경계 처리 규칙을 정의하여 정확히 80% 미만일 때만 작성을 거부하도록 관련 명세
항목을 일관되게 갱신하세요.
- Around line 37-40: 투표의 방 상태 제약을 하나의 일관된 정책으로 결정한 뒤, User Story 2의 설명, 관련
생성·수정·삭제·참여 시나리오, 그리고 FR-011에서 동일하게 반영하세요. 특히 진행 중인 방만 허용할 경우 모든 해당 작업의 상태 검사를
명시하고, 참여자에게 상태 제한 없이 허용할 경우 Line 39의 제한 문구를 제거하거나 완화하세요.
In `@specs/005-room-domain/spec.md`:
- Around line 230-235: “내가 참여한 방의 활동이 시작됨” 트리거의 수신 대상을 참여자 전원 또는 호스트 제외 멤버 중 하나로
확정하고, 해당 범위를 다른 설명과 일관되게 반영하세요. 또한 closeRoomRecruit에서 조기 마감과 활동 시작이 함께 발생할 때 각
트리거의 중복 방지 규칙과 허용되는 발화 관계를 명시해 알림 계약과 테스트가 동일한 기준을 사용하도록 하세요.
In `@specs/006-notification-domain/spec.md`:
- Around line 126-135: 알림 삭제 권한을 요구하는 문구를 현재 정책과 일치시키세요. 수동 삭제를 지원하지 않는 결정이라면
‘알림 소유자 검증’에서 삭제를 제거하고, 알림 상세 조회·읽음 처리 권한만 유지하며 FR-021의 평생 보존 정책과 모순되지 않게 정리하세요.
---
Nitpick comments:
In `@specs/006-notification-domain/spec.md`:
- Line 183: 벤더 종속적인 FcmToken 명칭을 PushToken 또는 DeviceToken 같은 일반화된 명칭으로 변경하고 관련
설명도 일관되게 갱신하세요. specs/006-notification-domain/spec.md 183-183에서는 일반화된 토큰 명칭을
적용하고, specs/006-notification-domain/checklists/requirements.md 9-9에서는 해당 명칭을
기준으로 벤더 중립성 검증을 유지하세요.
- Around line 98-99: 알림 트리거 처리 규칙에서 푸시 “전달”을 디바이스 도달이 아닌 외부 푸시 채널의 수락으로 명확히
정의하고, 외부 채널 장애 시 재시도 정책과 실패 큐 적재 기준을 추가하세요. 동일 알림의 재시도가 중복 푸시를 만들지 않도록 알림 또는 전달
시도의 멱등성 키와 중복 처리 기준도 명시해 테스트 가능한 계약으로 만드세요.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 8a709913-7fa8-45bd-b5c5-758daf5d3bb7
📒 Files selected for processing (13)
.specify/feature.jsonspecs/001-feed-features/checklists/requirements.mdspecs/001-feed-features/spec.mdspecs/002-follow-domain/checklists/requirements.mdspecs/002-follow-domain/spec.mdspecs/003-book-domain/checklists/requirements.mdspecs/003-book-domain/spec.mdspecs/004-roompost-domain/checklists/requirements.mdspecs/004-roompost-domain/spec.mdspecs/005-room-domain/checklists/requirements.mdspecs/005-room-domain/spec.mdspecs/006-notification-domain/checklists/requirements.mdspecs/006-notification-domain/spec.md
| - **FR-014**: 사용자는 공개 피드에 좋아요를 토글할 수 있어야 한다(ON/OFF). | ||
| - **FR-015**: 비공개 피드에 대한 다른 사용자의 좋아요 또는 댓글 작성 시도는 거부되어야 한다. | ||
| - **FR-016**: 좋아요 카운트는 동시 토글 시나리오에서도 정합해야 한다(중복 증가/감소 없음). | ||
| - **FR-017**: 사용자는 임의의 공개 피드를 저장/저장 해제할 수 있으며, 저장된 피드는 자신만 볼 수 있는 별도 목록으로 제공되어야 한다. |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
비공개 피드의 작성자 반응 규칙을 FR에 명시하세요.
User Story와 Edge Cases는 작성자가 자신의 비공개 피드에 좋아요·댓글을 할 수 있다고 설명하지만, FR-014는 공개 피드만 허용하고 FR-015는 타 사용자만 거부합니다. 작성자의 허용 범위와 댓글 도메인의 책임을 명시하지 않으면 인가 동작이 구현마다 달라집니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/001-feed-features/spec.md` around lines 149 - 152, FR-014~FR-015의 비공개
피드 반응 규칙을 보완하여 작성자는 자신의 비공개 피드에 좋아요와 댓글을 작성할 수 있음을 명시하세요. 다른 사용자의 비공개 피드 반응은 계속
거부하도록 유지하고, 댓글 작성 권한을 담당하는 도메인 규칙도 명확히 기술하세요.
| - **SC-001**: 사용자는 작성 화면 진입부터 피드 생성 완료까지 평균 60초 이내에 마칠 수 있다(이미지 0~3장 기준). | ||
| - **SC-002**: 사용자가 피드 목록(전체/내/타인/책별/저장) 첫 화면을 요청한 뒤, 95%의 요청이 사용자가 "지연 없이 떴다"고 인식하는 시간 내에 첫 결과를 받는다. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
성공 기준의 측정 방법과 임계치를 명시하세요.
두 도메인 모두 “지연 없이” 또는 “운영 기준치”처럼 검증 방법이 없는 표현을 사용합니다.
specs/001-feed-features/spec.md#L184-L185: SC-002의 사용자 인식 지연 기준에 측정 방식과 판정 임계치를 추가하세요.specs/002-follow-domain/spec.md#L160-L166: SC-001과 SC-007을 재현 가능한 수치·측정 방법으로 정의하세요.
📍 Affects 2 files
specs/001-feed-features/spec.md#L184-L185(this comment)specs/002-follow-domain/spec.md#L160-L166
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/001-feed-features/spec.md` around lines 184 - 185, Update SC-002 in
specs/001-feed-features/spec.md:184-185 to define a reproducible measurement
method and numeric latency threshold for the first feed-list result, replacing
the subjective “지연 없이” criterion. Update SC-001 and SC-007 in
specs/002-follow-domain/spec.md:160-166 with explicit measurable values, test
conditions, and pass/fail criteria so both success criteria can be independently
reproduced.
| - **알림 연동**: 본 PRD는 *본 도메인이 직접 발화하는* 알림 트리거만을 보증한다. 좋아요·댓글로 인한 알림(피드 좋아요/피드 댓글/피드 댓글 답글/피드 댓글 좋아요)의 트리거 발화는 각각 좋아요 공통 도메인과 댓글 도메인이 책임지며, 본 도메인은 그 발화의 *대상이 피드라는 사실*만 인정한다. 알림 트리거 수신 이후의 저장·표시·푸시 전달 흐름은 알림 도메인 PRD(#359)를 따른다. | ||
|
|
||
| **본 도메인이 직접 발화하는 트리거**: | ||
| - **"팔로잉한 사용자가 새 피드를 작성함"**: 사용자가 *공개* 피드를 생성하는 데 성공한 시점에, 작성자를 팔로잉 중인 사용자들에게 알림 트리거가 발화된다. 비공개 피드는 발화하지 않는다(트리거 수신자에게 노출되지 않을 콘텐츠는 알림도 보내지 않는다). 피드 수정·삭제는 트리거를 발화하지 않는다. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
새 피드 알림의 발화 주체를 단일하게 정리하세요.
specs/001-feed-features/spec.md#L204-L204: Feed가 이벤트를 생성하는지, Follow가 수신자만 제공하는지 명시하세요.specs/006-notification-domain/spec.md#L105-L105:피드 + 팔로우표기를 단일 생성자와 수신자 조회 책임으로 구분하세요.
📍 Affects 2 files
specs/001-feed-features/spec.md#L204-L204(this comment)specs/006-notification-domain/spec.md#L105-L105
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/001-feed-features/spec.md` at line 204, 새 피드 알림의 생성 주체를 Feed로 단일화하고, 공개
피드 생성 성공 시 Feed가 이벤트를 발행하도록 명시하세요. Follow는 팔로잉 사용자 목록을 조회해 수신자만 제공하며 이벤트를 생성하지
않는 책임으로 정리하세요. specs/001-feed-features/spec.md 204-204와
specs/006-notification-domain/spec.md 105-105의 `피드 + 팔로우` 설명을 동일한 생성자·수신자 책임
구분으로 수정하세요.
| **Independent Test**: 동일 사용자가 짧은 시간 안에 같은 대상에 대해 N번 토글했을 때 최종 관계 상태가 마지막 사용자 의도와 일치하며, 팔로워 수가 정합하다. | ||
|
|
||
| **Acceptance Scenarios**: | ||
|
|
||
| 1. **Given** A가 짧은 시간 안에 B에 대해 팔로우 → 언팔로우 → 팔로우를 빠르게 요청했을 때, **When** 모든 요청이 처리된 후, **Then** 최종 관계 상태는 "팔로우", 팔로워 수는 1번의 팔로우만 반영된다(중복 증가 0건). | ||
| 2. **Given** 시스템이 일시적 자원 경합 상태로 1차 처리에 실패하더라도, **When** 사용자에게 응답이 돌아왔을 때, **Then** 응답에는 "성공" 또는 "사용자가 다시 시도해야 함을 명확히 안내하는 오류" 중 하나만 포함되며, "성공으로 보이지만 실제로는 처리 안 됨" 상태는 발생하지 않는다. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
동시 토글에서 “마지막 의도”를 판정하는 공통 순서 계약이 없습니다.
specs/002-follow-domain/spec.md#L90-L95: 클라이언트 시퀀스/버전 또는 서버 직렬화·오래된 요청 무시 규칙을 추가하세요.specs/002-follow-domain/checklists/requirements.md#L17-L18: 해당 계약이 정의되기 전까지 “모호하지 않음” 항목을 완료로 표시하지 마세요.
📍 Affects 2 files
specs/002-follow-domain/spec.md#L90-L95(this comment)specs/002-follow-domain/checklists/requirements.md#L17-L18
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/002-follow-domain/spec.md` around lines 90 - 95, 동시 토글에서 마지막 사용자 의도를
결정하는 공통 순서 계약이 정의되지 않았습니다. specs/002-follow-domain/spec.md 90-95행의 Acceptance
Scenarios에 클라이언트 시퀀스/버전 검증 또는 서버 직렬화와 오래된 요청 무시 규칙을 명시하여 요청 처리 순서와 최종 상태 판정 기준을
추가하세요. specs/002-follow-domain/checklists/requirements.md 17-18행에서는 해당 계약이 명확히
정의될 때까지 “모호하지 않음” 항목을 완료로 표시하지 마세요.
| - **FR-013**: 팔로우 요청이 성공한 경우, 시스템은 알림 도메인에 "팔로우됨" 트리거를 정확히 1회 발화해야 한다. | ||
| - **FR-014**: 언팔로우 요청이 성공한 경우, 시스템은 알림 트리거를 발화하지 않아야 한다. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
알림 트리거를 재시도 가능한 멱등 계약으로 정의하세요.
specs/002-follow-domain/spec.md#L142-L143: 팔로우 상태 전이에서 고유 이벤트 ID를 만들고 재시도 시 동일 이벤트로 처리하세요.specs/006-notification-domain/spec.md#L174-L174: 이벤트 ID 기반 중복 제거와 중복 수신 처리 규칙을 추가하세요.
📍 Affects 2 files
specs/002-follow-domain/spec.md#L142-L143(this comment)specs/006-notification-domain/spec.md#L174-L174
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/002-follow-domain/spec.md` around lines 142 - 143,
specs/002-follow-domain/spec.md:142-143의 팔로우 상태 전이 요구사항에 고유 이벤트 ID 생성과 재시도 시 동일
이벤트 ID를 사용하는 멱등 계약을 명시하세요. specs/006-notification-domain/spec.md:174의 알림 처리
요구사항에는 이벤트 ID 기반 중복 제거와 중복 수신 시 동일 이벤트로 안전하게 처리하는 규칙을 추가하세요.
|
|
||
| ## Feature Readiness | ||
|
|
||
| - [x] All functional requirements have clear acceptance criteria — FR-001~FR-024가 User Story 시나리오와 매핑 |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
기능 요구사항 범위를 FR-025까지 반영하세요.
연결된 spec.md에는 FR-025가 정의되어 있지만 체크리스트는 FR-001~FR-024만 매핑한다고 표시합니다. 체크리스트를 FR-001~FR-025로 수정하고 FR-025의 수용 시나리오 매핑도 확인해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/004-roompost-domain/checklists/requirements.md` at line 27, Update the
functional requirements checklist entry to cover FR-001 through FR-025, and
verify that FR-025 is mapped to its corresponding User Story acceptance
scenario.
| ### User Story 2 - 투표(Vote) 만들기·수정·삭제 그리고 투표하기 (Priority: P1) | ||
|
|
||
| 방 참여자는 짧은 질문과 선택지 묶음으로 투표를 생성하고, 다른 참여자는 그 투표에 참여한다(한 사용자는 한 투표에 정확히 하나의 선택지만 선택; 다른 선택지로 바꾸려면 항목을 변경한다; 더 이상 의견이 없으면 투표를 취소한다). 투표는 *진행 중인 방*에서만 가능하다. | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
투표의 방 상태 제약을 일관되게 정의하세요.
Line 39는 투표가 진행 중인 방에서만 가능하다고 명시하지만, 생성 시나리오와 FR-011은 참여자라면 생성할 수 있도록 되어 있고 진행 중 상태를 검사하지 않습니다. 투표 생성·수정·삭제·참여 중 어느 작업에 상태 제약이 적용되는지 정한 뒤 User Story, 시나리오, FR을 동일하게 맞춰야 합니다.
Also applies to: 47-55, 152-155
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/004-roompost-domain/spec.md` around lines 37 - 40, 투표의 방 상태 제약을 하나의 일관된
정책으로 결정한 뒤, User Story 2의 설명, 관련 생성·수정·삭제·참여 시나리오, 그리고 FR-011에서 동일하게 반영하세요. 특히
진행 중인 방만 허용할 경우 모든 해당 작업의 상태 검사를 명시하고, 참여자에게 상태 제한 없이 허용할 경우 Line 39의 제한 문구를
제거하거나 완화하세요.
| 6. **Given** B가 어떤 선택지에 투표하지 않은 상태에서, **When** B가 그 선택지에 대해 "투표 취소"를 요청하면, **Then** 작업이 거부된다. | ||
| 7. **Given** A가 본인이 만든 투표를 수정한다, **When** 본문 내용만을 변경한다, **Then** 투표 본문이 갱신된다. 페이지·총평 여부·선택지·방·작성자는 수정 대상이 아니다. | ||
| 8. **Given** B가 A가 만든 투표를 수정·삭제하려고 시도하면, **Then** 작업이 거부된다. | ||
| 9. **Given** 투표가 *총평*으로 표시되어 생성될 때, **When** 작성 시 책 진행률이 80% 미만이면, **Then** 작성이 거부된다. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
투표 총평의 “진행률 80%” 계산 계약을 명시하세요.
현재 책 명세는 전체 페이지 수는 정의하지만 진행률의 주체와 계산 기준을 정의하지 않습니다. 작성자의 독서 진행률인지, 방의 진행률인지, 어떤 페이지 값을 기준으로 반올림하는지 명시하지 않으면 80% 조건을 일관되게 판정할 수 없습니다.
Also applies to: 153-153, 204-205
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/004-roompost-domain/spec.md` at line 55, 투표 총평 생성 조건에서 사용하는 진행률의 주체와 계산
기준을 명시하세요. 작성자 또는 방 중 누구의 진행률인지, 기준이 되는 현재 페이지와 전체 페이지 값, 백분율 계산 및 반올림·경계 처리 규칙을
정의하여 정확히 80% 미만일 때만 작성을 거부하도록 관련 명세 항목을 일관되게 갱신하세요.
| **본 도메인이 직접 발화하는 트리거**: | ||
| - **"내가 호스트인 방에 새 참여자가 들어옴"**: 사용자가 방에 참여하는 데 성공한 시점에, *그 방의 호스트*에게 알림 트리거가 발화된다. 참여 취소(나가기)는 트리거를 발화하지 않는다(참여 성공 1회당 1건). | ||
| - **"내가 참여한 방의 모집이 조기 마감됨"**: 호스트가 모집을 마감(`closeRoomRecruit`)해 방의 상태가 `RECRUITING` → `IN_PROGRESS`로 전환된 시점에, 그 방의 *호스트를 제외한* 모든 참여자에게 알림 트리거가 발화된다. 자연 시작일 도래에 의한 자동 전환과 구분된다. | ||
| - **"내가 참여한 방의 활동이 시작됨"**: 방의 상태가 `IN_PROGRESS`로 진입한 시점에 그 방의 *참여자 전원*(또는 호스트를 제외한 멤버 — 운영 구현에 따름)에게 알림 트리거가 발화된다. 본 PRD는 *발화한다는 사실*과 *대상 범위가 방 참여자라는 점*만 보장한다. | ||
|
|
||
| > 위 \"조기 마감\"과 \"활동 시작\"은 모집 마감 시점에서 *함께* 발화될 수 있는 별개의 트리거다. 둘의 정확한 메시지·발화 순서·중복 방지 정책은 알림 도메인 PRD(#359)와 알림 템플릿이 다룬다. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
활동 시작 알림의 수신 대상을 하나로 확정하세요.
Line 233이 “참여자 전원 또는 호스트 제외 멤버”로 열려 있어 동일한 상태 전환에서도 수신자가 달라질 수 있습니다. 또한 조기 마감과 활동 시작 트리거가 함께 발화될 수 있으므로, 대상 범위와 중복 방지 규칙을 확정해야 알림 계약과 테스트를 작성할 수 있습니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/005-room-domain/spec.md` around lines 230 - 235, “내가 참여한 방의 활동이 시작됨”
트리거의 수신 대상을 참여자 전원 또는 호스트 제외 멤버 중 하나로 확정하고, 해당 범위를 다른 설명과 일관되게 반영하세요. 또한
closeRoomRecruit에서 조기 마감과 활동 시작이 함께 발생할 때 각 트리거의 중복 방지 규칙과 허용되는 발화 관계를 명시해 알림
계약과 테스트가 동일한 기준을 사용하도록 하세요.
| - **알림 소유자 검증**: 사용자는 자신이 수신자인 알림에 대해서만 읽음 처리·삭제·상세 조회가 가능하다. 타인의 알림에 대한 어떤 조작도 거부된다. | ||
| - **이미 읽음 처리된 알림의 재읽음**: 상태는 변경되지 않으나 라우팅 정보는 매번 응답된다(클라이언트가 클릭 시 항상 화면 이동 가능해야 함). | ||
| - **수신 여부 토글 멱등성 차단**: 이미 동일한 상태로 변경을 요청하면 거부된다(켜진 상태에서 *켜기*, 꺼진 상태에서 *끄기*). | ||
| - **자기 행위에 대한 알림**: 자기 자신에게 알림이 가는 행위(예: 내 댓글에 내가 답글)는 본 PRD가 직접 방지하지 않는다. 각 발화 도메인 PRD가 그 의미 없는 자기 알림을 *발화하지 않도록* 책임을 진다(또는 그렇게 설계되어 있다). | ||
| - **수신 여부 OFF 디바이스의 동작**: 그 디바이스로 푸시는 전달되지 않으나, 알림 센터에는 변함없이 누적된다. 사용자가 앱을 열면 모두 보인다. | ||
| - **타 사용자 토큰 조작 방어**: 다른 사용자의 디바이스 토큰을 자신이 수정·삭제·수신 여부 토글하려는 시도는 거부된다. | ||
| - **알림 라우팅 미정**: 라우팅 종류가 "이동 안 함"(NONE)인 알림은 클릭해도 화면이 이동하지 않으나 읽음 처리는 정상 동작한다. | ||
| - **외부 푸시 채널 일시 장애**: 외부 푸시 전달이 실패해도 알림 센터에 누적된 알림은 손실되어서는 안 된다(저장과 전달은 독립적). | ||
| - **삭제·탈퇴된 발화 주체**: 발화를 만든 행위자(예: 좋아요 누른 사용자)가 이후 탈퇴해도, 이미 발화된 알림 자체는 사용자 입장에서 일관되게 보여야 한다(상세 정책은 사용자 라이프사이클 도메인 PRD를 따른다). | ||
| - **알림 보존 (확정 — 현재 정책)**: 사용자별 알림은 *평생 누적*된다. 자동 삭제·만료 정책은 없으며, 사용자 수동 삭제 기능도 *현재 시점에는 제공되지 않는다*. 사용자 알림 센터에 도착한 알림은 읽음 처리 여부와 무관하게 계속 남는다. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
알림 삭제 권한을 제거하거나 요구사항으로 추가하세요.
이 Edge Case는 사용자가 자신의 알림을 삭제할 수 있는 것처럼 설명하지만, Line 135와 FR-021은 현재 수동 삭제를 제공하지 않는다고 명시합니다. 삭제를 지원하지 않는다면 Edge Case에서 제거하고, 지원한다면 삭제 범위·보존 정책·성공 조건을 FR에 추가해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/006-notification-domain/spec.md` around lines 126 - 135, 알림 삭제 권한을 요구하는
문구를 현재 정책과 일치시키세요. 수동 삭제를 지원하지 않는 결정이라면 ‘알림 소유자 검증’에서 삭제를 제거하고, 알림 상세 조회·읽음 처리
권한만 유지하며 FR-021의 평생 보존 정책과 모순되지 않게 정리하세요.
#️⃣ 연관된 이슈
📝 작업 내용
📸 스크린샷
💬 리뷰 요구사항
📌 PR 진행 시 이러한 점들을 참고해 주세요
Summary by CodeRabbit