<aside> 📌
밴드 도메인은 BScene 플랫폼 내에서 음악 그룹과 관련된 라이프사이클, 멤버십, 소셜 상호작용을 관리합니다. 오디오 스트리밍, 공연 스케줄링, 게시물 생성의 핵심 엔티티 역할을 수행하며, owner·regular member·session member 등 복잡한 멤버십 상태와 한 명의 사용자가 밴드마다 서로 다른 프로필을 유지할 수 있는 멀티 페르소나 시스템을 지원합니다.
graph TD
User["User"] -->|"보유"| Profile["BandMemberProfile"]
User -->|"팔로우"| Follow["Follow"]
Follow -->|"대상"| Band["Band"]
Profile -->|"사용"| Member["BandMember"]
Member -->|"소속"| Band
Band -->|"owner"| User
Member -->|"상태"| Status["BandMemberStatus"]
Member -->|"타입"| Type["BandMemberType"]
| 기능 요구사항 | 코드 엔티티 |
|---|---|
| 밴드 생성 및 관리 | BandController, BandService |
| 밴드 멤버십 상태 추적 | BandMember, BandMemberStatus |
| 밴드 팔로우 및 알림 수신 | FollowRepository, BandAdapter |
| 사용자 선호 기반 밴드 추천 | BandRecommendationService |
| 스트리밍 시스템에 멤버 데이터 제공 | StreamAdapter, BandMemberPort |
Port 구현체는 BandMemberPortConfig에 정의되어 있습니다.
| Adapter | Target Port | 목적 |
|---|---|---|
| UserAdapter | BandPort | 마이페이지 및 온보딩을 위한 사용자 중심 밴드 데이터를 제공합니다. |
| StreamAdapter | BandMemberPort | 라이브 스트리밍 시스템을 위한 실시간 멤버 프로필 데이터를 제공합니다. |
| BandAdapter | FollowPort | 밴드 프로필의 팔로워 수 및 페이지네이션을 처리합니다. |
BandService.createBand 메서드가 생성 절차를 관리합니다.
BScene은 User와 밴드별 정체성을 BandMemberProfile로 분리합니다. 이를 통해 한 사용자가 A 밴드에서는 "Guitarist" 정체성을, B 밴드에서는 "Vocalist" 페르소나를 동시에 유지할 수 있습니다.
멤버십은 INVITED → ACCEPTED 또는 REJECTED의 상태 진행을 따릅니다.
| Status | 설명 | 허용 동작 |
|---|---|---|
| INVITED | owner가 초대하거나 링크로 진입한 직후의 초기 상태입니다. | Accept, Reject |
| ACCEPTED | 정식 밴드 멤버 상태입니다. | Stream(활성 상태인 경우), Post, Leave |
| REJECTED | 사용자가 초대를 거절한 상태입니다. | 없음(이력 보존용 기록) |
| Member Type | 설명 | 소유권 이전 대상 |
|---|---|---|
| MEMBER | 정규 밴드 멤버입니다. | Yes |
| SESSION | 모집을 통한 임시/계약직 멤버입니다. | No |
FAN 모드의 사용자는 밴드를 팔로우할 수 있으며, 동시 요청 발생 시 DataIntegrityViolationException을 포착하여 FollowErrorCode.ALREADY_FOLLOWED 에러로 변환하는 방식으로 처리합니다. 아키텍처는 헥사고날 패턴을 사용하며 BandPort 인터페이스를 통해 follow 서비스와 band 도메인을 분리합니다.
| 구성 요소 | 가중치 | 설명 |
|---|---|---|
| Explicit | 0.6 | Genre(3.0), Region(2.0), Recent Activity(1.0)에 대한 매칭입니다. |
| Implicit | 0.4 | 팔로우한 밴드와의 유사도(가중치 1.0) 또는 클릭한 밴드와의 유사도(가중치 0.5)입니다. |
| Popularity | 0.5 | 총 팔로워 수(30%)와 최근 팔로워 성장률(70%)의 결합 점수입니다. |
Python 기반의 ml-server는 SentenceTransformer와 ko-sroberta-multitask 모델을 사용하여 밴드 설명을 임베딩으로 변환하고 코사인 유사도를 계산합니다. 0.55 임계값을 초과하는 결과는 band_similarity 테이블에 저장되며, 무중단 갱신을 위해 스테이징 테이블 적재 후 원자적 스왝 방식을 사용합니다.
사용자의 클릭은 InteractionService.recordClick을 트리거합니다. 시스템은 ON DUPLICATE KEY UPDATE 쿼리를 사용하여 클릭 카운트에 대한 원자적 증가 연산과 last_interacted_at 갱신을 수행하며, 스팸 방지를 위한 중복 제거 로직도 함께 적용합니다.