Table users { id int [pk ] name varchar email varchar [unique ] password varchar role varchar // admin | instructor | learner created_at datetime updated_at datetime } Table courses { id int [pk ] categories_id int title jsonb // { "th": "...", "en": "..." } description jsonb // { "th": "...", "en": "..." } price decimal is_free boolean status varchar // draft | pending | approved | rejected instructor_id int approved_by int // admin user id created_at datetime updated_at datetime } Table categories { id int [pk ] name jsonb // multi-language category name description jsonb // optional created_at datetime updated_at datetime } Table chapters { id int [pk ] course_id int title jsonb // multi-language sort_order int created_at datetime updated_at datetime } Table lessons { id int [pk ] chapter_id int title jsonb // multi-language content jsonb // multi-language lesson content type varchar // video | pdf | text | quiz sort_order int created_at datetime updated_at datetime } Table quizzes { id int [pk ] lesson_id int title jsonb // multi-language passing_score int time_limit int created_at datetime updated_at datetime } Table questions { id int [pk ] quiz_id int question jsonb // multi-language score int created_at datetime updated_at datetime } Table choices { id int [pk ] question_id int text jsonb // multi-language is_correct boolean created_at datetime updated_at datetime } Table enrollments { id int [pk ] user_id int course_id int status varchar // enrolled | completed enrolled_at datetime created_at datetime updated_at datetime } Table announcements { id int [pk ] course_id int instructor_id int title jsonb // multi-language content jsonb // multi-language is_pinned boolean // pin important announcements to top published_at datetime // scheduled publish date created_at datetime updated_at datetime } Table announcement_attachments { id int [pk ] announcement_id int file_name varchar file_path varchar file_size int mime_type varchar created_at datetime } Table orders { id int [pk ] user_id int total_amount decimal status varchar // pending | paid | cancelled created_at datetime updated_at datetime } Table order_items { id int [pk ] order_id int course_id int price decimal created_at datetime updated_at datetime } Table payments { id int [pk ] order_id int provider varchar transaction_id varchar amount decimal status varchar // success | failed paid_at datetime created_at datetime updated_at datetime } Table instructor_balances { id int [pk ] instructor_id int available_amount decimal withdrawn_amount decimal created_at datetime updated_at datetime } Table withdrawal_requests { id int [pk ] instructor_id int amount decimal status varchar // pending | approved | rejected | paid approved_by int created_at datetime updated_at datetime } Ref: courses.instructor_id > users.id Ref: courses.approved_by > users.id Ref: courses.categories_id > categories.id Ref: chapters.course_id > courses.id Ref: lessons.chapter_id > chapters.id Ref: quizzes.lesson_id > lessons.id Ref: questions.quiz_id > quizzes.id Ref: choices.question_id > questions.id Ref: enrollments.user_id > users.id Ref: enrollments.course_id > courses.id Ref: announcements.course_id > courses.id Ref: announcements.instructor_id > users.id Ref: announcement_attachments.announcement_id > announcements.id Ref: orders.user_id > users.id Ref: order_items.order_id > orders.id Ref: order_items.course_id > courses.id Ref: payments.order_id > orders.id Ref: instructor_balances.instructor_id > users.id Ref: withdrawal_requests.instructor_id > users.id Ref: withdrawal_requests.approved_by > users.id