post-community 연동 PRD

Background

community는 Community·CommunityMember Entity, CommunityDomainService, UseCase 10개, Controller, EventWorker까지 갖춘 완성 컨텍스트입니다(domain/community/**, application/community/**, presentation/community/**). postuserId/title/content/type(PostType: FREE/NOTICE/QUESTION/REVIEW)만 가진 전역 게시판으로, community를 전혀 참조하지 않습니다(domain/post/entity/Post.kt#PostcommunityId·SportCategory 필드 0건, post-community 상호 import 0건).

모임 기능이 완성됐는데도 모임 안에서 게시글을 쓸 방법이 없고, 종목별로 게시글을 묶어 볼 방법도 없는 것이 현재의 갭입니다. 이 PRD는 새 도메인을 만드는 것이 아니라 기존 post·community 두 컨텍스트를 연동해 재사용하는 것을 목표로 합니다.

Problem Definition

  • AS-IS: PostcommunityId가 없어 특정 모임에 소속시킬 수 없습니다(domain/post/entity/Post.kt:19-36). PostType은 종목 개념이 없고, PostCriteria(application/post/dto/PostCriteria.kt)의 검색 조건도 type/userId/keyword뿐이라 종목별 필터가 불가능합니다.
  • 사용자가 모임에 가입해도 그 모임 전용 게시판이 없어, 모임 관련 소통은 전역 게시판(비소속)에 뒤섞이거나 채팅(message Room, contextType=COMMUNITY)으로만 가능합니다.
  • 종목(축구/농구/러닝 등)별로 게시글을 묶어 보는 기능이 없어, 관심 종목 콘텐츠를 찾기 위해 전체 게시글을 훑어야 합니다.
  • docs/domain-context-map.md:20-21이 community를 “(VO만) — 구축 중”으로 기술하고 있어 실제 코드 상태(완성된 10개 UseCase)와 어긋납니다. SupportToCoreDependencyRulesTest.kt#DomainClassification.core 목록에도 community가 빠져 있어 코어 도메인 간 의존 규칙(R3) 검증 대상에서 누락돼 있습니다.

Goals / Non-Goals

Goals

  • post가 community에 선택적으로 소속될 수 있게 한다 — 모임 소속 게시글과 기존 전역(비소속) 게시글이 공존한다.
  • post가 종목(SportCategory)으로 분류될 수 있게 한다 — community의 기존 SportCategory VO를 재사용하고, 신규 종목 enum을 정의하지 않는다.
  • community의 기존 가시성·멤버십 규칙(CommunityVisibility, MembershipStatus, CommunityDomainService.requireActiveMember)을 그대로 재사용해 모임 소속 게시글의 열람·작성 인가를 구현한다 — 새 인가 모델을 설계하지 않는다.
  • 문서(docs/domain-context-map.md)와 아키텍처 검증 상수(DomainClassification.core)를 실제 코드 상태와 정합시킨다.

Non-Goals

  • 실제 인원 모집·신청·수수료(10%) — recruitment 소관 별도 과제, 이 PRD 범위 아님.
  • 소모임 시설 예약(booking) 연동 — 범위 아님.
  • community 본체 enum(CommunityRole/CommunityVisibility/MembershipStatus) 변경 — 근거 없이 변경하지 않는다. SportCategory재사용만 하고 값 추가·의미 변경을 하지 않는다.
  • 상품(goods)/주문/티켓(ticketing) 도메인 — 범위 아님.
  • 모임 게시글에 대한 신고·좋아요·북마크 등 부가 인터랙션 — 이 PRD 범위 아님(후속 과제).
  • 모임 탈퇴·강퇴 시 과거 작성 게시글의 삭제·이관 — 범위 아님. 게시글은 유지되고 열람 인가만 현재 시점 멤버십 상태로 재판정한다(Open Questions 참고).

User Scenarios

#페르소나시나리오유형
1PUBLIC 모임 멤버가입한 PUBLIC 모임 안에서 게시글을 작성하면, 같은 모임 멤버뿐 아니라 비멤버도 목록·상세를 열람할 수 있다해피 패스
2PRIVATE 모임 ACTIVE 멤버가입 승인된 PRIVATE 모임 안에서 게시글을 작성·열람·댓글 작성한다해피 패스
3PRIVATE 모임 비멤버PRIVATE 모임 게시글 목록·상세·댓글에 접근을 시도하면 거부된다(403)예외
4미가입 사용자어떤 모임에도 속하지 않고 전역(비소속) 게시글을 작성·열람한다 — 기존 동작 그대로해피 패스
5관심 종목 탐색 사용자SportCategory=RUNNING으로 게시글을 필터링하면 모임 소속·비소속을 가리지 않고 러닝 관련 게시글만 조회된다해피 패스
6종목 미지정 게시글 작성자전역 게시글 작성 시 종목을 지정하지 않으면, 종목 필터 없이 조회할 때만 노출되고 특정 종목 필터에는 걸리지 않는다엣지
7PRIVATE 모임 HOST모임 소속 게시글을 NOTICE로 작성한다해피 패스
8PRIVATE 모임 일반 멤버(MEMBER)모임 소속 게시글을 NOTICE로 작성 시도하면 거부된다예외
9전역 게시글 작성자모임에 속하지 않은 채로 NOTICE 게시글을 작성한다 — 기존처럼 제한 없이 허용(하위 호환)예외 경계 확인
10PENDING_APPROVAL 상태 가입 신청자아직 승인되지 않은 PRIVATE 모임의 게시글에 접근을 시도하면 비멤버와 동일하게 거부된다예외
11빈 상태 조회자특정 종목·특정 모임에 게시글이 0건이면 빈 목록을 정상 응답으로 받는다(에러 아님)엣지

Benchmarking

제품명카테고리참조 패턴URL
Strava Clubs피트니스 SNS클럽 생성 시 종목(sport type) 1개 필수 지정 → 클럽 피드가 종목 기준 필터링. 게시글은 Club Announcements(운영자만 작성)/Member Posts(멤버 누구나 작성) 2종으로 작성 권한이 게시글 성격에 따라 분리https://support.strava.com/hc/en-us/articles/18288273144973-Club-Posts
Band(밴드)소모임 SNS밴드(모임) 공개/비공개 설정 + 게시판 내 공지사항 탭을 일반글과 별도 노출, 공지 작성은 운영자 중심https://namu.wiki/w/%EB%B0%B4%EB%93%9C(SNS)
문토(Munto)관심사 기반 커뮤니티지속 소속 단위 ‘클럽’(승인 기반 멤버십)과 비소속으로도 이용 가능한 ‘라운지’(전역 게시판)를 이원화 — 모임 소속 여부와 무관하게 게시글 작성이 가능한 구조https://www.munto.kr/

Functional Requirements

ID요구사항우선순위
FR-1게시글은 특정 community에 선택적으로 소속될 수 있다(communityId 미지정 시 기존과 동일한 전역 게시글). 소속 시 어느 모임의 게시글인지 목록·상세 응답에 식별 가능해야 한다.P0
FR-2모임 소속 게시글의 열람(목록·상세·댓글) 인가는 소속 모임의 CommunityVisibility를 따른다 — PUBLIC 모임 게시글은 비멤버도 열람 가능, PRIVATE 모임 게시글은 ACTIVE 멤버만 열람 가능(비멤버·PENDING_APPROVAL은 거부).P0
FR-3모임 소속 게시글의 작성(게시글·댓글)은 해당 모임의 ACTIVE 멤버(HOST 포함)만 가능하다 — 비멤버는 거부된다.P0
FR-4community에 소속되지 않은 게시글(communityId 미지정)은 인가 검사 없이 기존과 동일하게 전체 공개로 동작한다(하위 호환).P0
FR-5게시글은 종목(SportCategory)으로 선택적으로 분류될 수 있다. 신규 종목 enum을 정의하지 않고 community의 기존 SportCategory VO를 재사용한다. 모임 소속 게시글은 작성 시점에 소속 모임의 sportCategory를 자동 상속한다(작성자가 별도로 지정하지 않는다).P1
FR-6게시글 목록·검색 조회에 종목(SportCategory) 필터를 추가한다. 필터를 지정하지 않으면 종목 미지정 게시글을 포함한 전체가 조회되고, 특정 종목으로 필터링하면 그 종목으로 분류된 게시글만(모임 소속·비소속 무관) 조회된다.P1
FR-7PostType=NOTICE인 게시글은 모임 소속일 경우 해당 모임의 HOST만 작성할 수 있다. 모임 비소속(전역) NOTICE 게시글은 기존 동작(작성 제한 없음)을 그대로 유지한다. FREE/QUESTION/REVIEW는 모임 소속 여부와 무관하게 작성 권한 제한이 없다.P1
FR-8docs/domain-context-map.md의 community 컨텍스트 설명을 실제 완성 상태(Entity·DomainService·UseCase 10개·Controller·EventWorker 완비)로 갱신하고, SupportToCoreDependencyRulesTest.kt#DomainClassification.core 목록에 community를 등록해 코어 간 의존 규칙(R3) 검증 대상에 포함시킨다.P2

Non-Functional Requirements

  • 모임 소속 여부·종목 필터가 추가된 게시글 목록 조회 API는 기존 SearchPostsUseCase 응답 시간 특성을 유지한다 — 신규 필터 추가로 인한 조회 지연은 P95 500ms 이내(로컬 개발 환경 기준, 기존 게시판 조회와 동일 목표선).
  • 페이지 크기 상한은 기존 정책(PostCriteria.MAX_PAGE_SIZE = 100)을 그대로 유지한다.
  • PRIVATE 모임 게시글에 대한 비인가 접근은 403(Forbidden)으로 응답한다 — 기존 CommunityDomainService.requireActiveMember 인가 실패 시 응답 규약과 동일하게 맞춘다.
  • community_id 컬럼은 FK 제약 없이 일반 컬럼으로 추가한다(정합성은 애플리케이션 레벨) — private-db-schema-convention의 FK 컬럼 금지 규칙을 따른다.
  • 신규 컬럼(community_id, sport_category)은 nullable로 단일 마이그레이션 추가하고 기존 행은 NULL로 유지한다(백필 없음) — 무중단 배포 전제(private-db-schema-convention “컬럼 추가(nullable)” 케이스).

Operations

  • 모임 소속 게시글 작성·PRIVATE 모임 접근 거부(403) 발생 건수를 로그 또는 카운터로 관측한다 — 인가 로직 배포 직후 예상보다 거부율이 급증하면 멤버십 상태 조회 로직 결함 신호로 본다.
  • 신규 필터(종목·모임 소속) 포함 게시글 조회 API의 응답 시간을 배포 전후로 비교해 회귀 여부를 확인한다.
  • FR-8 반영 후 SupportToCoreDependencyRulesTest가 community 패키지를 대상으로도 통과하는지 CI에서 확인한다.

Success Metrics

측정 항목만 확정합니다(목표 수치는 런칭 후 베이스라인 확보 뒤 별도 결정).

  • 전체 게시글 대비 모임 소속 게시글(communityId non-null) 비율 — 측정: DB 집계 쿼리
  • 전체 게시글 대비 종목 지정 게시글(sportCategory non-null) 비율 — 측정: DB 집계 쿼리
  • 종목 필터를 포함한 게시글 조회 API 호출 비율 — 측정: API 호출 로그 집계
  • PRIVATE 모임 게시글 비인가 접근 시도(403) 건수 대비 전체 모임 게시글 접근 요청 건수 — 측정: API 응답 로그 집계
  • 모임 가입 후 D7 이내 해당 모임에 첫 게시글을 작성한 사용자 비율 — 측정: 가입 이벤트·게시글 작성 이벤트 타임스탬프 대조

Milestones

해당 없음 — 단일 범위로 P0(FR-1~FR-4)부터 P2(FR-8)까지 한 번에 진행합니다. 규모가 티켓 분해 단계에서 커지면 P0(모임 소속·인가) → P1(종목 분류·필터·NOTICE 권한) → P2(문서 정합) 순서로 wave를 나눌 수 있습니다(TPM 판단 영역).

Open Questions

  • 모임 탈퇴·강퇴 이력이 있는 사용자의 과거 작성 게시글 열람 인가 기준 — 이 PRD의 기본값은 “게시글은 유지되고, 열람 인가는 조회 시점의 현재 멤버십 상태로 판정한다”(작성자 본인도 탈퇴 후 PRIVATE 모임 게시글을 재열람할 수 없음)입니다. 다른 정책(예: 작성자 본인은 항상 열람 가능)을 원하면 알려주세요.
  • 댓글에도 게시글과 동일한 열람·작성 인가(FR-2/FR-3)를 적용하는 것으로 전제했습니다 — 댓글만 별도 완화된 규칙이 필요하면 알려주세요.
  • 종목 필터와 모임 소속 필터를 동시에 지정했을 때의 AND 조합 여부(예: 특정 모임 + 특정 종목 동시 필터) — 이 PRD는 두 필터가 독립적으로 AND 결합된다고 전제합니다.

Document History

날짜변경 내용
2026-07-06최초 작성 — post-community 연동(모임 소속 게시글, 종목별 분류) FR-1~FR-8 확정. 이전 stale 초안(20260706-모임커뮤니티컨텍스트구축-prd.md)은 폐기 대상이며 참조하지 않음