users
social_accounts
onboarding_profiles
practice_contents
reference_audios
courses
course_steps
user_course_progress
training_sessions
voice_recordings
analysis_results
analysis_segments
users
├── 1:N social_accounts
├── 1:N onboarding_profiles
├── 1:N user_course_progress
└── 1:N training_sessions
practice_contents
├── 1:N reference_audios
├── 1:N course_steps
└── 1:N training_sessions
courses
├── 1:N course_steps
└── 1:N user_course_progress
course_steps
├── 1:N training_sessions
└── 1:N user_course_progress(last_step_id)
training_sessions
└── 1:N voice_recordings
voice_recordings
└── 1:1 analysis_results
analysis_results
└── 1:N analysis_segments
회원 기본 정보와 인증/권한 정보를 저장한다.
| 컬럼 | 타입 | 제약 | 설명 |
|---|---|---|---|
| id | BIGINT | PK, IDENTITY, NN | 사용자 식별자 |
| VARCHAR(255) | UK, NULL | 일반 로그인 이메일. OAuth 회원은 없을 수 있음 | |
| password | VARCHAR(255) | NULL | 일반 로그인 비밀번호 해시. OAuth 전용 회원은 NULL |
| nickname | VARCHAR(50) | NN | 사용자 표시 이름 |
| status | VARCHAR(20) | NN, CHECK | 회원 상태 |
| terms_agreed_at | TIMESTAMPTZ | NN | 서비스 이용약관 동의 시각 |
| privacy_agreed_at | TIMESTAMPTZ | NN | 개인정보 처리방침 동의 시각 |
| last_login_at | TIMESTAMPTZ | NULL | 마지막 로그인 시각 |
| created_at | TIMESTAMPTZ | NN | 생성 시각 |
| updated_at | TIMESTAMPTZ | NN | 수정 시각 |
| deleted_at | TIMESTAMPTZ | NULL | 탈퇴/삭제 시각 |
| role | VARCHAR(63) | NN, CHECK | 사용자 권한 |
제약조건:
PK: users_pkey(id)
UK: uq_users_email(email)
CHECK: status IN ('ACTIVE', 'SUSPENDED', 'WITHDRAWN')
CHECK: role IN ('USER', 'ADMIN')
OAuth/SNS 로그인 계정 연결 정보를 저장한다.
| 컬럼 | 타입 | 제약 | 설명 |
|---|---|---|---|
| id | BIGINT | PK, IDENTITY, NN | 소셜 계정 식별자 |
| user_id | BIGINT | FK, NN | 연결된 사용자 ID |
| provider | VARCHAR(20) | NN, CHECK | OAuth 제공자 |
| provider_user_id | VARCHAR(255) | NN | 제공자 내부 사용자 ID |
| provider_email | VARCHAR(255) | NULL | 제공자에서 내려준 이메일 |
| created_at | TIMESTAMPTZ | NN | 연결 생성 시각 |
제약조건:
PK: social_accounts_pkey(id)
FK: user_id -> users.id
UK: uq_social_accounts_provider_user(provider, provider_user_id)
UK: uq_social_accounts_user_provider(user_id, provider)
CHECK: provider IN ('GOOGLE', 'KAKAO', 'NAVER', 'APPLE')
온보딩 설문 결과와 학습 목표를 저장한다.
| 컬럼 | 타입 | 제약 | 설명 |
|---|---|---|---|
| id | BIGINT | PK, IDENTITY, NN | 온보딩 프로필 식별자 |
| user_id | BIGINT | FK, NN | 사용자 ID |
| current_level | VARCHAR(30) | NULL | 현재 말하기 수준 |
| goal_text | VARCHAR(500) | NULL | 학습 목표 |
| daily_goal_minutes | INTEGER | NULL | 하루 목표 학습 시간 |
| weekly_goal_count | INTEGER | NULL | 주간 목표 학습 횟수 |
| survey_answers | JSONB | NN | 복수 선택형 온보딩 응답 |
| completed_at | TIMESTAMPTZ | NULL | 온보딩 완료 시각 |
| updated_at | TIMESTAMPTZ | NN | 수정 시각 |
제약조건:
PK: onboarding_profiles_pkey(id)
FK: user_id -> users.id