@hed-hog/lms 0.0.349 → 0.0.351

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 (496) hide show
  1. package/dist/achievement/achievement.controller.d.ts +62 -0
  2. package/dist/achievement/achievement.controller.d.ts.map +1 -0
  3. package/dist/achievement/achievement.controller.js +90 -0
  4. package/dist/achievement/achievement.controller.js.map +1 -0
  5. package/dist/achievement/achievement.mcp-tools.d.ts +19 -0
  6. package/dist/achievement/achievement.mcp-tools.d.ts.map +1 -0
  7. package/dist/achievement/achievement.mcp-tools.js +157 -0
  8. package/dist/achievement/achievement.mcp-tools.js.map +1 -0
  9. package/dist/achievement/achievement.module.d.ts +3 -0
  10. package/dist/achievement/achievement.module.d.ts.map +1 -0
  11. package/dist/achievement/achievement.module.js +26 -0
  12. package/dist/achievement/achievement.module.js.map +1 -0
  13. package/dist/achievement/achievement.service.d.ts +72 -0
  14. package/dist/achievement/achievement.service.d.ts.map +1 -0
  15. package/dist/achievement/achievement.service.js +200 -0
  16. package/dist/achievement/achievement.service.js.map +1 -0
  17. package/dist/achievement/dto/create-achievement.dto.d.ts +12 -0
  18. package/dist/achievement/dto/create-achievement.dto.d.ts.map +1 -0
  19. package/dist/achievement/dto/create-achievement.dto.js +60 -0
  20. package/dist/achievement/dto/create-achievement.dto.js.map +1 -0
  21. package/dist/achievement/dto/update-achievement.dto.d.ts +11 -0
  22. package/dist/achievement/dto/update-achievement.dto.d.ts.map +1 -0
  23. package/dist/achievement/dto/update-achievement.dto.js +57 -0
  24. package/dist/achievement/dto/update-achievement.dto.js.map +1 -0
  25. package/dist/bitcode-wallet/bitcode-wallet.controller.d.ts +114 -0
  26. package/dist/bitcode-wallet/bitcode-wallet.controller.d.ts.map +1 -0
  27. package/dist/bitcode-wallet/bitcode-wallet.controller.js +102 -0
  28. package/dist/bitcode-wallet/bitcode-wallet.controller.js.map +1 -0
  29. package/dist/bitcode-wallet/bitcode-wallet.mcp-tools.d.ts +25 -0
  30. package/dist/bitcode-wallet/bitcode-wallet.mcp-tools.d.ts.map +1 -0
  31. package/dist/bitcode-wallet/bitcode-wallet.mcp-tools.js +160 -0
  32. package/dist/bitcode-wallet/bitcode-wallet.mcp-tools.js.map +1 -0
  33. package/dist/bitcode-wallet/bitcode-wallet.module.d.ts +3 -0
  34. package/dist/bitcode-wallet/bitcode-wallet.module.d.ts.map +1 -0
  35. package/dist/bitcode-wallet/bitcode-wallet.module.js +26 -0
  36. package/dist/bitcode-wallet/bitcode-wallet.module.js.map +1 -0
  37. package/dist/bitcode-wallet/bitcode-wallet.service.d.ts +127 -0
  38. package/dist/bitcode-wallet/bitcode-wallet.service.d.ts.map +1 -0
  39. package/dist/bitcode-wallet/bitcode-wallet.service.js +264 -0
  40. package/dist/bitcode-wallet/bitcode-wallet.service.js.map +1 -0
  41. package/dist/bitcode-wallet/dto/create-bitcode-wallet-transaction.dto.d.ts +8 -0
  42. package/dist/bitcode-wallet/dto/create-bitcode-wallet-transaction.dto.d.ts.map +1 -0
  43. package/dist/bitcode-wallet/dto/create-bitcode-wallet-transaction.dto.js +33 -0
  44. package/dist/bitcode-wallet/dto/create-bitcode-wallet-transaction.dto.js.map +1 -0
  45. package/dist/bitcode-wallet/dto/create-bitcode-wallet.dto.d.ts +4 -0
  46. package/dist/bitcode-wallet/dto/create-bitcode-wallet.dto.d.ts.map +1 -0
  47. package/dist/bitcode-wallet/dto/create-bitcode-wallet.dto.js +22 -0
  48. package/dist/bitcode-wallet/dto/create-bitcode-wallet.dto.js.map +1 -0
  49. package/dist/bitcode-wallet/dto/update-bitcode-wallet-transaction.dto.d.ts +7 -0
  50. package/dist/bitcode-wallet/dto/update-bitcode-wallet-transaction.dto.d.ts.map +1 -0
  51. package/dist/bitcode-wallet/dto/update-bitcode-wallet-transaction.dto.js +35 -0
  52. package/dist/bitcode-wallet/dto/update-bitcode-wallet-transaction.dto.js.map +1 -0
  53. package/dist/bitcode-wallet/dto/update-bitcode-wallet.dto.d.ts +4 -0
  54. package/dist/bitcode-wallet/dto/update-bitcode-wallet.dto.d.ts.map +1 -0
  55. package/dist/bitcode-wallet/dto/update-bitcode-wallet.dto.js +23 -0
  56. package/dist/bitcode-wallet/dto/update-bitcode-wallet.dto.js.map +1 -0
  57. package/dist/certificate/certificate.controller.d.ts +24 -2
  58. package/dist/certificate/certificate.controller.d.ts.map +1 -1
  59. package/dist/certificate/certificate.controller.js +20 -6
  60. package/dist/certificate/certificate.controller.js.map +1 -1
  61. package/dist/certificate/certificate.mcp-tools.d.ts +24 -0
  62. package/dist/certificate/certificate.mcp-tools.d.ts.map +1 -0
  63. package/dist/certificate/certificate.mcp-tools.js +188 -0
  64. package/dist/certificate/certificate.mcp-tools.js.map +1 -0
  65. package/dist/certificate/certificate.module.d.ts.map +1 -1
  66. package/dist/certificate/certificate.module.js +2 -1
  67. package/dist/certificate/certificate.module.js.map +1 -1
  68. package/dist/certificate/certificate.service.d.ts +30 -4
  69. package/dist/certificate/certificate.service.d.ts.map +1 -1
  70. package/dist/certificate/certificate.service.js +157 -8
  71. package/dist/certificate/certificate.service.js.map +1 -1
  72. package/dist/certificate/dto/update-certificate-public-access.dto.d.ts +4 -0
  73. package/dist/certificate/dto/update-certificate-public-access.dto.d.ts.map +1 -0
  74. package/dist/certificate/dto/update-certificate-public-access.dto.js +21 -0
  75. package/dist/certificate/dto/update-certificate-public-access.dto.js.map +1 -0
  76. package/dist/class-group/class-group.mcp-tools.d.ts +87 -0
  77. package/dist/class-group/class-group.mcp-tools.d.ts.map +1 -0
  78. package/dist/class-group/class-group.mcp-tools.js +553 -0
  79. package/dist/class-group/class-group.mcp-tools.js.map +1 -0
  80. package/dist/class-group/class-group.module.d.ts.map +1 -1
  81. package/dist/class-group/class-group.module.js +2 -1
  82. package/dist/class-group/class-group.module.js.map +1 -1
  83. package/dist/class-group/class-group.service.d.ts +3 -1
  84. package/dist/class-group/class-group.service.d.ts.map +1 -1
  85. package/dist/class-group/class-group.service.js +45 -2
  86. package/dist/class-group/class-group.service.js.map +1 -1
  87. package/dist/course/course-operations-integration.service.d.ts +40 -0
  88. package/dist/course/course-operations-integration.service.d.ts.map +1 -0
  89. package/dist/course/course-operations-integration.service.js +372 -0
  90. package/dist/course/course-operations-integration.service.js.map +1 -0
  91. package/dist/course/course-structure.controller.d.ts +67 -14
  92. package/dist/course/course-structure.controller.d.ts.map +1 -1
  93. package/dist/course/course-structure.controller.js +45 -2
  94. package/dist/course/course-structure.controller.js.map +1 -1
  95. package/dist/course/course-structure.service.d.ts +58 -9
  96. package/dist/course/course-structure.service.d.ts.map +1 -1
  97. package/dist/course/course-structure.service.js +260 -62
  98. package/dist/course/course-structure.service.js.map +1 -1
  99. package/dist/course/course-video-conversion.service.d.ts +37 -0
  100. package/dist/course/course-video-conversion.service.d.ts.map +1 -0
  101. package/dist/course/course-video-conversion.service.js +308 -0
  102. package/dist/course/course-video-conversion.service.js.map +1 -0
  103. package/dist/course/course.controller.d.ts +29 -0
  104. package/dist/course/course.controller.d.ts.map +1 -1
  105. package/dist/course/course.controller.js +23 -0
  106. package/dist/course/course.controller.js.map +1 -1
  107. package/dist/course/course.mcp-tools.d.ts +90 -0
  108. package/dist/course/course.mcp-tools.d.ts.map +1 -0
  109. package/dist/course/course.mcp-tools.js +520 -0
  110. package/dist/course/course.mcp-tools.js.map +1 -0
  111. package/dist/course/course.module.d.ts.map +1 -1
  112. package/dist/course/course.module.js +23 -3
  113. package/dist/course/course.module.js.map +1 -1
  114. package/dist/course/course.service.d.ts +30 -1
  115. package/dist/course/course.service.d.ts.map +1 -1
  116. package/dist/course/course.service.js +159 -70
  117. package/dist/course/course.service.js.map +1 -1
  118. package/dist/course/dto/create-course-structure-lesson.dto.d.ts +5 -1
  119. package/dist/course/dto/create-course-structure-lesson.dto.d.ts.map +1 -1
  120. package/dist/course/dto/create-course-structure-lesson.dto.js +16 -2
  121. package/dist/course/dto/create-course-structure-lesson.dto.js.map +1 -1
  122. package/dist/course/dto/create-course.dto.d.ts +2 -0
  123. package/dist/course/dto/create-course.dto.d.ts.map +1 -1
  124. package/dist/course/dto/create-course.dto.js +16 -0
  125. package/dist/course/dto/create-course.dto.js.map +1 -1
  126. package/dist/course/dto/update-course-resources.dto.d.ts +11 -0
  127. package/dist/course/dto/update-course-resources.dto.d.ts.map +1 -0
  128. package/dist/course/dto/update-course-resources.dto.js +51 -0
  129. package/dist/course/dto/update-course-resources.dto.js.map +1 -0
  130. package/dist/course-lesson-discussion/course-lesson-discussion.controller.d.ts +23 -0
  131. package/dist/course-lesson-discussion/course-lesson-discussion.controller.d.ts.map +1 -0
  132. package/dist/course-lesson-discussion/course-lesson-discussion.controller.js +78 -0
  133. package/dist/course-lesson-discussion/course-lesson-discussion.controller.js.map +1 -0
  134. package/dist/course-lesson-discussion/course-lesson-discussion.mcp-tools.d.ts +22 -0
  135. package/dist/course-lesson-discussion/course-lesson-discussion.mcp-tools.d.ts.map +1 -0
  136. package/dist/course-lesson-discussion/course-lesson-discussion.mcp-tools.js +120 -0
  137. package/dist/course-lesson-discussion/course-lesson-discussion.mcp-tools.js.map +1 -0
  138. package/dist/course-lesson-discussion/course-lesson-discussion.module.d.ts +3 -0
  139. package/dist/course-lesson-discussion/course-lesson-discussion.module.d.ts.map +1 -0
  140. package/dist/course-lesson-discussion/course-lesson-discussion.module.js +26 -0
  141. package/dist/course-lesson-discussion/course-lesson-discussion.module.js.map +1 -0
  142. package/dist/course-lesson-discussion/course-lesson-discussion.service.d.ts +49 -0
  143. package/dist/course-lesson-discussion/course-lesson-discussion.service.d.ts.map +1 -0
  144. package/dist/course-lesson-discussion/course-lesson-discussion.service.js +272 -0
  145. package/dist/course-lesson-discussion/course-lesson-discussion.service.js.map +1 -0
  146. package/dist/course-lesson-discussion/dto/create-course-lesson-discussion-topic.dto.d.ts +6 -0
  147. package/dist/course-lesson-discussion/dto/create-course-lesson-discussion-topic.dto.d.ts.map +1 -0
  148. package/dist/course-lesson-discussion/dto/create-course-lesson-discussion-topic.dto.js +33 -0
  149. package/dist/course-lesson-discussion/dto/create-course-lesson-discussion-topic.dto.js.map +1 -0
  150. package/dist/course-lesson-note/course-lesson-note.controller.d.ts +53 -0
  151. package/dist/course-lesson-note/course-lesson-note.controller.d.ts.map +1 -0
  152. package/dist/course-lesson-note/course-lesson-note.controller.js +93 -0
  153. package/dist/course-lesson-note/course-lesson-note.controller.js.map +1 -0
  154. package/dist/course-lesson-note/course-lesson-note.mcp-tools.d.ts +27 -0
  155. package/dist/course-lesson-note/course-lesson-note.mcp-tools.d.ts.map +1 -0
  156. package/dist/course-lesson-note/course-lesson-note.mcp-tools.js +145 -0
  157. package/dist/course-lesson-note/course-lesson-note.mcp-tools.js.map +1 -0
  158. package/dist/course-lesson-note/course-lesson-note.module.d.ts +3 -0
  159. package/dist/course-lesson-note/course-lesson-note.module.d.ts.map +1 -0
  160. package/dist/course-lesson-note/course-lesson-note.module.js +26 -0
  161. package/dist/course-lesson-note/course-lesson-note.module.js.map +1 -0
  162. package/dist/course-lesson-note/course-lesson-note.service.d.ts +59 -0
  163. package/dist/course-lesson-note/course-lesson-note.service.d.ts.map +1 -0
  164. package/dist/course-lesson-note/course-lesson-note.service.js +195 -0
  165. package/dist/course-lesson-note/course-lesson-note.service.js.map +1 -0
  166. package/dist/course-lesson-note/dto/create-course-lesson-note.dto.d.ts +6 -0
  167. package/dist/course-lesson-note/dto/create-course-lesson-note.dto.d.ts.map +1 -0
  168. package/dist/course-lesson-note/dto/create-course-lesson-note.dto.js +33 -0
  169. package/dist/course-lesson-note/dto/create-course-lesson-note.dto.js.map +1 -0
  170. package/dist/course-lesson-note/dto/update-course-lesson-note.dto.d.ts +6 -0
  171. package/dist/course-lesson-note/dto/update-course-lesson-note.dto.d.ts.map +1 -0
  172. package/dist/course-lesson-note/dto/update-course-lesson-note.dto.js +35 -0
  173. package/dist/course-lesson-note/dto/update-course-lesson-note.dto.js.map +1 -0
  174. package/dist/dashboard/dashboard.mcp-tools.d.ts +10 -0
  175. package/dist/dashboard/dashboard.mcp-tools.d.ts.map +1 -0
  176. package/dist/dashboard/dashboard.mcp-tools.js +46 -0
  177. package/dist/dashboard/dashboard.mcp-tools.js.map +1 -0
  178. package/dist/dashboard/dashboard.module.d.ts.map +1 -1
  179. package/dist/dashboard/dashboard.module.js +2 -1
  180. package/dist/dashboard/dashboard.module.js.map +1 -1
  181. package/dist/enterprise/enterprise.controller.d.ts +3 -3
  182. package/dist/enterprise/enterprise.controller.d.ts.map +1 -1
  183. package/dist/enterprise/enterprise.controller.js +0 -1
  184. package/dist/enterprise/enterprise.controller.js.map +1 -1
  185. package/dist/enterprise/enterprise.mcp-tools.d.ts +82 -0
  186. package/dist/enterprise/enterprise.mcp-tools.d.ts.map +1 -0
  187. package/dist/enterprise/enterprise.mcp-tools.js +516 -0
  188. package/dist/enterprise/enterprise.mcp-tools.js.map +1 -0
  189. package/dist/enterprise/enterprise.module.d.ts.map +1 -1
  190. package/dist/enterprise/enterprise.module.js +2 -1
  191. package/dist/enterprise/enterprise.module.js.map +1 -1
  192. package/dist/enterprise/enterprise.service.d.ts +3 -3
  193. package/dist/enterprise/training/enterprise-training.module.d.ts.map +1 -1
  194. package/dist/enterprise/training/enterprise-training.module.js +11 -1
  195. package/dist/enterprise/training/enterprise-training.module.js.map +1 -1
  196. package/dist/enterprise/training/training-admin.mcp-tools.d.ts +79 -0
  197. package/dist/enterprise/training/training-admin.mcp-tools.d.ts.map +1 -0
  198. package/dist/enterprise/training/training-admin.mcp-tools.js +620 -0
  199. package/dist/enterprise/training/training-admin.mcp-tools.js.map +1 -0
  200. package/dist/enterprise/training/training-instructor.mcp-tools.d.ts +47 -0
  201. package/dist/enterprise/training/training-instructor.mcp-tools.d.ts.map +1 -0
  202. package/dist/enterprise/training/training-instructor.mcp-tools.js +275 -0
  203. package/dist/enterprise/training/training-instructor.mcp-tools.js.map +1 -0
  204. package/dist/enterprise/training/training-student.controller.d.ts +24 -0
  205. package/dist/enterprise/training/training-student.controller.d.ts.map +1 -1
  206. package/dist/enterprise/training/training-student.controller.js +22 -0
  207. package/dist/enterprise/training/training-student.controller.js.map +1 -1
  208. package/dist/enterprise/training/training-student.mcp-tools.d.ts +27 -0
  209. package/dist/enterprise/training/training-student.mcp-tools.d.ts.map +1 -0
  210. package/dist/enterprise/training/training-student.mcp-tools.js +186 -0
  211. package/dist/enterprise/training/training-student.mcp-tools.js.map +1 -0
  212. package/dist/enterprise/training/training-student.service.d.ts +32 -0
  213. package/dist/enterprise/training/training-student.service.d.ts.map +1 -1
  214. package/dist/enterprise/training/training-student.service.js +138 -0
  215. package/dist/enterprise/training/training-student.service.js.map +1 -1
  216. package/dist/evaluation/evaluation.mcp-tools.d.ts +25 -0
  217. package/dist/evaluation/evaluation.mcp-tools.d.ts.map +1 -0
  218. package/dist/evaluation/evaluation.mcp-tools.js +220 -0
  219. package/dist/evaluation/evaluation.mcp-tools.js.map +1 -0
  220. package/dist/evaluation/evaluation.module.d.ts.map +1 -1
  221. package/dist/evaluation/evaluation.module.js +2 -1
  222. package/dist/evaluation/evaluation.module.js.map +1 -1
  223. package/dist/evaluation/evaluation.service.d.ts.map +1 -1
  224. package/dist/evaluation/evaluation.service.js +9 -2
  225. package/dist/evaluation/evaluation.service.js.map +1 -1
  226. package/dist/exam/dto/create-exam-question.dto.d.ts +2 -0
  227. package/dist/exam/dto/create-exam-question.dto.d.ts.map +1 -1
  228. package/dist/exam/dto/create-exam-question.dto.js +10 -0
  229. package/dist/exam/dto/create-exam-question.dto.js.map +1 -1
  230. package/dist/exam/dto/create-exam.dto.d.ts +2 -0
  231. package/dist/exam/dto/create-exam.dto.d.ts.map +1 -1
  232. package/dist/exam/dto/create-exam.dto.js +10 -0
  233. package/dist/exam/dto/create-exam.dto.js.map +1 -1
  234. package/dist/exam/dto/create-question-subject.dto.d.ts +5 -0
  235. package/dist/exam/dto/create-question-subject.dto.d.ts.map +1 -0
  236. package/dist/exam/dto/create-question-subject.dto.js +28 -0
  237. package/dist/exam/dto/create-question-subject.dto.js.map +1 -0
  238. package/dist/exam/exam-attempt.controller.d.ts +4 -0
  239. package/dist/exam/exam-attempt.controller.d.ts.map +1 -1
  240. package/dist/exam/exam-attempt.service.d.ts +7 -1
  241. package/dist/exam/exam-attempt.service.d.ts.map +1 -1
  242. package/dist/exam/exam-attempt.service.js +47 -17
  243. package/dist/exam/exam-attempt.service.js.map +1 -1
  244. package/dist/exam/exam.controller.d.ts +34 -0
  245. package/dist/exam/exam.controller.d.ts.map +1 -1
  246. package/dist/exam/exam.controller.js +27 -0
  247. package/dist/exam/exam.controller.js.map +1 -1
  248. package/dist/exam/exam.mcp-tools.d.ts +62 -0
  249. package/dist/exam/exam.mcp-tools.d.ts.map +1 -0
  250. package/dist/exam/exam.mcp-tools.js +430 -0
  251. package/dist/exam/exam.mcp-tools.js.map +1 -0
  252. package/dist/exam/exam.module.d.ts.map +1 -1
  253. package/dist/exam/exam.module.js +2 -1
  254. package/dist/exam/exam.module.js.map +1 -1
  255. package/dist/exam/exam.service.d.ts +38 -0
  256. package/dist/exam/exam.service.d.ts.map +1 -1
  257. package/dist/exam/exam.service.js +114 -17
  258. package/dist/exam/exam.service.js.map +1 -1
  259. package/dist/index.d.ts +10 -0
  260. package/dist/index.d.ts.map +1 -1
  261. package/dist/index.js +10 -0
  262. package/dist/index.js.map +1 -1
  263. package/dist/instructor/instructor.mcp-tools.d.ts +41 -0
  264. package/dist/instructor/instructor.mcp-tools.d.ts.map +1 -0
  265. package/dist/instructor/instructor.mcp-tools.js +326 -0
  266. package/dist/instructor/instructor.mcp-tools.js.map +1 -0
  267. package/dist/instructor/instructor.module.d.ts.map +1 -1
  268. package/dist/instructor/instructor.module.js +2 -1
  269. package/dist/instructor/instructor.module.js.map +1 -1
  270. package/dist/lms.module.d.ts.map +1 -1
  271. package/dist/lms.module.js +18 -0
  272. package/dist/lms.module.js.map +1 -1
  273. package/dist/realtime/lms-realtime.controller.d.ts +7 -0
  274. package/dist/realtime/lms-realtime.controller.d.ts.map +1 -0
  275. package/dist/realtime/lms-realtime.controller.js +34 -0
  276. package/dist/realtime/lms-realtime.controller.js.map +1 -0
  277. package/dist/realtime/lms-realtime.module.d.ts +3 -0
  278. package/dist/realtime/lms-realtime.module.d.ts.map +1 -0
  279. package/dist/realtime/lms-realtime.module.js +25 -0
  280. package/dist/realtime/lms-realtime.module.js.map +1 -0
  281. package/dist/realtime/lms-realtime.service.d.ts +36 -0
  282. package/dist/realtime/lms-realtime.service.d.ts.map +1 -0
  283. package/dist/realtime/lms-realtime.service.js +59 -0
  284. package/dist/realtime/lms-realtime.service.js.map +1 -0
  285. package/dist/realtime/lms-realtime.subscriber.d.ts +10 -0
  286. package/dist/realtime/lms-realtime.subscriber.d.ts.map +1 -0
  287. package/dist/realtime/lms-realtime.subscriber.js +70 -0
  288. package/dist/realtime/lms-realtime.subscriber.js.map +1 -0
  289. package/dist/reports/reports.mcp-tools.d.ts +10 -0
  290. package/dist/reports/reports.mcp-tools.d.ts.map +1 -0
  291. package/dist/reports/reports.mcp-tools.js +50 -0
  292. package/dist/reports/reports.mcp-tools.js.map +1 -0
  293. package/dist/reports/reports.module.d.ts.map +1 -1
  294. package/dist/reports/reports.module.js +2 -1
  295. package/dist/reports/reports.module.js.map +1 -1
  296. package/dist/training/training.mcp-tools.d.ts +20 -0
  297. package/dist/training/training.mcp-tools.d.ts.map +1 -0
  298. package/dist/training/training.mcp-tools.js +181 -0
  299. package/dist/training/training.mcp-tools.js.map +1 -0
  300. package/dist/training/training.module.d.ts.map +1 -1
  301. package/dist/training/training.module.js +2 -1
  302. package/dist/training/training.module.js.map +1 -1
  303. package/dist/video-resolution-profile/dto/create-video-resolution-profile.dto.d.ts +6 -0
  304. package/dist/video-resolution-profile/dto/create-video-resolution-profile.dto.d.ts.map +1 -0
  305. package/dist/video-resolution-profile/dto/create-video-resolution-profile.dto.js +33 -0
  306. package/dist/video-resolution-profile/dto/create-video-resolution-profile.dto.js.map +1 -0
  307. package/dist/video-resolution-profile/dto/update-video-resolution-profile.dto.d.ts +6 -0
  308. package/dist/video-resolution-profile/dto/update-video-resolution-profile.dto.d.ts.map +1 -0
  309. package/dist/video-resolution-profile/dto/update-video-resolution-profile.dto.js +33 -0
  310. package/dist/video-resolution-profile/dto/update-video-resolution-profile.dto.js.map +1 -0
  311. package/dist/video-resolution-profile/video-resolution-profile.controller.d.ts +38 -0
  312. package/dist/video-resolution-profile/video-resolution-profile.controller.d.ts.map +1 -0
  313. package/dist/video-resolution-profile/video-resolution-profile.controller.js +89 -0
  314. package/dist/video-resolution-profile/video-resolution-profile.controller.js.map +1 -0
  315. package/dist/video-resolution-profile/video-resolution-profile.mcp-tools.d.ts +26 -0
  316. package/dist/video-resolution-profile/video-resolution-profile.mcp-tools.d.ts.map +1 -0
  317. package/dist/video-resolution-profile/video-resolution-profile.mcp-tools.js +160 -0
  318. package/dist/video-resolution-profile/video-resolution-profile.mcp-tools.js.map +1 -0
  319. package/dist/video-resolution-profile/video-resolution-profile.module.d.ts +3 -0
  320. package/dist/video-resolution-profile/video-resolution-profile.module.d.ts.map +1 -0
  321. package/dist/video-resolution-profile/video-resolution-profile.module.js +26 -0
  322. package/dist/video-resolution-profile/video-resolution-profile.module.js.map +1 -0
  323. package/dist/video-resolution-profile/video-resolution-profile.service.d.ts +45 -0
  324. package/dist/video-resolution-profile/video-resolution-profile.service.d.ts.map +1 -0
  325. package/dist/video-resolution-profile/video-resolution-profile.service.js +117 -0
  326. package/dist/video-resolution-profile/video-resolution-profile.service.js.map +1 -0
  327. package/hedhog/data/integration_event_catalog.yaml +69 -0
  328. package/hedhog/data/menu.yaml +51 -0
  329. package/hedhog/data/route.yaml +2484 -0
  330. package/hedhog/data/video_resolution_profile.yaml +7 -0
  331. package/hedhog/frontend/app/_components/class-form-sheet.tsx.ejs +432 -422
  332. package/hedhog/frontend/app/_components/course-form-sheet.tsx.ejs +200 -67
  333. package/hedhog/frontend/app/_components/course-picker.tsx.ejs +228 -0
  334. package/hedhog/frontend/app/_components/create-lms-instructor-sheet.tsx.ejs +7 -4
  335. package/hedhog/frontend/app/_components/create-lms-person-sheet.tsx.ejs +2 -2
  336. package/hedhog/frontend/app/_components/create-lms-student-person-sheet.tsx.ejs +2 -2
  337. package/hedhog/frontend/app/_lib/editor/templateSerializer.ts.ejs +34 -4
  338. package/hedhog/frontend/app/_lib/editor/types.ts.ejs +28 -3
  339. package/hedhog/frontend/app/_lib/hooks/use-lms-realtime-refresh.ts.ejs +58 -0
  340. package/hedhog/frontend/app/achievements/page.tsx.ejs +850 -0
  341. package/hedhog/frontend/app/bitcodes/page.tsx.ejs +1016 -0
  342. package/hedhog/frontend/app/certificates/issued/page.tsx.ejs +68 -5
  343. package/hedhog/frontend/app/certificates/models/CanvasStage.tsx.ejs +29 -8
  344. package/hedhog/frontend/app/certificates/models/LeftPanel.tsx.ejs +14 -0
  345. package/hedhog/frontend/app/certificates/models/RightPanel.tsx.ejs +194 -9
  346. package/hedhog/frontend/app/certificates/models/page.tsx.ejs +15 -5
  347. package/hedhog/frontend/app/classes/[id]/page.tsx.ejs +16 -5
  348. package/hedhog/frontend/app/classes/page.tsx.ejs +126 -2105
  349. package/hedhog/frontend/app/courses/[id]/_components/CourseCertificateCard.tsx.ejs +19 -9
  350. package/hedhog/frontend/app/courses/[id]/_components/CourseClassificationCard.tsx.ejs +24 -1
  351. package/hedhog/frontend/app/courses/[id]/_components/CourseContentCard.tsx.ejs +1 -1
  352. package/hedhog/frontend/app/courses/[id]/_components/CourseMainInfoCard.tsx.ejs +1 -1
  353. package/hedhog/frontend/app/courses/[id]/_components/CourseRelationsCard.tsx.ejs +51 -11
  354. package/hedhog/frontend/app/courses/[id]/_components/CourseSectionCard.tsx.ejs +11 -6
  355. package/hedhog/frontend/app/courses/[id]/_components/CourseSummaryCard.tsx.ejs +7 -4
  356. package/hedhog/frontend/app/courses/[id]/_components/course-edit-types.ts.ejs +2 -0
  357. package/hedhog/frontend/app/courses/[id]/page.tsx.ejs +24 -96
  358. package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree-dnd.tsx.ejs +80 -66
  359. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-course.tsx.ejs +1286 -230
  360. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-lesson.tsx.ejs +1334 -153
  361. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-session.tsx.ejs +11 -11
  362. package/hedhog/frontend/app/courses/[id]/structure/_components/mock-data.ts.ejs +1 -1
  363. package/hedhog/frontend/app/courses/[id]/structure/_components/shortcuts-help.tsx.ejs +62 -52
  364. package/hedhog/frontend/app/courses/[id]/structure/_components/tree-context-menu.tsx.ejs +106 -4
  365. package/hedhog/frontend/app/courses/[id]/structure/_components/types.ts.ejs +4 -1
  366. package/hedhog/frontend/app/courses/[id]/structure/_data/adapters/course-structure.adapter.ts.ejs +30 -7
  367. package/hedhog/frontend/app/courses/[id]/structure/_data/services/course-structure.service.ts.ejs +138 -6
  368. package/hedhog/frontend/app/courses/[id]/structure/_data/types/api-course.types.ts.ejs +16 -2
  369. package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-structure-mutations.ts.ejs +1 -0
  370. package/hedhog/frontend/app/courses/page.tsx.ejs +282 -113
  371. package/hedhog/frontend/app/enterprise/[id]/page.tsx.ejs +1 -1
  372. package/hedhog/frontend/app/enterprise/_components/enterprise-admin-create-sheet.tsx.ejs +10 -3
  373. package/hedhog/frontend/app/enterprise/_components/enterprise-course-create-sheet.tsx.ejs +3 -0
  374. package/hedhog/frontend/app/enterprise/_components/enterprise-course-edit-sheet.tsx.ejs +7 -0
  375. package/hedhog/frontend/app/enterprise/_components/enterprise-detail-sheet.tsx.ejs +8 -4
  376. package/hedhog/frontend/app/enterprise/_components/enterprise-person-edit-sheet.tsx.ejs +2 -2
  377. package/hedhog/frontend/app/enterprise/_components/enterprise-sheet.tsx.ejs +10 -4
  378. package/hedhog/frontend/app/enterprise/_components/enterprise-student-create-sheet.tsx.ejs +10 -3
  379. package/hedhog/frontend/app/enterprise/_components/enterprise-user-create-sheet.tsx.ejs +10 -3
  380. package/hedhog/frontend/app/evaluations/_components/evaluation-topic-form-sheet.tsx.ejs +10 -3
  381. package/hedhog/frontend/app/exams/[id]/questions/page.tsx.ejs +186 -5
  382. package/hedhog/frontend/app/exams/page.tsx.ejs +89 -26
  383. package/hedhog/frontend/app/instructor-skills/page.tsx.ejs +10 -3
  384. package/hedhog/frontend/app/instructors/_components/instructor-form-sheet.tsx.ejs +190 -17
  385. package/hedhog/frontend/app/instructors/page.tsx.ejs +1 -0
  386. package/hedhog/frontend/app/layout.tsx.ejs +5 -1
  387. package/hedhog/frontend/app/paths/page.tsx.ejs +19 -29
  388. package/hedhog/frontend/app/reports/evaluations/page.tsx.ejs +10 -10
  389. package/hedhog/frontend/app/training/page.tsx.ejs +19 -29
  390. package/hedhog/frontend/app/video-resolution-profiles/page.tsx.ejs +607 -0
  391. package/hedhog/frontend/messages/en.json +563 -20
  392. package/hedhog/frontend/messages/pt.json +563 -20
  393. package/hedhog/query/triggers.sql +53 -0
  394. package/hedhog/table/achievement.yaml +46 -0
  395. package/hedhog/table/bitcode_wallet.yaml +18 -0
  396. package/hedhog/table/bitcode_wallet_transaction.yaml +22 -0
  397. package/hedhog/table/certificate.yaml +3 -0
  398. package/hedhog/table/course.yaml +8 -0
  399. package/hedhog/table/course_file.yaml +23 -0
  400. package/hedhog/table/course_lesson.yaml +5 -0
  401. package/hedhog/table/course_lesson_discussion_like.yaml +21 -0
  402. package/hedhog/table/course_lesson_discussion_topic.yaml +35 -0
  403. package/hedhog/table/course_lesson_file.yaml +8 -0
  404. package/hedhog/table/course_lesson_note.yaml +34 -0
  405. package/hedhog/table/course_video_resolution_profile.yaml +22 -0
  406. package/hedhog/table/exam.yaml +5 -0
  407. package/hedhog/table/learning_path_enrollment.yaml +6 -0
  408. package/hedhog/table/question.yaml +10 -0
  409. package/hedhog/table/question_subject.yaml +17 -0
  410. package/hedhog/table/student_activity_streak.yaml +25 -0
  411. package/hedhog/table/video_resolution_profile.yaml +18 -0
  412. package/package.json +8 -7
  413. package/src/achievement/achievement.controller.ts +60 -0
  414. package/src/achievement/achievement.mcp-tools.ts +108 -0
  415. package/src/achievement/achievement.module.ts +13 -0
  416. package/src/achievement/achievement.service.ts +252 -0
  417. package/src/achievement/dto/create-achievement.dto.ts +50 -0
  418. package/src/achievement/dto/update-achievement.dto.ts +47 -0
  419. package/src/bitcode-wallet/bitcode-wallet.controller.ts +69 -0
  420. package/src/bitcode-wallet/bitcode-wallet.mcp-tools.ts +107 -0
  421. package/src/bitcode-wallet/bitcode-wallet.module.ts +13 -0
  422. package/src/bitcode-wallet/bitcode-wallet.service.ts +361 -0
  423. package/src/bitcode-wallet/dto/create-bitcode-wallet-transaction.dto.ts +27 -0
  424. package/src/bitcode-wallet/dto/create-bitcode-wallet.dto.ts +7 -0
  425. package/src/bitcode-wallet/dto/update-bitcode-wallet-transaction.dto.ts +28 -0
  426. package/src/bitcode-wallet/dto/update-bitcode-wallet.dto.ts +8 -0
  427. package/src/certificate/certificate.controller.ts +17 -3
  428. package/src/certificate/certificate.mcp-tools.ts +131 -0
  429. package/src/certificate/certificate.module.ts +2 -1
  430. package/src/certificate/certificate.service.ts +193 -7
  431. package/src/certificate/dto/update-certificate-public-access.dto.ts +6 -0
  432. package/src/class-group/class-group.mcp-tools.ts +435 -0
  433. package/src/class-group/class-group.module.ts +2 -1
  434. package/src/class-group/class-group.service.ts +51 -1
  435. package/src/course/course-operations-integration.service.ts +520 -0
  436. package/src/course/course-structure.controller.ts +46 -10
  437. package/src/course/course-structure.service.ts +236 -27
  438. package/src/course/course-video-conversion.service.ts +415 -0
  439. package/src/course/course.controller.ts +18 -0
  440. package/src/course/course.mcp-tools.ts +409 -0
  441. package/src/course/course.module.ts +23 -3
  442. package/src/course/course.service.ts +178 -29
  443. package/src/course/dto/create-course-structure-lesson.dto.ts +13 -2
  444. package/src/course/dto/create-course.dto.ts +16 -0
  445. package/src/course/dto/update-course-resources.dto.ts +39 -0
  446. package/src/course-lesson-discussion/course-lesson-discussion.controller.ts +55 -0
  447. package/src/course-lesson-discussion/course-lesson-discussion.mcp-tools.ts +75 -0
  448. package/src/course-lesson-discussion/course-lesson-discussion.module.ts +13 -0
  449. package/src/course-lesson-discussion/course-lesson-discussion.service.ts +354 -0
  450. package/src/course-lesson-discussion/dto/create-course-lesson-discussion-topic.dto.ts +16 -0
  451. package/src/course-lesson-note/course-lesson-note.controller.ts +68 -0
  452. package/src/course-lesson-note/course-lesson-note.mcp-tools.ts +96 -0
  453. package/src/course-lesson-note/course-lesson-note.module.ts +13 -0
  454. package/src/course-lesson-note/course-lesson-note.service.ts +248 -0
  455. package/src/course-lesson-note/dto/create-course-lesson-note.dto.ts +16 -0
  456. package/src/course-lesson-note/dto/update-course-lesson-note.dto.ts +18 -0
  457. package/src/dashboard/dashboard.mcp-tools.ts +23 -0
  458. package/src/dashboard/dashboard.module.ts +2 -1
  459. package/src/enterprise/enterprise.controller.ts +0 -1
  460. package/src/enterprise/enterprise.mcp-tools.ts +403 -0
  461. package/src/enterprise/enterprise.module.ts +2 -1
  462. package/src/enterprise/training/enterprise-training.module.ts +11 -1
  463. package/src/enterprise/training/training-admin.mcp-tools.ts +479 -0
  464. package/src/enterprise/training/training-instructor.mcp-tools.ts +210 -0
  465. package/src/enterprise/training/training-student.controller.ts +17 -1
  466. package/src/enterprise/training/training-student.mcp-tools.ts +136 -0
  467. package/src/enterprise/training/training-student.service.ts +167 -1
  468. package/src/evaluation/evaluation.mcp-tools.ts +155 -0
  469. package/src/evaluation/evaluation.module.ts +2 -1
  470. package/src/evaluation/evaluation.service.ts +9 -2
  471. package/src/exam/dto/create-exam-question.dto.ts +8 -0
  472. package/src/exam/dto/create-exam.dto.ts +8 -0
  473. package/src/exam/dto/create-question-subject.dto.ts +12 -0
  474. package/src/exam/exam-attempt.service.ts +46 -14
  475. package/src/exam/exam.controller.ts +19 -0
  476. package/src/exam/exam.mcp-tools.ts +337 -0
  477. package/src/exam/exam.module.ts +2 -1
  478. package/src/exam/exam.service.ts +121 -0
  479. package/src/index.ts +10 -0
  480. package/src/instructor/instructor.mcp-tools.ts +243 -0
  481. package/src/instructor/instructor.module.ts +2 -1
  482. package/src/lms.module.ts +18 -1
  483. package/src/realtime/lms-realtime.controller.ts +12 -0
  484. package/src/realtime/lms-realtime.module.ts +12 -0
  485. package/src/realtime/lms-realtime.service.ts +98 -0
  486. package/src/realtime/lms-realtime.subscriber.ts +61 -0
  487. package/src/reports/reports.mcp-tools.ts +27 -0
  488. package/src/reports/reports.module.ts +2 -1
  489. package/src/training/training.mcp-tools.ts +128 -0
  490. package/src/training/training.module.ts +2 -1
  491. package/src/video-resolution-profile/dto/create-video-resolution-profile.dto.ts +16 -0
  492. package/src/video-resolution-profile/dto/update-video-resolution-profile.dto.ts +16 -0
  493. package/src/video-resolution-profile/video-resolution-profile.controller.ts +62 -0
  494. package/src/video-resolution-profile/video-resolution-profile.mcp-tools.ts +128 -0
  495. package/src/video-resolution-profile/video-resolution-profile.module.ts +13 -0
  496. package/src/video-resolution-profile/video-resolution-profile.service.ts +117 -0
@@ -1,5 +1,5 @@
1
1
  import { Role, User } from '@hed-hog/api';
2
- import { Controller, Get, Param, ParseIntPipe, Query } from '@nestjs/common';
2
+ import { Body, Controller, Get, Param, ParseIntPipe, Post, Query } from '@nestjs/common';
3
3
  import { TrainingStudentService } from './training-student.service';
4
4
 
5
5
  @Role()
@@ -62,4 +62,20 @@ export class TrainingStudentController {
62
62
  ) {
63
63
  return this.trainingStudentService.getMyEvaluations(userId, classGroupId);
64
64
  }
65
+
66
+ @Get('streak')
67
+ getStreak(
68
+ @User('id') userId: number,
69
+ @Query('days', new ParseIntPipe({ optional: true })) days?: number,
70
+ ) {
71
+ return this.trainingStudentService.getStreak(userId, days);
72
+ }
73
+
74
+ @Post('streak/activities')
75
+ registerStreakActivity(
76
+ @User('id') userId: number,
77
+ @Body() body?: { activityType?: string; source?: string; activityDateKey?: string },
78
+ ) {
79
+ return this.trainingStudentService.registerStreakActivity(userId, body);
80
+ }
65
81
  }
@@ -0,0 +1,136 @@
1
+ import { McpContext, McpTool } from '@hed-hog/core';
2
+ import { Injectable } from '@nestjs/common';
3
+ import { TrainingStudentService } from './training-student.service';
4
+
5
+ @Injectable()
6
+ export class LmsTrainingStudentMcpTools {
7
+ constructor(private readonly trainingStudentService: TrainingStudentService) {}
8
+
9
+ @McpTool({
10
+ name: 'lms.training-student.dashboard',
11
+ description: 'Returns the training dashboard summary for the authenticated student.',
12
+ inputSchema: {
13
+ type: 'object',
14
+ properties: {
15
+ enterpriseId: { type: 'number', description: 'Enterprise ID (optional; inferred from user if omitted)' },
16
+ },
17
+ },
18
+ readOnly: true,
19
+ })
20
+ async getDashboard(args: { enterpriseId?: number }, context: McpContext): Promise<any> {
21
+ return this.trainingStudentService.getDashboard(context.userId, args.enterpriseId);
22
+ }
23
+
24
+ @McpTool({
25
+ name: 'lms.training-student.class-groups.list',
26
+ description: 'Lists class groups in which the authenticated student is enrolled.',
27
+ inputSchema: {
28
+ type: 'object',
29
+ properties: {
30
+ enterpriseId: { type: 'number', description: 'Enterprise ID' },
31
+ search: { type: 'string', description: 'Search term' },
32
+ status: { type: 'string', description: 'Filter by status (open|ongoing|completed|cancelled)' },
33
+ deliveryMode: { type: 'string', description: 'Filter by delivery mode (presential|online|hybrid)' },
34
+ },
35
+ },
36
+ readOnly: true,
37
+ })
38
+ async getClassGroups(args: Record<string, any>, context: McpContext): Promise<any> {
39
+ return this.trainingStudentService.getClassGroups(context.userId, args);
40
+ }
41
+
42
+ @McpTool({
43
+ name: 'lms.training-student.class-groups.get',
44
+ description: 'Returns details of a specific class group for the authenticated student.',
45
+ inputSchema: {
46
+ type: 'object',
47
+ properties: {
48
+ classGroupId: { type: 'number', description: 'Class group ID' },
49
+ },
50
+ required: ['classGroupId'],
51
+ },
52
+ readOnly: true,
53
+ })
54
+ async getClassGroupDetail(args: { classGroupId: number }, context: McpContext): Promise<any> {
55
+ return this.trainingStudentService.getClassGroupDetail(context.userId, args.classGroupId);
56
+ }
57
+
58
+ @McpTool({
59
+ name: 'lms.training-student.class-groups.sessions',
60
+ description: 'Lists sessions for a class group (student view).',
61
+ inputSchema: {
62
+ type: 'object',
63
+ properties: {
64
+ classGroupId: { type: 'number', description: 'Class group ID' },
65
+ },
66
+ required: ['classGroupId'],
67
+ },
68
+ readOnly: true,
69
+ })
70
+ async getClassGroupSessions(args: { classGroupId: number }, context: McpContext): Promise<any> {
71
+ return this.trainingStudentService.getClassGroupSessions(context.userId, args.classGroupId);
72
+ }
73
+
74
+ @McpTool({
75
+ name: 'lms.training-student.class-groups.materials',
76
+ description: 'Lists materials for a class group (student view).',
77
+ inputSchema: {
78
+ type: 'object',
79
+ properties: {
80
+ classGroupId: { type: 'number', description: 'Class group ID' },
81
+ },
82
+ required: ['classGroupId'],
83
+ },
84
+ readOnly: true,
85
+ })
86
+ async getClassGroupMaterials(args: { classGroupId: number }, context: McpContext): Promise<any> {
87
+ return this.trainingStudentService.getClassGroupMaterials(context.userId, args.classGroupId);
88
+ }
89
+
90
+ @McpTool({
91
+ name: 'lms.training-student.class-groups.my-evaluations',
92
+ description: 'Returns the evaluations submitted by the authenticated student for a class group.',
93
+ inputSchema: {
94
+ type: 'object',
95
+ properties: {
96
+ classGroupId: { type: 'number', description: 'Class group ID' },
97
+ },
98
+ required: ['classGroupId'],
99
+ },
100
+ readOnly: true,
101
+ })
102
+ async getMyEvaluations(args: { classGroupId: number }, context: McpContext): Promise<any> {
103
+ return this.trainingStudentService.getMyEvaluations(context.userId, args.classGroupId);
104
+ }
105
+
106
+ @McpTool({
107
+ name: 'lms.training-student.streak.get',
108
+ description: 'Returns the learning streak data for the authenticated student.',
109
+ inputSchema: {
110
+ type: 'object',
111
+ properties: {
112
+ days: { type: 'number', description: 'Number of days to include (default: 30)' },
113
+ },
114
+ },
115
+ readOnly: true,
116
+ })
117
+ async getStreak(args: { days?: number }, context: McpContext): Promise<any> {
118
+ return this.trainingStudentService.getStreak(context.userId, args.days);
119
+ }
120
+
121
+ @McpTool({
122
+ name: 'lms.training-student.streak.register-activity',
123
+ description: 'Registers a learning activity for the authenticated student (updates streak).',
124
+ inputSchema: {
125
+ type: 'object',
126
+ properties: {
127
+ activityType: { type: 'string', description: 'Type of activity' },
128
+ source: { type: 'string', description: 'Activity source identifier' },
129
+ activityDateKey: { type: 'string', description: 'Date key for the activity (YYYY-MM-DD)' },
130
+ },
131
+ },
132
+ })
133
+ async registerStreakActivity(args: Record<string, any>, context: McpContext): Promise<any> {
134
+ return this.trainingStudentService.registerStreakActivity(context.userId, args);
135
+ }
136
+ }
@@ -1,10 +1,73 @@
1
1
  import { PrismaService } from '@hed-hog/api-prisma';
2
- import { Injectable, NotFoundException } from '@nestjs/common';
2
+ import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
3
3
 
4
4
  @Injectable()
5
5
  export class TrainingStudentService {
6
6
  constructor(private readonly prisma: PrismaService) {}
7
7
 
8
+ async registerStreakActivity(
9
+ userId: number,
10
+ payload?: { activityType?: string; source?: string; activityDateKey?: string },
11
+ ) {
12
+ const personId = await this.resolvePersonIdFromUser(userId);
13
+ const activityDateKey = this.normalizeActivityDateKey(payload?.activityDateKey);
14
+ const activityType = this.normalizeText(payload?.activityType, 100);
15
+ const source = this.normalizeText(payload?.source, 100) ?? 'class-app';
16
+
17
+ await this.prisma.$executeRaw`
18
+ INSERT INTO "student_activity_streak" (
19
+ "person_id",
20
+ "activity_date_key",
21
+ "activity_type",
22
+ "source",
23
+ "last_activity_at"
24
+ )
25
+ VALUES (
26
+ ${personId},
27
+ ${activityDateKey},
28
+ ${activityType},
29
+ ${source},
30
+ NOW()
31
+ )
32
+ ON CONFLICT ("person_id", "activity_date_key")
33
+ DO UPDATE SET
34
+ "activity_type" = COALESCE(EXCLUDED."activity_type", "student_activity_streak"."activity_type"),
35
+ "source" = COALESCE(EXCLUDED."source", "student_activity_streak"."source"),
36
+ "last_activity_at" = NOW(),
37
+ "updated_at" = NOW();
38
+ `;
39
+
40
+ return this.getStreak(userId, 14);
41
+ }
42
+
43
+ async getStreak(userId: number, days = 14) {
44
+ const safeDays = Number.isFinite(days) ? Math.max(7, Math.min(60, Math.trunc(days))) : 14;
45
+ const personId = await this.resolvePersonIdFromUser(userId);
46
+
47
+ const rows = await this.prisma.$queryRaw<Array<{ activity_date_key: string }>>`
48
+ SELECT "activity_date_key"
49
+ FROM "student_activity_streak"
50
+ WHERE "person_id" = ${personId}
51
+ ORDER BY "activity_date_key" DESC;
52
+ `;
53
+
54
+ const uniqueKeys = Array.from(
55
+ new Set(rows.map((row) => row.activity_date_key).filter((key): key is string => !!key)),
56
+ ).sort((a, b) => b.localeCompare(a));
57
+
58
+ const currentStreak = this.calculateCurrentStreak(uniqueKeys);
59
+ const bestStreak = this.calculateBestStreak(uniqueKeys);
60
+ const calendar = this.buildStreakCalendar(uniqueKeys, safeDays);
61
+
62
+ return {
63
+ currentStreak,
64
+ bestStreak,
65
+ totalActiveDays: uniqueKeys.length,
66
+ lastActivityDate: uniqueKeys[0] ?? null,
67
+ days: calendar,
68
+ };
69
+ }
70
+
8
71
  async getDashboard(userId: number, enterpriseId?: number) {
9
72
  const personUser = await this.prisma.person_user.findFirst({
10
73
  where: { user_id: userId },
@@ -759,4 +822,107 @@ export class TrainingStudentService {
759
822
  result.setDate(result.getDate() + diff);
760
823
  return result;
761
824
  }
825
+
826
+ private toDateKey(date: Date) {
827
+ const year = date.getFullYear();
828
+ const month = String(date.getMonth() + 1).padStart(2, '0');
829
+ const day = String(date.getDate()).padStart(2, '0');
830
+ return `${year}-${month}-${day}`;
831
+ }
832
+
833
+ private dateFromKey(key: string) {
834
+ return new Date(`${key}T00:00:00`);
835
+ }
836
+
837
+ private normalizeActivityDateKey(activityDateKey?: string) {
838
+ if (!activityDateKey) {
839
+ return this.toDateKey(new Date());
840
+ }
841
+
842
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(activityDateKey)) {
843
+ throw new BadRequestException('activityDateKey must use the YYYY-MM-DD format');
844
+ }
845
+
846
+ return activityDateKey;
847
+ }
848
+
849
+ private normalizeText(value: string | undefined, maxLength: number) {
850
+ if (!value) {
851
+ return null;
852
+ }
853
+
854
+ const normalized = value.trim();
855
+ if (!normalized) {
856
+ return null;
857
+ }
858
+
859
+ return normalized.slice(0, maxLength);
860
+ }
861
+
862
+ private calculateCurrentStreak(dateKeysDesc: string[]) {
863
+ if (dateKeysDesc.length === 0) {
864
+ return 0;
865
+ }
866
+
867
+ let streak = 0;
868
+ let cursor = this.startOfDay(new Date());
869
+ for (const dateKey of dateKeysDesc) {
870
+ const value = this.startOfDay(this.dateFromKey(dateKey));
871
+ const diff = Math.round((cursor.getTime() - value.getTime()) / 86400000);
872
+ if (diff > 1) {
873
+ break;
874
+ }
875
+ streak += 1;
876
+ cursor = value;
877
+ }
878
+
879
+ return streak;
880
+ }
881
+
882
+ private calculateBestStreak(dateKeysDesc: string[]) {
883
+ if (dateKeysDesc.length === 0) {
884
+ return 0;
885
+ }
886
+
887
+ const dateKeysAsc = [...dateKeysDesc].sort((a, b) => a.localeCompare(b));
888
+ let best = 1;
889
+ let current = 1;
890
+
891
+ for (let i = 1; i < dateKeysAsc.length; i += 1) {
892
+ const previous = this.startOfDay(this.dateFromKey(dateKeysAsc[i - 1]));
893
+ const next = this.startOfDay(this.dateFromKey(dateKeysAsc[i]));
894
+ const diff = Math.round((next.getTime() - previous.getTime()) / 86400000);
895
+ if (diff === 1) {
896
+ current += 1;
897
+ } else {
898
+ current = 1;
899
+ }
900
+ if (current > best) {
901
+ best = current;
902
+ }
903
+ }
904
+
905
+ return best;
906
+ }
907
+
908
+ private buildStreakCalendar(dateKeysDesc: string[], days: number) {
909
+ const dateKeySet = new Set(dateKeysDesc);
910
+ const today = this.startOfDay(new Date());
911
+
912
+ return Array.from({ length: days }, (_, index) => {
913
+ const offset = days - index - 1;
914
+ const date = this.startOfDay(this.addDays(today, -offset));
915
+ const key = this.toDateKey(date);
916
+ return {
917
+ date: key,
918
+ completed: dateKeySet.has(key),
919
+ };
920
+ });
921
+ }
922
+
923
+ private startOfDay(date: Date) {
924
+ const result = new Date(date);
925
+ result.setHours(0, 0, 0, 0);
926
+ return result;
927
+ }
762
928
  }
@@ -0,0 +1,155 @@
1
+ import { McpContext, McpTool } from '@hed-hog/core';
2
+ import { Injectable } from '@nestjs/common';
3
+ import { EvaluationService } from './evaluation.service';
4
+
5
+ @Injectable()
6
+ export class LmsEvaluationMcpTools {
7
+ constructor(private readonly evaluationService: EvaluationService) {}
8
+
9
+ @McpTool({
10
+ name: 'lms.evaluations.list',
11
+ description: 'Lists evaluations with optional filters (course, class, instructor, evaluator, date range).',
12
+ inputSchema: {
13
+ type: 'object',
14
+ properties: {
15
+ page: { type: 'number', description: 'Page number (default: 1)' },
16
+ pageSize: { type: 'number', description: 'Items per page (default: 20)' },
17
+ search: { type: 'string', description: 'Search term' },
18
+ courseId: { type: 'number', description: 'Filter by course ID' },
19
+ classId: { type: 'number', description: 'Filter by class group ID' },
20
+ instructorId: { type: 'number', description: 'Filter by instructor ID' },
21
+ evaluatorId: { type: 'number', description: 'Filter by evaluator ID' },
22
+ dateFrom: { type: 'string', description: 'Start date filter (ISO8601)' },
23
+ dateTo: { type: 'string', description: 'End date filter (ISO8601)' },
24
+ },
25
+ },
26
+ readOnly: true,
27
+ })
28
+ async listEvaluations(args: Record<string, any>, _context: McpContext): Promise<any> {
29
+ return this.evaluationService.list(args);
30
+ }
31
+
32
+ @McpTool({
33
+ name: 'lms.evaluations.stats',
34
+ description: 'Returns aggregate evaluation statistics.',
35
+ inputSchema: { type: 'object', properties: {} },
36
+ readOnly: true,
37
+ })
38
+ async getStats(_args: Record<string, any>, _context: McpContext): Promise<any> {
39
+ return this.evaluationService.stats();
40
+ }
41
+
42
+ @McpTool({
43
+ name: 'lms.evaluations.filter-options',
44
+ description: 'Returns available filter options for the evaluations list (courses, instructors, evaluators).',
45
+ inputSchema: { type: 'object', properties: {} },
46
+ readOnly: true,
47
+ })
48
+ async getFilterOptions(_args: Record<string, any>, _context: McpContext): Promise<any> {
49
+ return this.evaluationService.filterOptions();
50
+ }
51
+
52
+ @McpTool({
53
+ name: 'lms.evaluations.topics.list',
54
+ description: 'Lists evaluation topics with optional pagination and filters.',
55
+ inputSchema: {
56
+ type: 'object',
57
+ properties: {
58
+ page: { type: 'number', description: 'Page number' },
59
+ pageSize: { type: 'number', description: 'Items per page' },
60
+ search: { type: 'string', description: 'Search term' },
61
+ targetType: { type: 'string', description: 'Filter by target type' },
62
+ },
63
+ },
64
+ readOnly: true,
65
+ })
66
+ async listTopics(args: Record<string, any>, _context: McpContext): Promise<any> {
67
+ return this.evaluationService.listTopics(args);
68
+ }
69
+
70
+ @McpTool({
71
+ name: 'lms.evaluations.topics.get',
72
+ description: 'Returns a single evaluation topic by ID.',
73
+ inputSchema: {
74
+ type: 'object',
75
+ properties: {
76
+ id: { type: 'number', description: 'Topic ID' },
77
+ },
78
+ required: ['id'],
79
+ },
80
+ readOnly: true,
81
+ })
82
+ async getTopic(args: { id: number }, _context: McpContext): Promise<any> {
83
+ return this.evaluationService.getTopicById(args.id);
84
+ }
85
+
86
+ @McpTool({
87
+ name: 'lms.evaluations.topics.create',
88
+ description: 'Creates a new evaluation topic.',
89
+ inputSchema: {
90
+ type: 'object',
91
+ properties: {
92
+ name: { type: 'string', description: 'Topic name (required, max 255)' },
93
+ description: { type: 'string', description: 'Topic description' },
94
+ targetType: { type: 'string', description: 'Target type (COURSE|COURSE_LESSON|COURSE_CLASS_SESSION|QUESTION|EXAM)' },
95
+ order: { type: 'number', description: 'Display order' },
96
+ isActive: { type: 'boolean', description: 'Whether the topic is active' },
97
+ },
98
+ required: ['name', 'targetType'],
99
+ },
100
+ })
101
+ async createTopic(args: Record<string, any>, _context: McpContext): Promise<any> {
102
+ return this.evaluationService.createTopic(args as any);
103
+ }
104
+
105
+ @McpTool({
106
+ name: 'lms.evaluations.topics.update',
107
+ description: 'Updates an existing evaluation topic.',
108
+ inputSchema: {
109
+ type: 'object',
110
+ properties: {
111
+ id: { type: 'number', description: 'Topic ID' },
112
+ name: { type: 'string', description: 'Topic name' },
113
+ description: { type: 'string', description: 'Topic description' },
114
+ targetType: { type: 'string', description: 'Target type' },
115
+ order: { type: 'number', description: 'Display order' },
116
+ isActive: { type: 'boolean', description: 'Whether the topic is active' },
117
+ },
118
+ required: ['id'],
119
+ },
120
+ })
121
+ async updateTopic(args: { id: number; [key: string]: any }, _context: McpContext): Promise<any> {
122
+ const { id, ...dto } = args;
123
+ return this.evaluationService.updateTopic(id, dto as any);
124
+ }
125
+
126
+ @McpTool({
127
+ name: 'lms.evaluations.topics.delete',
128
+ description: 'Deletes an evaluation topic by ID.',
129
+ inputSchema: {
130
+ type: 'object',
131
+ properties: {
132
+ id: { type: 'number', description: 'Topic ID' },
133
+ },
134
+ required: ['id'],
135
+ },
136
+ })
137
+ async deleteTopic(args: { id: number }, _context: McpContext): Promise<any> {
138
+ return this.evaluationService.deleteTopic(args.id);
139
+ }
140
+
141
+ @McpTool({
142
+ name: 'lms.evaluations.topics.reorder',
143
+ description: 'Reorders evaluation topics.',
144
+ inputSchema: {
145
+ type: 'object',
146
+ properties: {
147
+ ids: { type: 'array', description: 'Topic IDs in the desired order', items: { type: 'number' } },
148
+ },
149
+ required: ['ids'],
150
+ },
151
+ })
152
+ async reorderTopics(args: { ids: number[] }, _context: McpContext): Promise<any> {
153
+ return this.evaluationService.reorderTopics(args.ids);
154
+ }
155
+ }
@@ -1,12 +1,13 @@
1
1
  import { PrismaModule } from '@hed-hog/api-prisma';
2
2
  import { forwardRef, Module } from '@nestjs/common';
3
3
  import { EvaluationController } from './evaluation.controller';
4
+ import { LmsEvaluationMcpTools } from './evaluation.mcp-tools';
4
5
  import { EvaluationService } from './evaluation.service';
5
6
 
6
7
  @Module({
7
8
  imports: [forwardRef(() => PrismaModule)],
8
9
  controllers: [EvaluationController],
9
- providers: [EvaluationService],
10
+ providers: [EvaluationService, LmsEvaluationMcpTools],
10
11
  exports: [forwardRef(() => EvaluationService)],
11
12
  })
12
13
  export class EvaluationModule {}
@@ -114,7 +114,14 @@ export class EvaluationService {
114
114
  sessionWhere.course_class_group_id = params.classId;
115
115
  }
116
116
  if (params.instructorId) {
117
- sessionWhere.course_class_group = { instructor_id: params.instructorId };
117
+ sessionWhere.OR = [
118
+ { course_class_group: { instructor_id: params.instructorId } },
119
+ {
120
+ course_class_session_instructor: {
121
+ some: { instructor_id: params.instructorId },
122
+ },
123
+ },
124
+ ];
118
125
  }
119
126
  if (Object.keys(sessionWhere).length > 0) {
120
127
  topicWhere.course_class_session = sessionWhere;
@@ -252,7 +259,7 @@ export class EvaluationService {
252
259
  }
253
260
  if (group.instructor?.person) {
254
261
  instructorName = group.instructor.person.name;
255
- instructorId = group.instructor.person.id;
262
+ instructorId = group.instructor.id;
256
263
  }
257
264
  }
258
265
  } else if (targetType === 'question' && topic.question) {
@@ -68,10 +68,18 @@ export class MatchingPairDto {
68
68
  }
69
69
 
70
70
  export class CreateExamQuestionDto {
71
+ @IsInt()
72
+ @Min(1)
73
+ subjectId: number;
74
+
71
75
  @IsString()
72
76
  @IsNotEmpty()
73
77
  statement: string;
74
78
 
79
+ @IsString()
80
+ @IsOptional()
81
+ explanation?: string;
82
+
75
83
  @IsString()
76
84
  @IsIn(EXAM_QUESTION_TYPES)
77
85
  @IsOptional()
@@ -25,6 +25,14 @@ export class CreateExamDto {
25
25
  @IsOptional()
26
26
  shuffle?: boolean;
27
27
 
28
+ @IsBoolean()
29
+ @IsOptional()
30
+ showAnswerKeyAfterFinish?: boolean;
31
+
32
+ @IsEnum(['beginner', 'intermediate', 'advanced'])
33
+ @IsOptional()
34
+ level?: 'beginner' | 'intermediate' | 'advanced';
35
+
28
36
  @IsEnum(['draft', 'published', 'closed', 'archived'])
29
37
  @IsOptional()
30
38
  status?: 'draft' | 'published' | 'closed' | 'archived';
@@ -0,0 +1,12 @@
1
+ import { IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
2
+
3
+ export class CreateQuestionSubjectDto {
4
+ @IsString()
5
+ @IsNotEmpty()
6
+ @MaxLength(255)
7
+ name: string;
8
+
9
+ @IsString()
10
+ @IsOptional()
11
+ description?: string;
12
+ }
@@ -1,8 +1,11 @@
1
1
  import { PrismaService } from '@hed-hog/api-prisma';
2
+ import { IntegrationDeveloperApiService } from '@hed-hog/core';
2
3
  import {
3
4
  BadRequestException,
5
+ Inject,
4
6
  Injectable,
5
7
  NotFoundException,
8
+ forwardRef,
6
9
  } from '@nestjs/common';
7
10
  import {
8
11
  OBJECTIVE_EXAM_QUESTION_TYPES,
@@ -14,7 +17,11 @@ import { SubmitExamAttemptDto } from './dto/submit-exam-attempt.dto';
14
17
 
15
18
  @Injectable()
16
19
  export class ExamAttemptService {
17
- constructor(private readonly prisma: PrismaService) {}
20
+ constructor(
21
+ private readonly prisma: PrismaService,
22
+ @Inject(forwardRef(() => IntegrationDeveloperApiService))
23
+ private readonly integrationApi: IntegrationDeveloperApiService,
24
+ ) {}
18
25
 
19
26
  async getAttemptState(
20
27
  examId: number,
@@ -117,6 +124,26 @@ export class ExamAttemptService {
117
124
  await this.persistAnswers(attempt.id, exam, dto.answers ?? []);
118
125
  const completed = await this.completeAttempt(exam, attempt.id, dto.force ?? false);
119
126
 
127
+ const minScore = exam.min_score ?? 0;
128
+ const passed = completed.score !== null && completed.score !== undefined
129
+ ? completed.score >= minScore
130
+ : null;
131
+
132
+ await this.integrationApi.publishEvent({
133
+ eventName: 'lms.exam.attempt.submitted',
134
+ sourceModule: 'lms',
135
+ aggregateType: 'exam_attempt',
136
+ aggregateId: String(completed.id),
137
+ payload: {
138
+ examId: exam.id,
139
+ attemptId: completed.id,
140
+ studentId,
141
+ score: completed.score ?? null,
142
+ passed,
143
+ attemptNumber: completed.attempt_number,
144
+ },
145
+ }).catch(() => null);
146
+
120
147
  return this.buildAttemptPayload(exam, studentId, completed);
121
148
  }
122
149
 
@@ -435,6 +462,7 @@ export class ExamAttemptService {
435
462
  exam.require_all_questions_answered_to_finish,
436
463
  ),
437
464
  showResult: Boolean(exam.show_result ?? true),
465
+ showAnswerKeyAfterFinish: Boolean(exam.show_answer_key ?? false),
438
466
  },
439
467
  attempts: {
440
468
  allowed: attemptsAllowed,
@@ -496,19 +524,23 @@ export class ExamAttemptService {
496
524
  const answer = answersByQuestion.get(item.question_id);
497
525
  return this.requiresManualReview(item.question?.question_type) && Boolean(answer);
498
526
  }).length,
499
- answersSummary: (exam.exam_question ?? []).map((item: any) => {
500
- const answer = answersByQuestion.get(item.question_id);
501
- return {
502
- questionId: item.question_id,
503
- hasAnswer: Boolean(answer),
504
- isCorrect:
505
- typeof answer?.is_correct === 'boolean' ? Boolean(answer.is_correct) : null,
506
- pointsAwarded: answer?.points_awarded ?? 0,
507
- requiresManualReview: this.requiresManualReview(
508
- item.question?.question_type,
509
- ),
510
- };
511
- }),
527
+ answersSummary: Boolean(exam.show_answer_key ?? false)
528
+ ? (exam.exam_question ?? []).map((item: any) => {
529
+ const answer = answersByQuestion.get(item.question_id);
530
+ return {
531
+ questionId: item.question_id,
532
+ hasAnswer: Boolean(answer),
533
+ isCorrect:
534
+ typeof answer?.is_correct === 'boolean'
535
+ ? Boolean(answer.is_correct)
536
+ : null,
537
+ pointsAwarded: answer?.points_awarded ?? 0,
538
+ requiresManualReview: this.requiresManualReview(
539
+ item.question?.question_type,
540
+ ),
541
+ };
542
+ })
543
+ : [],
512
544
  };
513
545
  }
514
546