smarteye-backend / scripts /init_db_complete.sql
AkJeond's picture
fix: ์ดˆ๊ธฐํ™” SQL ๋ฐ README ๋ฌธ์„œ์˜ ํฌ๋งทํŒ… ๊ทœ์น™ ์—…๋ฐ์ดํŠธ
a7d9336
-- ============================================================================
-- SmartEyeSsen Database Schema (Final Production Version v2)
-- ============================================================================
-- ํ”„๋กœ์ ํŠธ๋ช…: SmartEyeSsen - AI ๊ธฐ๋ฐ˜ ํ•™์Šต์ง€ ๋ถ„์„ ์‹œ์Šคํ…œ
-- ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค: smarteyessen_db
-- ๋ฌธ์ž์…‹: utf8mb4 (์ด๋ชจ์ง€, ๋‹ค๊ตญ์–ด ์ง€์›)
-- ์—”์ง„: InnoDB (ํŠธ๋žœ์žญ์…˜, ์™ธ๋ž˜ํ‚ค ์ง€์›)
-- ์ด ํ…Œ์ด๋ธ” ์ˆ˜: 12๊ฐœ
-- ์ตœ์ข… ์ˆ˜์ •์ผ: 2025-01-22 (v2)
-- ์ž‘์„ฑ์ž: SmartEyeSsen Team
-- ์ฃผ์š” ๋ณ€๊ฒฝ์‚ฌํ•ญ: ๋ฌธ์ œ ๋ ˆ์ด์•„์›ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฐ˜์˜ (์•ต์ปค/์ž์‹ ๊ฐœ๋…)
-- ============================================================================
-- ============================================================================
-- ๐Ÿ“‹ ํ…Œ์ด๋ธ” ๋ชฉ๋ก ๋ฐ ๊ด€๊ณ„ (v2)
-- ============================================================================
-- 1. users (์‚ฌ์šฉ์ž ๊ด€๋ฆฌ) - ๋…๋ฆฝ ํ…Œ์ด๋ธ”
-- 2. document_types (๋ฌธ์„œ ํƒ€์ž… ์ •์˜) - ๋…๋ฆฝ ํ…Œ์ด๋ธ” [์ˆ˜์ •]
-- 3. projects (ํ”„๋กœ์ ํŠธ/์„ธ์…˜) - FK: user_id, doc_type_id
-- 4. pages (ํŽ˜์ด์ง€ ์ •๋ณด) - FK: project_id
-- 5. layout_elements (๋ ˆ์ด์•„์›ƒ ์š”์†Œ) - FK: page_id [์ˆ˜์ •]
-- 6. text_contents (OCR ๊ฒฐ๊ณผ) - FK: element_id (1:1)
-- 7. ai_descriptions (AI ์„ค๋ช…) - FK: element_id (1:1)
-- 8. question_groups (๋ฌธ์ œ ๊ทธ๋ฃน) - FK: page_id, anchor_element_id [์ˆ˜์ •]
-- 9. question_elements (๋ฌธ์ œ-์š”์†Œ ๋งคํ•‘) - FK: question_group_id, element_id
-- 10. text_versions (ํ…์ŠคํŠธ ๋ฒ„์ „ ๊ด€๋ฆฌ) - FK: page_id, user_id
-- 11. formatting_rules (ํฌ๋งทํŒ… ๊ทœ์น™) - FK: doc_type_id [์ˆ˜์ •]
-- 12. combined_results (ํ†ตํ•ฉ ๋ฌธ์„œ ์บ์‹œ) - FK: project_id (1:1)
-- ============================================================================
-- ๐Ÿ”— ์ฃผ์š” ๊ด€๊ณ„ ์š”์•ฝ (v2)
-- ============================================================================
-- users โ†’ projects (1:N)
-- document_types โ†’ projects (1:N)
-- document_types โ†’ formatting_rules (1:N)
-- projects โ†’ pages (1:N)
-- projects โ†’ combined_results (1:1)
-- pages โ†’ layout_elements (1:N)
-- pages โ†’ question_groups (1:N)
-- pages โ†’ text_versions (1:N)
-- layout_elements โ†’ text_contents (1:1)
-- layout_elements โ†’ ai_descriptions (1:1)
-- layout_elements โ†’ question_groups (1:1) [์‹ ๊ทœ] - ์•ต์ปค ๊ด€๊ณ„
-- layout_elements โ† question_elements (N:1)
-- question_groups โ†’ question_elements (1:N)
-- ============================================================================
-- ๐Ÿ†• v2 ์ฃผ์š” ๋ณ€๊ฒฝ์‚ฌํ•ญ
-- ============================================================================
-- 1. document_types.sorting_method: 'coordinate_based' โ†’ 'reading_order'๋กœ ํ†ตํ•ฉ
-- 2. layout_elements.order_index: ์‚ญ์ œ (Y,X ์ขŒํ‘œ๋กœ ๋™์  ์ •๋ ฌ)
-- 3. question_groups.question_number: ์‚ญ์ œ
-- 4. question_groups.anchor_element_id: ์ถ”๊ฐ€ (FK โ†’ layout_elements)
-- 5. layout_elements โ†” question_groups: 1:1 ์•ต์ปค ๊ด€๊ณ„ ์‹ ์„ค
-- 6. formatting_rules: ์•ต์ปค/์ž์‹ ํด๋ž˜์Šค ๊ทœ์น™ ์ถ”๊ฐ€
-- ============================================================================
-- ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ƒ์„ฑ (๊ธฐ์กด DB๊ฐ€ ์žˆ์œผ๋ฉด ์‚ญ์ œ ํ›„ ์žฌ์ƒ์„ฑ)
-- ============================================================================
-- โš ๏ธ docker-entrypoint์˜ mysql ํด๋ผ์ด์–ธํŠธ ๊ธฐ๋ณธ ๋ฌธ์ž์…‹์€ latin1์ด๋ฏ€๋กœ
-- ํ•œ๊ธ€ INSERT ๋ฌธ์ด ๊นจ์ง€์ง€ ์•Š๋„๋ก ์„ธ์…˜ ๋ฌธ์ž์…‹์„ ๋จผ์ € ๊ฐ•์ œํ•œ๋‹ค.
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;
DROP DATABASE IF EXISTS smarteyessen_db;
CREATE DATABASE smarteyessen_db
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE smarteyessen_db;
-- ============================================================================
-- 1๏ธโƒฃ Users Table (์‚ฌ์šฉ์ž ๊ด€๋ฆฌ)
-- ============================================================================
-- ์„ค๋ช…: ์‹œ์Šคํ…œ ์‚ฌ์šฉ์ž ์ •๋ณด (ํ•™์ƒ, ๊ต์‚ฌ, ๊ด€๋ฆฌ์ž)
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ, ๊ถŒํ•œ ๊ด€๋ฆฌ, API ํ‚ค ๊ด€๋ฆฌ
-- ============================================================================
CREATE TABLE users (
-- ๊ธฐ๋ณธ ์ •๋ณด
user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '์‚ฌ์šฉ์ž ๊ณ ์œ  ID',
email VARCHAR(255) NOT NULL UNIQUE COMMENT '์ด๋ฉ”์ผ (๋กœ๊ทธ์ธ ID)',
name VARCHAR(100) NOT NULL COMMENT '์‚ฌ์šฉ์ž ์ด๋ฆ„',
role VARCHAR(50) NOT NULL DEFAULT 'user' COMMENT '์—ญํ•  (admin/teacher/student/user)',
-- ๋ณด์•ˆ ์ •๋ณด
password_hash VARCHAR(255) NOT NULL COMMENT 'bcrypt ํ•ด์‹œ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ',
api_key VARCHAR(255) DEFAULT NULL COMMENT 'OpenAI API ํ‚ค (AES-256 ์•”ํ˜ธํ™” ์ €์žฅ)',
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '๊ณ„์ • ์ƒ์„ฑ์ผ',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '๋งˆ์ง€๋ง‰ ์ˆ˜์ •์ผ',
-- ์ธ๋ฑ์Šค
INDEX idx_email (email) COMMENT '์ด๋ฉ”์ผ ๊ฒ€์ƒ‰ ์ตœ์ ํ™”',
INDEX idx_role (role) COMMENT '์—ญํ• ๋ณ„ ํ•„ํ„ฐ๋ง ์ตœ์ ํ™”'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='์‹œ์Šคํ…œ ์‚ฌ์šฉ์ž ์ •๋ณด';
-- ============================================================================
-- 2๏ธโƒฃ Document_Types Table (๋ฌธ์„œ ํƒ€์ž… ์ •์˜) [์ˆ˜์ •]
-- ============================================================================
-- ์„ค๋ช…: ๋ฌธ์„œ ์ข…๋ฅ˜๋ณ„ ์ฒ˜๋ฆฌ ๋ฐฉ์‹ ์ •์˜ (๋ฌธ์ œ์ง€/์ผ๋ฐ˜๋ฌธ์„œ)
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ๋ชจ๋ธ ์„ ํƒ, ์ •๋ ฌ ๋ฐฉ์‹ ์ง€์ •, ํฌ๋งทํŒ… ๊ทœ์น™ ์—ฐ๊ฒฐ
-- [v2 ๋ณ€๊ฒฝ] sorting_method ENUM: 'coordinate_based' โ†’ 'reading_order'๋กœ ํ†ตํ•ฉ
-- ============================================================================
CREATE TABLE document_types (
-- ๊ธฐ๋ณธ ์ •๋ณด
doc_type_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '๋ฌธ์„œ ํƒ€์ž… ๊ณ ์œ  ID',
type_name VARCHAR(100) NOT NULL UNIQUE COMMENT 'ํƒ€์ž…๋ช… (worksheet/document/form)',
-- ์ฒ˜๋ฆฌ ์„ค์ • [์ˆ˜์ •]
model_name VARCHAR(100) NOT NULL COMMENT 'AI ๋ชจ๋ธ๋ช… (SmartEyeSsen/DocLayout-YOLO)',
sorting_method ENUM('QUESTION_BASED', 'READING_ORDER') NOT NULL
COMMENT '์ •๋ ฌ ๋ฐฉ์‹: QUESTION_BASED(๋ฌธ์ œ์ง€, ์•ต์ปค-์ž์‹ ์žฌ๊ท€), READING_ORDER(์ผ๋ฐ˜๋ฌธ์„œ, Y/X ์ขŒํ‘œ)',
-- ๋ถ€๊ฐ€ ์ •๋ณด
description TEXT DEFAULT NULL COMMENT 'ํƒ€์ž… ์„ค๋ช…',
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '์ƒ์„ฑ์ผ',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '์ˆ˜์ •์ผ',
-- ์ธ๋ฑ์Šค
INDEX idx_type_name (type_name) COMMENT 'ํƒ€์ž…๋ช… ๊ฒ€์ƒ‰ ์ตœ์ ํ™”'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='๋ฌธ์„œ ํƒ€์ž… ์ •์˜ (๋ฌธ์ œ์ง€/์ผ๋ฐ˜๋ฌธ์„œ) - v2: ์ •๋ ฌ ๋ฐฉ์‹ ๋ช…ํ™•ํ™”';
-- ============================================================================
-- 3๏ธโƒฃ Projects Table (ํ”„๋กœ์ ํŠธ/์„ธ์…˜ ๊ด€๋ฆฌ)
-- ============================================================================
-- ์„ค๋ช…: ์‚ฌ์šฉ์ž์˜ ๋ถ„์„ ํ”„๋กœ์ ํŠธ (์—ฌ๋Ÿฌ ํŽ˜์ด์ง€ ํฌํ•จ)
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ, ์ง„ํ–‰๋ฅ  ์ถ”์ , ์ƒํƒœ ๊ด€๋ฆฌ
-- ============================================================================
CREATE TABLE projects (
-- ๊ธฐ๋ณธ ์ •๋ณด
project_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ํ”„๋กœ์ ํŠธ ๊ณ ์œ  ID',
user_id INT NOT NULL COMMENT '์†Œ์œ ์ž ID (FK: users, ON DELETE CASCADE)',
doc_type_id INT NOT NULL COMMENT '๋ฌธ์„œ ํƒ€์ž… ID (FK: document_types, ON DELETE RESTRICT)',
project_name VARCHAR(255) NOT NULL COMMENT 'ํ”„๋กœ์ ํŠธ ์ด๋ฆ„',
-- ์ง„ํ–‰ ์ƒํƒœ
total_pages INT DEFAULT 0 COMMENT '์ด ํŽ˜์ด์ง€ ์ˆ˜ (ํŠธ๋ฆฌ๊ฑฐ๋กœ ์ž๋™ ๊ณ„์‚ฐ)',
analysis_mode ENUM('AUTO', 'MANUAL', 'HYBRID') DEFAULT 'AUTO'
COMMENT '๋ถ„์„ ๋ชจ๋“œ: AUTO(์ž๋™), MANUAL(์ˆ˜๋™), HYBRID(ํ˜ผํ•ฉ)',
status ENUM('CREATED', 'IN_PROGRESS', 'COMPLETED', 'ERROR') DEFAULT 'CREATED'
COMMENT 'ํ”„๋กœ์ ํŠธ ์ƒํƒœ: CREATED(์ƒ์„ฑ๋จ), IN_PROGRESS(์ง„ํ–‰์ค‘), COMPLETED(์™„๋ฃŒ), ERROR(์˜ค๋ฅ˜)',
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ์ผ',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '๋งˆ์ง€๋ง‰ ์ˆ˜์ •์ผ',
-- ์™ธ๋ž˜ํ‚ค ์ œ์•ฝ์กฐ๊ฑด
CONSTRAINT fk_projects_user
FOREIGN KEY (user_id) REFERENCES users(user_id)
ON DELETE CASCADE,
CONSTRAINT fk_projects_doctype
FOREIGN KEY (doc_type_id) REFERENCES document_types(doc_type_id)
ON DELETE RESTRICT,
-- ์ธ๋ฑ์Šค
INDEX idx_user_id (user_id) COMMENT '์‚ฌ์šฉ์ž๋ณ„ ํ”„๋กœ์ ํŠธ ์กฐํšŒ ์ตœ์ ํ™”',
INDEX idx_doc_type_id (doc_type_id) COMMENT 'ํƒ€์ž…๋ณ„ ํ”„๋กœ์ ํŠธ ์กฐํšŒ ์ตœ์ ํ™”',
INDEX idx_status (status) COMMENT '์ƒํƒœ๋ณ„ ํ•„ํ„ฐ๋ง ์ตœ์ ํ™”'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='์‚ฌ์šฉ์ž ํ”„๋กœ์ ํŠธ ํ…Œ์ด๋ธ”. ๋ถ„์„ ์„ธ์…˜ ๋‹จ์œ„ ๊ด€๋ฆฌ.';
-- ============================================================================
-- 4๏ธโƒฃ Pages Table (ํŽ˜์ด์ง€ ์ •๋ณด)
-- ============================================================================
-- ์„ค๋ช…: ํ”„๋กœ์ ํŠธ ๋‚ด ๊ฐœ๋ณ„ ํŽ˜์ด์ง€ (์ด๋ฏธ์ง€ ํŒŒ์ผ)
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ํŽ˜์ด์ง€ ์ˆœ์„œ ๊ด€๋ฆฌ, ๋ถ„์„ ์ƒํƒœ ์ถ”์ , ์ด๋ฏธ์ง€ ์ €์žฅ
-- ============================================================================
CREATE TABLE pages (
-- ๊ธฐ๋ณธ ์ •๋ณด
page_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ํŽ˜์ด์ง€ ๊ณ ์œ  ID',
project_id INT NOT NULL COMMENT '์†Œ์† ํ”„๋กœ์ ํŠธ ID (FK: projects, ON DELETE CASCADE)',
page_number INT NOT NULL COMMENT 'ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ (1๋ถ€ํ„ฐ ์‹œ์ž‘)',
-- ์ด๋ฏธ์ง€ ์ •๋ณด
image_path VARCHAR(500) NOT NULL COMMENT '์ด๋ฏธ์ง€ ํŒŒ์ผ ๊ฒฝ๋กœ',
image_width INT DEFAULT NULL COMMENT '์ด๋ฏธ์ง€ ๋„ˆ๋น„ (ํ”ฝ์…€)',
image_height INT DEFAULT NULL COMMENT '์ด๋ฏธ์ง€ ๋†’์ด (ํ”ฝ์…€)',
-- ๋ถ„์„ ์ƒํƒœ
analysis_status ENUM('PENDING', 'PROCESSING', 'COMPLETED', 'ERROR') DEFAULT 'PENDING'
COMMENT '๋ถ„์„ ์ƒํƒœ: PENDING(๋Œ€๊ธฐ), PROCESSING(์ฒ˜๋ฆฌ์ค‘), COMPLETED(์™„๋ฃŒ), ERROR(์˜ค๋ฅ˜)',
processing_time FLOAT DEFAULT NULL COMMENT '์ฒ˜๋ฆฌ ์‹œ๊ฐ„ (์ดˆ)',
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'ํŽ˜์ด์ง€ ์ถ”๊ฐ€์ผ',
analyzed_at TIMESTAMP NULL DEFAULT NULL COMMENT '๋ถ„์„ ์™„๋ฃŒ์ผ',
-- ์™ธ๋ž˜ํ‚ค ์ œ์•ฝ์กฐ๊ฑด
CONSTRAINT fk_pages_project
FOREIGN KEY (project_id) REFERENCES projects(project_id)
ON DELETE CASCADE,
-- ๊ณ ์œ ํ‚ค ๋ฐ ์ธ๋ฑ์Šค
UNIQUE KEY uk_project_page (project_id, page_number)
COMMENT 'ํ”„๋กœ์ ํŠธ ๋‚ด ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ ์ค‘๋ณต ๋ฐฉ์ง€',
INDEX idx_project_id (project_id) COMMENT 'ํ”„๋กœ์ ํŠธ๋ณ„ ํŽ˜์ด์ง€ ์กฐํšŒ ์ตœ์ ํ™”',
INDEX idx_analysis_status (analysis_status) COMMENT '์ƒํƒœ๋ณ„ ํ•„ํ„ฐ๋ง ์ตœ์ ํ™”'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='ํ”„๋กœ์ ํŠธ ๋‚ด ํŽ˜์ด์ง€ ์ •๋ณด ํ…Œ์ด๋ธ”';
-- ============================================================================
-- 5๏ธโƒฃ Layout_Elements Table (๋ ˆ์ด์•„์›ƒ ์š”์†Œ) [์ˆ˜์ •]
-- ============================================================================
-- ์„ค๋ช…: AI ๋ชจ๋ธ์ด ๊ฒ€์ถœํ•œ ๋ ˆ์ด์•„์›ƒ ์š”์†Œ (์ œ๋ชฉ, ๋ณธ๋ฌธ, ๊ทธ๋ฆผ ๋“ฑ)
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ๋ฐ”์šด๋”ฉ ๋ฐ•์Šค ์ €์žฅ, ํด๋ž˜์Šค ๋ถ„๋ฅ˜, ์ขŒํ‘œ ๊ด€๋ฆฌ
-- [v2 ๋ณ€๊ฒฝ] order_index ์ปฌ๋Ÿผ ์‚ญ์ œ (Y,X ์ขŒํ‘œ๋กœ ๋™์  ์ •๋ ฌ)
-- ============================================================================
CREATE TABLE layout_elements (
-- ๊ธฐ๋ณธ ์ •๋ณด
element_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '์š”์†Œ ๊ณ ์œ  ID',
page_id INT NOT NULL COMMENT '์†Œ์† ํŽ˜์ด์ง€ ID (FK: pages, ON DELETE CASCADE)',
-- ๋ถ„๋ฅ˜ ์ •๋ณด
class_name VARCHAR(100) NOT NULL COMMENT 'ํด๋ž˜์Šค๋ช… (question_number/figure/table/text ๋“ฑ)',
confidence FLOAT NOT NULL COMMENT '์‹ ๋ขฐ๋„ (0.0~1.0)',
-- ๋ฐ”์šด๋”ฉ ๋ฐ•์Šค ์ขŒํ‘œ
bbox_x INT NOT NULL COMMENT 'X ์ขŒํ‘œ (์™ผ์ชฝ ์ƒ๋‹จ)',
bbox_y INT NOT NULL COMMENT 'Y ์ขŒํ‘œ (์™ผ์ชฝ ์ƒ๋‹จ)',
bbox_width INT NOT NULL COMMENT '๋„ˆ๋น„ (ํ”ฝ์…€)',
bbox_height INT NOT NULL COMMENT '๋†’์ด (ํ”ฝ์…€)',
-- ์ž๋™ ๊ณ„์‚ฐ ์ปฌ๋Ÿผ (GENERATED COLUMN)
area INT GENERATED ALWAYS AS (bbox_width * bbox_height) STORED
COMMENT '๋ฉด์  (์ž๋™ ๊ณ„์‚ฐ)',
y_position INT GENERATED ALWAYS AS (bbox_y) STORED
COMMENT 'Y ์ •๋ ฌ์šฉ ์ขŒํ‘œ (์ž๋™ ๊ณ„์‚ฐ)',
x_position INT GENERATED ALWAYS AS (bbox_x) STORED
COMMENT 'X ์ •๋ ฌ์šฉ ์ขŒํ‘œ (์ž๋™ ๊ณ„์‚ฐ)',
-- [v2 ์‚ญ์ œ] order_index: (Y,X) ์ขŒํ‘œ๋กœ ๋™์  ์ •๋ ฌํ•˜๋ฏ€๋กœ ๋ถˆํ•„์š”
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '์ƒ์„ฑ์ผ',
-- ์™ธ๋ž˜ํ‚ค
CONSTRAINT fk_layout_elements_page
FOREIGN KEY (page_id) REFERENCES pages(page_id)
ON DELETE CASCADE,
-- ์ธ๋ฑ์Šค
INDEX idx_page_id (page_id) COMMENT 'ํŽ˜์ด์ง€๋ณ„ ์š”์†Œ ์กฐํšŒ ์ตœ์ ํ™”',
INDEX idx_class_name (class_name) COMMENT 'ํด๋ž˜์Šค๋ณ„ ํ•„ํ„ฐ๋ง ์ตœ์ ํ™”',
INDEX idx_position (page_id, y_position, x_position)
COMMENT '์ขŒํ‘œ ๊ธฐ๋ฐ˜ ์ •๋ ฌ ์ตœ์ ํ™” (๋ณตํ•ฉ ์ธ๋ฑ์Šค) - ํ•ต์‹ฌ ์ธ๋ฑ์Šค'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='AI๊ฐ€ ๊ฒ€์ถœํ•œ ๋ ˆ์ด์•„์›ƒ ์š”์†Œ - v2: order_index ์‚ญ์ œ, (Y,X) ๋™์  ์ •๋ ฌ';
-- ============================================================================
-- 6๏ธโƒฃ Text_Contents Table (OCR ๊ฒฐ๊ณผ)
-- ============================================================================
-- ์„ค๋ช…: ๋ ˆ์ด์•„์›ƒ ์š”์†Œ์—์„œ ์ถ”์ถœํ•œ ํ…์ŠคํŠธ (OCR ๊ฒฐ๊ณผ)
-- ์ฃผ์š” ๊ธฐ๋Šฅ: OCR ํ…์ŠคํŠธ ์ €์žฅ, ์–ธ์–ด ๊ฐ์ง€, ์ „๋ฌธ ๊ฒ€์ƒ‰
-- ๊ด€๊ณ„: layout_elements์™€ 1:1 ๊ด€๊ณ„
-- ============================================================================
CREATE TABLE text_contents (
-- ๊ธฐ๋ณธ ์ •๋ณด
text_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'OCR ๊ฒฐ๊ณผ ๊ณ ์œ  ID',
element_id INT NOT NULL COMMENT '๋ ˆ์ด์•„์›ƒ ์š”์†Œ ID (1:1 ๋งคํ•‘, FK: layout_elements, ON DELETE CASCADE)',
-- OCR ๊ฒฐ๊ณผ
ocr_text TEXT NOT NULL COMMENT 'OCR ์ถ”์ถœ ํ…์ŠคํŠธ',
ocr_engine VARCHAR(50) DEFAULT 'PaddleOCR' COMMENT '์‚ฌ์šฉํ•œ OCR ์—”์ง„',
ocr_confidence FLOAT DEFAULT NULL COMMENT 'OCR ์‹ ๋ขฐ๋„ (0.0~1.0)',
language VARCHAR(10) DEFAULT 'ko' COMMENT '์–ธ์–ด ์ฝ”๋“œ (ko/en/ja/zh)',
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '์ƒ์„ฑ์ผ',
-- ์™ธ๋ž˜ํ‚ค
CONSTRAINT fk_text_contents_element
FOREIGN KEY (element_id) REFERENCES layout_elements(element_id)
ON DELETE CASCADE,
-- ์ œ์•ฝ์กฐ๊ฑด ๋ฐ ์ธ๋ฑ์Šค
UNIQUE KEY uk_element (element_id) COMMENT '1:1 ๊ด€๊ณ„ ๋ณด์žฅ (์ค‘๋ณต ๋ฐฉ์ง€)',
INDEX idx_language (language) COMMENT '์–ธ์–ด๋ณ„ ํ•„ํ„ฐ๋ง ์ตœ์ ํ™”',
FULLTEXT INDEX ft_ocr_text (ocr_text) WITH PARSER ngram
COMMENT 'ํ•œ๊ธ€/์˜๋ฌธ ์ „๋ฌธ ๊ฒ€์ƒ‰ (n-gram ํŒŒ์„œ ์‚ฌ์šฉ)'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='OCR ์ถ”์ถœ ํ…์ŠคํŠธ';
-- ============================================================================
-- 7๏ธโƒฃ AI_Descriptions Table (AI ์„ค๋ช…)
-- ============================================================================
-- ์„ค๋ช…: ๊ทธ๋ฆผ/ํ‘œ์— ๋Œ€ํ•œ AI ์ƒ์„ฑ ์„ค๋ช… (GPT-4o-mini)
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ์‹œ๊ฐ ์ž๋ฃŒ ํ…์ŠคํŠธ ์„ค๋ช…, ํ”„๋กฌํ”„ํŠธ ์ด๋ ฅ ๊ด€๋ฆฌ
-- ๊ด€๊ณ„: layout_elements์™€ 1:1 ๊ด€๊ณ„
-- ============================================================================
CREATE TABLE ai_descriptions (
-- ๊ธฐ๋ณธ ์ •๋ณด
ai_desc_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'AI ์„ค๋ช… ๊ณ ์œ  ID',
element_id INT NOT NULL COMMENT '๋ ˆ์ด์•„์›ƒ ์š”์†Œ ID (1:1 ๋งคํ•‘, FK: layout_elements, ON DELETE CASCADE)',
-- AI ์ƒ์„ฑ ๊ฒฐ๊ณผ
description TEXT NOT NULL COMMENT 'AI๊ฐ€ ์ƒ์„ฑํ•œ ์„ค๋ช… ํ…์ŠคํŠธ',
ai_model VARCHAR(100) DEFAULT 'gpt-4o-mini' COMMENT '์‚ฌ์šฉํ•œ AI ๋ชจ๋ธ๋ช…',
prompt_used TEXT DEFAULT NULL COMMENT '์‚ฌ์šฉํ•œ ํ”„๋กฌํ”„ํŠธ (๋””๋ฒ„๊น…์šฉ)',
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '์ƒ์„ฑ์ผ',
-- ์™ธ๋ž˜ํ‚ค
CONSTRAINT fk_ai_descriptions_element
FOREIGN KEY (element_id) REFERENCES layout_elements(element_id)
ON DELETE CASCADE,
-- ์ œ์•ฝ์กฐ๊ฑด ๋ฐ ์ธ๋ฑ์Šค
UNIQUE KEY uk_element (element_id) COMMENT '1:1 ๊ด€๊ณ„ ๋ณด์žฅ (์ค‘๋ณต ๋ฐฉ์ง€)',
INDEX idx_ai_model (ai_model) COMMENT '๋ชจ๋ธ๋ณ„ ํ•„ํ„ฐ๋ง ์ตœ์ ํ™”'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='๊ทธ๋ฆผ/ํ‘œ์— ๋Œ€ํ•œ AI ์ƒ์„ฑ ์„ค๋ช…';
-- ============================================================================
-- 8๏ธโƒฃ Question_Groups Table (๋ฌธ์ œ ๊ทธ๋ฃน) [์ˆ˜์ •]
-- ============================================================================
-- ์„ค๋ช…: ๋ฌธ์ œ์ง€์—์„œ ๊ฐ์ง€๋œ ๋ฌธ์ œ ๋‹จ์œ„ (์•ต์ปค ์š”์†Œ ๊ธฐ์ค€)
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ์•ต์ปค ์š”์†Œ ๊ด€๋ฆฌ, Y์ขŒํ‘œ ๋ฒ”์œ„ ์ €์žฅ, ์š”์†Œ ์นด์šดํŠธ
-- ๊ด€๊ณ„: pages์™€ 1:N, layout_elements์™€ 1:1 (์•ต์ปค)
-- [v2 ๋ณ€๊ฒฝ] question_number ์‚ญ์ œ, anchor_element_id ์ถ”๊ฐ€
-- ============================================================================
CREATE TABLE question_groups (
-- ๊ธฐ๋ณธ ์ •๋ณด
question_group_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '๋ฌธ์ œ ๊ทธ๋ฃน ๊ณ ์œ  ID',
page_id INT NOT NULL COMMENT '์†Œ์† ํŽ˜์ด์ง€ ID (FK: pages, ON DELETE CASCADE)',
-- [v2 ์ถ”๊ฐ€] ์•ต์ปค ์š”์†Œ ์ฐธ์กฐ
anchor_element_id INT NOT NULL COMMENT '์•ต์ปค ์š”์†Œ ID (FK: layout_elements, ON DELETE CASCADE)',
-- Y์ขŒํ‘œ ๋ฒ”์œ„ (์•ต์ปค Y ์ขŒํ‘œ ~ ๋‹ค์Œ ์•ต์ปค ์ง์ „)
start_y INT NOT NULL COMMENT '๋ฌธ์ œ ์‹œ์ž‘ Y์ขŒํ‘œ',
end_y INT NOT NULL COMMENT '๋ฌธ์ œ ์ข…๋ฃŒ Y์ขŒํ‘œ',
-- ํ†ต๊ณ„ ์ •๋ณด
element_count INT DEFAULT 0 COMMENT '๋ฌธ์ œ์— ์†ํ•œ ์š”์†Œ ๊ฐœ์ˆ˜ (์ž์‹ ์š”์†Œ ์ˆ˜)',
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '์ƒ์„ฑ์ผ',
-- ์™ธ๋ž˜ํ‚ค
CONSTRAINT fk_question_groups_page
FOREIGN KEY (page_id) REFERENCES pages(page_id)
ON DELETE CASCADE,
-- [v2 ์ถ”๊ฐ€] ์•ต์ปค ์š”์†Œ์™€ 1:1 ๊ด€๊ณ„
CONSTRAINT fk_question_groups_anchor
FOREIGN KEY (anchor_element_id) REFERENCES layout_elements(element_id)
ON DELETE CASCADE,
-- ์ œ์•ฝ์กฐ๊ฑด ๋ฐ ์ธ๋ฑ์Šค
-- [v2 ์ˆ˜์ •] anchor_element_id๋Š” ์œ ๋‹ˆํฌ (ํ•˜๋‚˜์˜ ์•ต์ปค๋Š” ํ•˜๋‚˜์˜ ๊ทธ๋ฃน๋งŒ ์ƒ์„ฑ)
UNIQUE KEY uk_anchor_element (anchor_element_id)
COMMENT '์•ต์ปค ์š”์†Œ ์ค‘๋ณต ๋ฐฉ์ง€ (1:1 ๊ด€๊ณ„)',
INDEX idx_page_id (page_id) COMMENT 'ํŽ˜์ด์ง€๋ณ„ ๋ฌธ์ œ ์กฐํšŒ ์ตœ์ ํ™”'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='๋ฌธ์ œ ๊ทธ๋ฃน - v2: ์•ต์ปค ์š”์†Œ ๊ธฐ์ค€, question_number ์‚ญ์ œ';
-- ============================================================================
-- 9๏ธโƒฃ Question_Elements Table (๋ฌธ์ œ-์š”์†Œ ๋งคํ•‘)
-- ============================================================================
-- ์„ค๋ช…: ๋ฌธ์ œ ๊ทธ๋ฃน๊ณผ ์ž์‹ ์š”์†Œ์˜ ๋งคํ•‘ ํ…Œ์ด๋ธ”
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ๋ฌธ์ œ๋ณ„ ์ž์‹ ์š”์†Œ ๊ทธ๋ฃนํ•‘, ์ˆœ์„œ ๊ด€๋ฆฌ
-- ๊ด€๊ณ„: question_groups (1:N) โ†’ question_elements โ†’ (N:1) layout_elements
-- ============================================================================
CREATE TABLE question_elements (
-- ๊ธฐ๋ณธ ์ •๋ณด
qe_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '๋งคํ•‘ ๋ ˆ์ฝ”๋“œ ๊ณ ์œ  ID',
question_group_id INT NOT NULL COMMENT '๋ฌธ์ œ ๊ทธ๋ฃน ID (FK: question_groups, ON DELETE CASCADE)',
element_id INT NOT NULL COMMENT '์ž์‹ ์š”์†Œ ID (FK: layout_elements, ON DELETE CASCADE)',
-- ์ˆœ์„œ ์ •๋ณด
order_in_question INT NOT NULL COMMENT '๋ฌธ์ œ ๋‚ด ์š”์†Œ ์ˆœ์„œ (1, 2, 3, ...) - Y์ขŒํ‘œ ๊ธฐ์ค€ ์ž๋™ ์ •๋ ฌ',
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '์ƒ์„ฑ์ผ',
-- ์™ธ๋ž˜ํ‚ค
CONSTRAINT fk_question_elements_group
FOREIGN KEY (question_group_id) REFERENCES question_groups(question_group_id)
ON DELETE CASCADE,
CONSTRAINT fk_question_elements_element
FOREIGN KEY (element_id) REFERENCES layout_elements(element_id)
ON DELETE CASCADE,
-- ์ œ์•ฝ์กฐ๊ฑด ๋ฐ ์ธ๋ฑ์Šค
UNIQUE KEY uk_question_element (question_group_id, element_id)
COMMENT '๋ฌธ์ œ-์š”์†Œ ์ค‘๋ณต ๋งคํ•‘ ๋ฐฉ์ง€',
INDEX idx_order (question_group_id, order_in_question)
COMMENT '์ˆœ์„œ๋ณ„ ์ •๋ ฌ ์ตœ์ ํ™” (๋ณตํ•ฉ ์ธ๋ฑ์Šค)'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='๋ฌธ์ œ-์š”์†Œ ๋งคํ•‘ ํ…Œ์ด๋ธ” (์ž์‹ ์š”์†Œ ๊ด€๋ฆฌ)';
-- ============================================================================
-- ๐Ÿ”Ÿ Text_Versions Table (ํ…์ŠคํŠธ ๋ฒ„์ „ ๊ด€๋ฆฌ)
-- ============================================================================
-- ์„ค๋ช…: ํŽ˜์ด์ง€๋ณ„ ํ…์ŠคํŠธ ๋ฒ„์ „ ์ด๋ ฅ (์›๋ณธ/์ž๋™ํฌ๋งท/์‚ฌ์šฉ์ž์ˆ˜์ •)
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ๋ฒ„์ „ ๊ด€๋ฆฌ, ์ˆ˜์ • ์ด๋ ฅ ์ถ”์ , ํ˜„์žฌ ๋ฒ„์ „ ํ”Œ๋ž˜๊ทธ
-- ๊ด€๊ณ„: pages์™€ 1:N ๊ด€๊ณ„
-- ============================================================================
CREATE TABLE text_versions (
-- ๊ธฐ๋ณธ ์ •๋ณด
version_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '๋ฒ„์ „ ๊ณ ์œ  ID',
page_id INT NOT NULL COMMENT '์†Œ์† ํŽ˜์ด์ง€ ID (FK: pages, ON DELETE CASCADE)',
user_id INT DEFAULT NULL COMMENT '์ˆ˜์ •ํ•œ ์‚ฌ์šฉ์ž ID (์‚ฌ์šฉ์ž ์ˆ˜์ • ์‹œ, FK: users, ON DELETE SET NULL)',
-- ๋ฒ„์ „ ์ •๋ณด
content TEXT NOT NULL COMMENT 'ํ…์ŠคํŠธ ๋‚ด์šฉ',
version_number INT NOT NULL COMMENT '๋ฒ„์ „ ๋ฒˆํ˜ธ (1, 2, 3, ...)',
version_type ENUM('ORIGINAL', 'AUTO_FORMATTED', 'USER_EDITED') NOT NULL
COMMENT '๋ฒ„์ „ ์œ ํ˜•: ORIGINAL(์›๋ณธ), AUTO_FORMATTED(์ž๋™ํฌ๋งท), USER_EDITED(์‚ฌ์šฉ์ž์ˆ˜์ •)',
-- ์ƒํƒœ ํ”Œ๋ž˜๊ทธ
is_current BOOLEAN DEFAULT FALSE COMMENT 'ํ˜„์žฌ ๋ฒ„์ „ ์—ฌ๋ถ€ (TRUE: ํ˜„์žฌ ๋ฒ„์ „)',
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '๋ฒ„์ „ ์ƒ์„ฑ์ผ',
-- ์™ธ๋ž˜ํ‚ค
CONSTRAINT fk_text_versions_page
FOREIGN KEY (page_id) REFERENCES pages(page_id)
ON DELETE CASCADE,
CONSTRAINT fk_text_versions_user
FOREIGN KEY (user_id) REFERENCES users(user_id)
ON DELETE SET NULL,
-- ์ œ์•ฝ์กฐ๊ฑด ๋ฐ ์ธ๋ฑ์Šค
UNIQUE KEY uk_page_version (page_id, version_number)
COMMENT 'ํŽ˜์ด์ง€ ๋‚ด ๋ฒ„์ „ ๋ฒˆํ˜ธ ์ค‘๋ณต ๋ฐฉ์ง€',
INDEX idx_page_id (page_id) COMMENT 'ํŽ˜์ด์ง€๋ณ„ ๋ฒ„์ „ ์กฐํšŒ ์ตœ์ ํ™”',
INDEX idx_is_current (is_current) COMMENT 'ํ˜„์žฌ ๋ฒ„์ „ ๋น ๋ฅธ ์กฐํšŒ'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='ํŽ˜์ด์ง€๋ณ„ ํ…์ŠคํŠธ ๋ฒ„์ „ ๊ด€๋ฆฌ';
-- ============================================================================
-- 1๏ธโƒฃ1๏ธโƒฃ Formatting_Rules Table (ํฌ๋งทํŒ… ๊ทœ์น™) [์ˆ˜์ •]
-- ============================================================================
-- ์„ค๋ช…: ๋ฌธ์„œ ํƒ€์ž…๋ณ„ ํด๋ž˜์Šค๋ณ„ ํฌ๋งทํŒ… ๊ทœ์น™ (์ ‘๋‘์‚ฌ/์ ‘๋ฏธ์‚ฌ/๋“ค์—ฌ์“ฐ๊ธฐ)
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ์ž๋™ ํฌ๋งทํŒ… ๊ทœ์น™ ๊ด€๋ฆฌ, ๋™์  ๊ทœ์น™ ๋ณ€๊ฒฝ
-- ๊ด€๊ณ„: document_types์™€ 1:N ๊ด€๊ณ„
-- [v2 ๋ณ€๊ฒฝ] ์•ต์ปค/์ž์‹ ํด๋ž˜์Šค ๊ทœ์น™ ์ถ”๊ฐ€ (Initial Data ์ฐธ์กฐ)
-- ============================================================================
CREATE TABLE formatting_rules (
-- ๊ธฐ๋ณธ ์ •๋ณด
rule_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '๊ทœ์น™ ๊ณ ์œ  ID',
doc_type_id INT NOT NULL COMMENT '๋ฌธ์„œ ํƒ€์ž… ID (FK: document_types, ON DELETE CASCADE)',
class_name VARCHAR(100) NOT NULL COMMENT '์ ์šฉ ํด๋ž˜์Šค๋ช… (question_number/figure/text ๋“ฑ)',
-- ํฌ๋งทํŒ… ์„ค์ •
prefix VARCHAR(200) DEFAULT '' COMMENT '์ ‘๋‘์‚ฌ (์˜ˆ: "\\n\\n", " ")',
suffix VARCHAR(200) DEFAULT '' COMMENT '์ ‘๋ฏธ์‚ฌ (์˜ˆ: ". ", "\\n")',
indent_level INT DEFAULT 0 COMMENT '๋“ค์—ฌ์“ฐ๊ธฐ ๋ ˆ๋ฒจ (0~10)',
-- ์Šคํƒ€์ผ ์„ค์ • (์„ ํƒ ์‚ฌํ•ญ)
font_size VARCHAR(20) DEFAULT NULL COMMENT 'ํฐํŠธ ํฌ๊ธฐ (์˜ˆ: "14pt")',
font_weight VARCHAR(20) DEFAULT NULL COMMENT 'ํฐํŠธ ๋‘๊ป˜ (์˜ˆ: "bold")',
-- ํƒ€์ž„์Šคํƒฌํ”„
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '๊ทœ์น™ ์ƒ์„ฑ์ผ',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '๊ทœ์น™ ์ˆ˜์ •์ผ',
-- ์™ธ๋ž˜ํ‚ค
CONSTRAINT fk_formatting_rules_doctype
FOREIGN KEY (doc_type_id) REFERENCES document_types(doc_type_id)
ON DELETE CASCADE,
-- ์ œ์•ฝ์กฐ๊ฑด ๋ฐ ์ธ๋ฑ์Šค
UNIQUE KEY uk_type_class (doc_type_id, class_name)
COMMENT 'ํƒ€์ž…๋ณ„ ํด๋ž˜์Šค ๊ทœ์น™ ์ค‘๋ณต ๋ฐฉ์ง€',
INDEX idx_doc_type_id (doc_type_id) COMMENT 'ํƒ€์ž…๋ณ„ ๊ทœ์น™ ์กฐํšŒ ์ตœ์ ํ™”'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='๋ฌธ์„œ ํƒ€์ž…๋ณ„ ํฌ๋งทํŒ… ๊ทœ์น™ - v2: ์•ต์ปค/์ž์‹ ํด๋ž˜์Šค ๊ทœ์น™ ์ถ”๊ฐ€';
-- ============================================================================
-- 1๏ธโƒฃ2๏ธโƒฃ Combined_Results Table (ํ†ตํ•ฉ ๋ฌธ์„œ ์บ์‹œ)
-- ============================================================================
-- ์„ค๋ช…: ํ”„๋กœ์ ํŠธ์˜ ๋ชจ๋“  ํŽ˜์ด์ง€๋ฅผ ํ†ตํ•ฉํ•œ ์ตœ์ข… ๊ฒฐ๊ณผ ์บ์‹œ
-- ์ฃผ์š” ๊ธฐ๋Šฅ: ํ†ตํ•ฉ ํ…์ŠคํŠธ ์ €์žฅ, ํ†ต๊ณ„ ์ •๋ณด, ๋‹ค์šด๋กœ๋“œ ์ตœ์ ํ™”
-- ๊ด€๊ณ„: projects์™€ 1:1 ๊ด€๊ณ„
-- ============================================================================
CREATE TABLE combined_results (
-- ๊ธฐ๋ณธ ์ •๋ณด
combined_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ํ†ตํ•ฉ ๊ฒฐ๊ณผ ๊ณ ์œ  ID',
project_id INT NOT NULL COMMENT 'ํ”„๋กœ์ ํŠธ ID (1:1 ๋งคํ•‘, FK: projects, ON DELETE CASCADE)',
-- ํ†ตํ•ฉ ๊ฒฐ๊ณผ
combined_text LONGTEXT NOT NULL COMMENT 'ํ†ตํ•ฉ๋œ ์ „์ฒด ํ…์ŠคํŠธ (ํŽ˜์ด์ง€๋ณ„ ๊ฒฐ๊ณผ ํ•ฉ์นจ)',
combined_stats JSON DEFAULT NULL COMMENT 'ํ†ต๊ณ„ ์ •๋ณด (JSON ํ˜•์‹: ํŽ˜์ด์ง€์ˆ˜, ๋‹จ์–ด์ˆ˜, ๋ฌธ์ œ์ˆ˜ ๋“ฑ)',
-- ํƒ€์ž„์Šคํƒฌํ”„
generated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '์ตœ์ดˆ ์ƒ์„ฑ์ผ',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ์ผ',
-- ์™ธ๋ž˜ํ‚ค
CONSTRAINT fk_combined_results_project
FOREIGN KEY (project_id) REFERENCES projects(project_id)
ON DELETE CASCADE,
-- ์ œ์•ฝ์กฐ๊ฑด ๋ฐ ์ธ๋ฑ์Šค
UNIQUE KEY uk_project (project_id) COMMENT '1:1 ๊ด€๊ณ„ ๋ณด์žฅ (ํ”„๋กœ์ ํŠธ๋‹น 1๊ฐœ ์บ์‹œ)',
INDEX idx_project_id (project_id) COMMENT 'ํ”„๋กœ์ ํŠธ๋ณ„ ์บ์‹œ ์กฐํšŒ ์ตœ์ ํ™”'
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ ๋ฌธ์„œ ์บ์‹œ';
-- ============================================================================
-- ๐Ÿ”ง Triggers (ํŠธ๋ฆฌ๊ฑฐ)
-- ============================================================================
-- ํŠธ๋ฆฌ๊ฑฐ 1: ํŽ˜์ด์ง€ ์ถ”๊ฐ€ ์‹œ projects.total_pages ์ž๋™ ์ฆ๊ฐ€
-- ============================================================================
DELIMITER //
CREATE TRIGGER trg_update_total_pages
AFTER INSERT ON pages
FOR EACH ROW
BEGIN
-- ์ƒˆ ํŽ˜์ด์ง€๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์˜ total_pages๋ฅผ 1 ์ฆ๊ฐ€
UPDATE projects
SET total_pages = (
SELECT COUNT(*)
FROM pages
WHERE project_id = NEW.project_id
)
WHERE project_id = NEW.project_id;
END//
DELIMITER ;
-- ============================================================================
-- ํŠธ๋ฆฌ๊ฑฐ 2: ํŽ˜์ด์ง€ ์‚ญ์ œ ์‹œ projects.total_pages ์ž๋™ ๊ฐ์†Œ
-- ============================================================================
DELIMITER //
CREATE TRIGGER trg_update_total_pages_on_delete
AFTER DELETE ON pages
FOR EACH ROW
BEGIN
-- ํŽ˜์ด์ง€๊ฐ€ ์‚ญ์ œ๋˜๋ฉด ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์˜ total_pages๋ฅผ ์žฌ๊ณ„์‚ฐ
UPDATE projects
SET total_pages = (
SELECT COUNT(*)
FROM pages
WHERE project_id = OLD.project_id
)
WHERE project_id = OLD.project_id;
END//
DELIMITER ;
-- ============================================================================
-- ๐Ÿ“Š Initial Data (์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ) [v2 ์ˆ˜์ •]
-- ============================================================================
-- ์‹œ์Šคํ…œ ๊ธฐ๋ณธ ์„ค์ • ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
-- ============================================================================
-- 1. Document Types (๋ฌธ์„œ ํƒ€์ž… 2๊ฐœ) [์ˆ˜์ •]
INSERT INTO document_types (type_name, model_name, sorting_method, description) VALUES
('worksheet', 'SmartEyeSsen', 'QUESTION_BASED', '์‹œํ—˜ ๋ฌธ์ œ์ง€ - ์•ต์ปค/์ž์‹ ์žฌ๊ท€ ์ •๋ ฌ (question_type, question_number ๊ธฐ์ค€)'),
('document', 'DocLayout-YOLO', 'READING_ORDER', '์ผ๋ฐ˜ ๋ฌธ์„œ - Y/X ์ขŒํ‘œ ๊ธฐ์ค€ ์ˆœ์ฐจ ์ •๋ ฌ');
-- 2. Formatting Rules - worksheet (๋ฌธ์ œ์ง€) [formatter_rules.py ๊ธฐ์ค€]
INSERT INTO formatting_rules (doc_type_id, class_name, prefix, suffix, indent_level, font_size, font_weight) VALUES
(1, 'question type', '\n\n[', ']\n', 0, NULL, NULL),
(1, 'question number', '\n\n', '. ', 0, NULL, NULL),
(1, 'second_question_number', '\n ', '', 3, NULL, NULL),
(1, 'question text', '', '\n', 3, NULL, NULL),
(1, 'plain text', '', '\n', 0, NULL, NULL),
(1, 'unit', '', '\n', 3, NULL, NULL),
(1, 'list', ' - ', '\n', 0, NULL, NULL),
(1, 'choices', '', '\n', 3, NULL, NULL),
(1, 'figure', '\n [๊ทธ๋ฆผ ์„ค๋ช…]\n', '\n\n', 3, NULL, NULL),
(1, 'table', '\n [ํ‘œ ์„ค๋ช…]\n', '\n\n', 3, NULL, NULL),
(1, 'flowchart', '\n [์ˆœ์„œ๋„ ์„ค๋ช…]\n', '\n\n', 3, NULL, NULL),
(1, 'figure_caption', ' (๊ทธ๋ฆผ ์บก์…˜) ', '\n\n', 0, NULL, NULL),
(1, 'table caption', ' (ํ‘œ ์บก์…˜) ', '\n\n', 0, NULL, NULL),
(1, 'table footnote', ' * ', '\n', 0, NULL, NULL),
(1, 'formula_caption', ' (์ˆ˜์‹ ์„ค๋ช…) ', '\n', 0, NULL, NULL),
(1, 'isolated_formula', '\n [์ˆ˜์‹]\n', '\n', 3, NULL, NULL);
-- 3. Formatting Rules - document (์ผ๋ฐ˜ ๋ฌธ์„œ)
INSERT INTO formatting_rules (doc_type_id, class_name, prefix, suffix, indent_level, font_size, font_weight) VALUES
(2, 'title', '', '\n\n', 0, NULL, NULL),
(2, 'heading', '\n', '\n\n', 0, NULL, NULL),
(2, 'plain text', '', '\n\n', 0, NULL, NULL),
(2, 'list', '', '\n', 0, NULL, NULL),
(2, 'figure', '\n[๊ทธ๋ฆผ] ', '\n\n', 0, NULL, NULL),
(2, 'table', '\n[ํ‘œ] ', '\n\n', 0, NULL, NULL),
(2, 'figure_caption', '(๊ทธ๋ฆผ ์บก์…˜) ', '\n', 0, NULL, NULL),
(2, 'table caption', '(ํ‘œ ์บก์…˜) ', '\n', 0, NULL, NULL),
(2, 'table footnote', '* ', '\n', 0, NULL, NULL);
-- ============================================================================
-- ๐ŸŽ‰ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ƒ์„ฑ ์™„๋ฃŒ! (v2)
-- ============================================================================
-- ๐Ÿ“‹ ๋‹ค์Œ ๋‹จ๊ณ„:
-- 1. MySQL Workbench์—์„œ erd_schema_v2.sql ํŒŒ์ผ ์‹คํ–‰
-- 2. ํ…Œ์ด๋ธ” ์ƒ์„ฑ ํ™•์ธ: SHOW TABLES;
-- 3. ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ ํ™•์ธ:
-- - SELECT * FROM document_types;
-- - SELECT * FROM formatting_rules WHERE doc_type_id = 1;
-- 4. ๋ฐฑ์—”๋“œ ORM ์—ฐ๊ฒฐ (SQLAlchemy)
-- - question_groups.anchor_element_id FK ์„ค์ • ํ™•์ธ
-- - layout_elements โ†” question_groups ๊ด€๊ณ„ ๋งคํ•‘
-- 5. ๋ฌธ์ œ ๋ ˆ์ด์•„์›ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„
-- - services/sorting_service.py ์ƒ์„ฑ
-- - ์•ต์ปค ์š”์†Œ ํ•„ํ„ฐ๋ง (question_type, question_number, ...)
-- - Y์ขŒํ‘œ ๊ธฐ์ค€ ์žฌ๊ท€์  ๋ถ„ํ• 
-- - ์ž์‹ ์š”์†Œ (Y,X) ์ •๋ ฌ ๋ฐ question_elements ์ €์žฅ
-- 6. API ์—”๋“œํฌ์ธํŠธ ๊ฐœ๋ฐœ
-- - POST /api/pages/{page_id}/sort
-- - GET /api/pages/{page_id}/sorted-result
-- 7. ํ…Œ์ŠคํŠธ
-- - 16ํŽ˜์ด์ง€ (section + question_number)
-- - 42ํŽ˜์ด์ง€ (question_number๋งŒ)
-- - 14ํŽ˜์ด์ง€ (question_number + second_question_number)
-- ============================================================================
-- ============================================================================
-- ๐Ÿ” v2 ์ฃผ์š” ๋ณ€๊ฒฝ์‚ฌํ•ญ ์š”์•ฝ
-- ============================================================================
-- 1. document_types.sorting_method:
-- - 'coordinate_based' โ†’ 'reading_order'๋กœ ํ†ตํ•ฉ
-- - 'question_based': ์•ต์ปค/์ž์‹ ์žฌ๊ท€ ์ •๋ ฌ
-- - 'reading_order': Y/X ์ขŒํ‘œ ์ˆœ์ฐจ ์ •๋ ฌ
--
-- 2. layout_elements:
-- - order_index ์ปฌ๋Ÿผ ์‚ญ์ œ
-- - (Y,X) ์ขŒํ‘œ๋กœ ๋™์  ์ •๋ ฌ (idx_position ์ธ๋ฑ์Šค ํ™œ์šฉ)
--
-- 3. question_groups:
-- - question_number ์ปฌ๋Ÿผ ์‚ญ์ œ
-- - anchor_element_id ์ปฌ๋Ÿผ ์ถ”๊ฐ€ (FK โ†’ layout_elements)
-- - layout_elements์™€ 1:1 ์•ต์ปค ๊ด€๊ณ„ ์‹ ์„ค
--
-- 4. formatting_rules:
-- - ์•ต์ปค ํด๋ž˜์Šค 5๊ฐœ ์ถ”๊ฐ€
-- (question_type, unit, question_number, second_question_number, third_question_number)
-- - ์ž์‹ ํด๋ž˜์Šค 11๊ฐœ ์ถ”๊ฐ€
-- (question_text, list, choices, parenthesis_blank, underline_blank,
-- figure, table, flowchart, equation, caption, footnote)
--
-- 5. ๊ด€๊ณ„ ๋ณ€๊ฒฝ:
-- - layout_elements โ†” question_groups: 1:1 ์•ต์ปค ๊ด€๊ณ„ (์‹ ๊ทœ)
-- - anchor_element_id๋Š” UNIQUE (ํ•˜๋‚˜์˜ ์•ต์ปค = ํ•˜๋‚˜์˜ ๊ทธ๋ฃน)
-- - ON DELETE CASCADE: ์•ต์ปค ์‚ญ์ œ ์‹œ ๊ทธ๋ฃน ๋ฐ question_elements ์—ฐ์‡„ ์‚ญ์ œ
--
-- ============================================================================
-- ============================================================================
-- ๊ธฐ๋ณธ ํ…Œ์ŠคํŠธ ์‚ฌ์šฉ์ž ์ƒ์„ฑ
-- ============================================================================
INSERT INTO users (user_id, email, name, role, password_hash, api_key, created_at, updated_at)
VALUES
(1, 'test@smarteyessen.com', 'ํ…Œ์ŠคํŠธ ์‚ฌ์šฉ์ž', 'user', 'dummy_hash_for_test', NULL, NOW(), NOW()),
(2, 'admin@smarteyessen.com', '๊ด€๋ฆฌ์ž', 'admin', 'dummy_hash_for_admin', NULL, NOW(), NOW())
ON DUPLICATE KEY UPDATE
email = VALUES(email),
name = VALUES(name);
-- ============================================================================