Skip to content

Chore/spec kit setup - #371

Merged
hd0rable merged 15 commits into
developfrom
chore/spec-kit-setup
Jul 27, 2026
Merged

Chore/spec kit setup#371
hd0rable merged 15 commits into
developfrom
chore/spec-kit-setup

Conversation

@hd0rable

@hd0rable hd0rable commented Jul 27, 2026

Copy link
Copy Markdown
Member

#️⃣ 연관된 이슈

closes #이슈번호

📝 작업 내용

이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

📸 스크린샷

💬 리뷰 요구사항

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

📌 PR 진행 시 이러한 점들을 참고해 주세요

* P1 : 꼭 반영해 주세요 (Request Changes) - 이슈가 발생하거나 취약점이 발견되는 케이스 등
* P2 : 반영을 적극적으로 고려해 주시면 좋을 것 같아요 (Comment)
* P3 : 이런 방법도 있을 것 같아요~ 등의 사소한 의견입니다 (Chore)

Summary by CodeRabbit

  • 문서화
    • 피드, 팔로우, 책, 방 게시글, 방, 알림 기능의 사용자 요구사항과 이용 시나리오를 문서화했습니다.
    • 각 기능의 수용 기준, 성공 지표, 예외 상황 및 범위를 정리했습니다.
    • 기능별 품질 검토 체크리스트를 추가하고 요구사항 검증을 완료했습니다.
    • 피드 기능 디렉터리 지정 정보를 최신화했습니다.

hyunjun-jang and others added 15 commits May 17, 2026 16:55
- 운영 중인 피드 도메인을 사용자 관점으로 정형화 (신규 기능 정의 아님)
- 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)
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

피드, 팔로우, 책, RoomPost, 방, 알림 도메인의 PRD와 요구사항 체크리스트를 추가했다. 각 문서에는 사용자 시나리오, 기능 요구사항, 성공 기준, 엣지 케이스와 가정이 포함되며, Spec Kit 대상 디렉터리가 팔로우 도메인으로 변경됐다.

Changes

도메인 기능 명세

Layer / File(s) Summary
피드 도메인 명세
specs/001-feed-features/*
피드 작성·탐색·반응·개인화 노출·작성 컨텍스트와 안전성 요구사항 및 품질 체크리스트를 정의했다.
팔로우 도메인 명세
.specify/feature.json, specs/002-follow-domain/*
팔로우 토글·조회·동시성·알림 연동 요구사항과 품질 체크리스트를 추가하고 대상 디렉터리를 변경했다.
책 도메인 명세
specs/003-book-domain/*
책 검색·상세·저장·방 선택·인기 발견과 외부 데이터 처리 요구사항 및 검증 항목을 정의했다.
RoomPost 도메인 명세
specs/004-roompost-domain/*
기록·투표·목록·핀·AI 독후감 생성의 요구사항과 권한·정합성 기준을 정의했다.
방 도메인 명세
specs/005-room-domain/*
방 생성·참여·운영·상태 전이·추천과 관련 품질 체크리스트를 정의했다.
알림 도메인 명세
specs/006-notification-domain/*
알림 조회·읽음 처리·디바이스 설정·트리거·푸시 전달 요구사항과 검증 항목을 정의했다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Poem

깡충 뛰는 토끼가 문서를 펼쳐,
여섯 도메인 길을 가지런히 세워.
피드와 팔로우, 책과 방,
알림까지 스펙의 달빛 아래 반짝반짝! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 스펙 킷 문서 추가라는 핵심 변경과 관련되어 있으며, 변경 방향을 간결하게 요약합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/spec-kit-setup

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Test Results

498 tests   498 ✅  50s ⏱️
148 suites    0 💤
148 files      0 ❌

Results for commit 7008460.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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: FcmTokenPushToken 또는 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

📥 Commits

Reviewing files that changed from the base of the PR and between 9094777 and 7008460.

📒 Files selected for processing (13)
  • .specify/feature.json
  • specs/001-feed-features/checklists/requirements.md
  • specs/001-feed-features/spec.md
  • specs/002-follow-domain/checklists/requirements.md
  • specs/002-follow-domain/spec.md
  • specs/003-book-domain/checklists/requirements.md
  • specs/003-book-domain/spec.md
  • specs/004-roompost-domain/checklists/requirements.md
  • specs/004-roompost-domain/spec.md
  • specs/005-room-domain/checklists/requirements.md
  • specs/005-room-domain/spec.md
  • specs/006-notification-domain/checklists/requirements.md
  • specs/006-notification-domain/spec.md

Comment on lines +149 to +152
- **FR-014**: 사용자는 공개 피드에 좋아요를 토글할 수 있어야 한다(ON/OFF).
- **FR-015**: 비공개 피드에 대한 다른 사용자의 좋아요 또는 댓글 작성 시도는 거부되어야 한다.
- **FR-016**: 좋아요 카운트는 동시 토글 시나리오에서도 정합해야 한다(중복 증가/감소 없음).
- **FR-017**: 사용자는 임의의 공개 피드를 저장/저장 해제할 수 있으며, 저장된 피드는 자신만 볼 수 있는 별도 목록으로 제공되어야 한다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 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의 비공개
피드 반응 규칙을 보완하여 작성자는 자신의 비공개 피드에 좋아요와 댓글을 작성할 수 있음을 명시하세요. 다른 사용자의 비공개 피드 반응은 계속
거부하도록 유지하고, 댓글 작성 권한을 담당하는 도메인 규칙도 명확히 기술하세요.

Comment on lines +184 to +185
- **SC-001**: 사용자는 작성 화면 진입부터 피드 생성 완료까지 평균 60초 이내에 마칠 수 있다(이미지 0~3장 기준).
- **SC-002**: 사용자가 피드 목록(전체/내/타인/책별/저장) 첫 화면을 요청한 뒤, 95%의 요청이 사용자가 "지연 없이 떴다"고 인식하는 시간 내에 첫 결과를 받는다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 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)를 따른다.

**본 도메인이 직접 발화하는 트리거**:
- **"팔로잉한 사용자가 새 피드를 작성함"**: 사용자가 *공개* 피드를 생성하는 데 성공한 시점에, 작성자를 팔로잉 중인 사용자들에게 알림 트리거가 발화된다. 비공개 피드는 발화하지 않는다(트리거 수신자에게 노출되지 않을 콘텐츠는 알림도 보내지 않는다). 피드 수정·삭제는 트리거를 발화하지 않는다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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의 `피드 + 팔로우` 설명을 동일한 생성자·수신자 책임
구분으로 수정하세요.

Comment on lines +90 to +95
**Independent Test**: 동일 사용자가 짧은 시간 안에 같은 대상에 대해 N번 토글했을 때 최종 관계 상태가 마지막 사용자 의도와 일치하며, 팔로워 수가 정합하다.

**Acceptance Scenarios**:

1. **Given** A가 짧은 시간 안에 B에 대해 팔로우 → 언팔로우 → 팔로우를 빠르게 요청했을 때, **When** 모든 요청이 처리된 후, **Then** 최종 관계 상태는 "팔로우", 팔로워 수는 1번의 팔로우만 반영된다(중복 증가 0건).
2. **Given** 시스템이 일시적 자원 경합 상태로 1차 처리에 실패하더라도, **When** 사용자에게 응답이 돌아왔을 때, **Then** 응답에는 "성공" 또는 "사용자가 다시 시도해야 함을 명확히 안내하는 오류" 중 하나만 포함되며, "성공으로 보이지만 실제로는 처리 안 됨" 상태는 발생하지 않는다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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행에서는 해당 계약이 명확히
정의될 때까지 “모호하지 않음” 항목을 완료로 표시하지 마세요.

Comment on lines +142 to +143
- **FR-013**: 팔로우 요청이 성공한 경우, 시스템은 알림 도메인에 "팔로우됨" 트리거를 정확히 1회 발화해야 한다.
- **FR-014**: 언팔로우 요청이 성공한 경우, 시스템은 알림 트리거를 발화하지 않아야 한다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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 시나리오와 매핑

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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.

Comment on lines +37 to +40
### User Story 2 - 투표(Vote) 만들기·수정·삭제 그리고 투표하기 (Priority: P1)

방 참여자는 짧은 질문과 선택지 묶음으로 투표를 생성하고, 다른 참여자는 그 투표에 참여한다(한 사용자는 한 투표에 정확히 하나의 선택지만 선택; 다른 선택지로 바꾸려면 항목을 변경한다; 더 이상 의견이 없으면 투표를 취소한다). 투표는 *진행 중인 방*에서만 가능하다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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** 작성이 거부된다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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% 미만일 때만 작성을 거부하도록 관련 명세 항목을 일관되게 갱신하세요.

Comment on lines +230 to +235
**본 도메인이 직접 발화하는 트리거**:
- **"내가 호스트인 방에 새 참여자가 들어옴"**: 사용자가 방에 참여하는 데 성공한 시점에, *그 방의 호스트*에게 알림 트리거가 발화된다. 참여 취소(나가기)는 트리거를 발화하지 않는다(참여 성공 1회당 1건).
- **"내가 참여한 방의 모집이 조기 마감됨"**: 호스트가 모집을 마감(`closeRoomRecruit`)해 방의 상태가 `RECRUITING` → `IN_PROGRESS`로 전환된 시점에, 그 방의 *호스트를 제외한* 모든 참여자에게 알림 트리거가 발화된다. 자연 시작일 도래에 의한 자동 전환과 구분된다.
- **"내가 참여한 방의 활동이 시작됨"**: 방의 상태가 `IN_PROGRESS`로 진입한 시점에 그 방의 *참여자 전원*(또는 호스트를 제외한 멤버 — 운영 구현에 따름)에게 알림 트리거가 발화된다. 본 PRD는 *발화한다는 사실*과 *대상 범위가 방 참여자라는 점*만 보장한다.

> 위 \"조기 마감\"과 \"활동 시작\"은 모집 마감 시점에서 *함께* 발화될 수 있는 별개의 트리거다. 둘의 정확한 메시지·발화 순서·중복 방지 정책은 알림 도메인 PRD(#359)와 알림 템플릿이 다룬다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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에서 조기 마감과 활동 시작이 함께 발생할 때 각 트리거의 중복 방지 규칙과 허용되는 발화 관계를 명시해 알림
계약과 테스트가 동일한 기준을 사용하도록 하세요.

Comment on lines +126 to +135
- **알림 소유자 검증**: 사용자는 자신이 수신자인 알림에 대해서만 읽음 처리·삭제·상세 조회가 가능하다. 타인의 알림에 대한 어떤 조작도 거부된다.
- **이미 읽음 처리된 알림의 재읽음**: 상태는 변경되지 않으나 라우팅 정보는 매번 응답된다(클라이언트가 클릭 시 항상 화면 이동 가능해야 함).
- **수신 여부 토글 멱등성 차단**: 이미 동일한 상태로 변경을 요청하면 거부된다(켜진 상태에서 *켜기*, 꺼진 상태에서 *끄기*).
- **자기 행위에 대한 알림**: 자기 자신에게 알림이 가는 행위(예: 내 댓글에 내가 답글)는 본 PRD가 직접 방지하지 않는다. 각 발화 도메인 PRD가 그 의미 없는 자기 알림을 *발화하지 않도록* 책임을 진다(또는 그렇게 설계되어 있다).
- **수신 여부 OFF 디바이스의 동작**: 그 디바이스로 푸시는 전달되지 않으나, 알림 센터에는 변함없이 누적된다. 사용자가 앱을 열면 모두 보인다.
- **타 사용자 토큰 조작 방어**: 다른 사용자의 디바이스 토큰을 자신이 수정·삭제·수신 여부 토글하려는 시도는 거부된다.
- **알림 라우팅 미정**: 라우팅 종류가 "이동 안 함"(NONE)인 알림은 클릭해도 화면이 이동하지 않으나 읽음 처리는 정상 동작한다.
- **외부 푸시 채널 일시 장애**: 외부 푸시 전달이 실패해도 알림 센터에 누적된 알림은 손실되어서는 안 된다(저장과 전달은 독립적).
- **삭제·탈퇴된 발화 주체**: 발화를 만든 행위자(예: 좋아요 누른 사용자)가 이후 탈퇴해도, 이미 발화된 알림 자체는 사용자 입장에서 일관되게 보여야 한다(상세 정책은 사용자 라이프사이클 도메인 PRD를 따른다).
- **알림 보존 (확정 — 현재 정책)**: 사용자별 알림은 *평생 누적*된다. 자동 삭제·만료 정책은 없으며, 사용자 수동 삭제 기능도 *현재 시점에는 제공되지 않는다*. 사용자 알림 센터에 도착한 알림은 읽음 처리 여부와 무관하게 계속 남는다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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의 평생 보존 정책과 모순되지 않게 정리하세요.

@hd0rable
hd0rable merged commit 10ed529 into develop Jul 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant