# 2026-03-27 작업 내역: 임시 음성 채널 기능 구현

## 체인지로그 (Changelog)
- **2026-03-27**: Kord 봇 음성 채널 제어 시스템 스펙 기획 및 전체 로직 구현 완료

## 본문 (Body)

### 1. 🎯 주요 목표 (Objective)
사용자가 봇 서버의 특정한 '생성용 채널(Generator)'에 입장하면, 유저 본인 소유의 '임시 전용 채널'을 만들어 주고, 빈 방이 되었을 때 삭제하여 채널 환경을 깔끔하게 유지하는 자동화 시스템 및 티어 기반 한도 제어 시스템을 구축.

### 2. 📝 진행 내역 (Work Done)
- **DB 스키마(Prisma) 설계 및 반영**:
  - `SubscriptionTier` (FREE, STANDARD, PRO, PREMIUM) 추가.
  - `UserSubscription`, `GuildOwnership` 모델 생성하여 관리자 티어에 따른 리소스 상속 체계 마련.
  - `VoiceGenerator`, `TempVoiceChannel`, `UserVoiceProfile` 모델 반영.
- **백엔드 리소스 개발**:
  - `src/commands/voiceSetup.ts`: 특정 채널을 생성용(Generator)으로 지정하는 슬래시 커맨드.
  - `src/events/voiceStateUpdate.ts`, `src/services/VoiceService.ts`: 유저 접속 및 퇴장 이벤트를 감지하여 데이터베이스 검증을 거친 후 동적으로 채널을 생성/삭제하는 핵심 로직 구현.
- **인터랙션/UI 개발**:
  - `src/events/interactionCreate.ts`: 생성된 임시 채널 채팅창에 띄워진 조작 패널(단일 드롭다운 StringSelectMenu)에 대응하는 Modal 및 Select Menu 핸들러 추가. (이름 변경, 인원수 제한, Lock/Unlock, Kick, Ban)
  - 사용자 피드백 반영: 조작 패널을 기존 6개 버튼에서 단일 드롭다운(StringSelectMenu)으로 리팩토링하여 UI 깔끔함 확보.

### 3. 🤔 주요 의사결정 (Decisions Made)
- **차단(Ban) 동작 정의**: 특정 인터랙션에서 유저 밴 기능을 수행할 경우, 음성 채널 설정(Overwrite) API를 사용하여 해당 유저의 `Connect`, `ViewChannel` 권한을 모두 박탈함으로써 채널 텍스트 캐시 및 접속을 완전히 보이지 않게(투명화) 설계함.
- **티어 권한 소유 구조**: 서버 단위가 주체가 되는 것이 아니라, 봇을 초대한 '사용자 단위'가 주체가 되도록 `GuildOwnership`과 `UserSubscription`을 연결. 추후 다양한 서비스에 재활용 가능하도록 기반 구축. (`Docs/Decisions/subscription_tiers.md` 참고)

### 4. 🛠️ 트러블슈팅 (Troubleshooting)
- **TypeScript 타입 캐스팅 관련 이슈**: 
  - *문제*: `interactionCreate`에서 `interaction.member.voice` 에 접근 시 `APIInteractionGuildMember` 타입과의 충돌로 컴파일(`yarn build`) 에러 발생.
  - *해결*: `interaction.member as GuildMember` 명시적 타입 캐스팅을 통해 `voice.channel` 객체 보장 및 에러 해결 완료.
- **런타임 초기화 - 디스코드 권한(Intents) 충돌**:
  - *문제*: 로컬 구동 테스트 중 `Error: Used disallowed intents` 발생.
  - *원인*: `KordClient` 부팅 시 `GuildMembers`, `MessageContent`, `Presence` 세 가지 Privileged Gateway Intent를 요구하나 디스코드 온라인 설정상 비활성화되어 있음.
  - *해결*: 개발 과정에선 소스 오류가 아님을 확인 후, 사용자에게 디스코드 포털에서의 활성화 작업 요청 조치.
- **채널 생성 권한 충돌 (50013: Missing Permissions)**:
  - *문제*: 봇이 임시 채널을 생성할 때 방장에게 `ManageRoles`, `ManageChannels` 등의 오버라이드 권한을 주려 했으나, 봇 자신에게 해당 권한이 서버 수준에서 부족하여 생성 실패 에러 발생.
  - *해결*: 권한 덮어쓰기 로직에 try-catch 래핑을 추가하여 실패 시 권한 오버라이드를 제외한 순정 채널로 생성하도록 우회 해결. 자세한 사항은 [50013_Missing_Permissions.md](../Troubleshooting/50013_Missing_Permissions.md) 참고.
- **퇴장 시 채널 미삭제 및 유령 방 버그**:
  - *문제*: 채널 내에 음악봇 등 봇만 남았을 때 삭제 조건이 작동하지 않고, 권한 문제로 삭제가 실패했을 때 DB 무결성이 깨지는 버그.
  - *해결*: 휴먼 카운트(`humanCount`) 도입 및 삭제 롤백 검증 처리. 자세한 사항은 [handleLeave_ghost_channel.md](../Troubleshooting/handleLeave_ghost_channel.md) 참조.
- **멀티 인스턴스 대응 및 봇 재부팅 복구 (Boot Recovery)**:
  - *사유*: 봇 재시작, 크래시, 혹은 다중 노드(Multi-Instance) 환경에서 DB와 디스코드 실제 채널 상태가 어긋나게 될 경우를 방지.
  - *해결*: `ioredis` 분산 락(Distributed Lock)과 결합된 `VoiceService.syncChannels` 메서드를 구현하여, 부팅 시 딱 하나의 인스턴스만 DB를 훑으며 삭제되어야 할 유령 방들을 크로스체크 및 안전하게 청소(Garbage Collection)하도록 반영.
