== Креирање на курс === Актери - Експерт === Предуслов: табела `expert_course` Шемата нема врска помеѓу `expert` и `course`, па нема каде да се запише кој експерт го креирал курсот. Оваа табела мора да се додаде во DDL пред овој случај на употреба да работи. {{{ CREATE TABLE expert_course ( expert_id bigint NOT NULL, course_id bigint NOT NULL, CONSTRAINT pk_expert_course PRIMARY KEY (expert_id, course_id), CONSTRAINT fk_ec_expert FOREIGN KEY (expert_id) REFERENCES expert (expert_id) ON DELETE CASCADE, CONSTRAINT fk_ec_course FOREIGN KEY (course_id) REFERENCES course (course_id) ON DELETE CASCADE ); }}} === Чекор 1 При клик на копчето за креирање на курс на навбарот на корисникот му се прикажува форма со полиња. При пополнување на овие полиња и клик на копчето "Create" се креира курс во базата. {{{ BEGIN; DROP TABLE IF EXISTS temp_course_id; DROP TABLE IF EXISTS temp_course_version_id; DROP TABLE IF EXISTS temp_course_content_id; DROP TABLE IF EXISTS temp_course_lecture_id; DROP TABLE IF EXISTS temp_tag_id; CREATE TEMP TABLE temp_course_id (course_id BIGINT); CREATE TEMP TABLE temp_course_version_id (course_version_id BIGINT); CREATE TEMP TABLE temp_course_content_id (course_content_id BIGINT); CREATE TEMP TABLE temp_course_lecture_id (course_lecture_id BIGINT); CREATE TEMP TABLE temp_tag_id (tag_id BIGINT, tag_type tag_type); -- 1. Курс WITH new_course AS ( INSERT INTO course (image_url, difficulty, duration_minutes, price, color) VALUES ('https://example.com/image.png', 'intermediate', 120, 50.00, '#008CC2') RETURNING course_id ) INSERT INTO temp_course_id (course_id) SELECT course_id FROM new_course; -- 2. Верзија на курс WITH new_course_version AS ( INSERT INTO course_version (version_number, created_at, is_active, course_id) SELECT 1, CURRENT_DATE, true, course_id FROM temp_course_id RETURNING course_version_id ) INSERT INTO temp_course_version_id (course_version_id) SELECT course_version_id FROM new_course_version; -- 3. Преводи на курсот -- what_will_be_learned е text[] колона, па се внесува заедно со преводот. INSERT INTO course_translate (language_id, title_short, title, description_short, description, description_long, what_will_be_learned, course_id) SELECT (SELECT id FROM language WHERE value = 'en'), 'Advanced Sales', 'Advanced Sales For Senior Salesman', 'Short desc', 'Normal desc', 'Long desc', ARRAY['Advanced sales techniques', 'How to successfully close deals'], course_id FROM temp_course_id; INSERT INTO course_translate (language_id, title_short, title, description_short, description, description_long, what_will_be_learned, course_id) SELECT (SELECT id FROM language WHERE value = 'mk'), 'Напредна Продажба', 'Напредна Продажба за Сениор Продавачи', 'Кратка дескрипција', 'Нормална дескрипција', 'Долга дескрипција', ARRAY['Напредни техники на продажба', 'Како до успешно затворање на продажби'], course_id FROM temp_course_id; -- 4. Модул WITH new_course_content AS ( INSERT INTO course_content (position, course_version_id) SELECT 1, course_version_id FROM temp_course_version_id RETURNING course_content_id ) INSERT INTO temp_course_content_id (course_content_id) SELECT course_content_id FROM new_course_content; INSERT INTO course_content_translate (title, language_id, course_content_id) SELECT 'Module 1: Sales Strategies', (SELECT id FROM language WHERE value = 'en'), course_content_id FROM temp_course_content_id; INSERT INTO course_content_translate (title, language_id, course_content_id) SELECT 'Модул 1: Продажни Стратегии', (SELECT id FROM language WHERE value = 'mk'), course_content_id FROM temp_course_content_id; -- 5. Лекција WITH new_course_lecture AS ( INSERT INTO course_lecture (duration_minutes, position, content_type, course_content_id) SELECT 30, 1, 'video', course_content_id FROM temp_course_content_id RETURNING course_lecture_id ) INSERT INTO temp_course_lecture_id (course_lecture_id) SELECT course_lecture_id FROM new_course_lecture; INSERT INTO course_lecture_translate (title, language_id, content_file_name, description, content_text, course_lecture_id) SELECT 'Lecture 1: Intro', (SELECT id FROM language WHERE value = 'en'), 'lecture1.mp4', 'Introduction to advanced sales', NULL, -- content_type = 'video' -> нема текстуална содржина course_lecture_id FROM temp_course_lecture_id; INSERT INTO course_lecture_translate (title, language_id, content_file_name, description, content_text, course_lecture_id) SELECT 'Предавање 1: Вовед', (SELECT id FROM language WHERE value = 'mk'), 'lecture1.mp4', 'Вовед во напредна продажба', NULL, course_lecture_id FROM temp_course_lecture_id; -- 6. Тагови -- ВНИМАНИЕ: ова креира НОВИ тагови при секое креирање на курс. -- Во продукција формата треба да нуди постоечки тагови, па овој блок -- се заменува со SELECT врз tag/tag_translate по избраните вредности. WITH new_tags AS ( INSERT INTO tag (tag_type) VALUES ('skill'), ('topic') RETURNING tag_id, tag_type ) INSERT INTO temp_tag_id (tag_id, tag_type) SELECT tag_id, tag_type FROM new_tags; INSERT INTO tag_translate (language_id, value, tag_id) SELECT (SELECT id FROM language WHERE value = 'en'), CASE tag_type WHEN 'skill' THEN 'Skill' WHEN 'topic' THEN 'Topic' END, tag_id FROM temp_tag_id; INSERT INTO tag_translate (language_id, value, tag_id) SELECT (SELECT id FROM language WHERE value = 'mk'), CASE tag_type WHEN 'skill' THEN 'Вештина' WHEN 'topic' THEN 'Тема' END, tag_id FROM temp_tag_id; INSERT INTO course_tag (tag_id, course_id) SELECT t.tag_id, c.course_id FROM temp_tag_id t CROSS JOIN temp_course_id c; -- 7. Врска експерт <-> курс INSERT INTO expert_course (course_id, expert_id) SELECT course_id, 1 FROM temp_course_id; COMMIT; }}} ==== Забелешки - Сите вредности за `difficulty`, `content_type` и `tag_type` мора да се со мали букви — тоа се лабели на PostgreSQL enum типови и се осетливи на голема/мала буква. - `tag_type` има само две вредности: `skill` и `topic`. Вредноста `interest` не постои и предизвикува грешка, а не празен резултат. - Целиот блок мора да биде во една трансакција. Ако некој од чекорите падне, курсот не смее да остане делумно креиран. - `uq_course_version_one_active` дозволува само една активна верзија по курс. При креирање на нова верзија, старата мора прво да се постави на `is_active = false`.