[BE-09] 컨텍스트 룸 provision + 커뮤니티 채팅 연동
작업 내용 (설계 의도)
변경 사항
근거 TDD: 20260704-채팅시스템고도화-tdd.md (FR-4/5/16/17, 도메인 이벤트 연동, 자동 가입 멱등).
커뮤니티 이벤트를 소비해 전용 그룹 채팅방을 자동 생성·참여·퇴장시킨다. 도메인 교차 참조 없이 presentation EventWorker + ID로 연결.
domain/message/service/RoomContextDomainService.kt(신규):provision(contextType, contextId, name, hostUserId)—findByContext없으면Room.createForContext(BE-03a) 생성 + 방장 참여.joinContext(contextType, contextId, userId)— 이미 참여자면 skip(멱등).leaveContext(contextType, contextId, userId)— 참여자 soft-delete.application/message/usecase/: ProvisionContextRoomUseCase, JoinContextRoomUseCase, LeaveContextRoomUseCase (신규).presentation/community/worker/CommunityChatIntegrationEventWorker.kt(신규):@TransactionalEventListener(AFTER_COMMIT).- CommunityCreatedEvent → ProvisionContextRoomUseCase(COMMUNITY, communityId, name, hostUserId).
- CommunityMemberJoinedEvent → JoinContextRoomUseCase(COMMUNITY, communityId, userId).
- CommunityMemberLeftEvent → LeaveContextRoomUseCase(COMMUNITY, communityId, userId).
- 멱등: eventId 기반 중복 소비 방어 +
existsByRoomIdAndUserIdskip. - 롤백: EventWorker는 community 플래그와 함께 비활성. 컨텍스트 룸은 additive.
의존
- BE-03a (Room.createForContext, findByContext)
- BE-08 (커뮤니티 이벤트)
다이어그램
처리 흐름
sequenceDiagram participant Com as CommunityDomainService participant Pub as EventPublisher participant W as CommunityChatIntegrationEventWorker participant UC as Provision/Join/LeaveContextRoomUseCase participant DS as RoomContextDomainService Com-->>Pub: CommunityCreatedEvent Pub->>W: AFTER_COMMIT W->>UC: provision(COMMUNITY, id, name, host) UC->>DS: findByContext or createForContext + 방장 참여
테스트 케이스
- 커뮤니티 개설 이벤트 수신 시 contextType=COMMUNITY 전용 그룹 방이 자동 생성되고 방장이 참여자로 등록된다.
- 멤버 가입 이벤트 수신 시 해당 커뮤니티 방에 참여자로 자동 등록된다.
- 이미 참여 중인 사용자의 가입 이벤트를 재수신해도 중복 참여자가 생기지 않는다 (멱등).
- 멤버 탈퇴/강퇴 이벤트 수신 시 연결된 방에서 자동 퇴장 처리된다.
- 동일 커뮤니티에 대해 방이 이미 있으면 provision이 새 방을 만들지 않는다.