@hed-hog/lms 0.0.364 → 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 (218) hide show
  1. package/dist/bitcode-wallet/bitcode-wallet.service.d.ts +1 -0
  2. package/dist/bitcode-wallet/bitcode-wallet.service.d.ts.map +1 -1
  3. package/dist/bitcode-wallet/bitcode-wallet.service.js +22 -3
  4. package/dist/bitcode-wallet/bitcode-wallet.service.js.map +1 -1
  5. package/dist/course/course-export-scorm12-worker.service.d.ts +21 -0
  6. package/dist/course/course-export-scorm12-worker.service.d.ts.map +1 -0
  7. package/dist/course/course-export-scorm12-worker.service.js +109 -0
  8. package/dist/course/course-export-scorm12-worker.service.js.map +1 -0
  9. package/dist/course/course-export-scorm12.service.d.ts +42 -0
  10. package/dist/course/course-export-scorm12.service.d.ts.map +1 -0
  11. package/dist/course/course-export-scorm12.service.js +628 -0
  12. package/dist/course/course-export-scorm12.service.js.map +1 -0
  13. package/dist/course/course-export.service.d.ts +84 -0
  14. package/dist/course/course-export.service.d.ts.map +1 -0
  15. package/dist/course/course-export.service.js +237 -0
  16. package/dist/course/course-export.service.js.map +1 -0
  17. package/dist/course/course-structure.controller.d.ts +17 -9
  18. package/dist/course/course-structure.controller.d.ts.map +1 -1
  19. package/dist/course/course-structure.controller.js +17 -4
  20. package/dist/course/course-structure.controller.js.map +1 -1
  21. package/dist/course/course-structure.service.d.ts +12 -4
  22. package/dist/course/course-structure.service.d.ts.map +1 -1
  23. package/dist/course/course-structure.service.js +98 -23
  24. package/dist/course/course-structure.service.js.map +1 -1
  25. package/dist/course/course-video-hls.service.d.ts +57 -0
  26. package/dist/course/course-video-hls.service.d.ts.map +1 -0
  27. package/dist/course/course-video-hls.service.js +767 -0
  28. package/dist/course/course-video-hls.service.js.map +1 -0
  29. package/dist/course/course.controller.d.ts +45 -13
  30. package/dist/course/course.controller.d.ts.map +1 -1
  31. package/dist/course/course.controller.js +40 -26
  32. package/dist/course/course.controller.js.map +1 -1
  33. package/dist/course/course.mcp-tools.js +1 -1
  34. package/dist/course/course.mcp-tools.js.map +1 -1
  35. package/dist/course/course.module.d.ts.map +1 -1
  36. package/dist/course/course.module.js +11 -0
  37. package/dist/course/course.module.js.map +1 -1
  38. package/dist/course/course.service.d.ts +6 -9
  39. package/dist/course/course.service.d.ts.map +1 -1
  40. package/dist/course/course.service.js +57 -48
  41. package/dist/course/course.service.js.map +1 -1
  42. package/dist/course/dto/cleanup-course-storage.dto.d.ts +1 -1
  43. package/dist/course/dto/cleanup-course-storage.dto.d.ts.map +1 -1
  44. package/dist/course/dto/cleanup-course-storage.dto.js +1 -0
  45. package/dist/course/dto/cleanup-course-storage.dto.js.map +1 -1
  46. package/dist/course/dto/cleanup-upload-history.dto.d.ts +1 -1
  47. package/dist/course/dto/cleanup-upload-history.dto.d.ts.map +1 -1
  48. package/dist/course/dto/cleanup-upload-history.dto.js +1 -1
  49. package/dist/course/dto/cleanup-upload-history.dto.js.map +1 -1
  50. package/dist/course/dto/create-course-bulk-job.dto.d.ts +2 -1
  51. package/dist/course/dto/create-course-bulk-job.dto.d.ts.map +1 -1
  52. package/dist/course/dto/create-course-bulk-job.dto.js +6 -1
  53. package/dist/course/dto/create-course-bulk-job.dto.js.map +1 -1
  54. package/dist/course/dto/create-course-export.dto.d.ts +14 -0
  55. package/dist/course/dto/create-course-export.dto.d.ts.map +1 -0
  56. package/dist/course/dto/create-course-export.dto.js +71 -0
  57. package/dist/course/dto/create-course-export.dto.js.map +1 -0
  58. package/dist/course/dto/create-course-structure-lesson.dto.d.ts +2 -2
  59. package/dist/course/dto/create-course-structure-lesson.dto.d.ts.map +1 -1
  60. package/dist/course/dto/create-course-structure-lesson.dto.js +3 -2
  61. package/dist/course/dto/create-course-structure-lesson.dto.js.map +1 -1
  62. package/dist/course/lms-bulk-upload-automation.service.d.ts +16 -1
  63. package/dist/course/lms-bulk-upload-automation.service.d.ts.map +1 -1
  64. package/dist/course/lms-bulk-upload-automation.service.js +102 -8
  65. package/dist/course/lms-bulk-upload-automation.service.js.map +1 -1
  66. package/dist/course/lms-bulk-upload-infra.service.d.ts +1 -0
  67. package/dist/course/lms-bulk-upload-infra.service.d.ts.map +1 -1
  68. package/dist/course/lms-bulk-upload-infra.service.js +32 -8
  69. package/dist/course/lms-bulk-upload-infra.service.js.map +1 -1
  70. package/dist/course/lms-bulk-upload.controller.d.ts +30 -3
  71. package/dist/course/lms-bulk-upload.controller.d.ts.map +1 -1
  72. package/dist/course/lms-bulk-upload.controller.js +43 -2
  73. package/dist/course/lms-bulk-upload.controller.js.map +1 -1
  74. package/dist/course/lms-bulk-upload.service.d.ts +11 -0
  75. package/dist/course/lms-bulk-upload.service.d.ts.map +1 -1
  76. package/dist/course/lms-bulk-upload.service.js +59 -6
  77. package/dist/course/lms-bulk-upload.service.js.map +1 -1
  78. package/dist/course/lms-setting.controller.d.ts +2 -1
  79. package/dist/course/lms-setting.controller.d.ts.map +1 -1
  80. package/dist/course/lms-setting.controller.js +4 -2
  81. package/dist/course/lms-setting.controller.js.map +1 -1
  82. package/dist/course/scorm12-schemas.d.ts +4 -0
  83. package/dist/course/scorm12-schemas.d.ts.map +1 -0
  84. package/dist/course/scorm12-schemas.js +9 -0
  85. package/dist/course/scorm12-schemas.js.map +1 -0
  86. package/dist/enterprise/training/training-student.service.d.ts +51 -0
  87. package/dist/enterprise/training/training-student.service.d.ts.map +1 -1
  88. package/dist/enterprise/training/training-student.service.js +217 -4
  89. package/dist/enterprise/training/training-student.service.js.map +1 -1
  90. package/dist/evaluation/evaluation.service.d.ts +18 -0
  91. package/dist/evaluation/evaluation.service.d.ts.map +1 -1
  92. package/dist/evaluation/evaluation.service.js +125 -0
  93. package/dist/evaluation/evaluation.service.js.map +1 -1
  94. package/dist/exam/dto/create-standalone-question.dto.d.ts +12 -0
  95. package/dist/exam/dto/create-standalone-question.dto.d.ts.map +1 -0
  96. package/dist/exam/dto/create-standalone-question.dto.js +70 -0
  97. package/dist/exam/dto/create-standalone-question.dto.js.map +1 -0
  98. package/dist/exam/exam.module.d.ts.map +1 -1
  99. package/dist/exam/exam.module.js +2 -1
  100. package/dist/exam/exam.module.js.map +1 -1
  101. package/dist/exam/exam.service.d.ts +21 -0
  102. package/dist/exam/exam.service.d.ts.map +1 -1
  103. package/dist/exam/exam.service.js +80 -0
  104. package/dist/exam/exam.service.js.map +1 -1
  105. package/dist/exam/question.controller.d.ts +27 -0
  106. package/dist/exam/question.controller.d.ts.map +1 -0
  107. package/dist/exam/question.controller.js +53 -0
  108. package/dist/exam/question.controller.js.map +1 -0
  109. package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.d.ts +4 -0
  110. package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.d.ts.map +1 -1
  111. package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.js +161 -25
  112. package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.js.map +1 -1
  113. package/dist/libraries/lms/tsconfig.tsbuildinfo +1 -1
  114. package/dist/lms-commerce-access.subscriber.d.ts +11 -0
  115. package/dist/lms-commerce-access.subscriber.d.ts.map +1 -0
  116. package/dist/lms-commerce-access.subscriber.js +74 -0
  117. package/dist/lms-commerce-access.subscriber.js.map +1 -0
  118. package/dist/lms.module.d.ts.map +1 -1
  119. package/dist/lms.module.js +6 -5
  120. package/dist/lms.module.js.map +1 -1
  121. package/dist/platforma/platforma-video.service.d.ts +39 -0
  122. package/dist/platforma/platforma-video.service.d.ts.map +1 -0
  123. package/dist/platforma/platforma-video.service.js +301 -0
  124. package/dist/platforma/platforma-video.service.js.map +1 -0
  125. package/dist/platforma/platforma.controller.d.ts +95 -1
  126. package/dist/platforma/platforma.controller.d.ts.map +1 -1
  127. package/dist/platforma/platforma.controller.js +160 -2
  128. package/dist/platforma/platforma.controller.js.map +1 -1
  129. package/dist/student-xp/dto/grant-skill-card-xp.dto.d.ts +5 -0
  130. package/dist/student-xp/dto/grant-skill-card-xp.dto.d.ts.map +1 -0
  131. package/dist/student-xp/dto/grant-skill-card-xp.dto.js +26 -0
  132. package/dist/student-xp/dto/grant-skill-card-xp.dto.js.map +1 -0
  133. package/dist/student-xp/student-xp.controller.d.ts +15 -0
  134. package/dist/student-xp/student-xp.controller.d.ts.map +1 -1
  135. package/dist/student-xp/student-xp.controller.js +24 -0
  136. package/dist/student-xp/student-xp.controller.js.map +1 -1
  137. package/dist/student-xp/student-xp.service.d.ts +16 -0
  138. package/dist/student-xp/student-xp.service.d.ts.map +1 -1
  139. package/dist/student-xp/student-xp.service.js +51 -1
  140. package/dist/student-xp/student-xp.service.js.map +1 -1
  141. package/hedhog/data/evaluation_topic.yaml +17 -0
  142. package/hedhog/data/menu.yaml +0 -17
  143. package/hedhog/data/queue_definition.yaml +48 -0
  144. package/hedhog/data/route.yaml +94 -124
  145. package/hedhog/data/setting_group.yaml +19 -19
  146. package/hedhog/frontend/app/bulk-upload-sessions/page.tsx.ejs +337 -41
  147. package/hedhog/frontend/app/courses/[id]/page.tsx.ejs +69 -4
  148. package/hedhog/frontend/app/courses/[id]/structure/_components/course-export-sheet.tsx.ejs +420 -0
  149. package/hedhog/frontend/app/courses/[id]/structure/_components/course-exports-tab.tsx.ejs +308 -0
  150. package/hedhog/frontend/app/courses/[id]/structure/_components/course-overview-tab.tsx.ejs +17 -15
  151. package/hedhog/frontend/app/courses/[id]/structure/_components/detail-lesson.tsx.ejs +51 -63
  152. package/hedhog/frontend/app/courses/[id]/structure/_components/detail-panel.tsx.ejs +8 -3
  153. package/hedhog/frontend/app/courses/[id]/structure/_components/detail-session.tsx.ejs +31 -8
  154. package/hedhog/frontend/app/courses/[id]/structure/_components/drag-overlay.tsx.ejs +16 -9
  155. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-course.tsx.ejs +201 -401
  156. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-lesson.tsx.ejs +378 -690
  157. package/hedhog/frontend/app/courses/[id]/structure/_components/mock-data.ts.ejs +1 -2
  158. package/hedhog/frontend/app/courses/[id]/structure/_components/tree-row-lesson.tsx.ejs +3 -9
  159. package/hedhog/frontend/app/courses/[id]/structure/_components/types.ts.ejs +1 -1
  160. package/hedhog/frontend/app/courses/[id]/structure/_data/adapters/course-structure.adapter.ts.ejs +6 -10
  161. package/hedhog/frontend/app/courses/[id]/structure/_data/services/course-structure.service.ts.ejs +49 -0
  162. package/hedhog/frontend/app/courses/[id]/structure/_data/types/api-course.types.ts.ejs +4 -3
  163. package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-content-overview.ts.ejs +0 -1
  164. package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-exports.ts.ejs +106 -0
  165. package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-structure-mutations.ts.ejs +28 -1
  166. package/hedhog/frontend/app/courses/[id]/structure/_data/use-lms-settings-query.ts.ejs +0 -2
  167. package/hedhog/frontend/app/courses/page.tsx.ejs +45 -0
  168. package/hedhog/frontend/messages/en.json +26 -28
  169. package/hedhog/frontend/messages/pt.json +26 -28
  170. package/hedhog/table/course_export.yaml +62 -0
  171. package/package.json +13 -9
  172. package/src/bitcode-wallet/bitcode-wallet.service.ts +43 -4
  173. package/src/course/course-export-scorm12-worker.service.ts +124 -0
  174. package/src/course/course-export-scorm12.service.ts +668 -0
  175. package/src/course/course-export.service.ts +280 -0
  176. package/src/course/course-structure.controller.ts +14 -2
  177. package/src/course/course-structure.service.ts +100 -7
  178. package/src/course/course-video-hls.service.ts +946 -0
  179. package/src/course/course.controller.ts +33 -19
  180. package/src/course/course.mcp-tools.ts +1 -1
  181. package/src/course/course.module.ts +11 -0
  182. package/src/course/course.service.ts +73 -60
  183. package/src/course/dto/cleanup-course-storage.dto.ts +1 -0
  184. package/src/course/dto/cleanup-upload-history.dto.ts +1 -1
  185. package/src/course/dto/create-course-bulk-job.dto.ts +7 -3
  186. package/src/course/dto/create-course-export.dto.ts +56 -0
  187. package/src/course/dto/create-course-structure-lesson.dto.ts +4 -3
  188. package/src/course/lms-bulk-upload-automation.service.ts +153 -6
  189. package/src/course/lms-bulk-upload-infra.service.ts +39 -6
  190. package/src/course/lms-bulk-upload.controller.ts +32 -2
  191. package/src/course/lms-bulk-upload.service.ts +70 -7
  192. package/src/course/lms-setting.controller.ts +4 -2
  193. package/src/course/scorm12-schemas.ts +9 -0
  194. package/src/enterprise/training/training-student.service.ts +221 -2
  195. package/src/evaluation/evaluation.service.ts +123 -0
  196. package/src/exam/dto/create-standalone-question.dto.ts +66 -0
  197. package/src/exam/exam.module.ts +2 -1
  198. package/src/exam/exam.service.ts +86 -0
  199. package/src/exam/question.controller.ts +28 -0
  200. package/src/lesson-xp-map/lesson-xp-ai-calculation.service.ts +205 -31
  201. package/src/lms-commerce-access.subscriber.ts +88 -0
  202. package/src/lms.module.ts +6 -5
  203. package/src/platforma/platforma-video.service.ts +346 -0
  204. package/src/platforma/platforma.controller.ts +95 -1
  205. package/src/platforma/platforma.service.ts +268 -268
  206. package/src/student-xp/dto/grant-skill-card-xp.dto.ts +10 -0
  207. package/src/student-xp/student-xp.controller.ts +18 -2
  208. package/src/student-xp/student-xp.service.ts +84 -2
  209. package/hedhog/data/video_resolution_profile.yaml +0 -7
  210. package/hedhog/frontend/app/video-resolution-profiles/page.tsx.ejs +0 -607
  211. package/hedhog/table/course_video_resolution_profile.yaml +0 -22
  212. package/hedhog/table/video_resolution_profile.yaml +0 -18
  213. package/src/video-resolution-profile/dto/create-video-resolution-profile.dto.ts +0 -16
  214. package/src/video-resolution-profile/dto/update-video-resolution-profile.dto.ts +0 -16
  215. package/src/video-resolution-profile/video-resolution-profile.controller.ts +0 -62
  216. package/src/video-resolution-profile/video-resolution-profile.mcp-tools.ts +0 -128
  217. package/src/video-resolution-profile/video-resolution-profile.module.ts +0 -13
  218. package/src/video-resolution-profile/video-resolution-profile.service.ts +0 -117
@@ -588,6 +588,8 @@
588
588
  "statusProgress": "{completed}/{total} itens obrigatórios concluídos",
589
589
  "ready": "Pronto para publicar",
590
590
  "notReady": "Ainda não pronto",
591
+ "publishButton": "Publicar curso",
592
+ "alreadyPublished": "Curso já publicado",
591
593
  "items": {
592
594
  "title": "Título comercial preenchido",
593
595
  "description": "Descrição pública preenchida",
@@ -1206,36 +1208,32 @@
1206
1208
  },
1207
1209
  "addResource": "Adicionar recurso",
1208
1210
  "noResources": "Nenhum recurso adicionado",
1209
- "fileStorageVideosByResolution": "Vídeos por resolução (File Storage)",
1210
- "videoResolutionPlaceholder": "Ex.: 1080p",
1211
- "uploadVideoForResolution": "Enviar vídeo para esta resolução",
1212
- "noResolutionVideosYet": "Nenhum vídeo por resolução enviado ainda.",
1213
- "loadingVideoProfiles": "Carregando perfis de vídeo do curso...",
1214
- "videoProfilesLoadError": "Não foi possível carregar os perfis de vídeo do curso.",
1215
- "retryLoadVideoProfiles": "Tentar carregar novamente",
1216
- "noVideoProfilesConfigured": "Configure os perfis de vídeo na aba Resoluções do curso antes de anexar vídeos File Storage.",
1211
+ "hlsStatusTitle": "Streaming HLS",
1212
+ "hlsStatusReady": "Streaming disponível para os alunos.",
1213
+ "hlsStatusProcessing": "Processando vídeo...",
1214
+ "hlsStatusPending": "Nenhum vídeo processado ainda.",
1217
1215
  "originalVideoTitle": "Vídeo original em alta resolução",
1218
- "originalVideoHint": "Envie um original para gerar automaticamente os vídeos dos perfis do curso.",
1219
- "originalVideoPurpose": "Este arquivo original é usado apenas para gerar as versões de vídeo do curso.",
1220
- "fileStorageVideoHint": "Use o vídeo original abaixo para gerar automaticamente as versões por perfil do curso.",
1221
- "uploadOriginalForConversion": "Enviar original para conversão",
1216
+ "originalVideoHint": "Envie um original para gerar automaticamente o streaming HLS do curso.",
1217
+ "originalVideoPurpose": "Este arquivo original é usado apenas para gerar o streaming adaptativo do curso.",
1218
+ "fileStorageVideoHint": "Use o vídeo original abaixo para gerar automaticamente o streaming HLS do curso.",
1219
+ "uploadOriginalForConversion": "Enviar vídeo para processamento",
1222
1220
  "replaceOriginalForConversion": "Substituir vídeo original",
1223
1221
  "retryConversionWithSavedOriginal": "Iniciar novo job com o original salvo",
1224
- "videoUploadBlockedWhileProcessing": "O upload de original fica bloqueado enquanto a conversão atual estiver em andamento.",
1222
+ "videoUploadBlockedWhileProcessing": "O upload de original fica bloqueado enquanto o processamento atual estiver em andamento.",
1225
1223
  "videoJobStateLoading": "Aguardando o status mais recente do job atual para liberar novas ações.",
1226
1224
  "videoProviderSavePending": "Aguarde o provedor ser salvo antes de enviar o vídeo original.",
1227
1225
  "videoUploadMaxSizeError": "O vídeo excede o limite de {size}.",
1228
- "videoConversionQueued": "Conversão de vídeo enviada para a fila #{id}.",
1229
- "videoConversionFailed": "Não foi possível enviar o vídeo para conversão.",
1226
+ "videoConversionQueued": "Processamento de vídeo enviado para a fila #{id}.",
1227
+ "videoConversionFailed": "Não foi possível enviar o vídeo para processamento.",
1230
1228
  "videoConversionRetryFailed": "Não foi possível iniciar um novo job com o vídeo original salvo.",
1231
- "videoConversionJob": "Conversão na fila #{id}",
1232
- "videoJobFeedbackTitle": "Acompanhamento da conversão",
1233
- "videoJobToggleDetails": "Alternar detalhes da conversão",
1234
- "videoJobCollapsedSummary": "Conversão concluída com sucesso. Os vídeos processados aparecem na lista de resoluções acima.",
1235
- "videoJobLoading": "Carregando andamento da conversão...",
1236
- "videoJobPendingLoad": "Preparando acompanhamento do job de conversão...",
1237
- "awaitingConversion": "Aguardando conversão...",
1238
- "videoJobLoadError": "Não foi possível carregar o andamento da conversão.",
1229
+ "videoConversionJob": "Processamento na fila #{id}",
1230
+ "videoJobFeedbackTitle": "Acompanhamento do processamento",
1231
+ "videoJobToggleDetails": "Alternar detalhes do processamento",
1232
+ "videoJobCollapsedSummary": "Processamento concluído com sucesso. O streaming HLS está disponível para os alunos.",
1233
+ "videoJobLoading": "Carregando andamento do processamento...",
1234
+ "videoJobPendingLoad": "Preparando acompanhamento do processamento...",
1235
+ "awaitingConversion": "Aguardando processamento...",
1236
+ "videoJobLoadError": "Não foi possível carregar o andamento do processamento.",
1239
1237
  "retryLoadVideoJob": "Tentar novamente",
1240
1238
  "videoJobIdLabel": "Job",
1241
1239
  "videoJobAttemptsLabel": "Tentativas",
@@ -1251,7 +1249,6 @@
1251
1249
  "videoJobRecentEvents": "Eventos recentes",
1252
1250
  "videoJobTranscriptionEvents": "Eventos recentes da transcrição",
1253
1251
  "videoJobNoEvents": "Nenhum evento registrado ainda.",
1254
- "videoProfilesLockedWhileProcessing": "Os vídeos por perfil ficam bloqueados enquanto a conversão do original está ativa.",
1255
1252
  "videoJobStatuses": {
1256
1253
  "pending": "Na fila",
1257
1254
  "scheduled": "Agendado",
@@ -1283,8 +1280,9 @@
1283
1280
  },
1284
1281
  "videoJobProgress": {
1285
1282
  "download_original": "Baixando vídeo original...",
1286
- "probe_duration": "Lendo duração do vídeo...",
1287
- "convert_profile": "Convertendo vídeo para o perfil {profileName}...",
1283
+ "probe_duration": "Lendo dimensões e duração do vídeo...",
1284
+ "hls_encode": "Gerando streaming HLS...",
1285
+ "hls_upload": "Enviando segmentos HLS para storage...",
1288
1286
  "extract_frames": "Extraindo imagens do vídeo...",
1289
1287
  "extract_frames_done": "Imagens extraídas: {count}.",
1290
1288
  "extract_audio": "Extraindo áudio do vídeo...",
@@ -1351,8 +1349,7 @@
1351
1349
  "types": {
1352
1350
  "video": "Vídeo",
1353
1351
  "post": "Post",
1354
- "questao": "Questão",
1355
- "exercicio": "Exercício"
1352
+ "questao": "Questão"
1356
1353
  },
1357
1354
  "statuses": {
1358
1355
  "preparada": "Preparada",
@@ -1391,6 +1388,7 @@
1391
1388
  "videoUploadFailed": "Falha ao enviar {count} arquivo(s) de vídeo.",
1392
1389
  "newQuestion": "Nova questão",
1393
1390
  "editQuestion": "Editar questão",
1391
+ "loadingQuestions": "Carregando questões...",
1394
1392
  "selectQuestion": "Selecionar questão...",
1395
1393
  "searchQuestion": "Buscar questão...",
1396
1394
  "noQuestionsFound": "Nenhuma questão encontrada",
@@ -0,0 +1,62 @@
1
+ columns:
2
+ - type: pk
3
+ - name: course_id
4
+ type: fk
5
+ references:
6
+ table: course
7
+ column: id
8
+ onDelete: CASCADE
9
+ - name: user_id
10
+ type: fk
11
+ references:
12
+ table: user
13
+ column: id
14
+ onDelete: CASCADE
15
+ - name: format
16
+ type: varchar
17
+ length: 32
18
+ - name: status
19
+ type: enum
20
+ values: [pending, processing, completed, failed]
21
+ default: pending
22
+ - name: queue_job_id
23
+ type: fk
24
+ isNullable: true
25
+ references:
26
+ table: queue_job
27
+ column: id
28
+ onDelete: SET NULL
29
+ - name: file_id
30
+ type: fk
31
+ isNullable: true
32
+ references:
33
+ table: file
34
+ column: id
35
+ onDelete: SET NULL
36
+ - name: settings
37
+ type: jsonb
38
+ isNullable: true
39
+ - name: duration_seconds
40
+ type: int
41
+ isNullable: true
42
+ - name: error_message
43
+ type: text
44
+ isNullable: true
45
+ - name: notification_id
46
+ type: int
47
+ isNullable: true
48
+ - name: started_at
49
+ type: datetime
50
+ isNullable: true
51
+ - name: finished_at
52
+ type: datetime
53
+ isNullable: true
54
+ - type: created_at
55
+ - type: updated_at
56
+
57
+ indices:
58
+ - columns: [course_id]
59
+ - columns: [user_id]
60
+ - columns: [course_id, status]
61
+ - columns: [queue_job_id]
62
+ - columns: [file_id]
package/package.json CHANGED
@@ -1,25 +1,29 @@
1
1
  {
2
2
  "name": "@hed-hog/lms",
3
- "version": "0.0.364",
3
+ "version": "0.0.365",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "dependencies": {
7
- "@aws-sdk/client-s3": "^3.888.0",
7
+ "@aws-sdk/client-s3": "3.1014.0",
8
+ "archiver": "^5.3.2",
9
+ "@types/archiver": "^5.3.4",
10
+ "@aws-sdk/s3-request-presigner": "3.1014.0",
8
11
  "@nestjs/common": "*",
9
12
  "@nestjs/config": "^4.0.2",
10
13
  "@nestjs/core": "^11",
11
14
  "@nestjs/jwt": "^11",
12
15
  "@nestjs/mapped-types": "*",
13
- "@hed-hog/api-types": "0.0.1",
14
16
  "@hed-hog/api-prisma": "0.0.6",
15
17
  "@hed-hog/api-locale": "0.0.14",
16
- "@hed-hog/api": "0.0.8",
17
18
  "@hed-hog/api-pagination": "0.0.7",
18
- "@hed-hog/finance": "0.0.364",
19
- "@hed-hog/category": "0.0.364",
20
- "@hed-hog/core": "0.0.364",
21
- "@hed-hog/crm": "0.0.364",
22
- "@hed-hog/queue": "0.0.364"
19
+ "@hed-hog/api-types": "0.0.1",
20
+ "@hed-hog/category": "0.0.365",
21
+ "@hed-hog/crm": "0.0.365",
22
+ "@hed-hog/api": "0.0.8",
23
+ "@hed-hog/finance": "0.0.365",
24
+ "@hed-hog/commerce": "0.0.365",
25
+ "@hed-hog/queue": "0.0.365",
26
+ "@hed-hog/core": "0.0.365"
23
27
  },
24
28
  "exports": {
25
29
  ".": {
@@ -223,10 +223,8 @@ export class BitcodeWalletService {
223
223
  }
224
224
 
225
225
  async getCurrentUserWallet(userId: number) {
226
- const personId = await this.resolvePersonIdFromUser(userId);
227
- const existingWallet = await this.findWalletByPersonId(personId);
228
-
229
- return existingWallet ? this.getById(existingWallet.id) : null;
226
+ const personId = await this.resolveOrCreatePersonForUser(userId);
227
+ return this.getOrCreateWalletByPersonId(personId);
230
228
  }
231
229
 
232
230
  async creditCurrentUserWallet(
@@ -344,6 +342,47 @@ export class BitcodeWalletService {
344
342
  return Number(row.personId);
345
343
  }
346
344
 
345
+ private async resolveOrCreatePersonForUser(userId: number): Promise<number> {
346
+ const existing = await this.querySingle<{ personId: number }>(
347
+ `SELECT person_id AS "personId" FROM person_user WHERE user_id = $1 LIMIT 1`,
348
+ [userId]
349
+ );
350
+ if (existing) return Number(existing.personId);
351
+
352
+ // Gather name: prefer commerce_customer (richer), fall back to user record
353
+ const customerRow = await this.querySingle<{ name: string }>(
354
+ `SELECT name FROM commerce_customer
355
+ WHERE user_id = $1 AND deleted_at IS NULL
356
+ ORDER BY id DESC LIMIT 1`,
357
+ [userId]
358
+ );
359
+
360
+ const userRow = await this.querySingle<{ name: string }>(
361
+ `SELECT name FROM "user" WHERE id = $1`,
362
+ [userId]
363
+ );
364
+
365
+ const personName = customerRow?.name || userRow?.name || `Usuário #${userId}`;
366
+
367
+ const person = await this.querySingle<{ id: number }>(
368
+ `INSERT INTO person (name, type, status, created_at, updated_at)
369
+ VALUES ($1, 'individual'::person_type_6dfa750c4d_enum, 'active'::person_status_7efb97d61c_enum, NOW(), NOW())
370
+ RETURNING id`,
371
+ [personName]
372
+ );
373
+
374
+ if (!person) throw new Error('Failed to create person profile');
375
+
376
+ await this.querySingle(
377
+ `INSERT INTO person_user (person_id, user_id, created_at, updated_at)
378
+ VALUES ($1, $2, NOW(), NOW())
379
+ ON CONFLICT DO NOTHING`,
380
+ [person.id, userId]
381
+ );
382
+
383
+ return person.id;
384
+ }
385
+
347
386
  private async findWalletByPersonId(personId: number) {
348
387
  return this.querySingle<{ id: number }>(
349
388
  `SELECT id FROM bitcode_wallet WHERE person_id = $1`,
@@ -0,0 +1,124 @@
1
+ import { FileService, NotificationService } from '@hed-hog/core';
2
+ import { IJobHandler, QueueHandlerRegistry } from '@hed-hog/queue';
3
+ import {
4
+ Inject,
5
+ Injectable,
6
+ Logger,
7
+ OnModuleInit,
8
+ forwardRef,
9
+ } from '@nestjs/common';
10
+ import { promises as fs } from 'fs';
11
+ import { tmpdir } from 'os';
12
+ import { join } from 'path';
13
+ import { CourseExportScorm12Service } from './course-export-scorm12.service';
14
+ import { CourseExportService, LMS_COURSE_EXPORT_SCORM12_JOB } from './course-export.service';
15
+
16
+ @Injectable()
17
+ export class CourseExportScorm12WorkerService implements OnModuleInit, IJobHandler {
18
+ private readonly logger = new Logger(CourseExportScorm12WorkerService.name);
19
+
20
+ constructor(
21
+ @Inject(forwardRef(() => FileService))
22
+ private readonly fileService: FileService,
23
+ @Inject(forwardRef(() => NotificationService))
24
+ private readonly notificationService: NotificationService,
25
+ @Inject(forwardRef(() => QueueHandlerRegistry))
26
+ private readonly registry: QueueHandlerRegistry,
27
+ private readonly courseExportService: CourseExportService,
28
+ private readonly scorm12Builder: CourseExportScorm12Service,
29
+ ) {}
30
+
31
+ onModuleInit() {
32
+ this.registry.register(LMS_COURSE_EXPORT_SCORM12_JOB, this);
33
+ this.logger.log(`Registered handler for job type: ${LMS_COURSE_EXPORT_SCORM12_JOB}`);
34
+ }
35
+
36
+ async handle(job: {
37
+ id: number;
38
+ type: string;
39
+ payload: Record<string, any>;
40
+ }): Promise<void> {
41
+ const { exportId, courseId, userId, notificationId, settings } =
42
+ job.payload as {
43
+ exportId: number;
44
+ courseId: number;
45
+ userId: number;
46
+ notificationId: number;
47
+ settings: Record<string, any>;
48
+ };
49
+
50
+ const startedAt = Date.now();
51
+ const workDir = await fs.mkdtemp(join(tmpdir(), `scorm-${job.id}-`));
52
+
53
+ try {
54
+ this.logger.log(`Starting SCORM 1.2 export ${exportId} for course ${courseId}`);
55
+ await this.courseExportService.markStarted(exportId);
56
+ await this.notificationService.updateProgress(userId, notificationId, {
57
+ progress: 5,
58
+ body: 'Iniciando exportação SCORM 1.2...',
59
+ });
60
+
61
+ const { zipPath, filename } = await this.scorm12Builder.buildPackage({
62
+ courseId,
63
+ settings,
64
+ workDir,
65
+ onProgress: async (pct, msg) => {
66
+ await this.notificationService.updateProgress(userId, notificationId, {
67
+ progress: pct,
68
+ body: msg,
69
+ });
70
+ },
71
+ });
72
+
73
+ await this.notificationService.updateProgress(userId, notificationId, {
74
+ progress: 90,
75
+ body: 'Fazendo upload do pacote SCORM...',
76
+ });
77
+
78
+ const stat = await fs.stat(zipPath);
79
+ const uploadedFile = await this.fileService.uploadFromPath(
80
+ 'course-exports',
81
+ zipPath,
82
+ {
83
+ originalname: filename,
84
+ mimetype: 'application/zip',
85
+ size: stat.size,
86
+ },
87
+ );
88
+
89
+ const durationSeconds = Math.round((Date.now() - startedAt) / 1000);
90
+ await this.courseExportService.markCompleted(
91
+ exportId,
92
+ uploadedFile.id,
93
+ durationSeconds,
94
+ );
95
+
96
+ await this.notificationService.updateProgress(userId, notificationId, {
97
+ progress: 100,
98
+ body: `Exportação SCORM 1.2 concluída em ${durationSeconds}s!`,
99
+ success: true,
100
+ });
101
+
102
+ this.logger.log(
103
+ `SCORM 1.2 export ${exportId} completed in ${durationSeconds}s, file id=${uploadedFile.id}`,
104
+ );
105
+ } catch (err) {
106
+ const msg =
107
+ err instanceof Error ? err.message : 'Erro desconhecido na exportação.';
108
+ this.logger.error(`SCORM 1.2 export ${exportId} failed: ${msg}`, err instanceof Error ? err.stack : undefined);
109
+
110
+ await this.courseExportService.markFailed(exportId, msg).catch(() => undefined);
111
+ await this.notificationService
112
+ .updateProgress(userId, notificationId, {
113
+ progress: 100,
114
+ body: `Falha na exportação: ${msg}`,
115
+ success: false,
116
+ })
117
+ .catch(() => undefined);
118
+
119
+ throw err;
120
+ } finally {
121
+ await fs.rm(workDir, { recursive: true, force: true }).catch(() => undefined);
122
+ }
123
+ }
124
+ }