# 데이터베이스 테이블 구조 이 문서는 [Prisma 스키마](../prisma/schema.prisma)를 기준으로 한 **PostgreSQL** 테이블 구조 요약입니다. ## 개요 | 항목 | 값 | |------|-----| | DB | PostgreSQL | | ORM | Prisma (`prisma-client-js`) | | 연결 | `DATABASE_URL` 환경 변수 | ## 열거형 (Enum) ### `SubscriptionTier` 구독 단계. | 값 | 설명 | |----|------| | `FREE` | 기본 | | `STANDARD` | 스탠다드 | | `PRO` | 프로 | | `PREMIUM` | 프리미엄 | ### `DeleteCondition` 임시 음성 채널 삭제 조건. | 값 | 설명 | |----|------| | `OWNER_LEAVE` | 소유자 퇴장 시 | | `EMPTY` | 비었을 때 (기본) | ### `EventStatus` 길드 이벤트 상태. | 값 | 설명 | |----|------| | `SCHEDULED` | 예정 (기본) | | `CANCELLED` | 취소 | | `COMPLETED` | 완료 | --- ## 테이블 목록 ### `GuildConfig` 디스코드 길드별 봇 설정. | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `guildId` | `String` | PK | | `prefix` | `String` | 기본 `!` | | `mimicEnabled` | `Boolean` | 기본 `false` | | `bigEmojiEnabled` | `Boolean` | 기본 `false` | | `locale` | `String?` | nullable | | `createdAt` | `DateTime` | 생성 시각 | | `updatedAt` | `DateTime` | 자동 갱신 | --- ### `InviteRole` 길드·초대 코드별 역할 매핑. | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `id` | `String` | PK, UUID | | `guildId` | `String` | | | `inviteCode` | `String` | | | `roleId` | `String` | | | `createdAt` | `DateTime` | | **유니크:** `(guildId, inviteCode)` --- ### `UserSubscription` 사용자 구독 정보. | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `userId` | `String` | PK | | `tier` | `SubscriptionTier` | 기본 `FREE` | | `createdAt` | `DateTime` | | | `updatedAt` | `DateTime` | | **관계:** `GuildOwnership[]` (1:N) --- ### `GuildOwnership` 구독 사용자가 소유하는 길드. | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `guildId` | `String` | PK | | `ownerId` | `String` | FK → `UserSubscription.userId`, `ON DELETE CASCADE` | | `createdAt` | `DateTime` | | **인덱스:** `ownerId` --- ### `VoiceGenerator` 음성 채널 생성기(부모 채널) 설정. | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `channelId` | `String` | PK | | `guildId` | `String` | | | `categoryId` | `String?` | | | `createdAt` | `DateTime` | | | `updatedAt` | `DateTime` | | **인덱스:** `guildId` --- ### `TempVoiceChannel` 생성된 임시 음성 채널. | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `channelId` | `String` | PK | | `guildId` | `String` | | | `ownerId` | `String` | | | `deleteWhen` | `DeleteCondition` | 기본 `EMPTY` | | `createdAt` | `DateTime` | | **인덱스:** `guildId`, `ownerId` --- ### `UserVoiceProfile` 길드별 사용자 음성 프로필(표시 이름·인원 제한 등). | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `userId` | `String` | 복합 PK | | `guildId` | `String` | 복합 PK | | `customName` | `String?` | | | `userLimit` | `Int?` | | | `createdAt` | `DateTime` | | | `updatedAt` | `DateTime` | | **PK:** `(userId, guildId)` --- ### `UserLocale` 사용자별 로케일. | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `userId` | `String` | PK | | `locale` | `String` | | | `createdAt` | `DateTime` | | | `updatedAt` | `DateTime` | | --- ### `AuditChannel` 감사 로그 전달 채널·비활성 카테고리. | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `guildId` | `String` | PK | | `channelId` | `String` | | | `disabledCategories` | `String[]` | 기본 `["BOOT", "SYSTEM"]` | | `createdAt` | `DateTime` | | | `updatedAt` | `DateTime` | | --- ### `VoiceGuildConfig` 길드 단위 음성(임시 채널) 기본 설정. | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `guildId` | `String` | PK | | `defaultNameTemplate` | `String` | 기본 `{{username}}'s Room` | | `defaultUserLimit` | `Int` | 기본 `0` | | `createdAt` | `DateTime` | | | `updatedAt` | `DateTime` | | --- ### `GuildEvent` 길드 일정/이벤트. | 컬럼 | 타입 | 제약 / 기본값 | |------|------|----------------| | `id` | `String` | PK, UUID | | `guildId` | `String` | | | `title` | `String` | | | `description` | `String?` | | | `startsAt` | `DateTime` | | | `timezone` | `String` | 기본 `Asia/Seoul` | | `status` | `EventStatus` | 기본 `SCHEDULED` | | `announcementChannelId` | `String?` | | | `createdByUserId` | `String` | | | `reminderEnabled` | `Boolean` | 기본 `true` | | `reminderOffsets` | `Int[]` | 기본 `[]` | | `sentReminderOffsets` | `Int[]` | 기본 `[]` | | `remindedOneHour` | `Boolean` | 기본 `false` | | `remindedTenMinutes` | `Boolean` | 기본 `false` | | `startedAnnounced` | `Boolean` | 기본 `false` | | `announcedAt` | `DateTime?` | | | `createdAt` | `DateTime` | | | `updatedAt` | `DateTime` | | **인덱스:** `(guildId, startsAt)`, `(guildId, status)` --- ## 관계 요약 ```mermaid erDiagram UserSubscription ||--o{ GuildOwnership : "userId" ``` - **UserSubscription** 1 — N **GuildOwnership** (`ownerId` → `userId`, 길드 삭제 시 소유권 행 CASCADE 삭제) 그 외 테이블은 Prisma 모델상 **명시적 `relation` 블록**이 없으며, `guildId` / `userId` / `channelId` 등이 애플리케이션 레벨에서 Discord ID로 연결됩니다. ## 스키마 변경 시 실제 DDL은 `prisma/migrations/` 아래 마이그레이션 SQL과 동기화됩니다. 구조를 바꾼 뒤에는 이 문서와 [schema.prisma](../prisma/schema.prisma)를 함께 맞추는 것이 좋습니다.