데이터베이스 스키마¶
Open Codelabs의 SQLite 데이터베이스 스키마를 설명합니다.
ERD (Entity Relationship Diagram)¶
erDiagram
CODELABS ||--o{ STEPS : "contains"
CODELABS ||--o{ ATTENDEES : "enrolled_by"
CODELABS ||--o{ HELP_REQUESTS : "receives"
CODELABS ||--o{ CHAT_MESSAGES : "stores"
CODELABS ||--o{ FEEDBACK : "collects"
CODELABS ||--o{ MATERIALS : "provides"
CODELABS ||--o{ QUIZZES : "includes"
ATTENDEES ||--o{ HELP_REQUESTS : "makes"
ATTENDEES ||--o{ FEEDBACK : "submits"
ATTENDEES ||--o{ QUIZ_SUBMISSIONS : "answers"
QUIZZES ||--o{ QUIZ_SUBMISSIONS : "has"
테이블 설명¶
codelabs¶
Codelab의 메타데이터와 설정을 저장합니다.
CREATE TABLE IF NOT EXISTS codelabs (
id VARCHAR(255) PRIMARY KEY NOT NULL,
title VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
author VARCHAR(255) NOT NULL,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
is_public INTEGER NOT NULL DEFAULT 1,
quiz_enabled INTEGER DEFAULT 0,
require_quiz INTEGER DEFAULT 0,
require_feedback INTEGER DEFAULT 0
);
| 컬럼 | 타입 | 설명 | 제약 |
|---|---|---|---|
id |
VARCHAR | UUID | PRIMARY KEY |
title |
VARCHAR | Codelab 제목 | NOT NULL |
description |
TEXT | Codelab 설명 | NOT NULL |
author |
VARCHAR | 작성자 이름 | NOT NULL |
created_at |
TEXT | 생성 시간 | DEFAULT CURRENT_TIMESTAMP |
is_public |
INTEGER | 공개 여부 (1: 공개, 0: 비공개) | DEFAULT 1 |
quiz_enabled |
INTEGER | 퀴즈 활성화 여부 | DEFAULT 0 |
require_quiz |
INTEGER | 수료 시 퀴즈 통과 필수 여부 | DEFAULT 0 |
require_feedback |
INTEGER | 수료 시 피드백 제출 필수 여부 | DEFAULT 0 |
steps¶
Codelab의 개별 단계를 저장합니다.
CREATE TABLE IF NOT EXISTS steps (
id VARCHAR(255) PRIMARY KEY NOT NULL,
codelab_id VARCHAR(255) NOT NULL,
step_number INTEGER NOT NULL,
title VARCHAR(255) NOT NULL,
content_markdown TEXT NOT NULL,
FOREIGN KEY (codelab_id) REFERENCES codelabs(id) ON DELETE CASCADE
);
| 컬럼 | 타입 | 설명 | 제약 |
|---|---|---|---|
id |
VARCHAR | UUID | PRIMARY KEY |
codelab_id |
VARCHAR | 속한 Codelab ID | FOREIGN KEY |
step_number |
INTEGER | 단계 순서 (1부터 시작) | NOT NULL |
title |
VARCHAR | Step 제목 | NOT NULL |
content_markdown |
TEXT | Markdown 콘텐츠 | NOT NULL |
attendees¶
Codelab 참가자 정보를 저장합니다.
CREATE TABLE IF NOT EXISTS attendees (
id VARCHAR(255) PRIMARY KEY NOT NULL,
codelab_id VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
code VARCHAR(255) NOT NULL,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
current_step INTEGER DEFAULT 1,
is_completed INTEGER DEFAULT 0,
completed_at TEXT,
FOREIGN KEY (codelab_id) REFERENCES codelabs(id) ON DELETE CASCADE
);
| 컬럼 | 타입 | 설명 | 제약 |
|---|---|---|---|
id |
VARCHAR | UUID | PRIMARY KEY |
codelab_id |
VARCHAR | 참여 중인 Codelab ID | FOREIGN KEY |
name |
VARCHAR | 참가자 이름 | NOT NULL |
code |
VARCHAR | 참가 코드 | NOT NULL |
current_step |
INTEGER | 현재 진행 중인 Step 번호 | DEFAULT 1 |
is_completed |
INTEGER | 수료 여부 (1: 완료, 0: 진행 중) | DEFAULT 0 |
completed_at |
TEXT | 수료 일시 | - |
created_at |
TEXT | 등록 시간 | DEFAULT CURRENT_TIMESTAMP |
help_requests¶
참가자의 도움 요청을 저장합니다.
CREATE TABLE IF NOT EXISTS help_requests (
id VARCHAR(255) PRIMARY KEY NOT NULL,
codelab_id VARCHAR(255) NOT NULL,
attendee_id VARCHAR(255) NOT NULL,
step_number INTEGER NOT NULL,
status VARCHAR(50) DEFAULT 'pending',
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (codelab_id) REFERENCES codelabs(id) ON DELETE CASCADE,
FOREIGN KEY (attendee_id) REFERENCES attendees(id) ON DELETE CASCADE
);
| 컬럼 | 타입 | 설명 | 제약 |
|---|---|---|---|
id |
VARCHAR | UUID | PRIMARY KEY |
codelab_id |
VARCHAR | Codelab ID | FOREIGN KEY |
attendee_id |
VARCHAR | 요청자 ID | FOREIGN KEY |
step_number |
INTEGER | 막힌 Step 번호 | NOT NULL |
status |
VARCHAR | 상태 (pending/resolved) | DEFAULT 'pending' |
created_at |
TEXT | 요청 시간 | DEFAULT CURRENT_TIMESTAMP |
chat_messages¶
실시간 채팅 및 DM 메시지를 저장합니다.
CREATE TABLE IF NOT EXISTS chat_messages (
id VARCHAR(255) PRIMARY KEY NOT NULL,
codelab_id VARCHAR(255) NOT NULL,
sender_name VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
msg_type VARCHAR(50) DEFAULT 'chat',
target_id VARCHAR(255),
FOREIGN KEY (codelab_id) REFERENCES codelabs(id) ON DELETE CASCADE
);
| 컬럼 | 타입 | 설명 | 제약 |
|---|---|---|---|
id |
VARCHAR | UUID | PRIMARY KEY |
codelab_id |
VARCHAR | Codelab ID | FOREIGN KEY |
sender_name |
VARCHAR | 발신자 이름 | NOT NULL |
message |
TEXT | 메시지 내용 | NOT NULL |
msg_type |
VARCHAR | 타입 (chat/dm) | DEFAULT 'chat' |
target_id |
VARCHAR | DM 대상 ID (Attendee ID) | - |
created_at |
TEXT | 전송 시간 | DEFAULT CURRENT_TIMESTAMP |
feedback¶
참가자 피드백을 저장합니다.
CREATE TABLE IF NOT EXISTS feedback (
id VARCHAR(255) PRIMARY KEY,
codelab_id VARCHAR(255) NOT NULL,
attendee_id VARCHAR(255),
difficulty VARCHAR(50) NOT NULL,
satisfaction VARCHAR(50) NOT NULL,
comment TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (codelab_id) REFERENCES codelabs(id) ON DELETE CASCADE
);
| 컬럼 | 타입 | 설명 | 제약 |
|---|---|---|---|
id |
VARCHAR | UUID | PRIMARY KEY |
codelab_id |
VARCHAR | Codelab ID | FOREIGN KEY |
attendee_id |
VARCHAR | 제출자 ID | UNIQUE (with codelab_id) |
difficulty |
VARCHAR | 난이도 (1-5) | NOT NULL |
satisfaction |
VARCHAR | 만족도 (1-5) | NOT NULL |
comment |
TEXT | 의견 (선택) | - |
created_at |
TEXT | 제출 시간 | DEFAULT CURRENT_TIMESTAMP |
materials¶
코드랩에 첨부된 자료(링크 또는 파일)를 저장합니다.
CREATE TABLE IF NOT EXISTS materials (
id VARCHAR(255) PRIMARY KEY NOT NULL,
codelab_id VARCHAR(255) NOT NULL,
title VARCHAR(255) NOT NULL,
material_type VARCHAR(50) NOT NULL,
link_url TEXT,
file_path TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (codelab_id) REFERENCES codelabs(id) ON DELETE CASCADE
);
| 컬럼 | 타입 | 설명 | 제약 |
|---|---|---|---|
id |
VARCHAR | UUID | PRIMARY KEY |
codelab_id |
VARCHAR | Codelab ID | FOREIGN KEY |
title |
VARCHAR | 자료 제목 | NOT NULL |
material_type |
VARCHAR | 유형 (link/file) | NOT NULL |
link_url |
TEXT | 링크 URL | - |
file_path |
TEXT | 파일 경로 | - |
created_at |
TEXT | 등록 시간 | DEFAULT CURRENT_TIMESTAMP |
quizzes¶
코드랩에 포함된 퀴즈 문항을 저장합니다.
CREATE TABLE IF NOT EXISTS quizzes (
id VARCHAR(255) PRIMARY KEY NOT NULL,
codelab_id VARCHAR(255) NOT NULL,
question TEXT NOT NULL,
options TEXT NOT NULL,
correct_answer INTEGER NOT NULL,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
quiz_type TEXT DEFAULT 'multiple_choice'
);
| 컬럼 | 타입 | 설명 | 제약 |
|---|---|---|---|
id |
VARCHAR | UUID | PRIMARY KEY |
codelab_id |
VARCHAR | Codelab ID | FOREIGN KEY |
question |
TEXT | 문제 내용 | NOT NULL |
options |
TEXT | 선택지 (JSON Array) | NOT NULL |
correct_answer |
INTEGER | 정답 인덱스 또는 값 | NOT NULL |
quiz_type |
TEXT | 유형 (multiple_choice/descriptive) | DEFAULT 'multiple_choice' |
created_at |
TEXT | 생성 시간 | DEFAULT CURRENT_TIMESTAMP |
quiz_submissions¶
참가자가 제출한 퀴즈 답변과 채점 결과를 저장합니다.
CREATE TABLE IF NOT EXISTS quiz_submissions (
id VARCHAR(255) PRIMARY KEY NOT NULL,
codelab_id VARCHAR(255) NOT NULL,
attendee_id VARCHAR(255) NOT NULL,
quiz_id VARCHAR(255) NOT NULL,
answer TEXT NOT NULL,
is_correct INTEGER NOT NULL,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (codelab_id) REFERENCES codelabs(id) ON DELETE CASCADE,
FOREIGN KEY (attendee_id) REFERENCES attendees(id) ON DELETE CASCADE,
FOREIGN KEY (quiz_id) REFERENCES quizzes(id) ON DELETE CASCADE
);
| 컬럼 | 타입 | 설명 | 제약 |
|---|---|---|---|
id |
VARCHAR | UUID | PRIMARY KEY |
codelab_id |
VARCHAR | Codelab ID | FOREIGN KEY |
attendee_id |
VARCHAR | 참가자 ID | FOREIGN KEY |
quiz_id |
VARCHAR | 퀴즈 ID | FOREIGN KEY |
answer |
TEXT | 제출 답변 | NOT NULL |
is_correct |
INTEGER | 정답 여부 (1: 정답, 0: 오답) | NOT NULL |
created_at |
TEXT | 제출 시간 | DEFAULT CURRENT_TIMESTAMP |
마이그레이션 목록¶
시스템은 sqlx를 사용하여 데이터베이스 스키마를 관리합니다. backend/migrations/ 폴더 내의 파일들은 다음 순서로 적용됩니다.
20251226161500_init.sql: 초기 테이블(codelabs, steps) 생성20251226161600_attendees.sql: 참가자, 도움 요청, 채팅 테이블 생성20251226161700_chat_enhancements.sql: 채팅 유형 및 대상 필드 추가20251227001500_attendee_progress.sql: 참가자 진행 단계 필드 추가20251227160000_create_feedback.sql: 피드백 테이블 생성20251227161000_add_attendee_feedback.sql: 피드백 제출자 정보 및 제약 추가20251227162000_add_is_public_to_codelabs.sql: 코드랩 공개 여부 필드 추가20251229150000_add_materials.sql: 첨부 자료 테이블 생성20251229160000_add_completion_to_attendees.sql: 수료 상태 및 일시 필드 추가20251229161000_quizzes.sql: 퀴즈 설정 필드 및 퀴즈 테이블 생성20251230113000_add_quiz_type.sql: 퀴즈 유형 필드 추가20251230120000_quiz_submissions.sql: 퀴즈 제출 결과 테이블 생성