@headless-lms/core 0.2.0 → 0.4.0

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 (307) hide show
  1. package/dist/assets/events.d.ts +42 -24
  2. package/dist/assets/events.js +1 -1
  3. package/dist/assets/events.js.map +1 -1
  4. package/dist/assets/file-urls.d.ts +20 -0
  5. package/dist/assets/file-urls.js +25 -0
  6. package/dist/assets/file-urls.js.map +1 -0
  7. package/dist/assets/index.d.ts +6 -4
  8. package/dist/assets/index.js +4 -2
  9. package/dist/assets/jobs.d.ts +15 -0
  10. package/dist/assets/jobs.js +30 -0
  11. package/dist/assets/jobs.js.map +1 -0
  12. package/dist/assets/model.d.ts +2 -2
  13. package/dist/assets/ports.d.ts +46 -15
  14. package/dist/assets/service.d.ts +38 -7
  15. package/dist/assets/service.js +287 -38
  16. package/dist/assets/service.js.map +1 -1
  17. package/dist/automations/actions.d.ts +13 -24
  18. package/dist/automations/actions.js +106 -42
  19. package/dist/automations/actions.js.map +1 -1
  20. package/dist/automations/catalog.js +226 -3
  21. package/dist/automations/catalog.js.map +1 -1
  22. package/dist/automations/community-derivations.d.ts +14 -0
  23. package/dist/automations/community-derivations.js +439 -0
  24. package/dist/automations/community-derivations.js.map +1 -0
  25. package/dist/automations/community-mail.d.ts +98 -0
  26. package/dist/automations/community-mail.js +70 -0
  27. package/dist/automations/community-mail.js.map +1 -0
  28. package/dist/automations/events.d.ts +18 -0
  29. package/dist/automations/index.d.ts +13 -4
  30. package/dist/automations/index.js +10 -2
  31. package/dist/automations/model.d.ts +10 -3
  32. package/dist/automations/model.js +15 -2
  33. package/dist/automations/model.js.map +1 -1
  34. package/dist/automations/notifications/debounce.d.ts +25 -0
  35. package/dist/automations/notifications/debounce.js +93 -0
  36. package/dist/automations/notifications/debounce.js.map +1 -0
  37. package/dist/automations/notifications/defaults.d.ts +8 -0
  38. package/dist/automations/notifications/defaults.js +316 -0
  39. package/dist/automations/notifications/defaults.js.map +1 -0
  40. package/dist/automations/notifications/delivery.d.ts +28 -0
  41. package/dist/automations/notifications/delivery.js +88 -0
  42. package/dist/automations/notifications/delivery.js.map +1 -0
  43. package/dist/automations/notifications/processor.d.ts +64 -0
  44. package/dist/automations/notifications/processor.js +270 -0
  45. package/dist/automations/notifications/processor.js.map +1 -0
  46. package/dist/automations/notifications/rules/content.d.ts +6 -0
  47. package/dist/automations/notifications/rules/content.js +39 -0
  48. package/dist/automations/notifications/rules/content.js.map +1 -0
  49. package/dist/automations/notifications/rules/discussion.d.ts +7 -0
  50. package/dist/automations/notifications/rules/discussion.js +678 -0
  51. package/dist/automations/notifications/rules/discussion.js.map +1 -0
  52. package/dist/automations/notifications/rules/entitlements.d.ts +6 -0
  53. package/dist/automations/notifications/rules/entitlements.js +249 -0
  54. package/dist/automations/notifications/rules/entitlements.js.map +1 -0
  55. package/dist/automations/notifications/rules/index.d.ts +6 -0
  56. package/dist/automations/notifications/rules/index.js +15 -0
  57. package/dist/automations/notifications/rules/index.js.map +1 -0
  58. package/dist/automations/notifications/rules/organizations.d.ts +6 -0
  59. package/dist/automations/notifications/rules/organizations.js +28 -0
  60. package/dist/automations/notifications/rules/organizations.js.map +1 -0
  61. package/dist/automations/notifications/rules/recipients.d.ts +32 -0
  62. package/dist/automations/notifications/rules/recipients.js +99 -0
  63. package/dist/automations/notifications/rules/recipients.js.map +1 -0
  64. package/dist/automations/notifications/service.d.ts +27 -0
  65. package/dist/automations/notifications/service.js +45 -0
  66. package/dist/automations/notifications/service.js.map +1 -0
  67. package/dist/automations/notifications/types.d.ts +7 -0
  68. package/dist/automations/notifications/types.js +473 -0
  69. package/dist/automations/notifications/types.js.map +1 -0
  70. package/dist/automations/ports.d.ts +121 -3
  71. package/dist/automations/schedule.d.ts +6 -0
  72. package/dist/automations/schedule.js +41 -0
  73. package/dist/automations/schedule.js.map +1 -0
  74. package/dist/automations/service.d.ts +20 -4
  75. package/dist/automations/service.js +246 -45
  76. package/dist/automations/service.js.map +1 -1
  77. package/dist/content/events.d.ts +712 -50
  78. package/dist/content/events.js +55 -1
  79. package/dist/content/events.js.map +1 -1
  80. package/dist/content/index.d.ts +6 -4
  81. package/dist/content/index.js +3 -1
  82. package/dist/content/model.d.ts +2 -2
  83. package/dist/content/notification-categories.d.ts +36 -0
  84. package/dist/content/notification-categories.js +64 -0
  85. package/dist/content/notification-categories.js.map +1 -0
  86. package/dist/content/ports.d.ts +90 -18
  87. package/dist/content/service.d.ts +57 -18
  88. package/dist/content/service.js +520 -25
  89. package/dist/content/service.js.map +1 -1
  90. package/dist/content/titles.d.ts +22 -0
  91. package/dist/content/titles.js +69 -0
  92. package/dist/content/titles.js.map +1 -0
  93. package/dist/content/types.d.ts +2 -2
  94. package/dist/discussion/authors.d.ts +10 -0
  95. package/dist/discussion/authors.js +23 -0
  96. package/dist/discussion/authors.js.map +1 -0
  97. package/dist/discussion/chats.d.ts +109 -0
  98. package/dist/discussion/chats.js +831 -0
  99. package/dist/discussion/chats.js.map +1 -0
  100. package/dist/discussion/digests.d.ts +24 -0
  101. package/dist/discussion/digests.js +104 -0
  102. package/dist/discussion/digests.js.map +1 -0
  103. package/dist/discussion/events.d.ts +785 -56
  104. package/dist/discussion/events.js +165 -5
  105. package/dist/discussion/events.js.map +1 -1
  106. package/dist/discussion/index.d.ts +12 -3
  107. package/dist/discussion/index.js +9 -1
  108. package/dist/discussion/jobs.d.ts +16 -0
  109. package/dist/discussion/jobs.js +40 -0
  110. package/dist/discussion/jobs.js.map +1 -0
  111. package/dist/discussion/mentions.d.ts +11 -0
  112. package/dist/discussion/mentions.js +35 -0
  113. package/dist/discussion/mentions.js.map +1 -0
  114. package/dist/discussion/ports.d.ts +372 -28
  115. package/dist/discussion/ports.js +6 -1
  116. package/dist/discussion/ports.js.map +1 -0
  117. package/dist/discussion/posts.d.ts +113 -0
  118. package/dist/discussion/posts.js +775 -0
  119. package/dist/discussion/posts.js.map +1 -0
  120. package/dist/discussion/service.d.ts +42 -11
  121. package/dist/discussion/service.js +364 -85
  122. package/dist/discussion/service.js.map +1 -1
  123. package/dist/discussion/subscriptions.d.ts +37 -0
  124. package/dist/discussion/subscriptions.js +99 -0
  125. package/dist/discussion/subscriptions.js.map +1 -0
  126. package/dist/discussion/titles.d.ts +26 -0
  127. package/dist/discussion/titles.js +84 -0
  128. package/dist/discussion/titles.js.map +1 -0
  129. package/dist/entitlements/events.d.ts +178 -11
  130. package/dist/entitlements/events.js +28 -1
  131. package/dist/entitlements/events.js.map +1 -1
  132. package/dist/entitlements/index.d.ts +6 -4
  133. package/dist/entitlements/index.js +3 -1
  134. package/dist/entitlements/jobs.d.ts +12 -0
  135. package/dist/entitlements/jobs.js +18 -0
  136. package/dist/entitlements/jobs.js.map +1 -0
  137. package/dist/entitlements/model.d.ts +3 -2
  138. package/dist/entitlements/ports.d.ts +128 -11
  139. package/dist/entitlements/rules.d.ts +12 -0
  140. package/dist/entitlements/rules.js +17 -0
  141. package/dist/entitlements/rules.js.map +1 -0
  142. package/dist/entitlements/service.d.ts +57 -3
  143. package/dist/entitlements/service.js +492 -2
  144. package/dist/entitlements/service.js.map +1 -1
  145. package/dist/identity/access.d.ts +6 -0
  146. package/dist/identity/access.js +7 -0
  147. package/dist/identity/access.js.map +1 -0
  148. package/dist/identity/devices.d.ts +30 -0
  149. package/dist/identity/devices.js +107 -0
  150. package/dist/identity/devices.js.map +1 -0
  151. package/dist/identity/events.d.ts +2 -2
  152. package/dist/identity/index.d.ts +7 -4
  153. package/dist/identity/index.js +4 -1
  154. package/dist/identity/model.d.ts +2 -1
  155. package/dist/identity/notification-settings.d.ts +28 -0
  156. package/dist/identity/notification-settings.js +113 -0
  157. package/dist/identity/notification-settings.js.map +1 -0
  158. package/dist/identity/ports.d.ts +97 -3
  159. package/dist/identity/service.d.ts +14 -3
  160. package/dist/identity/service.js +62 -5
  161. package/dist/identity/service.js.map +1 -1
  162. package/dist/integrations/events.d.ts +3 -3
  163. package/dist/integrations/model.js +1 -1
  164. package/dist/integrations/model.js.map +1 -1
  165. package/dist/integrations/service.js +2 -2
  166. package/dist/integrations/service.js.map +1 -1
  167. package/dist/organizations/access-scopes.d.ts +19 -0
  168. package/dist/organizations/access-scopes.js +89 -0
  169. package/dist/organizations/access-scopes.js.map +1 -0
  170. package/dist/organizations/events.d.ts +75 -33
  171. package/dist/organizations/events.js +6 -0
  172. package/dist/organizations/events.js.map +1 -1
  173. package/dist/organizations/index.d.ts +8 -6
  174. package/dist/organizations/index.js +5 -3
  175. package/dist/organizations/members.d.ts +8 -5
  176. package/dist/organizations/members.js.map +1 -1
  177. package/dist/organizations/notification-categories.d.ts +32 -0
  178. package/dist/organizations/notification-categories.js +51 -0
  179. package/dist/organizations/notification-categories.js.map +1 -0
  180. package/dist/organizations/ports.d.ts +17 -11
  181. package/dist/organizations/roles.d.ts +6 -10
  182. package/dist/organizations/roles.js +19 -7
  183. package/dist/organizations/roles.js.map +1 -1
  184. package/dist/organizations/service.d.ts +22 -11
  185. package/dist/organizations/service.js +164 -47
  186. package/dist/organizations/service.js.map +1 -1
  187. package/dist/organizations/types.d.ts +1 -10
  188. package/dist/progress/events.d.ts +14 -14
  189. package/dist/progress/index.d.ts +2 -2
  190. package/dist/progress/ports.d.ts +6 -1
  191. package/dist/progress/service.d.ts +3 -1
  192. package/dist/progress/service.js +6 -2
  193. package/dist/progress/service.js.map +1 -1
  194. package/dist/reporting/admin/index.d.ts +4 -0
  195. package/dist/reporting/admin/index.js +2 -0
  196. package/dist/reporting/admin/model.d.ts +108 -0
  197. package/dist/reporting/admin/ports.d.ts +27 -0
  198. package/dist/reporting/admin/service.d.ts +22 -0
  199. package/dist/reporting/admin/service.js +38 -0
  200. package/dist/reporting/admin/service.js.map +1 -0
  201. package/dist/reporting/member/index.d.ts +5 -0
  202. package/dist/reporting/member/index.js +2 -0
  203. package/dist/reporting/member/model.d.ts +157 -0
  204. package/dist/reporting/member/ports.d.ts +48 -0
  205. package/dist/reporting/member/service.d.ts +92 -0
  206. package/dist/reporting/member/service.js +364 -0
  207. package/dist/reporting/member/service.js.map +1 -0
  208. package/dist/shared/actor.d.ts +9 -0
  209. package/dist/shared/errors.d.ts +19 -1
  210. package/dist/shared/errors.js +27 -1
  211. package/dist/shared/errors.js.map +1 -1
  212. package/dist/shared/id.d.ts +14 -0
  213. package/dist/shared/id.js +15 -1
  214. package/dist/shared/id.js.map +1 -1
  215. package/dist/shared/mailer.d.ts +15 -2
  216. package/dist/shared/mailer.js +32 -5
  217. package/dist/shared/mailer.js.map +1 -1
  218. package/dist/shared/network.d.ts +10 -0
  219. package/dist/shared/network.js +211 -0
  220. package/dist/shared/network.js.map +1 -0
  221. package/dist/shared/notification-categories.d.ts +16 -0
  222. package/dist/shared/notification-categories.js +94 -0
  223. package/dist/shared/notification-categories.js.map +1 -0
  224. package/dist/shared/notification-settings.d.ts +14 -0
  225. package/dist/shared/notification-settings.js +61 -0
  226. package/dist/shared/notification-settings.js.map +1 -0
  227. package/dist/shared/ports.d.ts +48 -2
  228. package/dist/shared/settings.d.ts +2 -1
  229. package/dist/shared/settings.js +1 -0
  230. package/dist/shared/settings.js.map +1 -1
  231. package/dist/types/assets.d.ts +2 -2
  232. package/dist/types/automations.d.ts +15 -1
  233. package/dist/types/content.d.ts +2 -2
  234. package/dist/types/discussion.d.ts +11 -3
  235. package/dist/types/email-templates.d.ts +216 -1
  236. package/dist/types/entitlements.d.ts +2 -2
  237. package/dist/types/identity.d.ts +48 -2
  238. package/dist/types/index.d.ts +9 -8
  239. package/dist/types/notifications.d.ts +157 -0
  240. package/dist/types/ports.d.ts +6 -0
  241. package/dist/types/schemas/assets.d.ts +65 -37
  242. package/dist/types/schemas/assets.js +17 -12
  243. package/dist/types/schemas/assets.js.map +1 -1
  244. package/dist/types/schemas/automations.d.ts +9 -1
  245. package/dist/types/schemas/automations.js +13 -6
  246. package/dist/types/schemas/automations.js.map +1 -1
  247. package/dist/types/schemas/content.d.ts +396 -3
  248. package/dist/types/schemas/content.js +161 -3
  249. package/dist/types/schemas/content.js.map +1 -1
  250. package/dist/types/schemas/discussion.d.ts +443 -3
  251. package/dist/types/schemas/discussion.js +233 -4
  252. package/dist/types/schemas/discussion.js.map +1 -1
  253. package/dist/types/schemas/entitlements.d.ts +36 -2
  254. package/dist/types/schemas/entitlements.js +23 -1
  255. package/dist/types/schemas/entitlements.js.map +1 -1
  256. package/dist/types/schemas/identity.d.ts +27 -1
  257. package/dist/types/schemas/identity.js +14 -2
  258. package/dist/types/schemas/identity.js.map +1 -1
  259. package/dist/types/schemas/index.d.ts +9 -8
  260. package/dist/types/schemas/index.js +9 -8
  261. package/dist/types/schemas/notifications.d.ts +95 -0
  262. package/dist/types/schemas/notifications.js +56 -0
  263. package/dist/types/schemas/notifications.js.map +1 -0
  264. package/dist/types/schemas/organizations.d.ts +8 -0
  265. package/dist/types/schemas/organizations.js +2 -0
  266. package/dist/types/schemas/organizations.js.map +1 -1
  267. package/dist/types/schemas/progress.d.ts +3 -3
  268. package/dist/types/schemas/shared.d.ts +3 -1
  269. package/dist/types/schemas/shared.js +5 -1
  270. package/dist/types/schemas/shared.js.map +1 -1
  271. package/package.json +2 -2
  272. package/dist/reporting/courses/index.d.ts +0 -4
  273. package/dist/reporting/courses/index.js +0 -2
  274. package/dist/reporting/courses/model.d.ts +0 -24
  275. package/dist/reporting/courses/ports.d.ts +0 -13
  276. package/dist/reporting/courses/service.d.ts +0 -19
  277. package/dist/reporting/courses/service.js +0 -20
  278. package/dist/reporting/courses/service.js.map +0 -1
  279. package/dist/reporting/dashboard/index.d.ts +0 -4
  280. package/dist/reporting/dashboard/index.js +0 -2
  281. package/dist/reporting/dashboard/model.d.ts +0 -14
  282. package/dist/reporting/dashboard/ports.d.ts +0 -13
  283. package/dist/reporting/dashboard/service.d.ts +0 -19
  284. package/dist/reporting/dashboard/service.js +0 -20
  285. package/dist/reporting/dashboard/service.js.map +0 -1
  286. package/dist/reporting/learn/index.d.ts +0 -5
  287. package/dist/reporting/learn/index.js +0 -2
  288. package/dist/reporting/learn/model.d.ts +0 -23
  289. package/dist/reporting/learn/ports.d.ts +0 -43
  290. package/dist/reporting/learn/service.d.ts +0 -49
  291. package/dist/reporting/learn/service.js +0 -116
  292. package/dist/reporting/learn/service.js.map +0 -1
  293. package/dist/reporting/students/index.d.ts +0 -4
  294. package/dist/reporting/students/index.js +0 -2
  295. package/dist/reporting/students/model.d.ts +0 -51
  296. package/dist/reporting/students/model.js +0 -1
  297. package/dist/reporting/students/ports.d.ts +0 -15
  298. package/dist/reporting/students/ports.js +0 -1
  299. package/dist/reporting/students/service.d.ts +0 -20
  300. package/dist/reporting/students/service.js +0 -23
  301. package/dist/reporting/students/service.js.map +0 -1
  302. /package/dist/reporting/{courses → admin}/model.js +0 -0
  303. /package/dist/reporting/{courses → admin}/ports.js +0 -0
  304. /package/dist/reporting/{dashboard → member}/model.js +0 -0
  305. /package/dist/reporting/{dashboard → member}/ports.js +0 -0
  306. /package/dist/{reporting/learn/model.js → shared/actor.js} +0 -0
  307. /package/dist/{reporting/learn/ports.js → types/notifications.js} +0 -0
@@ -1,23 +0,0 @@
1
- import { Activity, Course, Download, DownloadAsset, Module } from "../../types/schemas/content.js";
2
- import "../../content/index.js";
3
- //#region src/reporting/learn/model.d.ts
4
- /** An active-entitlement pointer: the org + content item a student may consume. */
5
- interface ContentRef {
6
- orgId: string;
7
- contentId: string;
8
- }
9
- /** Per-course progress for the student surface. Derived on read against the
10
- * current published structure — never stored. */
11
- interface CourseProgressView {
12
- /** Keyed by activity id; absent key = not started. */
13
- activities: Record<string, 'in-progress' | 'completed'>;
14
- /** Integer 0–100: completed ÷ current published activities, rounded. */
15
- percent: number;
16
- /** The course target's own record says so. */
17
- completed: boolean;
18
- /** Per-activity reported state (the record's position map); absent key = none reported. */
19
- positions: Record<string, unknown>;
20
- }
21
- //#endregion
22
- export { type Activity, ContentRef, type Course, CourseProgressView, type Download, type DownloadAsset, type Module };
23
- //# sourceMappingURL=model.d.ts.map
@@ -1,43 +0,0 @@
1
- import { Activity, Course, Download, DownloadAsset, Module } from "../../types/schemas/content.js";
2
- import { ContentRef, CourseProgressView } from "./model.js";
3
- //#region src/reporting/learn/ports.d.ts
4
- /**
5
- * Inbound: the student-scoped read use-cases. Scoped by `(orgId, orgUserId)` —
6
- * the portal org resolved at the boundary. `null` ⇒ not enrolled (→ 404).
7
- */
8
- interface LearnReportService {
9
- listCourses(orgId: string, orgUserId: string): Promise<Course[]>;
10
- getCourse(orgId: string, orgUserId: string, courseId: string): Promise<Course | null>;
11
- listModules(orgId: string, orgUserId: string, courseId: string): Promise<Module[] | null>;
12
- listActivities(orgId: string, orgUserId: string, courseId: string): Promise<Activity[] | null>;
13
- courseProgress(orgId: string, orgUserId: string, courseId: string): Promise<CourseProgressView | null>;
14
- listDownloads(orgId: string, orgUserId: string): Promise<Download[]>;
15
- getDownload(orgId: string, orgUserId: string, downloadId: string): Promise<{
16
- download: Download;
17
- assets: DownloadAsset[];
18
- } | null>;
19
- /** Entitlement-gated. Returns null (→ 404) for every failure — never 403,
20
- * which would confirm the resource exists to someone not entitled to it. */
21
- downloadAssetUrl(orgId: string, orgUserId: string, downloadId: string, assetId: string): Promise<{
22
- url: string;
23
- filename: string;
24
- } | null>;
25
- }
26
- /**
27
- * Outbound: the student's active, non-expired course entitlements in PUBLISHED
28
- * courses, scoped to the portal org. Implemented by a Drizzle read repo; the
29
- * service resolves each ref against the content service for the full
30
- * Course/Module payload.
31
- */
32
- interface LearnEntitlementReader {
33
- activeRefs(orgId: string, orgUserId: string): Promise<ContentRef[]>;
34
- activeRef(orgId: string, orgUserId: string, courseId: string): Promise<ContentRef | null>;
35
- /** Active, non-expired grants to PUBLISHED downloads, scoped to the org. */
36
- activeDownloadRefs(orgId: string, orgUserId: string): Promise<ContentRef[]>;
37
- activeDownloadRef(orgId: string, orgUserId: string, downloadId: string): Promise<ContentRef | null>;
38
- /** Whether this asset is linked to this download. The paywall's second gate. */
39
- downloadHasAsset(orgId: string, downloadId: string, assetId: string): Promise<boolean>;
40
- }
41
- //#endregion
42
- export { LearnEntitlementReader, LearnReportService };
43
- //# sourceMappingURL=ports.d.ts.map
@@ -1,49 +0,0 @@
1
- import { Logger } from "../../types/ports.js";
2
- import { Activity, Course, Download, DownloadAsset, Module } from "../../types/schemas/content.js";
3
- import "../../shared/ports.js";
4
- import { AssetsService } from "../../assets/ports.js";
5
- import "../../assets/index.js";
6
- import { ContentService } from "../../content/ports.js";
7
- import "../../content/index.js";
8
- import { ProgressService } from "../../progress/ports.js";
9
- import "../../progress/index.js";
10
- import { CourseProgressView } from "./model.js";
11
- import { LearnEntitlementReader, LearnReportService } from "./ports.js";
12
- //#region src/reporting/learn/service.d.ts
13
- type LearnReportServiceParams = {
14
- reader: LearnEntitlementReader;
15
- content: ContentService;
16
- progress: ProgressService;
17
- assets: AssetsService;
18
- deliveryExpirySeconds: number;
19
- logger?: Logger;
20
- };
21
- declare class LearnReportServiceImpl implements LearnReportService {
22
- private readonly reader;
23
- private readonly content;
24
- private readonly progress;
25
- private readonly assets;
26
- private readonly deliveryExpirySeconds;
27
- private readonly logger;
28
- constructor(params: LearnReportServiceParams);
29
- listCourses(orgId: string, orgUserId: string): Promise<Course[]>;
30
- getCourse(orgId: string, orgUserId: string, courseId: string): Promise<Course | null>;
31
- listModules(orgId: string, orgUserId: string, courseId: string): Promise<Module[] | null>;
32
- listActivities(orgId: string, orgUserId: string, courseId: string): Promise<Activity[] | null>;
33
- courseProgress(orgId: string, orgUserId: string, courseId: string): Promise<CourseProgressView | null>;
34
- listDownloads(orgId: string, orgUserId: string): Promise<Download[]>;
35
- getDownload(orgId: string, orgUserId: string, downloadId: string): Promise<{
36
- download: Download;
37
- assets: DownloadAsset[];
38
- } | null>;
39
- /** The paywall. Two gates, in order: an active entitlement to a published
40
- * download, then the asset actually belonging to that download — so a
41
- * student entitled to X cannot reach an asset of Y by swapping the id. */
42
- downloadAssetUrl(orgId: string, orgUserId: string, downloadId: string, assetId: string): Promise<{
43
- url: string;
44
- filename: string;
45
- } | null>;
46
- }
47
- //#endregion
48
- export { LearnReportServiceImpl, LearnReportServiceParams };
49
- //# sourceMappingURL=service.d.ts.map
@@ -1,116 +0,0 @@
1
- import { noopLogger } from "../../shared/logger.js";
2
- //#region src/reporting/learn/service.ts
3
- function isActivityPublished(settings) {
4
- return settings?.published !== false;
5
- }
6
- var LearnReportServiceImpl = class {
7
- reader;
8
- content;
9
- progress;
10
- assets;
11
- deliveryExpirySeconds;
12
- logger;
13
- constructor(params) {
14
- this.reader = params.reader;
15
- this.content = params.content;
16
- this.progress = params.progress;
17
- this.assets = params.assets;
18
- this.deliveryExpirySeconds = params.deliveryExpirySeconds;
19
- this.logger = params.logger ?? noopLogger;
20
- }
21
- async listCourses(orgId, orgUserId) {
22
- const refs = await this.reader.activeRefs(orgId, orgUserId);
23
- return (await Promise.all(refs.map((ref) => this.content.getCourse(ref.orgId, ref.contentId)))).filter((c) => c !== null && c.status === "published");
24
- }
25
- async getCourse(orgId, orgUserId, courseId) {
26
- const ref = await this.reader.activeRef(orgId, orgUserId, courseId);
27
- if (!ref) return null;
28
- const course = await this.content.getCourse(ref.orgId, courseId);
29
- return course && course.status === "published" ? course : null;
30
- }
31
- async listModules(orgId, orgUserId, courseId) {
32
- const ref = await this.reader.activeRef(orgId, orgUserId, courseId);
33
- if (!ref) return null;
34
- return this.content.listCourseModules(ref.orgId, courseId);
35
- }
36
- async listActivities(orgId, orgUserId, courseId) {
37
- const ref = await this.reader.activeRef(orgId, orgUserId, courseId);
38
- if (!ref) return null;
39
- return (await this.content.listCourseActivities(ref.orgId, courseId)).filter((a) => isActivityPublished(a.settings));
40
- }
41
- async courseProgress(orgId, orgUserId, courseId) {
42
- const ref = await this.reader.activeRef(orgId, orgUserId, courseId);
43
- if (!ref) return null;
44
- const ids = (await this.content.listCourseActivities(ref.orgId, courseId)).filter((a) => isActivityPublished(a.settings)).map((a) => a.id);
45
- const records = await this.progress.listByTargets(ref.orgId, orgUserId, ids);
46
- const activities = {};
47
- const positions = {};
48
- let done = 0;
49
- for (const r of records) {
50
- if (r.targetType !== "activity") continue;
51
- activities[r.targetId] = r.completedAt ? "completed" : "in-progress";
52
- if (r.completedAt) done += 1;
53
- if (r.position != null) positions[r.targetId] = r.position;
54
- }
55
- const courseRecord = await this.progress.get(ref.orgId, {
56
- orgUserId,
57
- targetType: "course",
58
- targetId: courseId
59
- });
60
- return {
61
- activities,
62
- percent: ids.length > 0 ? Math.round(done / ids.length * 100) : 0,
63
- completed: courseRecord?.completedAt != null,
64
- positions
65
- };
66
- }
67
- async listDownloads(orgId, orgUserId) {
68
- const refs = await this.reader.activeDownloadRefs(orgId, orgUserId);
69
- return (await Promise.all(refs.map((ref) => this.content.getDownload(ref.orgId, ref.contentId)))).filter((d) => d !== null && d.status === "published");
70
- }
71
- async getDownload(orgId, orgUserId, downloadId) {
72
- const ref = await this.reader.activeDownloadRef(orgId, orgUserId, downloadId);
73
- if (!ref) return null;
74
- const download = await this.content.getDownload(ref.orgId, downloadId);
75
- if (!download || download.status !== "published") return null;
76
- return {
77
- download,
78
- assets: await this.content.listDownloadAssets(ref.orgId, downloadId)
79
- };
80
- }
81
- /** The paywall. Two gates, in order: an active entitlement to a published
82
- * download, then the asset actually belonging to that download — so a
83
- * student entitled to X cannot reach an asset of Y by swapping the id. */
84
- async downloadAssetUrl(orgId, orgUserId, downloadId, assetId) {
85
- const ref = await this.reader.activeDownloadRef(orgId, orgUserId, downloadId);
86
- if (!ref) return null;
87
- if (!await this.reader.downloadHasAsset(ref.orgId, downloadId, assetId)) {
88
- this.logger.warn("download asset not linked", {
89
- orgId,
90
- downloadId,
91
- assetId
92
- });
93
- return null;
94
- }
95
- const link = (await this.content.listDownloadAssets(ref.orgId, downloadId)).find((l) => l.assetId === assetId);
96
- if (!link) return null;
97
- const asset = await this.assets.get(ref.orgId, assetId);
98
- if (!asset) return null;
99
- const filename = link.displayName ?? asset.filename;
100
- const ticket = await this.assets.requestDownload(ref.orgId, assetId, filename, this.deliveryExpirySeconds);
101
- if (!ticket) return null;
102
- this.logger.info("download asset signed", {
103
- orgId,
104
- downloadId,
105
- assetId
106
- });
107
- return {
108
- url: ticket.url,
109
- filename
110
- };
111
- }
112
- };
113
- //#endregion
114
- export { LearnReportServiceImpl };
115
-
116
- //# sourceMappingURL=service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"service.js","names":[],"sources":["../../../src/reporting/learn/service.ts"],"sourcesContent":["import { type ContentServicePort } from '../../content/index.js';\nimport type { ProgressService } from '../../progress/index.js';\nimport type { AssetsService } from '../../assets/index.js';\nimport type {\n Activity,\n Course,\n CourseProgressView,\n Download,\n DownloadAsset,\n Module,\n} from './model.js';\nimport type { LearnEntitlementReader, LearnReportService } from './ports.js';\nimport type { Logger } from '../../shared/ports.js';\nimport { noopLogger } from '../../shared/logger.js';\n\nfunction isActivityPublished(settings: unknown): boolean {\n return (settings as { published?: boolean } | null)?.published !== false;\n}\n\nexport type LearnReportServiceParams = {\n reader: LearnEntitlementReader;\n content: ContentServicePort;\n progress: ProgressService;\n assets: AssetsService;\n deliveryExpirySeconds: number;\n logger?: Logger;\n};\n\nexport class LearnReportServiceImpl implements LearnReportService {\n private readonly reader: LearnEntitlementReader;\n private readonly content: ContentServicePort;\n private readonly progress: ProgressService;\n private readonly assets: AssetsService;\n private readonly deliveryExpirySeconds: number;\n private readonly logger: Logger;\n\n constructor(params: LearnReportServiceParams) {\n this.reader = params.reader;\n this.content = params.content;\n this.progress = params.progress;\n this.assets = params.assets;\n this.deliveryExpirySeconds = params.deliveryExpirySeconds;\n this.logger = params.logger ?? noopLogger;\n }\n\n async listCourses(orgId: string, orgUserId: string): Promise<Course[]> {\n const refs = await this.reader.activeRefs(orgId, orgUserId);\n const courses = await Promise.all(\n refs.map((ref) => this.content.getCourse(ref.orgId, ref.contentId)),\n );\n return courses.filter((c): c is Course => c !== null && c.status === 'published');\n }\n\n async getCourse(orgId: string, orgUserId: string, courseId: string): Promise<Course | null> {\n const ref = await this.reader.activeRef(orgId, orgUserId, courseId);\n if (!ref) {\n return null;\n }\n const course = await this.content.getCourse(ref.orgId, courseId);\n return course && course.status === 'published' ? course : null;\n }\n\n async listModules(orgId: string, orgUserId: string, courseId: string): Promise<Module[] | null> {\n const ref = await this.reader.activeRef(orgId, orgUserId, courseId);\n if (!ref) {\n return null;\n }\n return this.content.listCourseModules(ref.orgId, courseId);\n }\n\n async listActivities(\n orgId: string,\n orgUserId: string,\n courseId: string,\n ): Promise<Activity[] | null> {\n const ref = await this.reader.activeRef(orgId, orgUserId, courseId);\n if (!ref) {\n return null;\n }\n const activities = await this.content.listCourseActivities(ref.orgId, courseId);\n return activities.filter((a) => isActivityPublished(a.settings));\n }\n\n async courseProgress(\n orgId: string,\n orgUserId: string,\n courseId: string,\n ): Promise<CourseProgressView | null> {\n const ref = await this.reader.activeRef(orgId, orgUserId, courseId);\n if (!ref) {\n return null;\n }\n const courseActivities = await this.content.listCourseActivities(ref.orgId, courseId);\n const ids = courseActivities.filter((a) => isActivityPublished(a.settings)).map((a) => a.id);\n const records = await this.progress.listByTargets(ref.orgId, orgUserId, ids);\n const activities: CourseProgressView['activities'] = {};\n const positions: CourseProgressView['positions'] = {};\n let done = 0;\n for (const r of records) {\n if (r.targetType !== 'activity') {\n continue;\n }\n activities[r.targetId] = r.completedAt ? 'completed' : 'in-progress';\n if (r.completedAt) {\n done += 1;\n }\n if (r.position != null) {\n positions[r.targetId] = r.position;\n }\n }\n const courseRecord = await this.progress.get(ref.orgId, {\n orgUserId,\n targetType: 'course',\n targetId: courseId,\n });\n return {\n activities,\n percent: ids.length > 0 ? Math.round((done / ids.length) * 100) : 0,\n completed: courseRecord?.completedAt != null,\n positions,\n };\n }\n\n async listDownloads(orgId: string, orgUserId: string): Promise<Download[]> {\n const refs = await this.reader.activeDownloadRefs(orgId, orgUserId);\n const rows = await Promise.all(\n refs.map((ref) => this.content.getDownload(ref.orgId, ref.contentId)),\n );\n return rows.filter((d): d is Download => d !== null && d.status === 'published');\n }\n\n async getDownload(\n orgId: string,\n orgUserId: string,\n downloadId: string,\n ): Promise<{ download: Download; assets: DownloadAsset[] } | null> {\n const ref = await this.reader.activeDownloadRef(orgId, orgUserId, downloadId);\n if (!ref) {\n return null;\n }\n const download = await this.content.getDownload(ref.orgId, downloadId);\n if (!download || download.status !== 'published') {\n return null;\n }\n const assets = await this.content.listDownloadAssets(ref.orgId, downloadId);\n return { download, assets };\n }\n\n /** The paywall. Two gates, in order: an active entitlement to a published\n * download, then the asset actually belonging to that download — so a\n * student entitled to X cannot reach an asset of Y by swapping the id. */\n async downloadAssetUrl(\n orgId: string,\n orgUserId: string,\n downloadId: string,\n assetId: string,\n ): Promise<{ url: string; filename: string } | null> {\n const ref = await this.reader.activeDownloadRef(orgId, orgUserId, downloadId);\n if (!ref) {\n return null;\n }\n const linked = await this.reader.downloadHasAsset(ref.orgId, downloadId, assetId);\n if (!linked) {\n this.logger.warn('download asset not linked', { orgId, downloadId, assetId });\n return null;\n }\n const links = await this.content.listDownloadAssets(ref.orgId, downloadId);\n const link = links.find((l) => l.assetId === assetId);\n if (!link) {\n return null;\n }\n const asset = await this.assets.get(ref.orgId, assetId);\n if (!asset) {\n return null;\n }\n const filename = link.displayName ?? asset.filename;\n const ticket = await this.assets.requestDownload(\n ref.orgId,\n assetId,\n filename,\n this.deliveryExpirySeconds,\n );\n if (!ticket) {\n return null;\n }\n // Never log the signed URL — it is a bearer capability.\n this.logger.info('download asset signed', { orgId, downloadId, assetId });\n return { url: ticket.url, filename };\n }\n}\n"],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- import { Page, Student, StudentAnalytics, StudentCourseProgress, StudentsQuery } from "./model.js";
2
- import { StudentsReportRepository, StudentsReportService } from "./ports.js";
3
- import { StudentsReportServiceImpl } from "./service.js";
4
- export { type Page, type Student, type StudentAnalytics, type StudentCourseProgress, type StudentsQuery, type StudentsReportRepository, type StudentsReportService, StudentsReportServiceImpl };
@@ -1,2 +0,0 @@
1
- import { StudentsReportServiceImpl } from "./service.js";
2
- export { StudentsReportServiceImpl };
@@ -1,51 +0,0 @@
1
- import { OrgUserProfile, OrgUserStatus } from "../../types/schemas/organizations.js";
2
- import "../../types/index.js";
3
- //#region src/reporting/students/model.d.ts
4
- interface Student extends OrgUserProfile {
5
- /** As typed on the invite form. `name` is the composed rendering name and
6
- * drifts once the person edits their own profile; these are what the admin
7
- * edits. Null for anyone who arrived by self-signup. */
8
- firstName: string | null;
9
- lastName: string | null;
10
- entitlementCount: number;
11
- avgProgress: number;
12
- /** `invited` until they accept — the admin added them, they have not arrived. */
13
- status: OrgUserStatus;
14
- joinedAt: string;
15
- lastActiveAt: string | null;
16
- }
17
- interface StudentCourseProgress {
18
- courseId: string;
19
- title: string;
20
- /** Published activities in the course. */
21
- totalActivities: number;
22
- completedActivities: number;
23
- /** 0–100, completed published activities over the total. */
24
- progress: number;
25
- startedAt: string | null;
26
- lastActivityAt: string | null;
27
- completedAt: string | null;
28
- }
29
- interface StudentAnalytics {
30
- enrolled: number;
31
- started: number;
32
- completed: number;
33
- /** Mean of the per-course progress percentages (0–100). */
34
- avgProgress: number;
35
- courses: StudentCourseProgress[];
36
- }
37
- interface StudentsQuery {
38
- page: number;
39
- pageSize: number;
40
- search?: string | undefined;
41
- sort?: string | undefined;
42
- }
43
- interface Page<T> {
44
- rows: T[];
45
- total: number;
46
- page: number;
47
- pageSize: number;
48
- }
49
- //#endregion
50
- export { Page, Student, StudentAnalytics, StudentCourseProgress, StudentsQuery };
51
- //# sourceMappingURL=model.d.ts.map
@@ -1 +0,0 @@
1
- export {};
@@ -1,15 +0,0 @@
1
- import { Page, Student, StudentAnalytics, StudentsQuery } from "./model.js";
2
- //#region src/reporting/students/ports.d.ts
3
- interface StudentsReportService {
4
- list(orgId: string, query: StudentsQuery): Promise<Page<Student>>;
5
- get(orgId: string, id: string): Promise<Student | null>;
6
- analytics(orgId: string, id: string): Promise<StudentAnalytics | null>;
7
- }
8
- interface StudentsReportRepository {
9
- list(orgId: string, query: StudentsQuery): Promise<Page<Student>>;
10
- findById(orgId: string, id: string): Promise<Student | null>;
11
- analytics(orgId: string, id: string): Promise<StudentAnalytics | null>;
12
- }
13
- //#endregion
14
- export { StudentsReportRepository, StudentsReportService };
15
- //# sourceMappingURL=ports.d.ts.map
@@ -1 +0,0 @@
1
- export {};
@@ -1,20 +0,0 @@
1
- import { Logger } from "../../types/ports.js";
2
- import "../../shared/ports.js";
3
- import { Page, Student, StudentAnalytics, StudentsQuery } from "./model.js";
4
- import { StudentsReportRepository, StudentsReportService } from "./ports.js";
5
- //#region src/reporting/students/service.d.ts
6
- type StudentsReportServiceParams = {
7
- repo: StudentsReportRepository;
8
- logger?: Logger;
9
- };
10
- declare class StudentsReportServiceImpl implements StudentsReportService {
11
- private readonly repo;
12
- private readonly logger;
13
- constructor(params: StudentsReportServiceParams);
14
- list(orgId: string, query: StudentsQuery): Promise<Page<Student>>;
15
- get(orgId: string, id: string): Promise<Student | null>;
16
- analytics(orgId: string, id: string): Promise<StudentAnalytics | null>;
17
- }
18
- //#endregion
19
- export { StudentsReportServiceImpl, StudentsReportServiceParams };
20
- //# sourceMappingURL=service.d.ts.map
@@ -1,23 +0,0 @@
1
- import { noopLogger } from "../../shared/logger.js";
2
- //#region src/reporting/students/service.ts
3
- var StudentsReportServiceImpl = class {
4
- repo;
5
- logger;
6
- constructor(params) {
7
- this.repo = params.repo;
8
- this.logger = params.logger ?? noopLogger;
9
- }
10
- list(orgId, query) {
11
- return this.repo.list(orgId, query);
12
- }
13
- get(orgId, id) {
14
- return this.repo.findById(orgId, id);
15
- }
16
- analytics(orgId, id) {
17
- return this.repo.analytics(orgId, id);
18
- }
19
- };
20
- //#endregion
21
- export { StudentsReportServiceImpl };
22
-
23
- //# sourceMappingURL=service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"service.js","names":[],"sources":["../../../src/reporting/students/service.ts"],"sourcesContent":["// reporting/students — service implementation (inbound port).\nimport type { Page, Student, StudentAnalytics, StudentsQuery } from './model.js';\nimport type { StudentsReportRepository, StudentsReportService } from './ports.js';\nimport type { Logger } from '../../shared/ports.js';\nimport { noopLogger } from '../../shared/logger.js';\n\nexport type StudentsReportServiceParams = {\n repo: StudentsReportRepository;\n logger?: Logger;\n};\n\nexport class StudentsReportServiceImpl implements StudentsReportService {\n private readonly repo: StudentsReportRepository;\n private readonly logger: Logger;\n\n constructor(params: StudentsReportServiceParams) {\n this.repo = params.repo;\n this.logger = params.logger ?? noopLogger;\n }\n\n list(orgId: string, query: StudentsQuery): Promise<Page<Student>> {\n return this.repo.list(orgId, query);\n }\n\n get(orgId: string, id: string): Promise<Student | null> {\n return this.repo.findById(orgId, id);\n }\n\n analytics(orgId: string, id: string): Promise<StudentAnalytics | null> {\n return this.repo.analytics(orgId, id);\n }\n}\n"],"mappings":";;AAWA,IAAa,4BAAb,MAAwE;CACtE;CACA;CAEA,YAAY,QAAqC;EAC/C,KAAK,OAAO,OAAO;EACnB,KAAK,SAAS,OAAO,UAAU;CACjC;CAEA,KAAK,OAAe,OAA8C;EAChE,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK;CACpC;CAEA,IAAI,OAAe,IAAqC;EACtD,OAAO,KAAK,KAAK,SAAS,OAAO,EAAE;CACrC;CAEA,UAAU,OAAe,IAA8C;EACrE,OAAO,KAAK,KAAK,UAAU,OAAO,EAAE;CACtC;AACF"}
File without changes
File without changes
File without changes
File without changes