@hed-hog/lms 0.0.361 → 0.0.365

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (434) hide show
  1. package/dist/bitcode-wallet/bitcode-wallet.service.d.ts +66 -0
  2. package/dist/bitcode-wallet/bitcode-wallet.service.d.ts.map +1 -1
  3. package/dist/bitcode-wallet/bitcode-wallet.service.js +91 -0
  4. package/dist/bitcode-wallet/bitcode-wallet.service.js.map +1 -1
  5. package/dist/bitcode-wallet/dto/create-current-bitcode-wallet-transaction.dto.d.ts +8 -0
  6. package/dist/bitcode-wallet/dto/create-current-bitcode-wallet-transaction.dto.d.ts.map +1 -0
  7. package/dist/bitcode-wallet/dto/create-current-bitcode-wallet-transaction.dto.js +40 -0
  8. package/dist/bitcode-wallet/dto/create-current-bitcode-wallet-transaction.dto.js.map +1 -0
  9. package/dist/class-group/class-group.controller.d.ts +16 -16
  10. package/dist/class-group/class-group.service.d.ts +12 -12
  11. package/dist/course/course-audio-transcription.service.d.ts +3 -2
  12. package/dist/course/course-audio-transcription.service.d.ts.map +1 -1
  13. package/dist/course/course-audio-transcription.service.js +49 -8
  14. package/dist/course/course-audio-transcription.service.js.map +1 -1
  15. package/dist/course/course-export-scorm12-worker.service.d.ts +21 -0
  16. package/dist/course/course-export-scorm12-worker.service.d.ts.map +1 -0
  17. package/dist/course/course-export-scorm12-worker.service.js +109 -0
  18. package/dist/course/course-export-scorm12-worker.service.js.map +1 -0
  19. package/dist/course/course-export-scorm12.service.d.ts +42 -0
  20. package/dist/course/course-export-scorm12.service.d.ts.map +1 -0
  21. package/dist/course/course-export-scorm12.service.js +628 -0
  22. package/dist/course/course-export-scorm12.service.js.map +1 -0
  23. package/dist/course/course-export.service.d.ts +84 -0
  24. package/dist/course/course-export.service.d.ts.map +1 -0
  25. package/dist/course/course-export.service.js +237 -0
  26. package/dist/course/course-export.service.js.map +1 -0
  27. package/dist/course/course-lesson.controller.d.ts +4 -0
  28. package/dist/course/course-lesson.controller.d.ts.map +1 -1
  29. package/dist/course/course-lesson.controller.js +10 -0
  30. package/dist/course/course-lesson.controller.js.map +1 -1
  31. package/dist/course/course-structure.controller.d.ts +24 -9
  32. package/dist/course/course-structure.controller.d.ts.map +1 -1
  33. package/dist/course/course-structure.controller.js +30 -3
  34. package/dist/course/course-structure.controller.js.map +1 -1
  35. package/dist/course/course-structure.service.d.ts +25 -3
  36. package/dist/course/course-structure.service.d.ts.map +1 -1
  37. package/dist/course/course-structure.service.js +234 -24
  38. package/dist/course/course-structure.service.js.map +1 -1
  39. package/dist/course/course-video-conversion.service.d.ts +8 -0
  40. package/dist/course/course-video-conversion.service.d.ts.map +1 -1
  41. package/dist/course/course-video-conversion.service.js +87 -51
  42. package/dist/course/course-video-conversion.service.js.map +1 -1
  43. package/dist/course/course-video-hls.service.d.ts +57 -0
  44. package/dist/course/course-video-hls.service.d.ts.map +1 -0
  45. package/dist/course/course-video-hls.service.js +767 -0
  46. package/dist/course/course-video-hls.service.js.map +1 -0
  47. package/dist/course/course.controller.d.ts +115 -11
  48. package/dist/course/course.controller.d.ts.map +1 -1
  49. package/dist/course/course.controller.js +66 -28
  50. package/dist/course/course.controller.js.map +1 -1
  51. package/dist/course/course.mcp-tools.js +1 -1
  52. package/dist/course/course.mcp-tools.js.map +1 -1
  53. package/dist/course/course.module.d.ts.map +1 -1
  54. package/dist/course/course.module.js +13 -0
  55. package/dist/course/course.module.js.map +1 -1
  56. package/dist/course/course.service.d.ts +112 -11
  57. package/dist/course/course.service.d.ts.map +1 -1
  58. package/dist/course/course.service.js +682 -72
  59. package/dist/course/course.service.js.map +1 -1
  60. package/dist/course/dto/cleanup-course-storage.dto.d.ts +6 -0
  61. package/dist/course/dto/cleanup-course-storage.dto.d.ts.map +1 -0
  62. package/dist/course/dto/cleanup-course-storage.dto.js +34 -0
  63. package/dist/course/dto/cleanup-course-storage.dto.js.map +1 -0
  64. package/dist/course/dto/cleanup-upload-history.dto.d.ts +9 -0
  65. package/dist/course/dto/cleanup-upload-history.dto.d.ts.map +1 -0
  66. package/dist/course/dto/cleanup-upload-history.dto.js +36 -0
  67. package/dist/course/dto/cleanup-upload-history.dto.js.map +1 -0
  68. package/dist/course/dto/create-course-bulk-job.dto.d.ts +5 -0
  69. package/dist/course/dto/create-course-bulk-job.dto.d.ts.map +1 -0
  70. package/dist/course/dto/create-course-bulk-job.dto.js +26 -0
  71. package/dist/course/dto/create-course-bulk-job.dto.js.map +1 -0
  72. package/dist/course/dto/create-course-export.dto.d.ts +14 -0
  73. package/dist/course/dto/create-course-export.dto.d.ts.map +1 -0
  74. package/dist/course/dto/create-course-export.dto.js +71 -0
  75. package/dist/course/dto/create-course-export.dto.js.map +1 -0
  76. package/dist/course/dto/create-course-structure-lesson.dto.d.ts +2 -2
  77. package/dist/course/dto/create-course-structure-lesson.dto.d.ts.map +1 -1
  78. package/dist/course/dto/create-course-structure-lesson.dto.js +3 -2
  79. package/dist/course/dto/create-course-structure-lesson.dto.js.map +1 -1
  80. package/dist/course/lms-bulk-upload-automation.service.d.ts +54 -0
  81. package/dist/course/lms-bulk-upload-automation.service.d.ts.map +1 -0
  82. package/dist/course/lms-bulk-upload-automation.service.js +537 -0
  83. package/dist/course/lms-bulk-upload-automation.service.js.map +1 -0
  84. package/dist/course/lms-bulk-upload-infra.service.d.ts +32 -0
  85. package/dist/course/lms-bulk-upload-infra.service.d.ts.map +1 -0
  86. package/dist/course/lms-bulk-upload-infra.service.js +301 -0
  87. package/dist/course/lms-bulk-upload-infra.service.js.map +1 -0
  88. package/dist/course/lms-bulk-upload.constants.d.ts +4 -0
  89. package/dist/course/lms-bulk-upload.constants.d.ts.map +1 -0
  90. package/dist/course/lms-bulk-upload.constants.js +7 -0
  91. package/dist/course/lms-bulk-upload.constants.js.map +1 -0
  92. package/dist/course/lms-bulk-upload.controller.d.ts +144 -1
  93. package/dist/course/lms-bulk-upload.controller.d.ts.map +1 -1
  94. package/dist/course/lms-bulk-upload.controller.js +114 -4
  95. package/dist/course/lms-bulk-upload.controller.js.map +1 -1
  96. package/dist/course/lms-bulk-upload.service.d.ts +153 -3
  97. package/dist/course/lms-bulk-upload.service.d.ts.map +1 -1
  98. package/dist/course/lms-bulk-upload.service.js +659 -21
  99. package/dist/course/lms-bulk-upload.service.js.map +1 -1
  100. package/dist/course/lms-setting.controller.d.ts +6 -2
  101. package/dist/course/lms-setting.controller.d.ts.map +1 -1
  102. package/dist/course/lms-setting.controller.js +25 -8
  103. package/dist/course/lms-setting.controller.js.map +1 -1
  104. package/dist/course/scorm12-schemas.d.ts +4 -0
  105. package/dist/course/scorm12-schemas.d.ts.map +1 -0
  106. package/dist/course/scorm12-schemas.js +9 -0
  107. package/dist/course/scorm12-schemas.js.map +1 -0
  108. package/dist/enterprise/enterprise.controller.d.ts +20 -20
  109. package/dist/enterprise/enterprise.service.d.ts +20 -20
  110. package/dist/enterprise/training/training-admin.controller.d.ts +11 -11
  111. package/dist/enterprise/training/training-admin.service.d.ts +11 -11
  112. package/dist/enterprise/training/training-instructor.controller.d.ts +2 -2
  113. package/dist/enterprise/training/training-instructor.service.d.ts +2 -2
  114. package/dist/enterprise/training/training-student.controller.d.ts +1 -1
  115. package/dist/enterprise/training/training-student.service.d.ts +52 -1
  116. package/dist/enterprise/training/training-student.service.d.ts.map +1 -1
  117. package/dist/enterprise/training/training-student.service.js +217 -4
  118. package/dist/enterprise/training/training-student.service.js.map +1 -1
  119. package/dist/enterprise/training/training-viewer.controller.d.ts +2 -2
  120. package/dist/evaluation/evaluation.controller.d.ts +8 -8
  121. package/dist/evaluation/evaluation.service.d.ts +26 -8
  122. package/dist/evaluation/evaluation.service.d.ts.map +1 -1
  123. package/dist/evaluation/evaluation.service.js +125 -0
  124. package/dist/evaluation/evaluation.service.js.map +1 -1
  125. package/dist/exam/dto/create-standalone-question.dto.d.ts +12 -0
  126. package/dist/exam/dto/create-standalone-question.dto.d.ts.map +1 -0
  127. package/dist/exam/dto/create-standalone-question.dto.js +70 -0
  128. package/dist/exam/dto/create-standalone-question.dto.js.map +1 -0
  129. package/dist/exam/exam.module.d.ts.map +1 -1
  130. package/dist/exam/exam.module.js +2 -1
  131. package/dist/exam/exam.module.js.map +1 -1
  132. package/dist/exam/exam.service.d.ts +21 -0
  133. package/dist/exam/exam.service.d.ts.map +1 -1
  134. package/dist/exam/exam.service.js +80 -0
  135. package/dist/exam/exam.service.js.map +1 -1
  136. package/dist/exam/question.controller.d.ts +27 -0
  137. package/dist/exam/question.controller.d.ts.map +1 -0
  138. package/dist/exam/question.controller.js +53 -0
  139. package/dist/exam/question.controller.js.map +1 -0
  140. package/dist/lesson-xp-map/dto/create-lesson-xp-map.dto.d.ts +6 -0
  141. package/dist/lesson-xp-map/dto/create-lesson-xp-map.dto.d.ts.map +1 -0
  142. package/dist/lesson-xp-map/dto/create-lesson-xp-map.dto.js +34 -0
  143. package/dist/lesson-xp-map/dto/create-lesson-xp-map.dto.js.map +1 -0
  144. package/dist/lesson-xp-map/dto/create-lesson-xp-segment.dto.d.ts +28 -0
  145. package/dist/lesson-xp-map/dto/create-lesson-xp-segment.dto.d.ts.map +1 -0
  146. package/dist/lesson-xp-map/dto/create-lesson-xp-segment.dto.js +123 -0
  147. package/dist/lesson-xp-map/dto/create-lesson-xp-segment.dto.js.map +1 -0
  148. package/dist/lesson-xp-map/dto/review-lesson-xp-map.dto.d.ts +4 -0
  149. package/dist/lesson-xp-map/dto/review-lesson-xp-map.dto.d.ts.map +1 -0
  150. package/dist/lesson-xp-map/dto/review-lesson-xp-map.dto.js +22 -0
  151. package/dist/lesson-xp-map/dto/review-lesson-xp-map.dto.js.map +1 -0
  152. package/dist/lesson-xp-map/dto/update-lesson-xp-map.dto.d.ts +10 -0
  153. package/dist/lesson-xp-map/dto/update-lesson-xp-map.dto.d.ts.map +1 -0
  154. package/dist/lesson-xp-map/dto/update-lesson-xp-map.dto.js +52 -0
  155. package/dist/lesson-xp-map/dto/update-lesson-xp-map.dto.js.map +1 -0
  156. package/dist/lesson-xp-map/dto/update-lesson-xp-segment.dto.d.ts +15 -0
  157. package/dist/lesson-xp-map/dto/update-lesson-xp-segment.dto.d.ts.map +1 -0
  158. package/dist/lesson-xp-map/dto/update-lesson-xp-segment.dto.js +86 -0
  159. package/dist/lesson-xp-map/dto/update-lesson-xp-segment.dto.js.map +1 -0
  160. package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.d.ts +30 -0
  161. package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.d.ts.map +1 -0
  162. package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.js +440 -0
  163. package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.js.map +1 -0
  164. package/dist/lesson-xp-map/lesson-xp-map.controller.d.ts +87 -0
  165. package/dist/lesson-xp-map/lesson-xp-map.controller.d.ts.map +1 -0
  166. package/dist/lesson-xp-map/lesson-xp-map.controller.js +185 -0
  167. package/dist/lesson-xp-map/lesson-xp-map.controller.js.map +1 -0
  168. package/dist/lesson-xp-map/lesson-xp-map.module.d.ts +3 -0
  169. package/dist/lesson-xp-map/lesson-xp-map.module.d.ts.map +1 -0
  170. package/dist/lesson-xp-map/lesson-xp-map.module.js +34 -0
  171. package/dist/lesson-xp-map/lesson-xp-map.module.js.map +1 -0
  172. package/dist/lesson-xp-map/lesson-xp-map.service.d.ts +84 -0
  173. package/dist/lesson-xp-map/lesson-xp-map.service.d.ts.map +1 -0
  174. package/dist/lesson-xp-map/lesson-xp-map.service.js +353 -0
  175. package/dist/lesson-xp-map/lesson-xp-map.service.js.map +1 -0
  176. package/dist/lesson-xp-map/lesson-xp-segment.controller.d.ts +10 -0
  177. package/dist/lesson-xp-map/lesson-xp-segment.controller.d.ts.map +1 -0
  178. package/dist/lesson-xp-map/lesson-xp-segment.controller.js +63 -0
  179. package/dist/lesson-xp-map/lesson-xp-segment.controller.js.map +1 -0
  180. package/dist/lesson-xp-map/lesson-xp-segment.service.d.ts +27 -0
  181. package/dist/lesson-xp-map/lesson-xp-segment.service.d.ts.map +1 -0
  182. package/dist/lesson-xp-map/lesson-xp-segment.service.js +194 -0
  183. package/dist/lesson-xp-map/lesson-xp-segment.service.js.map +1 -0
  184. package/dist/libraries/lms/tsconfig.tsbuildinfo +1 -0
  185. package/dist/lms-commerce-access.subscriber.d.ts +11 -0
  186. package/dist/lms-commerce-access.subscriber.d.ts.map +1 -0
  187. package/dist/lms-commerce-access.subscriber.js +74 -0
  188. package/dist/lms-commerce-access.subscriber.js.map +1 -0
  189. package/dist/lms.module.d.ts.map +1 -1
  190. package/dist/lms.module.js +21 -5
  191. package/dist/lms.module.js.map +1 -1
  192. package/dist/platforma/dto/update-profile.dto.d.ts +17 -0
  193. package/dist/platforma/dto/update-profile.dto.d.ts.map +1 -0
  194. package/dist/platforma/dto/update-profile.dto.js +87 -0
  195. package/dist/platforma/dto/update-profile.dto.js.map +1 -0
  196. package/dist/platforma/platforma-video.service.d.ts +39 -0
  197. package/dist/platforma/platforma-video.service.d.ts.map +1 -0
  198. package/dist/platforma/platforma-video.service.js +301 -0
  199. package/dist/platforma/platforma-video.service.js.map +1 -0
  200. package/dist/platforma/platforma.controller.d.ts +182 -1
  201. package/dist/platforma/platforma.controller.d.ts.map +1 -1
  202. package/dist/platforma/platforma.controller.js +243 -2
  203. package/dist/platforma/platforma.controller.js.map +1 -1
  204. package/dist/platforma/platforma.service.d.ts +27 -0
  205. package/dist/platforma/platforma.service.d.ts.map +1 -0
  206. package/dist/platforma/platforma.service.js +274 -0
  207. package/dist/platforma/platforma.service.js.map +1 -0
  208. package/dist/student-xp/dto/grant-skill-card-xp.dto.d.ts +5 -0
  209. package/dist/student-xp/dto/grant-skill-card-xp.dto.d.ts.map +1 -0
  210. package/dist/student-xp/dto/grant-skill-card-xp.dto.js +26 -0
  211. package/dist/student-xp/dto/grant-skill-card-xp.dto.js.map +1 -0
  212. package/dist/student-xp/student-xp.controller.d.ts +56 -0
  213. package/dist/student-xp/student-xp.controller.d.ts.map +1 -0
  214. package/dist/student-xp/student-xp.controller.js +138 -0
  215. package/dist/student-xp/student-xp.controller.js.map +1 -0
  216. package/dist/student-xp/student-xp.module.d.ts +3 -0
  217. package/dist/student-xp/student-xp.module.d.ts.map +1 -0
  218. package/dist/student-xp/student-xp.module.js +25 -0
  219. package/dist/student-xp/student-xp.module.js.map +1 -0
  220. package/dist/student-xp/student-xp.service.d.ts +81 -0
  221. package/dist/student-xp/student-xp.service.d.ts.map +1 -0
  222. package/dist/student-xp/student-xp.service.js +247 -0
  223. package/dist/student-xp/student-xp.service.js.map +1 -0
  224. package/dist/xp-catalog/dto/create-xp-area.dto.d.ts +12 -0
  225. package/dist/xp-catalog/dto/create-xp-area.dto.d.ts.map +1 -0
  226. package/dist/xp-catalog/dto/create-xp-area.dto.js +63 -0
  227. package/dist/xp-catalog/dto/create-xp-area.dto.js.map +1 -0
  228. package/dist/xp-catalog/dto/create-xp-learning-type.dto.d.ts +11 -0
  229. package/dist/xp-catalog/dto/create-xp-learning-type.dto.d.ts.map +1 -0
  230. package/dist/xp-catalog/dto/create-xp-learning-type.dto.js +57 -0
  231. package/dist/xp-catalog/dto/create-xp-learning-type.dto.js.map +1 -0
  232. package/dist/xp-catalog/dto/create-xp-skill.dto.d.ts +11 -0
  233. package/dist/xp-catalog/dto/create-xp-skill.dto.d.ts.map +1 -0
  234. package/dist/xp-catalog/dto/create-xp-skill.dto.js +57 -0
  235. package/dist/xp-catalog/dto/create-xp-skill.dto.js.map +1 -0
  236. package/dist/xp-catalog/dto/update-xp-area.dto.d.ts +12 -0
  237. package/dist/xp-catalog/dto/update-xp-area.dto.d.ts.map +1 -0
  238. package/dist/xp-catalog/dto/update-xp-area.dto.js +66 -0
  239. package/dist/xp-catalog/dto/update-xp-area.dto.js.map +1 -0
  240. package/dist/xp-catalog/dto/update-xp-learning-type.dto.d.ts +11 -0
  241. package/dist/xp-catalog/dto/update-xp-learning-type.dto.d.ts.map +1 -0
  242. package/dist/xp-catalog/dto/update-xp-learning-type.dto.js +60 -0
  243. package/dist/xp-catalog/dto/update-xp-learning-type.dto.js.map +1 -0
  244. package/dist/xp-catalog/dto/update-xp-skill.dto.d.ts +11 -0
  245. package/dist/xp-catalog/dto/update-xp-skill.dto.d.ts.map +1 -0
  246. package/dist/xp-catalog/dto/update-xp-skill.dto.js +60 -0
  247. package/dist/xp-catalog/dto/update-xp-skill.dto.js.map +1 -0
  248. package/dist/xp-catalog/xp-area.controller.d.ts +25 -0
  249. package/dist/xp-catalog/xp-area.controller.d.ts.map +1 -0
  250. package/dist/xp-catalog/xp-area.controller.js +105 -0
  251. package/dist/xp-catalog/xp-area.controller.js.map +1 -0
  252. package/dist/xp-catalog/xp-area.service.d.ts +35 -0
  253. package/dist/xp-catalog/xp-area.service.d.ts.map +1 -0
  254. package/dist/xp-catalog/xp-area.service.js +168 -0
  255. package/dist/xp-catalog/xp-area.service.js.map +1 -0
  256. package/dist/xp-catalog/xp-catalog.module.d.ts +3 -0
  257. package/dist/xp-catalog/xp-catalog.module.d.ts.map +1 -0
  258. package/dist/xp-catalog/xp-catalog.module.js +29 -0
  259. package/dist/xp-catalog/xp-catalog.module.js.map +1 -0
  260. package/dist/xp-catalog/xp-learning-type.controller.d.ts +20 -0
  261. package/dist/xp-catalog/xp-learning-type.controller.d.ts.map +1 -0
  262. package/dist/xp-catalog/xp-learning-type.controller.js +96 -0
  263. package/dist/xp-catalog/xp-learning-type.controller.js.map +1 -0
  264. package/dist/xp-catalog/xp-learning-type.service.d.ts +30 -0
  265. package/dist/xp-catalog/xp-learning-type.service.d.ts.map +1 -0
  266. package/dist/xp-catalog/xp-learning-type.service.js +146 -0
  267. package/dist/xp-catalog/xp-learning-type.service.js.map +1 -0
  268. package/dist/xp-catalog/xp-skill.controller.d.ts +26 -0
  269. package/dist/xp-catalog/xp-skill.controller.d.ts.map +1 -0
  270. package/dist/xp-catalog/xp-skill.controller.js +113 -0
  271. package/dist/xp-catalog/xp-skill.controller.js.map +1 -0
  272. package/dist/xp-catalog/xp-skill.service.d.ts +37 -0
  273. package/dist/xp-catalog/xp-skill.service.d.ts.map +1 -0
  274. package/dist/xp-catalog/xp-skill.service.js +174 -0
  275. package/dist/xp-catalog/xp-skill.service.js.map +1 -0
  276. package/hedhog/data/evaluation_topic.yaml +17 -0
  277. package/hedhog/data/menu.yaml +91 -7
  278. package/hedhog/data/queue_definition.yaml +48 -0
  279. package/hedhog/data/route.yaml +511 -29
  280. package/hedhog/data/setting_group.yaml +20 -20
  281. package/hedhog/data/xp_area.yaml +164 -0
  282. package/hedhog/data/xp_learning_type.yaml +131 -0
  283. package/hedhog/data/xp_skill.yaml +1834 -0
  284. package/hedhog/frontend/app/achievements/page.tsx.ejs +108 -118
  285. package/hedhog/frontend/app/bitcodes/page.tsx.ejs +22 -34
  286. package/hedhog/frontend/app/bulk-upload-sessions/page.tsx.ejs +1749 -0
  287. package/hedhog/frontend/app/certificates/models/page.tsx.ejs +21 -45
  288. package/hedhog/frontend/app/classes/[id]/page.tsx.ejs +40 -74
  289. package/hedhog/frontend/app/classes/page.tsx.ejs +56 -85
  290. package/hedhog/frontend/app/courses/[id]/_components/CourseDangerZoneCard.tsx.ejs +3 -2
  291. package/hedhog/frontend/app/courses/[id]/_components/CourseMediaCard.tsx.ejs +48 -5
  292. package/hedhog/frontend/app/courses/[id]/page.tsx.ejs +73 -8
  293. package/hedhog/frontend/app/courses/[id]/structure/_components/course-export-sheet.tsx.ejs +420 -0
  294. package/hedhog/frontend/app/courses/[id]/structure/_components/course-exports-tab.tsx.ejs +308 -0
  295. package/hedhog/frontend/app/courses/[id]/structure/_components/course-operations-tab.tsx.ejs +19 -2
  296. package/hedhog/frontend/app/courses/[id]/structure/_components/course-overview-tab.tsx.ejs +1172 -0
  297. package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree-dnd.tsx.ejs +16 -0
  298. package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree.tsx.ejs +2 -0
  299. package/hedhog/frontend/app/courses/[id]/structure/_components/course-xp-overview-tab.tsx.ejs +623 -0
  300. package/hedhog/frontend/app/courses/[id]/structure/_components/detail-lesson-xp-tab.tsx.ejs +1458 -0
  301. package/hedhog/frontend/app/courses/[id]/structure/_components/detail-lesson.tsx.ejs +87 -46
  302. package/hedhog/frontend/app/courses/[id]/structure/_components/detail-panel.tsx.ejs +8 -3
  303. package/hedhog/frontend/app/courses/[id]/structure/_components/detail-session.tsx.ejs +31 -8
  304. package/hedhog/frontend/app/courses/[id]/structure/_components/drag-overlay.tsx.ejs +16 -9
  305. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-course.tsx.ejs +618 -480
  306. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-lesson.tsx.ejs +672 -737
  307. package/hedhog/frontend/app/courses/[id]/structure/_components/mock-data.ts.ejs +1 -2
  308. package/hedhog/frontend/app/courses/[id]/structure/_components/sortable-tree-row.tsx.ejs +3 -0
  309. package/hedhog/frontend/app/courses/[id]/structure/_components/store.ts.ejs +1 -0
  310. package/hedhog/frontend/app/courses/[id]/structure/_components/tree-display-settings-popover.tsx.ejs +101 -85
  311. package/hedhog/frontend/app/courses/[id]/structure/_components/tree-row-lesson.tsx.ejs +24 -10
  312. package/hedhog/frontend/app/courses/[id]/structure/_components/tree-row.tsx.ejs +3 -0
  313. package/hedhog/frontend/app/courses/[id]/structure/_components/types.ts.ejs +1 -1
  314. package/hedhog/frontend/app/courses/[id]/structure/_components/use-tree-display-settings.ts.ejs +7 -1
  315. package/hedhog/frontend/app/courses/[id]/structure/_components/xp-premium-pills.tsx.ejs +44 -0
  316. package/hedhog/frontend/app/courses/[id]/structure/_data/adapters/course-structure.adapter.ts.ejs +6 -10
  317. package/hedhog/frontend/app/courses/[id]/structure/_data/services/course-structure.service.ts.ejs +49 -0
  318. package/hedhog/frontend/app/courses/[id]/structure/_data/types/api-course.types.ts.ejs +4 -3
  319. package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-content-overview.ts.ejs +53 -0
  320. package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-exports.ts.ejs +106 -0
  321. package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-structure-mutations.ts.ejs +80 -1
  322. package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-xp-overview.ts.ejs +76 -0
  323. package/hedhog/frontend/app/courses/[id]/structure/_data/use-lesson-xp-map.ts.ejs +128 -0
  324. package/hedhog/frontend/app/courses/[id]/structure/_data/use-lms-settings-query.ts.ejs +0 -2
  325. package/hedhog/frontend/app/courses/[id]/structure/_data/use-transcription-segments.ts.ejs +30 -0
  326. package/hedhog/frontend/app/courses/[id]/structure/_utils/xp-color-config.ts.ejs +115 -0
  327. package/hedhog/frontend/app/courses/_components/CourseDeleteDialog.tsx.ejs +223 -0
  328. package/hedhog/frontend/app/courses/_components/CourseRowActions.tsx.ejs +89 -0
  329. package/hedhog/frontend/app/courses/page.tsx.ejs +445 -230
  330. package/hedhog/frontend/app/enterprise/page.tsx.ejs +39 -63
  331. package/hedhog/frontend/app/exams/[id]/questions/page.tsx.ejs +53 -77
  332. package/hedhog/frontend/app/exams/page.tsx.ejs +54 -90
  333. package/hedhog/frontend/app/instructor-skills/page.tsx.ejs +23 -36
  334. package/hedhog/frontend/app/instructors/page.tsx.ejs +72 -81
  335. package/hedhog/frontend/app/paths/page.tsx.ejs +40 -68
  336. package/hedhog/frontend/app/training/page.tsx.ejs +40 -68
  337. package/hedhog/frontend/app/xp/areas/page.tsx.ejs +782 -0
  338. package/hedhog/frontend/app/xp/learning-types/page.tsx.ejs +690 -0
  339. package/hedhog/frontend/app/xp/skills/page.tsx.ejs +811 -0
  340. package/hedhog/frontend/messages/en.json +412 -31
  341. package/hedhog/frontend/messages/pt.json +412 -31
  342. package/hedhog/table/course_export.yaml +62 -0
  343. package/hedhog/table/lesson_xp_map.yaml +50 -0
  344. package/hedhog/table/lesson_xp_segment.yaml +40 -0
  345. package/hedhog/table/lesson_xp_segment_area.yaml +24 -0
  346. package/hedhog/table/lesson_xp_segment_learning_type.yaml +24 -0
  347. package/hedhog/table/lesson_xp_segment_skill.yaml +24 -0
  348. package/hedhog/table/lms_bulk_upload_item.yaml +44 -0
  349. package/hedhog/table/lms_bulk_upload_session.yaml +42 -0
  350. package/hedhog/table/student_area_xp.yaml +30 -0
  351. package/hedhog/table/student_learning_type_xp.yaml +30 -0
  352. package/hedhog/table/student_skill_xp.yaml +30 -0
  353. package/hedhog/table/student_xp_event.yaml +34 -0
  354. package/hedhog/table/xp_area.yaml +39 -0
  355. package/hedhog/table/xp_learning_type.yaml +34 -0
  356. package/hedhog/table/xp_skill.yaml +39 -0
  357. package/package.json +13 -8
  358. package/src/bitcode-wallet/bitcode-wallet.service.ts +152 -0
  359. package/src/bitcode-wallet/dto/create-current-bitcode-wallet-transaction.dto.ts +32 -0
  360. package/src/course/course-audio-transcription.service.ts +58 -21
  361. package/src/course/course-export-scorm12-worker.service.ts +124 -0
  362. package/src/course/course-export-scorm12.service.ts +668 -0
  363. package/src/course/course-export.service.ts +280 -0
  364. package/src/course/course-lesson.controller.ts +6 -1
  365. package/src/course/course-structure.controller.ts +23 -1
  366. package/src/course/course-structure.service.ts +273 -7
  367. package/src/course/course-video-conversion.service.ts +113 -75
  368. package/src/course/course-video-hls.service.ts +946 -0
  369. package/src/course/course.controller.ts +54 -21
  370. package/src/course/course.mcp-tools.ts +1 -1
  371. package/src/course/course.module.ts +13 -0
  372. package/src/course/course.service.ts +906 -76
  373. package/src/course/dto/cleanup-course-storage.dto.ts +23 -0
  374. package/src/course/dto/cleanup-upload-history.dto.ts +26 -0
  375. package/src/course/dto/create-course-bulk-job.dto.ts +10 -0
  376. package/src/course/dto/create-course-export.dto.ts +56 -0
  377. package/src/course/dto/create-course-structure-lesson.dto.ts +4 -3
  378. package/src/course/lms-bulk-upload-automation.service.ts +707 -0
  379. package/src/course/lms-bulk-upload-infra.service.ts +360 -0
  380. package/src/course/lms-bulk-upload.constants.ts +5 -0
  381. package/src/course/lms-bulk-upload.controller.ts +110 -4
  382. package/src/course/lms-bulk-upload.service.ts +1092 -204
  383. package/src/course/lms-setting.controller.ts +26 -8
  384. package/src/course/scorm12-schemas.ts +9 -0
  385. package/src/enterprise/training/training-student.service.ts +221 -2
  386. package/src/evaluation/evaluation.service.ts +123 -0
  387. package/src/exam/dto/create-standalone-question.dto.ts +66 -0
  388. package/src/exam/exam.module.ts +2 -1
  389. package/src/exam/exam.service.ts +86 -0
  390. package/src/exam/question.controller.ts +28 -0
  391. package/src/lesson-xp-map/dto/create-lesson-xp-map.dto.ts +17 -0
  392. package/src/lesson-xp-map/dto/create-lesson-xp-segment.dto.ts +102 -0
  393. package/src/lesson-xp-map/dto/review-lesson-xp-map.dto.ts +7 -0
  394. package/src/lesson-xp-map/dto/update-lesson-xp-map.dto.ts +36 -0
  395. package/src/lesson-xp-map/dto/update-lesson-xp-segment.dto.ts +78 -0
  396. package/src/lesson-xp-map/lesson-xp-ai-calculation.service.ts +570 -0
  397. package/src/lesson-xp-map/lesson-xp-map.controller.ts +116 -0
  398. package/src/lesson-xp-map/lesson-xp-map.module.ts +21 -0
  399. package/src/lesson-xp-map/lesson-xp-map.service.ts +442 -0
  400. package/src/lesson-xp-map/lesson-xp-segment.controller.ts +36 -0
  401. package/src/lesson-xp-map/lesson-xp-segment.service.ts +229 -0
  402. package/src/lms-commerce-access.subscriber.ts +88 -0
  403. package/src/lms.module.ts +21 -5
  404. package/src/platforma/dto/update-profile.dto.ts +59 -0
  405. package/src/platforma/platforma-video.service.ts +346 -0
  406. package/src/platforma/platforma.controller.ts +152 -3
  407. package/src/platforma/platforma.service.ts +268 -0
  408. package/src/student-xp/dto/grant-skill-card-xp.dto.ts +10 -0
  409. package/src/student-xp/student-xp.controller.ts +92 -0
  410. package/src/student-xp/student-xp.module.ts +12 -0
  411. package/src/student-xp/student-xp.service.ts +318 -0
  412. package/src/xp-catalog/dto/create-xp-area.dto.ts +40 -0
  413. package/src/xp-catalog/dto/create-xp-learning-type.dto.ts +35 -0
  414. package/src/xp-catalog/dto/create-xp-skill.dto.ts +35 -0
  415. package/src/xp-catalog/dto/update-xp-area.dto.ts +43 -0
  416. package/src/xp-catalog/dto/update-xp-learning-type.dto.ts +38 -0
  417. package/src/xp-catalog/dto/update-xp-skill.dto.ts +38 -0
  418. package/src/xp-catalog/xp-area.controller.ts +64 -0
  419. package/src/xp-catalog/xp-area.service.ts +196 -0
  420. package/src/xp-catalog/xp-catalog.module.ts +16 -0
  421. package/src/xp-catalog/xp-learning-type.controller.ts +59 -0
  422. package/src/xp-catalog/xp-learning-type.service.ts +170 -0
  423. package/src/xp-catalog/xp-skill.controller.ts +71 -0
  424. package/src/xp-catalog/xp-skill.service.ts +205 -0
  425. package/hedhog/data/video_resolution_profile.yaml +0 -7
  426. package/hedhog/frontend/app/video-resolution-profiles/page.tsx.ejs +0 -607
  427. package/hedhog/table/course_video_resolution_profile.yaml +0 -22
  428. package/hedhog/table/video_resolution_profile.yaml +0 -18
  429. package/src/video-resolution-profile/dto/create-video-resolution-profile.dto.ts +0 -16
  430. package/src/video-resolution-profile/dto/update-video-resolution-profile.dto.ts +0 -16
  431. package/src/video-resolution-profile/video-resolution-profile.controller.ts +0 -62
  432. package/src/video-resolution-profile/video-resolution-profile.mcp-tools.ts +0 -128
  433. package/src/video-resolution-profile/video-resolution-profile.module.ts +0 -13
  434. package/src/video-resolution-profile/video-resolution-profile.service.ts +0 -117
@@ -13,28 +13,199 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.LmsBulkUploadService = void 0;
16
- const core_1 = require("@hed-hog/core");
17
16
  const api_prisma_1 = require("@hed-hog/api-prisma");
18
- const core_2 = require("@hed-hog/core");
17
+ const core_1 = require("@hed-hog/core");
19
18
  const common_1 = require("@nestjs/common");
19
+ const cleanup_upload_history_dto_1 = require("./dto/cleanup-upload-history.dto");
20
+ const lms_bulk_upload_infra_service_1 = require("./lms-bulk-upload-infra.service");
21
+ const lms_bulk_upload_constants_1 = require("./lms-bulk-upload.constants");
20
22
  let LmsBulkUploadService = class LmsBulkUploadService {
21
- constructor(settingService, prismaService, fileService) {
23
+ constructor(settingService, prismaService, fileService, webhookIntegrationService, bulkUploadInfraService) {
22
24
  this.settingService = settingService;
23
25
  this.prismaService = prismaService;
24
26
  this.fileService = fileService;
27
+ this.webhookIntegrationService = webhookIntegrationService;
28
+ this.bulkUploadInfraService = bulkUploadInfraService;
29
+ }
30
+ async configureBulkUpload(userId, payload) {
31
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
32
+ const storageProfileId = Number((_a = payload === null || payload === void 0 ? void 0 : payload.storageProfileId) !== null && _a !== void 0 ? _a : 0);
33
+ const settings = await this.settingService.getSettingValues([
34
+ 'lms-bulk-upload-lambda-role-arn',
35
+ ]);
36
+ const lambdaRoleArn = String((_b = settings['lms-bulk-upload-lambda-role-arn']) !== null && _b !== void 0 ? _b : '').trim();
37
+ if (!Number.isFinite(storageProfileId) || storageProfileId <= 0) {
38
+ throw new common_1.BadRequestException('Select a valid storage integration profile.');
39
+ }
40
+ const { profile, region, bucket, durationSeconds } = await this.resolveStorageProfileAndBucket(userId, {
41
+ storageProfileId,
42
+ });
43
+ const credentials = profile.config;
44
+ const accessKeyId = String((_c = credentials.access_key_id) !== null && _c !== void 0 ? _c : '').trim();
45
+ const secretAccessKey = String((_d = credentials.secret_access_key) !== null && _d !== void 0 ? _d : '').trim();
46
+ const sessionToken = String((_e = credentials.session_token) !== null && _e !== void 0 ? _e : '').trim() || undefined;
47
+ if (!accessKeyId || !secretAccessKey) {
48
+ throw new common_1.BadRequestException('Storage profile does not contain AWS credentials (access_key_id/secret_access_key).');
49
+ }
50
+ await this.fileService.headS3Bucket({
51
+ accessKeyId,
52
+ secretAccessKey,
53
+ sessionToken,
54
+ region,
55
+ bucket,
56
+ });
57
+ const roleArn = String((_f = credentials.role_arn) !== null && _f !== void 0 ? _f : '').trim();
58
+ const externalId = String((_g = credentials.external_id) !== null && _g !== void 0 ? _g : '').trim();
59
+ const tempCredentials = await this.fileService.getTemporaryCredentials({
60
+ accessKeyId,
61
+ secretAccessKey,
62
+ sessionToken,
63
+ region,
64
+ roleArn: roleArn || undefined,
65
+ externalId: externalId || undefined,
66
+ durationSeconds,
67
+ sessionName: `hedhog-desktop-u${userId}-${Date.now()}`,
68
+ });
69
+ await this.fileService.headS3Bucket({
70
+ accessKeyId: tempCredentials.AccessKeyId,
71
+ secretAccessKey: tempCredentials.SecretAccessKey,
72
+ sessionToken: tempCredentials.SessionToken,
73
+ region,
74
+ bucket,
75
+ });
76
+ const webhook = await this.ensureBulkUploadWebhook();
77
+ if (!webhook.public_url || !webhook.plainToken) {
78
+ throw new common_1.BadRequestException('Bulk upload webhook could not be provisioned with URL/token.');
79
+ }
80
+ const infrastructure = await this.bulkUploadInfraService.syncDesktopUploadInfrastructure({
81
+ bucketName: bucket,
82
+ region,
83
+ webhookUrl: String(webhook.public_url),
84
+ webhookSecret: String(webhook.plainToken),
85
+ accessKeyId,
86
+ secretAccessKey,
87
+ sessionToken,
88
+ lambdaRoleArn,
89
+ });
90
+ await this.settingService.setManySettings({
91
+ setting: [
92
+ {
93
+ slug: 'lms-bulk-upload-storage-profile-id',
94
+ value: String(storageProfileId),
95
+ },
96
+ ],
97
+ });
98
+ return {
99
+ success: true,
100
+ storageProfileId,
101
+ bucketName: bucket,
102
+ region,
103
+ credentials: {
104
+ expiresAt: (_j = (_h = tempCredentials.Expiration) === null || _h === void 0 ? void 0 : _h.toISOString()) !== null && _j !== void 0 ? _j : null,
105
+ },
106
+ infrastructure,
107
+ webhook,
108
+ };
109
+ }
110
+ async regenerateWebhookTokenAndSync(userId) {
111
+ var _a, _b, _c, _d;
112
+ const { profile, region, bucket } = await this.resolveStorageProfileAndBucket(userId);
113
+ const settings = await this.settingService.getSettingValues([
114
+ 'lms-bulk-upload-lambda-role-arn',
115
+ ]);
116
+ const lambdaRoleArn = String((_a = settings['lms-bulk-upload-lambda-role-arn']) !== null && _a !== void 0 ? _a : '').trim();
117
+ const credentials = profile.config;
118
+ const accessKeyId = String((_b = credentials.access_key_id) !== null && _b !== void 0 ? _b : '').trim();
119
+ const secretAccessKey = String((_c = credentials.secret_access_key) !== null && _c !== void 0 ? _c : '').trim();
120
+ const sessionToken = String((_d = credentials.session_token) !== null && _d !== void 0 ? _d : '').trim() || undefined;
121
+ if (!accessKeyId || !secretAccessKey) {
122
+ throw new common_1.BadRequestException('Storage profile does not contain AWS credentials (access_key_id/secret_access_key).');
123
+ }
124
+ await this.fileService.headS3Bucket({
125
+ accessKeyId,
126
+ secretAccessKey,
127
+ sessionToken,
128
+ region,
129
+ bucket,
130
+ });
131
+ const webhook = await this.ensureBulkUploadWebhook();
132
+ if (!webhook.public_url || !webhook.plainToken) {
133
+ throw new common_1.BadRequestException('Bulk upload webhook could not be provisioned with URL/token.');
134
+ }
135
+ const infrastructure = await this.bulkUploadInfraService.syncDesktopUploadInfrastructure({
136
+ bucketName: bucket,
137
+ region,
138
+ webhookUrl: String(webhook.public_url),
139
+ webhookSecret: String(webhook.plainToken),
140
+ accessKeyId,
141
+ secretAccessKey,
142
+ sessionToken,
143
+ lambdaRoleArn,
144
+ });
145
+ return {
146
+ success: true,
147
+ storageProfileId: Number(profile.id),
148
+ bucketName: bucket,
149
+ region,
150
+ infrastructure,
151
+ webhook,
152
+ };
153
+ }
154
+ async setBulkUploadLambdaRoleArn(value) {
155
+ const lambdaRoleArn = String(value !== null && value !== void 0 ? value : '').trim();
156
+ if (lambdaRoleArn) {
157
+ const iamRolePattern = /^arn:(aws[a-zA-Z-]*)?:iam::\d{12}:role\/?[a-zA-Z_0-9+=,.@\-_/]+$/;
158
+ if (!iamRolePattern.test(lambdaRoleArn)) {
159
+ throw new common_1.BadRequestException('lambdaRoleArn must be an IAM Role ARN (arn:aws:iam::<account-id>:role/<role-name>). Lambda function ARNs are not valid here.');
160
+ }
161
+ }
162
+ await this.settingService.setManySettings({
163
+ setting: [
164
+ {
165
+ slug: 'lms-bulk-upload-lambda-role-arn',
166
+ value: lambdaRoleArn,
167
+ },
168
+ ],
169
+ });
170
+ return {
171
+ success: true,
172
+ lambdaRoleArn,
173
+ };
25
174
  }
26
175
  async getBulkUploadSettings() {
176
+ var _a, _b, _c;
27
177
  const settings = await this.settingService.getSettingValues([
28
178
  'lms-bulk-upload-storage-profile-id',
29
- 'lms-bulk-upload-s3-bucket',
179
+ 'lms-bulk-upload-lambda-role-arn',
30
180
  'lms-bulk-upload-sts-duration-seconds',
31
181
  ]);
182
+ const storageProfileId = Number(settings['lms-bulk-upload-storage-profile-id'] || 0) || null;
183
+ let bucketName = '';
184
+ if (storageProfileId) {
185
+ const profile = await this.prismaService.integration_profile.findUnique({
186
+ where: { id: storageProfileId },
187
+ select: { config: true },
188
+ });
189
+ const config = (_a = profile === null || profile === void 0 ? void 0 : profile.config) !== null && _a !== void 0 ? _a : null;
190
+ bucketName = String((_b = config === null || config === void 0 ? void 0 : config.bucket) !== null && _b !== void 0 ? _b : '').trim();
191
+ }
192
+ const webhook = await this.prismaService.webhook_integration.findFirst({
193
+ where: {
194
+ OR: [
195
+ { slug: lms_bulk_upload_constants_1.LMS_BULK_UPLOAD_WEBHOOK_SLUG },
196
+ { slug: { startsWith: `${lms_bulk_upload_constants_1.LMS_BULK_UPLOAD_WEBHOOK_SLUG}-` } },
197
+ ],
198
+ },
199
+ orderBy: { id: 'asc' },
200
+ select: { id: true, status: true, public_uuid: true },
201
+ });
202
+ const webhookConfigured = (webhook === null || webhook === void 0 ? void 0 : webhook.status) === 'active' && Boolean(webhook === null || webhook === void 0 ? void 0 : webhook.public_uuid);
32
203
  return {
33
- storageProfileId: Number(settings['lms-bulk-upload-storage-profile-id'] || 0) || null,
34
- bucketName: typeof settings['lms-bulk-upload-s3-bucket'] === 'string'
35
- ? settings['lms-bulk-upload-s3-bucket'].trim()
36
- : '',
204
+ storageProfileId,
205
+ bucketName,
206
+ lambdaRoleArn: String((_c = settings['lms-bulk-upload-lambda-role-arn']) !== null && _c !== void 0 ? _c : '').trim(),
37
207
  sessionDurationSeconds: Number(settings['lms-bulk-upload-sts-duration-seconds'] || 3600) || 3600,
208
+ webhookConfigured,
38
209
  };
39
210
  }
40
211
  async getTemporaryCredentials(userId) {
@@ -109,14 +280,479 @@ let LmsBulkUploadService = class LmsBulkUploadService {
109
280
  };
110
281
  }
111
282
  }
112
- async resolveStorageProfileAndBucket(userId) {
283
+ async ensureBulkUploadWebhook() {
284
+ const existing = await this.prismaService.webhook_integration.findFirst({
285
+ where: {
286
+ OR: [
287
+ { slug: lms_bulk_upload_constants_1.LMS_BULK_UPLOAD_WEBHOOK_SLUG },
288
+ { slug: { startsWith: `${lms_bulk_upload_constants_1.LMS_BULK_UPLOAD_WEBHOOK_SLUG}-` } },
289
+ ],
290
+ },
291
+ orderBy: { id: 'asc' },
292
+ select: {
293
+ id: true,
294
+ slug: true,
295
+ status: true,
296
+ },
297
+ });
298
+ const webhook = !existing
299
+ ? await this.webhookIntegrationService.create({
300
+ slug: lms_bulk_upload_constants_1.LMS_BULK_UPLOAD_WEBHOOK_SLUG,
301
+ name: 'LMS Bulk Upload',
302
+ description: 'Webhook para integração de upload em massa do LMS',
303
+ status: 'active',
304
+ require_token: true,
305
+ })
306
+ : existing.status !== 'active'
307
+ ? await this.webhookIntegrationService.update(existing.id, {
308
+ status: 'active',
309
+ require_token: true,
310
+ })
311
+ : await this.webhookIntegrationService.get(existing.id);
312
+ const actions = await this.webhookIntegrationService.listActions(webhook.id);
313
+ const receiveAction = actions.find((action) => action.type === 'app_command' &&
314
+ action.app_command_slug === lms_bulk_upload_constants_1.LMS_BULK_UPLOAD_RECEIVE_VIDEO_COMMAND);
315
+ if (!receiveAction) {
316
+ await this.webhookIntegrationService.createAction(webhook.id, {
317
+ type: 'app_command',
318
+ name: 'Receber vídeo do upload em massa',
319
+ status: 'active',
320
+ order: 1,
321
+ app_command_slug: lms_bulk_upload_constants_1.LMS_BULK_UPLOAD_RECEIVE_VIDEO_COMMAND,
322
+ app_command_params: {},
323
+ });
324
+ }
325
+ else if (receiveAction.status !== 'active' || receiveAction.order !== 1) {
326
+ await this.webhookIntegrationService.updateAction(webhook.id, receiveAction.id, {
327
+ type: 'app_command',
328
+ name: 'Receber vídeo do upload em massa',
329
+ status: 'active',
330
+ order: 1,
331
+ app_command_slug: lms_bulk_upload_constants_1.LMS_BULK_UPLOAD_RECEIVE_VIDEO_COMMAND,
332
+ app_command_params: {},
333
+ });
334
+ }
335
+ // Always regenerate the token on every save so the Lambda env vars stay in sync
336
+ // with the latest webhook credentials.
337
+ return this.webhookIntegrationService.regenerateToken(webhook.id);
338
+ }
339
+ async startUploadSession(userId, payload) {
113
340
  var _a, _b, _c, _d, _e;
341
+ const files = ((_a = payload === null || payload === void 0 ? void 0 : payload.files) !== null && _a !== void 0 ? _a : [])
342
+ .map((file) => {
343
+ var _a, _b, _c;
344
+ return ({
345
+ uploadId: String((_a = file === null || file === void 0 ? void 0 : file.uploadId) !== null && _a !== void 0 ? _a : '').trim(),
346
+ fileName: String((_b = file === null || file === void 0 ? void 0 : file.fileName) !== null && _b !== void 0 ? _b : '').trim(),
347
+ sizeBytes: Math.max(0, Number((_c = file === null || file === void 0 ? void 0 : file.sizeBytes) !== null && _c !== void 0 ? _c : 0) || 0),
348
+ });
349
+ })
350
+ .filter((file) => file.uploadId.length > 0 && file.fileName.length > 0);
351
+ if (files.length === 0) {
352
+ throw new common_1.BadRequestException('Provide at least one file to register bulk upload session.');
353
+ }
354
+ const appName = String((_b = payload === null || payload === void 0 ? void 0 : payload.appName) !== null && _b !== void 0 ? _b : 'hedhog-desktop').trim().slice(0, 80) || 'hedhog-desktop';
355
+ const folderPath = String((_c = payload === null || payload === void 0 ? void 0 : payload.folderPath) !== null && _c !== void 0 ? _c : '').trim() || null;
356
+ const totalFiles = files.length;
357
+ const totalBytes = files.reduce((sum, file) => sum + file.sizeBytes, 0);
358
+ const now = new Date();
359
+ const insertedSession = await this.prismaService.$queryRawUnsafe(`INSERT INTO "lms_bulk_upload_session"
360
+ ("user_id", "app_name", "folder_path", "status", "progress_percent", "total_files", "total_bytes", "heartbeat_at", "started_at", "created_at", "updated_at")
361
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
362
+ RETURNING "id"`, userId, appName, folderPath, 'started', 0, totalFiles, totalBytes, now, now, now, now);
363
+ const sessionId = Number((_e = (_d = insertedSession === null || insertedSession === void 0 ? void 0 : insertedSession[0]) === null || _d === void 0 ? void 0 : _d.id) !== null && _e !== void 0 ? _e : 0);
364
+ if (!Number.isFinite(sessionId) || sessionId <= 0) {
365
+ throw new common_1.BadRequestException('Could not register bulk upload session.');
366
+ }
367
+ for (const file of files) {
368
+ await this.prismaService.$executeRawUnsafe(`INSERT INTO "lms_bulk_upload_item"
369
+ ("session_id", "upload_id", "file_name", "size_bytes", "status", "progress_percent", "last_heartbeat_at", "created_at", "updated_at")
370
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, sessionId, file.uploadId, file.fileName, file.sizeBytes, 'queued', 0, now, now, now);
371
+ }
372
+ return {
373
+ sessionId,
374
+ totalFiles,
375
+ totalBytes,
376
+ status: 'started',
377
+ };
378
+ }
379
+ async heartbeatUploadSession(userId, payload) {
380
+ var _a, _b, _c, _d, _e, _f;
381
+ const sessionId = Number((_a = payload === null || payload === void 0 ? void 0 : payload.sessionId) !== null && _a !== void 0 ? _a : 0);
382
+ if (!Number.isFinite(sessionId) || sessionId <= 0) {
383
+ throw new common_1.BadRequestException('Provide a valid sessionId for heartbeat.');
384
+ }
385
+ const sessionRows = await this.prismaService.$queryRawUnsafe(`SELECT "id", "user_id"
386
+ FROM "lms_bulk_upload_session"
387
+ WHERE "id" = $1
388
+ LIMIT 1`, sessionId);
389
+ const session = (_b = sessionRows === null || sessionRows === void 0 ? void 0 : sessionRows[0]) !== null && _b !== void 0 ? _b : null;
390
+ if (!session) {
391
+ throw new common_1.NotFoundException(`Bulk upload session ${sessionId} was not found.`);
392
+ }
393
+ if (Number(session.user_id) !== userId) {
394
+ throw new common_1.BadRequestException('You can only update your own bulk upload session.');
395
+ }
396
+ const now = new Date();
397
+ const normalizedItems = ((_c = payload === null || payload === void 0 ? void 0 : payload.items) !== null && _c !== void 0 ? _c : []).map((item) => {
398
+ var _a, _b, _c;
399
+ const status = this.normalizeItemStatus(item === null || item === void 0 ? void 0 : item.status);
400
+ return {
401
+ uploadId: String((_a = item === null || item === void 0 ? void 0 : item.uploadId) !== null && _a !== void 0 ? _a : '').trim(),
402
+ status,
403
+ progressPercent: this.clampPercent(item === null || item === void 0 ? void 0 : item.progressPercent),
404
+ errorMessage: String((_b = item === null || item === void 0 ? void 0 : item.errorMessage) !== null && _b !== void 0 ? _b : '').trim() || null,
405
+ uploadedKey: String((_c = item === null || item === void 0 ? void 0 : item.uploadedKey) !== null && _c !== void 0 ? _c : '').trim() || null,
406
+ };
407
+ }).filter((item) => item.uploadId.length > 0);
408
+ for (const item of normalizedItems) {
409
+ await this.prismaService.$executeRawUnsafe(`UPDATE "lms_bulk_upload_item"
410
+ SET
411
+ "status" = $3,
412
+ "progress_percent" = $4,
413
+ "error_message" = $5,
414
+ "uploaded_key" = $6,
415
+ "last_heartbeat_at" = $7,
416
+ "completed_at" = CASE WHEN $3 IN ('received', 'done', 'error', 'cancelled') THEN COALESCE("completed_at", $7) ELSE "completed_at" END,
417
+ "updated_at" = $7
418
+ WHERE "session_id" = $1
419
+ AND "upload_id" = $2`, sessionId, item.uploadId, item.status, item.progressPercent, item.errorMessage, item.uploadedKey, now);
420
+ }
421
+ const summaryRows = await this.prismaService.$queryRawUnsafe(`SELECT
422
+ COUNT(*)::int AS total,
423
+ COUNT(*) FILTER (WHERE "status" = 'done')::int AS done_count,
424
+ COUNT(*) FILTER (WHERE "status" = 'error')::int AS error_count,
425
+ COUNT(*) FILTER (WHERE "status" = 'cancelled')::int AS cancelled_count,
426
+ COUNT(*) FILTER (WHERE "status" = 'uploading')::int AS uploading_count,
427
+ COUNT(*) FILTER (WHERE "status" = 'queued')::int AS queued_count,
428
+ COALESCE(AVG("progress_percent"), 0)::float AS average_progress
429
+ FROM "lms_bulk_upload_item"
430
+ WHERE "session_id" = $1`, sessionId);
431
+ const summary = (_d = summaryRows === null || summaryRows === void 0 ? void 0 : summaryRows[0]) !== null && _d !== void 0 ? _d : {
432
+ total: 0,
433
+ done_count: 0,
434
+ error_count: 0,
435
+ cancelled_count: 0,
436
+ uploading_count: 0,
437
+ queued_count: 0,
438
+ average_progress: 0,
439
+ };
440
+ const requestedStatus = this.normalizeSessionStatus(payload === null || payload === void 0 ? void 0 : payload.status);
441
+ const computedStatus = this.computeSessionStatus(summary);
442
+ const finalStatus = requestedStatus !== null && requestedStatus !== void 0 ? requestedStatus : computedStatus;
443
+ const progressPercent = this.clampPercent((_f = (_e = payload === null || payload === void 0 ? void 0 : payload.progressPercent) !== null && _e !== void 0 ? _e : summary.average_progress) !== null && _f !== void 0 ? _f : 0);
444
+ const isTerminal = ['completed', 'failed', 'cancelled'].includes(finalStatus);
445
+ await this.prismaService.$executeRawUnsafe(`UPDATE "lms_bulk_upload_session"
446
+ SET
447
+ "status" = $2,
448
+ "progress_percent" = $3,
449
+ "heartbeat_at" = $4,
450
+ "finished_at" = CASE WHEN $5 THEN COALESCE("finished_at", $4) ELSE "finished_at" END,
451
+ "updated_at" = $4
452
+ WHERE "id" = $1`, sessionId, finalStatus, progressPercent, now, isTerminal);
453
+ return {
454
+ sessionId,
455
+ status: finalStatus,
456
+ progressPercent,
457
+ totals: {
458
+ total: Number(summary.total || 0),
459
+ done: Number(summary.done_count || 0),
460
+ error: Number(summary.error_count || 0),
461
+ cancelled: Number(summary.cancelled_count || 0),
462
+ },
463
+ };
464
+ }
465
+ async listUploadItems(params) {
466
+ var _a, _b, _c;
467
+ const page = Math.max(Number(params.page) || 1, 1);
468
+ const pageSize = Math.min(Math.max(Number(params.pageSize) || 20, 1), 100);
469
+ const offset = (page - 1) * pageSize;
470
+ const search = String((_a = params.search) !== null && _a !== void 0 ? _a : '').trim();
471
+ const status = this.normalizeItemStatus(params.status, true);
472
+ const where = [];
473
+ const args = [];
474
+ if (status) {
475
+ args.push(status);
476
+ where.push(`i."status" = $${args.length}`);
477
+ }
478
+ if (search) {
479
+ args.push(`%${search}%`);
480
+ const searchParam = `$${args.length}`;
481
+ where.push(`(i."file_name" ILIKE ${searchParam} OR s."app_name" ILIKE ${searchParam} OR COALESCE(sender."name", u."name", '') ILIKE ${searchParam} OR CAST(s."user_id" AS TEXT) ILIKE ${searchParam} OR COALESCE(mc."title", '') ILIKE ${searchParam} OR COALESCE(ml."title", '') ILIKE ${searchParam})`);
482
+ }
483
+ const whereSql = where.length > 0 ? `WHERE ${where.join(' AND ')}` : '';
484
+ const countRows = await this.prismaService.$queryRawUnsafe(`SELECT COUNT(*)::int AS total
485
+ FROM "lms_bulk_upload_item" i
486
+ JOIN "lms_bulk_upload_session" s ON s."id" = i."session_id"
487
+ LEFT JOIN "user" u ON u."id" = s."user_id"
488
+ LEFT JOIN LATERAL (
489
+ SELECT p."name"
490
+ FROM "person_user" pu
491
+ JOIN "person" p ON p."id" = pu."person_id"
492
+ WHERE pu."user_id" = s."user_id"
493
+ ORDER BY pu."id" DESC
494
+ LIMIT 1
495
+ ) sender ON TRUE
496
+ LEFT JOIN "course" mc ON mc."id" = i."matched_course_id"
497
+ LEFT JOIN "course_module" ms ON ms."id" = i."matched_session_id"
498
+ LEFT JOIN "course_lesson" ml ON ml."id" = i."matched_lesson_id"
499
+ ${whereSql}`, ...args);
500
+ const total = Number((_c = (_b = countRows === null || countRows === void 0 ? void 0 : countRows[0]) === null || _b === void 0 ? void 0 : _b.total) !== null && _c !== void 0 ? _c : 0);
501
+ const dataRows = await this.prismaService.$queryRawUnsafe(`SELECT
502
+ i."id",
503
+ i."session_id",
504
+ i."upload_id",
505
+ i."file_name",
506
+ i."size_bytes",
507
+ i."status",
508
+ i."progress_percent",
509
+ i."error_message",
510
+ i."uploaded_key",
511
+ i."received_at",
512
+ i."updated_at",
513
+ i."completed_at",
514
+ s."app_name",
515
+ s."user_id",
516
+ u."photo_id" AS user_photo_id,
517
+ COALESCE(sender."name", u."name") AS user_name,
518
+ s."status" AS session_status,
519
+ s."started_at" AS session_started_at,
520
+ mc."id" AS matched_course_id,
521
+ mc."title" AS matched_course_title,
522
+ mc."slug" AS matched_course_slug,
523
+ logo."file_id" AS matched_course_logo_file_id,
524
+ ms."id" AS matched_session_id,
525
+ ms."title" AS matched_session_title,
526
+ ml."id" AS matched_lesson_id,
527
+ ml."title" AS matched_lesson_title
528
+ FROM "lms_bulk_upload_item" i
529
+ JOIN "lms_bulk_upload_session" s ON s."id" = i."session_id"
530
+ LEFT JOIN "user" u ON u."id" = s."user_id"
531
+ LEFT JOIN LATERAL (
532
+ SELECT p."name"
533
+ FROM "person_user" pu
534
+ JOIN "person" p ON p."id" = pu."person_id"
535
+ WHERE pu."user_id" = s."user_id"
536
+ ORDER BY pu."id" DESC
537
+ LIMIT 1
538
+ ) sender ON TRUE
539
+ LEFT JOIN "course" mc ON mc."id" = i."matched_course_id"
540
+ LEFT JOIN "course_module" ms ON ms."id" = i."matched_session_id"
541
+ LEFT JOIN "course_lesson" ml ON ml."id" = i."matched_lesson_id"
542
+ LEFT JOIN LATERAL (
543
+ SELECT ci."file_id"
544
+ FROM "course_image" ci
545
+ INNER JOIN "image_type" it ON it."id" = ci."image_type_id"
546
+ WHERE ci."course_id" = mc."id"
547
+ AND it."slug" = 'course-logo'
548
+ ORDER BY ci."id" DESC
549
+ LIMIT 1
550
+ ) logo ON TRUE
551
+ ${whereSql}
552
+ ORDER BY i."updated_at" DESC
553
+ LIMIT $${args.length + 1}
554
+ OFFSET $${args.length + 2}`, ...args, pageSize, offset);
555
+ return {
556
+ data: dataRows.map((row) => ({
557
+ id: row.id,
558
+ sessionId: row.session_id,
559
+ uploadId: row.upload_id,
560
+ fileName: row.file_name,
561
+ sizeBytes: Number(row.size_bytes || 0),
562
+ status: row.status,
563
+ progressPercent: Number(row.progress_percent || 0),
564
+ errorMessage: row.error_message,
565
+ uploadedKey: row.uploaded_key,
566
+ receivedAt: row.received_at,
567
+ updatedAt: row.updated_at,
568
+ completedAt: row.completed_at,
569
+ appName: row.app_name,
570
+ userId: row.user_id,
571
+ userPhotoId: row.user_photo_id ? Number(row.user_photo_id) : null,
572
+ userName: row.user_name,
573
+ sessionStatus: row.session_status,
574
+ startedAt: row.session_started_at,
575
+ matchedCourseId: row.matched_course_id ? Number(row.matched_course_id) : null,
576
+ matchedCourseTitle: row.matched_course_title,
577
+ matchedCourseSlug: row.matched_course_slug,
578
+ matchedCourseLogoFileId: row.matched_course_logo_file_id ? Number(row.matched_course_logo_file_id) : null,
579
+ matchedSessionId: row.matched_session_id ? Number(row.matched_session_id) : null,
580
+ matchedSessionTitle: row.matched_session_title,
581
+ matchedLessonId: row.matched_lesson_id ? Number(row.matched_lesson_id) : null,
582
+ matchedLessonTitle: row.matched_lesson_title,
583
+ })),
584
+ total,
585
+ page,
586
+ pageSize,
587
+ lastPage: Math.max(1, Math.ceil(total / pageSize)),
588
+ };
589
+ }
590
+ async checkUploadedFiles(files) {
591
+ const normalized = files
592
+ .map((f) => {
593
+ var _a, _b;
594
+ return ({
595
+ fileName: String((_a = f === null || f === void 0 ? void 0 : f.fileName) !== null && _a !== void 0 ? _a : '').trim(),
596
+ sizeBytes: Math.max(0, Number((_b = f === null || f === void 0 ? void 0 : f.sizeBytes) !== null && _b !== void 0 ? _b : 0) || 0),
597
+ });
598
+ })
599
+ .filter((f) => f.fileName.length > 0);
600
+ if (normalized.length === 0)
601
+ return { uploaded: [] };
602
+ const conditions = normalized
603
+ .map((_, i) => `(file_name = $${i * 2 + 1} AND size_bytes = $${i * 2 + 2}::bigint)`)
604
+ .join(' OR ');
605
+ const args = normalized.flatMap((f) => [f.fileName, f.sizeBytes]);
606
+ const rows = await this.prismaService.$queryRawUnsafe(`SELECT file_name, size_bytes,
607
+ MAX(COALESCE(received_at, completed_at, updated_at)) AS uploaded_at
608
+ FROM "lms_bulk_upload_item"
609
+ WHERE status IN ('received', 'done')
610
+ AND (${conditions})
611
+ GROUP BY file_name, size_bytes`, ...args);
612
+ return {
613
+ uploaded: rows.map((row) => {
614
+ var _a, _b;
615
+ return ({
616
+ fileName: row.file_name,
617
+ sizeBytes: Number(row.size_bytes),
618
+ uploadedAt: (_b = (_a = row.uploaded_at) === null || _a === void 0 ? void 0 : _a.toISOString()) !== null && _b !== void 0 ? _b : null,
619
+ });
620
+ }),
621
+ };
622
+ }
623
+ async cleanupUploadHistory(payload) {
624
+ var _a, _b;
625
+ const statusSet = new Set();
626
+ for (const rawStatus of (_a = payload === null || payload === void 0 ? void 0 : payload.statuses) !== null && _a !== void 0 ? _a : []) {
627
+ const normalized = String(rawStatus !== null && rawStatus !== void 0 ? rawStatus : '').trim().toLowerCase();
628
+ if (cleanup_upload_history_dto_1.BULK_UPLOAD_CLEANUP_STATUSES.includes(normalized)) {
629
+ statusSet.add(normalized);
630
+ }
631
+ }
632
+ if (statusSet.size === 0) {
633
+ statusSet.add('done');
634
+ }
635
+ const statuses = Array.from(statusSet);
636
+ const allowedWindows = new Set(cleanup_upload_history_dto_1.BULK_UPLOAD_CLEANUP_WINDOWS);
637
+ const rawWindow = String((_b = payload === null || payload === void 0 ? void 0 : payload.timeWindow) !== null && _b !== void 0 ? _b : '').trim().toLowerCase();
638
+ const timeWindow = allowedWindows.has(rawWindow) ? rawWindow : 'last_day';
639
+ let cutoffDate = null;
640
+ if (timeWindow === 'last_hour') {
641
+ cutoffDate = new Date(Date.now() - 60 * 60 * 1000);
642
+ }
643
+ else if (timeWindow === 'last_day') {
644
+ cutoffDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
645
+ }
646
+ else if (timeWindow === 'last_week') {
647
+ cutoffDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
648
+ }
649
+ const statusPlaceholders = statuses.map((_, index) => `$${index + 1}`).join(', ');
650
+ const args = [...statuses];
651
+ let timeFilterSql = '';
652
+ if (cutoffDate) {
653
+ args.push(cutoffDate);
654
+ timeFilterSql = ` AND i."updated_at" >= $${args.length}`;
655
+ }
656
+ const deletedRows = await this.prismaService.$queryRawUnsafe(`DELETE FROM "lms_bulk_upload_item" i
657
+ USING "lms_bulk_upload_session" s
658
+ WHERE i."session_id" = s."id"
659
+ AND i."status" IN (${statusPlaceholders})
660
+ ${timeFilterSql}
661
+ RETURNING i."session_id"`, ...args);
662
+ const deletedItems = deletedRows.length;
663
+ const sessionIds = Array.from(new Set(deletedRows
664
+ .map((row) => Number(row.session_id || 0))
665
+ .filter((sessionId) => Number.isFinite(sessionId) && sessionId > 0)));
666
+ let deletedSessions = 0;
667
+ if (sessionIds.length > 0) {
668
+ const sessionPlaceholders = sessionIds
669
+ .map((_, index) => `$${index + 1}`)
670
+ .join(', ');
671
+ const deletedSessionRows = await this.prismaService.$queryRawUnsafe(`DELETE FROM "lms_bulk_upload_session" s
672
+ WHERE s."id" IN (${sessionPlaceholders})
673
+ AND NOT EXISTS (
674
+ SELECT 1
675
+ FROM "lms_bulk_upload_item" i
676
+ WHERE i."session_id" = s."id"
677
+ )
678
+ RETURNING s."id"`, ...sessionIds);
679
+ deletedSessions = deletedSessionRows.length;
680
+ }
681
+ return {
682
+ success: true,
683
+ deletedItems,
684
+ deletedSessions,
685
+ filtersApplied: {
686
+ statuses,
687
+ timeWindow,
688
+ },
689
+ };
690
+ }
691
+ clampPercent(value) {
692
+ const parsed = Number(value);
693
+ if (!Number.isFinite(parsed))
694
+ return 0;
695
+ return Math.max(0, Math.min(100, Math.round(parsed)));
696
+ }
697
+ normalizeSessionStatus(value) {
698
+ const normalized = String(value !== null && value !== void 0 ? value : '').trim().toLowerCase();
699
+ if (!normalized)
700
+ return null;
701
+ if (normalized === 'started' ||
702
+ normalized === 'uploading' ||
703
+ normalized === 'paused' ||
704
+ normalized === 'cancelling' ||
705
+ normalized === 'completed' ||
706
+ normalized === 'failed' ||
707
+ normalized === 'cancelled') {
708
+ return normalized;
709
+ }
710
+ return null;
711
+ }
712
+ normalizeItemStatus(value, allowEmpty = false) {
713
+ const normalized = String(value !== null && value !== void 0 ? value : '').trim().toLowerCase();
714
+ if (!normalized && allowEmpty)
715
+ return null;
716
+ if (normalized === 'queued' ||
717
+ normalized === 'uploading' ||
718
+ normalized === 'cancelling' ||
719
+ normalized === 'received' ||
720
+ normalized === 'done' ||
721
+ normalized === 'error' ||
722
+ normalized === 'cancelled' ||
723
+ normalized === 'lesson_not_found') {
724
+ return normalized;
725
+ }
726
+ return allowEmpty ? null : 'queued';
727
+ }
728
+ computeSessionStatus(summary) {
729
+ const total = Number(summary.total || 0);
730
+ const done = Number(summary.done_count || 0);
731
+ const error = Number(summary.error_count || 0);
732
+ const cancelled = Number(summary.cancelled_count || 0);
733
+ const uploading = Number(summary.uploading_count || 0);
734
+ const queued = Number(summary.queued_count || 0);
735
+ if (total === 0)
736
+ return 'started';
737
+ if (done === total)
738
+ return 'completed';
739
+ if (done + error + cancelled === total && error > 0)
740
+ return 'failed';
741
+ if (done + error + cancelled === total && cancelled > 0 && error === 0)
742
+ return 'cancelled';
743
+ if (uploading > 0)
744
+ return 'uploading';
745
+ if (queued === total)
746
+ return 'started';
747
+ return 'uploading';
748
+ }
749
+ async resolveStorageProfileAndBucket(userId, overrides) {
750
+ var _a, _b, _c, _d, _e, _f;
114
751
  const settings = await this.settingService.getSettingValues([
115
752
  'lms-bulk-upload-storage-profile-id',
116
- 'lms-bulk-upload-s3-bucket',
117
753
  'lms-bulk-upload-sts-duration-seconds',
118
754
  ]);
119
- const profileId = Number(settings['lms-bulk-upload-storage-profile-id'] || 0);
755
+ const profileId = Number((_b = (_a = overrides === null || overrides === void 0 ? void 0 : overrides.storageProfileId) !== null && _a !== void 0 ? _a : settings['lms-bulk-upload-storage-profile-id']) !== null && _b !== void 0 ? _b : 0);
120
756
  if (!Number.isFinite(profileId) || profileId <= 0) {
121
757
  throw new common_1.BadRequestException('LMS bulk upload storage profile is not configured (lms-bulk-upload-storage-profile-id).');
122
758
  }
@@ -133,17 +769,15 @@ let LmsBulkUploadService = class LmsBulkUploadService {
133
769
  if (profile.integration_type.slug !== 'storage') {
134
770
  throw new common_1.BadRequestException(`Integration profile ${profileId} is not a storage profile.`);
135
771
  }
136
- const providerSlug = String((_a = profile.integration_provider.slug) !== null && _a !== void 0 ? _a : '').toLowerCase();
772
+ const providerSlug = String((_c = profile.integration_provider.slug) !== null && _c !== void 0 ? _c : '').toLowerCase();
137
773
  if (providerSlug !== 's3') {
138
774
  throw new common_1.BadRequestException(`Integration provider ${providerSlug} is not supported for desktop bulk upload. Use AWS S3 profile.`);
139
775
  }
140
- const config = (_b = profile.config) !== null && _b !== void 0 ? _b : {};
141
- const region = String((_c = config.region) !== null && _c !== void 0 ? _c : '').trim() || 'us-east-1';
142
- const bucketFromSettings = String((_d = settings['lms-bulk-upload-s3-bucket']) !== null && _d !== void 0 ? _d : '').trim();
143
- const bucketFromProfile = String((_e = config.bucket) !== null && _e !== void 0 ? _e : '').trim();
144
- const bucket = bucketFromSettings || bucketFromProfile;
776
+ const config = (_d = profile.config) !== null && _d !== void 0 ? _d : {};
777
+ const region = String((_e = config.region) !== null && _e !== void 0 ? _e : '').trim() || 'us-east-1';
778
+ const bucket = String((_f = config.bucket) !== null && _f !== void 0 ? _f : '').trim();
145
779
  if (!bucket) {
146
- throw new common_1.BadRequestException('LMS bulk upload bucket is not configured. Set lms-bulk-upload-s3-bucket or profile bucket.');
780
+ throw new common_1.BadRequestException(`Storage integration profile ${profileId} does not define a bucket in config.bucket.`);
147
781
  }
148
782
  const durationSeconds = Math.max(900, Math.min(43200, Number(settings['lms-bulk-upload-sts-duration-seconds'] || 3600) || 3600));
149
783
  const prefix = `desktop/lms/u${userId}/`;
@@ -159,11 +793,15 @@ let LmsBulkUploadService = class LmsBulkUploadService {
159
793
  exports.LmsBulkUploadService = LmsBulkUploadService;
160
794
  exports.LmsBulkUploadService = LmsBulkUploadService = __decorate([
161
795
  (0, common_1.Injectable)(),
162
- __param(0, (0, common_1.Inject)((0, common_1.forwardRef)(() => core_2.SettingService))),
796
+ __param(0, (0, common_1.Inject)((0, common_1.forwardRef)(() => core_1.SettingService))),
163
797
  __param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => api_prisma_1.PrismaService))),
164
798
  __param(2, (0, common_1.Inject)((0, common_1.forwardRef)(() => core_1.FileService))),
165
- __metadata("design:paramtypes", [core_2.SettingService,
799
+ __param(3, (0, common_1.Inject)((0, common_1.forwardRef)(() => core_1.WebhookIntegrationService))),
800
+ __param(4, (0, common_1.Inject)((0, common_1.forwardRef)(() => lms_bulk_upload_infra_service_1.LmsBulkUploadInfraService))),
801
+ __metadata("design:paramtypes", [core_1.SettingService,
166
802
  api_prisma_1.PrismaService,
167
- core_1.FileService])
803
+ core_1.FileService,
804
+ core_1.WebhookIntegrationService,
805
+ lms_bulk_upload_infra_service_1.LmsBulkUploadInfraService])
168
806
  ], LmsBulkUploadService);
169
807
  //# sourceMappingURL=lms-bulk-upload.service.js.map