| Version 3 (modified by , 11 hours ago) ( diff ) |
|---|
Купување на курс
Актери
- Најавен корисник
Чекор 1
На најавен корисник му се прикажува листа од сите достапни курсеви од каде корисникот селектира еден.
SELECT
c.course_id,
c.image_url,
c.color,
c.difficulty,
c.duration_minutes,
c.price,
ct.title_short,
ct.title,
(
SELECT
COUNT(*)
FROM
course_translate
WHERE
course_id = c.course_id
) AS translated_languages,
(
SELECT
COUNT(*)
FROM
course_content cc
JOIN course_version cv
ON cc.course_version_id = cv.course_version_id
WHERE
cv.course_id = c.course_id
AND cv.is_active
) AS course_content_count,
(
SELECT
COUNT(*)
FROM
course_lecture cl
JOIN course_content cc
ON cl.course_content_id = cc.course_content_id
JOIN course_version cv
ON cc.course_version_id = cv.course_version_id
WHERE
cv.course_id = c.course_id
AND cv.is_active
) AS course_lecture_count,
(
SELECT
AVG(r.rating)
FROM
review r
JOIN enrollment e
ON e.enrollment_id = r.enrollment_id
JOIN course_version cv
ON cv.course_version_id = e.course_version_id
WHERE
cv.course_id = c.course_id
) AS avg_rating,
(
SELECT
JSON_AGG(tt.value)
FROM
course_tag ctag
JOIN tag t
ON t.tag_id = ctag.tag_id
JOIN tag_translate tt
ON tt.tag_id = t.tag_id
JOIN language l
ON l.id = tt.language_id
WHERE
ctag.course_id = c.course_id
AND l.value = 'en'
AND t.tag_type = 'skill'
) AS skills,
(
SELECT
JSON_AGG(tt.value)
FROM
course_tag ctag
JOIN tag t
ON t.tag_id = ctag.tag_id
JOIN tag_translate tt
ON tt.tag_id = t.tag_id
JOIN language l
ON l.id = tt.language_id
WHERE
ctag.course_id = c.course_id
AND l.value = 'en'
AND t.tag_type = 'topic'
) AS topics
FROM
course c
JOIN course_translate ct
ON ct.course_id = c.course_id
JOIN language lang
ON lang.id = ct.language_id
WHERE
lang.value = 'en'
AND EXISTS (
SELECT 1
FROM course_version cv
WHERE cv.course_id = c.course_id
AND cv.is_active
);
Чекор 2
Откако корисникот кликнал на курс, му се прикажуваат детални информации за курсот.
SELECT
c.course_id,
c.image_url,
c.color,
c.difficulty,
c.duration_minutes,
c.price,
ct.title_short,
ct.title,
ct.description_short,
ct.description,
ct.description_long,
(
SELECT
COUNT(*)
FROM
course_translate
WHERE
course_id = c.course_id
) AS translated_languages,
(
SELECT
COUNT(*)
FROM
course_content cc
JOIN course_version cv
ON cc.course_version_id = cv.course_version_id
WHERE
cv.course_id = c.course_id
AND cv.is_active
) AS course_content_count,
(
SELECT
COUNT(*)
FROM
course_lecture cl
JOIN course_content cc
ON cl.course_content_id = cc.course_content_id
JOIN course_version cv
ON cc.course_version_id = cv.course_version_id
WHERE
cv.course_id = c.course_id
AND cv.is_active
) AS course_lecture_count,
(
SELECT
AVG(r.rating)
FROM
review r
JOIN enrollment e
ON e.enrollment_id = r.enrollment_id
JOIN course_version cv
ON cv.course_version_id = e.course_version_id
WHERE
cv.course_id = c.course_id
) AS avg_rating,
(
SELECT
JSON_AGG(tt.value)
FROM
course_tag ctag
JOIN tag t
ON t.tag_id = ctag.tag_id
JOIN tag_translate tt
ON tt.tag_id = t.tag_id
JOIN language l
ON l.id = tt.language_id
WHERE
ctag.course_id = c.course_id
AND l.value = 'en'
AND t.tag_type = 'skill'
) AS skills,
(
SELECT
JSON_AGG(tt.value)
FROM
course_tag ctag
JOIN tag t
ON t.tag_id = ctag.tag_id
JOIN tag_translate tt
ON tt.tag_id = t.tag_id
JOIN language l
ON l.id = tt.language_id
WHERE
ctag.course_id = c.course_id
AND l.value = 'en'
AND t.tag_type = 'topic'
) AS topics,
-- what_will_be_learned е text[] колона во course_translate.
-- Ако се врати нормализираната табела course_translate_what_will_be_learned,
-- ова се заменува со корелиран подзапрос по ct.course_translate_id.
TO_JSON(ct.what_will_be_learned) AS what_will_be_learned,
(
SELECT
JSON_AGG(
JSONB_BUILD_OBJECT(
'title', cct.title,
'position', cc.position,
'lectures', (
SELECT
JSON_AGG(
JSONB_BUILD_OBJECT(
'title', clt.title,
'description', clt.description,
'duration_minutes', cl.duration_minutes,
'position', cl.position,
'content_type', cl.content_type
)
ORDER BY cl.position
)
FROM
course_lecture cl
JOIN course_lecture_translate clt
ON clt.course_lecture_id = cl.course_lecture_id
JOIN language ll
ON ll.id = clt.language_id
WHERE
cl.course_content_id = cc.course_content_id
AND ll.value = 'en'
)
)
ORDER BY cc.position
)
FROM
course_content cc
JOIN course_content_translate cct
ON cct.course_content_id = cc.course_content_id
JOIN language lc
ON lc.id = cct.language_id
JOIN course_version cv
ON cc.course_version_id = cv.course_version_id
WHERE
cv.course_id = c.course_id
AND cv.is_active
AND lc.value = 'en'
) AS course_content
FROM
course c
JOIN course_translate ct
ON ct.course_id = c.course_id
JOIN language lang
ON lang.id = ct.language_id
WHERE
lang.value = 'en'
AND c.course_id = :course_id;
Чекор 3
Корисникот кликнува на копчето за купување на курс.
INSERT INTO enrollment (purchase_date, activation_date, completion_date,
enrollment_status, user_id, course_version_id)
VALUES (DATE '2026-01-25', NULL, NULL, 'pending', 1, 2)
RETURNING enrollment_id;
purchase_date -> датум на купување activation_date -> датум на активација (NULL додека курсот не е активиран) completion_date -> датум на завршување (NULL додека курсот не е завршен) enrollment_status -> статус за тоа дали не е почнат, е почнат или е завршен курсот (при купување се внесува 'pending' бидејќи курсот сè уште не е започнат) user_id -> ид на корисник course_version_id -> ид на верзија на курсот која се купува
Ограничувањето ck_enrollment_status_dates бара:
- 'pending' -> activation_date IS NULL И completion_date IS NULL
- 'active' -> activation_date IS NOT NULL И completion_date IS NULL
- 'completed' -> двете полиња се пополнети
Ограничувањето uq_enrollment_user_version не дозволува ист корисник да купи иста верзија од курс двапати.
