| | 1 | == Купување на курс |
| | 2 | === Актери |
| | 3 | - Најавен корисник |
| | 4 | === Чекор 1 |
| | 5 | На најавен корисник му се прикажува листа од сите достапни курсеви од каде корисникот селектира еден. |
| | 6 | |
| | 7 | {{{ |
| | 8 | SELECT |
| | 9 | c.id, |
| | 10 | c.image_url, |
| | 11 | c.color, |
| | 12 | c.difficulty, |
| | 13 | c.duration_minutes, |
| | 14 | c.price, |
| | 15 | ct.title_short, |
| | 16 | ct.title, |
| | 17 | ( |
| | 18 | SELECT |
| | 19 | COUNT(*) |
| | 20 | FROM |
| | 21 | course_translate |
| | 22 | WHERE |
| | 23 | course_id = c.id |
| | 24 | ) AS translated_languages, |
| | 25 | ( |
| | 26 | SELECT |
| | 27 | COUNT(*) |
| | 28 | FROM |
| | 29 | course_content cc |
| | 30 | JOIN course_version cv |
| | 31 | ON cc.course_version_id = cv.id |
| | 32 | WHERE |
| | 33 | cv.course_id = c.id |
| | 34 | AND cv.active = TRUE |
| | 35 | ) AS course_content_count, |
| | 36 | ( |
| | 37 | SELECT |
| | 38 | COUNT(*) |
| | 39 | FROM |
| | 40 | course_lecture cl |
| | 41 | JOIN course_content cc |
| | 42 | ON cl.course_content_id = cc.id |
| | 43 | JOIN course_version cv |
| | 44 | ON cc.course_version_id = cv.id |
| | 45 | WHERE |
| | 46 | cv.course_id = c.id |
| | 47 | AND cv.active = TRUE |
| | 48 | ) AS course_lecture_count, |
| | 49 | ( |
| | 50 | SELECT |
| | 51 | AVG(r.rating) |
| | 52 | FROM |
| | 53 | review r |
| | 54 | JOIN enrollment e |
| | 55 | ON e.id = r.enrollment_id |
| | 56 | JOIN course_version cv |
| | 57 | ON cv.id = e.course_version_id |
| | 58 | WHERE |
| | 59 | cv.course_id = c.id |
| | 60 | ) AS avg_rating, |
| | 61 | ( |
| | 62 | SELECT |
| | 63 | tt.value |
| | 64 | FROM |
| | 65 | course_tag ctag |
| | 66 | JOIN tag t |
| | 67 | ON t.id = ctag.tag_id |
| | 68 | JOIN tag_translate tt |
| | 69 | ON t.id = tt.tag_id |
| | 70 | WHERE |
| | 71 | ctag.course_id = c.id |
| | 72 | AND tt.language = 'en' |
| | 73 | AND t.type = 'skill' |
| | 74 | ) AS skills, |
| | 75 | ( |
| | 76 | SELECT |
| | 77 | tt.value |
| | 78 | FROM |
| | 79 | course_tag ctag |
| | 80 | JOIN tag t |
| | 81 | ON t.id = ctag.tag_id |
| | 82 | JOIN tag_translate tt |
| | 83 | ON t.id = tt.tag_id |
| | 84 | WHERE |
| | 85 | ctag.course_id = c.id |
| | 86 | AND tt.language = 'en' |
| | 87 | AND t.type = 'interest' |
| | 88 | ) AS topics |
| | 89 | FROM |
| | 90 | course c |
| | 91 | JOIN course_translate ct |
| | 92 | ON c.id = ct.course_id |
| | 93 | WHERE |
| | 94 | ct.language = 'en'; |
| | 95 | }}} |
| | 96 | |
| | 97 | |
| | 98 | === Чекор 2 |
| | 99 | |
| | 100 | Откако корисникот кликнал на курс, му се прикажуваат детални информации за курсот. |
| | 101 | |
| | 102 | {{{ |
| | 103 | SELECT |
| | 104 | c.id, |
| | 105 | c.image_url, |
| | 106 | c.color, |
| | 107 | c.difficulty, |
| | 108 | c.duration_minutes, |
| | 109 | c.price, |
| | 110 | ct.title_short, |
| | 111 | ct.title, |
| | 112 | ct.description_short, |
| | 113 | ct.description, |
| | 114 | ct.description_long, |
| | 115 | |
| | 116 | ( |
| | 117 | SELECT |
| | 118 | COUNT(*) |
| | 119 | FROM |
| | 120 | course_translate |
| | 121 | WHERE |
| | 122 | course_id = c.id |
| | 123 | ) AS translated_languages, |
| | 124 | |
| | 125 | ( |
| | 126 | SELECT |
| | 127 | COUNT(*) |
| | 128 | FROM |
| | 129 | course_content cc |
| | 130 | JOIN course_version cv |
| | 131 | ON cc.course_version_id = cv.id |
| | 132 | WHERE |
| | 133 | cv.course_id = c.id |
| | 134 | AND cv.active = TRUE |
| | 135 | ) AS course_content_count, |
| | 136 | |
| | 137 | ( |
| | 138 | SELECT |
| | 139 | COUNT(*) |
| | 140 | FROM |
| | 141 | course_lecture cl |
| | 142 | JOIN course_content cc |
| | 143 | ON cl.course_content_id = cc.id |
| | 144 | JOIN course_version cv |
| | 145 | ON cc.course_version_id = cv.id |
| | 146 | WHERE |
| | 147 | cv.course_id = c.id |
| | 148 | AND cv.active = TRUE |
| | 149 | ) AS course_lecture_count, |
| | 150 | |
| | 151 | ( |
| | 152 | SELECT |
| | 153 | AVG(r.rating) |
| | 154 | FROM |
| | 155 | review r |
| | 156 | JOIN enrollment e |
| | 157 | ON e.id = r.enrollment_id |
| | 158 | JOIN course_version cv |
| | 159 | ON cv.id = e.course_version_id |
| | 160 | WHERE |
| | 161 | cv.course_id = c.id |
| | 162 | ) AS avg_rating, |
| | 163 | |
| | 164 | ( |
| | 165 | SELECT |
| | 166 | JSON_AGG(tt.value) |
| | 167 | FROM |
| | 168 | course_tag ctag |
| | 169 | JOIN tag t |
| | 170 | ON t.id = ctag.tag_id |
| | 171 | JOIN tag_translate tt |
| | 172 | ON t.id = tt.tag_id |
| | 173 | WHERE |
| | 174 | ctag.course_id = c.id |
| | 175 | AND tt.language = 'en' |
| | 176 | AND t.type = 'skill' |
| | 177 | ) AS skills, |
| | 178 | |
| | 179 | ( |
| | 180 | SELECT |
| | 181 | JSON_AGG(tt.value) |
| | 182 | FROM |
| | 183 | course_tag ctag |
| | 184 | JOIN tag t |
| | 185 | ON t.id = ctag.tag_id |
| | 186 | JOIN tag_translate tt |
| | 187 | ON t.id = tt.tag_id |
| | 188 | WHERE |
| | 189 | ctag.course_id = c.id |
| | 190 | AND tt.language = 'en' |
| | 191 | AND t.type = 'interest' |
| | 192 | ) AS topics, |
| | 193 | |
| | 194 | ( |
| | 195 | SELECT |
| | 196 | JSON_AGG(ctwwbl.what_will_be_learned) |
| | 197 | FROM |
| | 198 | course_translate_what_will_be_learned ctwwbl |
| | 199 | WHERE |
| | 200 | ctwwbl.course_translate_id = ct.id |
| | 201 | ) AS what_will_be_learned, |
| | 202 | |
| | 203 | ( |
| | 204 | SELECT |
| | 205 | JSON_AGG( |
| | 206 | JSONB_BUILD_OBJECT( |
| | 207 | 'title', cct.title, |
| | 208 | 'position', cc.position, |
| | 209 | 'lectures', ( |
| | 210 | SELECT |
| | 211 | JSON_AGG( |
| | 212 | JSONB_BUILD_OBJECT( |
| | 213 | 'title', clt.title, |
| | 214 | 'description', clt.description, |
| | 215 | 'duration_minutes', cl.duration_minutes, |
| | 216 | 'position', cl.position, |
| | 217 | 'content_type', cl.content_type |
| | 218 | ) |
| | 219 | ORDER BY cl.position |
| | 220 | ) |
| | 221 | FROM |
| | 222 | course_lecture cl |
| | 223 | JOIN course_lecture_translate clt |
| | 224 | ON clt.course_lecture_id = cl.id |
| | 225 | WHERE |
| | 226 | cl.course_content_id = cc.id |
| | 227 | AND clt.language = 'en' |
| | 228 | ) |
| | 229 | ) |
| | 230 | ORDER BY cc.position |
| | 231 | ) |
| | 232 | FROM |
| | 233 | course_content cc |
| | 234 | JOIN course_content_translate cct |
| | 235 | ON cct.course_content_id = cc.id |
| | 236 | JOIN course_version cv |
| | 237 | ON cc.course_version_id = cv.id |
| | 238 | WHERE |
| | 239 | cv.course_id = c.id |
| | 240 | AND cv.active = TRUE |
| | 241 | AND cct.language = 'en' |
| | 242 | ) AS course_content |
| | 243 | |
| | 244 | FROM |
| | 245 | course c |
| | 246 | JOIN course_translate ct |
| | 247 | ON c.id = ct.course_id |
| | 248 | |
| | 249 | WHERE |
| | 250 | ct.language = 'en'; |
| | 251 | }}} |
| | 252 | |
| | 253 | === Чекори 3 |
| | 254 | |
| | 255 | Корисникот кликнува на копчето за купување на курс |
| | 256 | |
| | 257 | {{{ |
| | 258 | INSERT INTO enrollment (purchase_date, activation_date, completion_date, enrollment_status, user_id, course_version_id) |
| | 259 | VALUES ('2026-01-25 00:00:00', null, null, 'pending', 1, 2); |
| | 260 | }}} |
| | 261 | |
| | 262 | purchase_date -> датум на купување |
| | 263 | activation_date -> датум на активација |
| | 264 | completion_date -> датум на завршување |
| | 265 | enrollment_status -> статус за тоа дали не е почнат, е почнат или е завршен курсот (default е pending бидејќи при купување на курсот тој не е започнат) |
| | 266 | user_id -> ид на корисник |
| | 267 | course_version_id -> ид на верзија на курсот која се купува |
| | 268 | |
| | 269 | |
| | 270 | |
| | 271 | |
| | 272 | |
| | 273 | |