@headless-lms/core 0.1.0 → 0.3.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 (249) hide show
  1. package/dist/assets/events.d.ts +90 -9
  2. package/dist/assets/events.js +19 -3
  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 +5 -4
  8. package/dist/assets/index.js +3 -2
  9. package/dist/assets/model.d.ts +2 -2
  10. package/dist/assets/ports.d.ts +45 -15
  11. package/dist/assets/service.d.ts +39 -7
  12. package/dist/assets/service.js +292 -37
  13. package/dist/assets/service.js.map +1 -1
  14. package/dist/automations/actions.d.ts +12 -15
  15. package/dist/automations/actions.js +188 -30
  16. package/dist/automations/actions.js.map +1 -1
  17. package/dist/automations/catalog.d.ts +5 -1
  18. package/dist/automations/catalog.js +514 -197
  19. package/dist/automations/catalog.js.map +1 -1
  20. package/dist/automations/community-derivations.d.ts +14 -0
  21. package/dist/automations/community-derivations.js +439 -0
  22. package/dist/automations/community-derivations.js.map +1 -0
  23. package/dist/automations/community-mail.d.ts +112 -0
  24. package/dist/automations/community-mail.js +90 -0
  25. package/dist/automations/community-mail.js.map +1 -0
  26. package/dist/automations/community-notifications.d.ts +16 -0
  27. package/dist/automations/community-notifications.js +84 -0
  28. package/dist/automations/community-notifications.js.map +1 -0
  29. package/dist/automations/events.d.ts +74 -24
  30. package/dist/automations/events.js +5 -5
  31. package/dist/automations/events.js.map +1 -1
  32. package/dist/automations/index.d.ts +7 -5
  33. package/dist/automations/index.js +3 -2
  34. package/dist/automations/model.d.ts +20 -3
  35. package/dist/automations/model.js +36 -3
  36. package/dist/automations/model.js.map +1 -1
  37. package/dist/automations/ports.d.ts +27 -8
  38. package/dist/automations/schedule.d.ts +6 -0
  39. package/dist/automations/schedule.js +41 -0
  40. package/dist/automations/schedule.js.map +1 -0
  41. package/dist/automations/seeds.d.ts +17 -0
  42. package/dist/automations/seeds.js +235 -0
  43. package/dist/automations/seeds.js.map +1 -0
  44. package/dist/automations/service.d.ts +41 -6
  45. package/dist/automations/service.js +542 -59
  46. package/dist/automations/service.js.map +1 -1
  47. package/dist/automations/types.d.ts +2 -2
  48. package/dist/automations/webhook-signing.d.ts +7 -0
  49. package/dist/automations/webhook-signing.js +22 -0
  50. package/dist/automations/webhook-signing.js.map +1 -0
  51. package/dist/content/events.d.ts +1013 -25
  52. package/dist/content/events.js +168 -19
  53. package/dist/content/events.js.map +1 -1
  54. package/dist/content/index.d.ts +5 -5
  55. package/dist/content/index.js +2 -2
  56. package/dist/content/model.d.ts +2 -2
  57. package/dist/content/ports.d.ts +109 -25
  58. package/dist/content/service.d.ts +68 -23
  59. package/dist/content/service.js +647 -60
  60. package/dist/content/service.js.map +1 -1
  61. package/dist/content/types.d.ts +2 -2
  62. package/dist/discussion/authors.d.ts +10 -0
  63. package/dist/discussion/authors.js +23 -0
  64. package/dist/discussion/authors.js.map +1 -0
  65. package/dist/discussion/chats.d.ts +104 -0
  66. package/dist/discussion/chats.js +798 -0
  67. package/dist/discussion/chats.js.map +1 -0
  68. package/dist/discussion/events.d.ts +633 -14
  69. package/dist/discussion/events.js +134 -5
  70. package/dist/discussion/events.js.map +1 -1
  71. package/dist/discussion/index.d.ts +7 -3
  72. package/dist/discussion/index.js +4 -1
  73. package/dist/discussion/model.d.ts +1 -2
  74. package/dist/discussion/ports.d.ts +288 -27
  75. package/dist/discussion/ports.js +6 -1
  76. package/dist/discussion/ports.js.map +1 -0
  77. package/dist/discussion/posts.d.ts +103 -0
  78. package/dist/discussion/posts.js +723 -0
  79. package/dist/discussion/posts.js.map +1 -0
  80. package/dist/discussion/service.d.ts +33 -11
  81. package/dist/discussion/service.js +297 -81
  82. package/dist/discussion/service.js.map +1 -1
  83. package/dist/entitlements/events.d.ts +264 -13
  84. package/dist/entitlements/events.js +49 -5
  85. package/dist/entitlements/events.js.map +1 -1
  86. package/dist/entitlements/index.d.ts +5 -4
  87. package/dist/entitlements/index.js +2 -1
  88. package/dist/entitlements/model.d.ts +3 -2
  89. package/dist/entitlements/ports.d.ts +124 -11
  90. package/dist/entitlements/rules.d.ts +12 -0
  91. package/dist/entitlements/rules.js +17 -0
  92. package/dist/entitlements/rules.js.map +1 -0
  93. package/dist/entitlements/service.d.ts +54 -3
  94. package/dist/entitlements/service.js +473 -2
  95. package/dist/entitlements/service.js.map +1 -1
  96. package/dist/identity/access.d.ts +6 -0
  97. package/dist/identity/access.js +7 -0
  98. package/dist/identity/access.js.map +1 -0
  99. package/dist/identity/events.d.ts +17 -3
  100. package/dist/identity/events.js +12 -2
  101. package/dist/identity/events.js.map +1 -1
  102. package/dist/identity/index.d.ts +6 -4
  103. package/dist/identity/index.js +3 -1
  104. package/dist/identity/model.d.ts +2 -1
  105. package/dist/identity/notifications.d.ts +27 -0
  106. package/dist/identity/notifications.js +101 -0
  107. package/dist/identity/notifications.js.map +1 -0
  108. package/dist/identity/ports.d.ts +76 -3
  109. package/dist/identity/service.d.ts +17 -3
  110. package/dist/identity/service.js +73 -5
  111. package/dist/identity/service.js.map +1 -1
  112. package/dist/integrations/events.d.ts +27 -3
  113. package/dist/integrations/events.js +15 -3
  114. package/dist/integrations/events.js.map +1 -1
  115. package/dist/integrations/model.js +1 -1
  116. package/dist/integrations/model.js.map +1 -1
  117. package/dist/integrations/service.js +2 -2
  118. package/dist/integrations/service.js.map +1 -1
  119. package/dist/organizations/access-scopes.d.ts +19 -0
  120. package/dist/organizations/access-scopes.js +89 -0
  121. package/dist/organizations/access-scopes.js.map +1 -0
  122. package/dist/organizations/events.d.ts +234 -25
  123. package/dist/organizations/events.js +58 -9
  124. package/dist/organizations/events.js.map +1 -1
  125. package/dist/organizations/index.d.ts +8 -7
  126. package/dist/organizations/index.js +4 -3
  127. package/dist/organizations/members.d.ts +8 -5
  128. package/dist/organizations/members.js.map +1 -1
  129. package/dist/organizations/ports.d.ts +20 -21
  130. package/dist/organizations/roles.d.ts +6 -10
  131. package/dist/organizations/roles.js +19 -7
  132. package/dist/organizations/roles.js.map +1 -1
  133. package/dist/organizations/service.d.ts +28 -14
  134. package/dist/organizations/service.js +274 -105
  135. package/dist/organizations/service.js.map +1 -1
  136. package/dist/organizations/types.d.ts +2 -11
  137. package/dist/progress/events.d.ts +34 -2
  138. package/dist/progress/events.js +15 -2
  139. package/dist/progress/events.js.map +1 -1
  140. package/dist/progress/index.d.ts +2 -2
  141. package/dist/progress/ports.d.ts +6 -1
  142. package/dist/progress/service.d.ts +5 -3
  143. package/dist/progress/service.js +9 -3
  144. package/dist/progress/service.js.map +1 -1
  145. package/dist/reporting/admin/index.d.ts +4 -0
  146. package/dist/reporting/admin/index.js +2 -0
  147. package/dist/reporting/admin/model.d.ts +108 -0
  148. package/dist/reporting/admin/ports.d.ts +27 -0
  149. package/dist/reporting/admin/service.d.ts +22 -0
  150. package/dist/reporting/admin/service.js +38 -0
  151. package/dist/reporting/admin/service.js.map +1 -0
  152. package/dist/reporting/member/index.d.ts +5 -0
  153. package/dist/reporting/member/index.js +2 -0
  154. package/dist/reporting/member/model.d.ts +124 -0
  155. package/dist/reporting/member/ports.d.ts +45 -0
  156. package/dist/reporting/member/service.d.ts +73 -0
  157. package/dist/reporting/member/service.js +286 -0
  158. package/dist/reporting/member/service.js.map +1 -0
  159. package/dist/shared/actor.d.ts +9 -0
  160. package/dist/shared/errors.d.ts +7 -1
  161. package/dist/shared/errors.js +10 -1
  162. package/dist/shared/errors.js.map +1 -1
  163. package/dist/shared/events.d.ts +5 -3
  164. package/dist/shared/events.js +1 -0
  165. package/dist/shared/events.js.map +1 -1
  166. package/dist/shared/id.d.ts +12 -0
  167. package/dist/shared/id.js +13 -1
  168. package/dist/shared/id.js.map +1 -1
  169. package/dist/shared/mailer.d.ts +6 -1
  170. package/dist/shared/mailer.js.map +1 -1
  171. package/dist/shared/network.d.ts +10 -0
  172. package/dist/shared/network.js +211 -0
  173. package/dist/shared/network.js.map +1 -0
  174. package/dist/shared/settings.js.map +1 -1
  175. package/dist/types/assets.d.ts +2 -2
  176. package/dist/types/automations.d.ts +21 -2
  177. package/dist/types/content.d.ts +2 -2
  178. package/dist/types/discussion.d.ts +12 -3
  179. package/dist/types/email-templates.d.ts +124 -1
  180. package/dist/types/entitlements.d.ts +2 -2
  181. package/dist/types/events.d.ts +3 -3
  182. package/dist/types/identity.d.ts +48 -2
  183. package/dist/types/index.d.ts +10 -10
  184. package/dist/types/organizations.d.ts +2 -2
  185. package/dist/types/ports.d.ts +7 -1
  186. package/dist/types/schemas/assets.d.ts +67 -36
  187. package/dist/types/schemas/assets.js +19 -13
  188. package/dist/types/schemas/assets.js.map +1 -1
  189. package/dist/types/schemas/automations.d.ts +88 -4
  190. package/dist/types/schemas/automations.js +46 -6
  191. package/dist/types/schemas/automations.js.map +1 -1
  192. package/dist/types/schemas/content.d.ts +385 -20
  193. package/dist/types/schemas/content.js +178 -15
  194. package/dist/types/schemas/content.js.map +1 -1
  195. package/dist/types/schemas/credentials.js.map +1 -1
  196. package/dist/types/schemas/discussion.d.ts +379 -4
  197. package/dist/types/schemas/discussion.js +209 -7
  198. package/dist/types/schemas/discussion.js.map +1 -1
  199. package/dist/types/schemas/entitlements.d.ts +44 -4
  200. package/dist/types/schemas/entitlements.js +32 -4
  201. package/dist/types/schemas/entitlements.js.map +1 -1
  202. package/dist/types/schemas/identity.d.ts +115 -5
  203. package/dist/types/schemas/identity.js +59 -6
  204. package/dist/types/schemas/identity.js.map +1 -1
  205. package/dist/types/schemas/index.d.ts +9 -9
  206. package/dist/types/schemas/index.js +9 -9
  207. package/dist/types/schemas/integrations.js.map +1 -1
  208. package/dist/types/schemas/organizations.d.ts +27 -5
  209. package/dist/types/schemas/organizations.js +14 -7
  210. package/dist/types/schemas/organizations.js.map +1 -1
  211. package/dist/types/schemas/outbox.d.ts +1 -0
  212. package/dist/types/schemas/outbox.js +1 -0
  213. package/dist/types/schemas/outbox.js.map +1 -1
  214. package/dist/types/schemas/progress.d.ts +1 -0
  215. package/dist/types/schemas/progress.js +1 -0
  216. package/dist/types/schemas/progress.js.map +1 -1
  217. package/dist/types/schemas/settings.js.map +1 -1
  218. package/dist/types/schemas/shared.d.ts +4 -1
  219. package/dist/types/schemas/shared.js +7 -1
  220. package/dist/types/schemas/shared.js.map +1 -1
  221. package/dist/types/shared.d.ts +1 -1
  222. package/package.json +2 -2
  223. package/dist/reporting/dashboard/index.d.ts +0 -4
  224. package/dist/reporting/dashboard/index.js +0 -2
  225. package/dist/reporting/dashboard/model.d.ts +0 -14
  226. package/dist/reporting/dashboard/ports.d.ts +0 -13
  227. package/dist/reporting/dashboard/service.d.ts +0 -19
  228. package/dist/reporting/dashboard/service.js +0 -20
  229. package/dist/reporting/dashboard/service.js.map +0 -1
  230. package/dist/reporting/learn/index.d.ts +0 -5
  231. package/dist/reporting/learn/index.js +0 -2
  232. package/dist/reporting/learn/model.d.ts +0 -23
  233. package/dist/reporting/learn/ports.d.ts +0 -42
  234. package/dist/reporting/learn/service.d.ts +0 -48
  235. package/dist/reporting/learn/service.js +0 -111
  236. package/dist/reporting/learn/service.js.map +0 -1
  237. package/dist/reporting/students/index.d.ts +0 -4
  238. package/dist/reporting/students/index.js +0 -2
  239. package/dist/reporting/students/model.d.ts +0 -31
  240. package/dist/reporting/students/ports.d.ts +0 -13
  241. package/dist/reporting/students/ports.js +0 -1
  242. package/dist/reporting/students/service.d.ts +0 -19
  243. package/dist/reporting/students/service.js +0 -20
  244. package/dist/reporting/students/service.js.map +0 -1
  245. /package/dist/reporting/{dashboard → admin}/model.js +0 -0
  246. /package/dist/reporting/{dashboard → admin}/ports.js +0 -0
  247. /package/dist/reporting/{learn → member}/model.js +0 -0
  248. /package/dist/reporting/{learn → member}/ports.js +0 -0
  249. /package/dist/{reporting/students/model.js → shared/actor.js} +0 -0
@@ -1,26 +1,155 @@
1
- import { commentReportSchema, commentSchema } from "../types/schemas/discussion.js";
1
+ import { idSchema } from "../types/schemas/shared.js";
2
+ import { chatSchema, commentReportSchema, commentSchema, messageFlagSchema, messageSchema, postFlagSchema, postSchema } from "../types/schemas/discussion.js";
2
3
  import { defineEvent } from "../shared/events.js";
4
+ import { z } from "zod";
3
5
  //#region src/discussion/events.ts
6
+ const publicComment = commentSchema.pick({
7
+ id: true,
8
+ orgId: true,
9
+ activityId: true,
10
+ postId: true,
11
+ communityId: true,
12
+ parentId: true,
13
+ orgUserId: true,
14
+ body: true,
15
+ status: true,
16
+ removedBy: true,
17
+ createdAt: true,
18
+ updatedAt: true
19
+ }).strip();
20
+ const reportedComment = commentReportSchema.extend({ communityId: idSchema.nullable() });
21
+ const publicCommentReport = reportedComment.pick({
22
+ id: true,
23
+ orgId: true,
24
+ communityId: true,
25
+ commentId: true,
26
+ orgUserId: true,
27
+ reason: true,
28
+ resolvedAt: true,
29
+ createdAt: true,
30
+ updatedAt: true
31
+ }).strip();
32
+ const reportedPost = postFlagSchema.extend({ communityId: idSchema });
33
+ const chatEventSchema = chatSchema.extend({ participantIds: z.array(idSchema) });
34
+ const publicChat = chatEventSchema.pick({
35
+ id: true,
36
+ orgId: true,
37
+ communityId: true,
38
+ kind: true,
39
+ status: true,
40
+ createdBy: true,
41
+ participantIds: true
42
+ }).strip();
43
+ const participantAddedSchema = z.object({
44
+ chatId: idSchema,
45
+ communityId: idSchema,
46
+ orgUserId: idSchema,
47
+ addedBy: idSchema
48
+ }).strict();
49
+ const publicMessage = messageSchema.omit({ body: true }).strip();
50
+ const publicMessageFlag = messageFlagSchema.omit({ reason: true }).strip();
4
51
  const discussionEvents = {
5
52
  commentCreated: defineEvent({
6
53
  type: "discussion.comment.created",
7
54
  version: 1,
8
- data: commentSchema
55
+ data: commentSchema,
56
+ publicData: publicComment
9
57
  }),
10
58
  commentPublished: defineEvent({
11
59
  type: "discussion.comment.published",
12
60
  version: 1,
13
- data: commentSchema
61
+ data: commentSchema,
62
+ publicData: publicComment
14
63
  }),
15
64
  commentRemoved: defineEvent({
16
65
  type: "discussion.comment.removed",
17
66
  version: 1,
18
- data: commentSchema
67
+ data: commentSchema,
68
+ publicData: publicComment
19
69
  }),
20
70
  commentReported: defineEvent({
21
71
  type: "discussion.comment.reported",
22
72
  version: 1,
23
- data: commentReportSchema
73
+ data: reportedComment,
74
+ publicData: publicCommentReport
75
+ }),
76
+ postCreated: defineEvent({
77
+ type: "discussion.post.created",
78
+ version: 1,
79
+ data: postSchema,
80
+ publicData: postSchema
81
+ }),
82
+ postUpdated: defineEvent({
83
+ type: "discussion.post.updated",
84
+ version: 1,
85
+ data: postSchema,
86
+ publicData: postSchema
87
+ }),
88
+ postPublished: defineEvent({
89
+ type: "discussion.post.published",
90
+ version: 1,
91
+ data: postSchema,
92
+ publicData: postSchema
93
+ }),
94
+ postRemoved: defineEvent({
95
+ type: "discussion.post.removed",
96
+ version: 1,
97
+ data: postSchema,
98
+ publicData: postSchema
99
+ }),
100
+ postReported: defineEvent({
101
+ type: "discussion.post.reported",
102
+ version: 1,
103
+ data: reportedPost,
104
+ publicData: reportedPost
105
+ }),
106
+ chatCreated: defineEvent({
107
+ type: "discussion.chat.created",
108
+ version: 1,
109
+ data: chatEventSchema,
110
+ publicData: publicChat
111
+ }),
112
+ chatUpdated: defineEvent({
113
+ type: "discussion.chat.updated",
114
+ version: 1,
115
+ data: chatEventSchema,
116
+ publicData: publicChat
117
+ }),
118
+ chatParticipantAdded: defineEvent({
119
+ type: "discussion.chat.participant.added",
120
+ version: 1,
121
+ data: participantAddedSchema,
122
+ publicData: participantAddedSchema
123
+ }),
124
+ messageSent: defineEvent({
125
+ type: "discussion.message.sent",
126
+ version: 1,
127
+ data: messageSchema,
128
+ publicData: publicMessage
129
+ }),
130
+ messageDeleted: defineEvent({
131
+ type: "discussion.message.deleted",
132
+ version: 1,
133
+ data: messageSchema,
134
+ publicData: publicMessage
135
+ }),
136
+ messageReported: defineEvent({
137
+ type: "discussion.message.reported",
138
+ version: 1,
139
+ data: messageFlagSchema,
140
+ publicData: publicMessageFlag
141
+ }),
142
+ digestDue: defineEvent({
143
+ type: "discussion.digest.due",
144
+ version: 1,
145
+ data: z.object({
146
+ communityId: idSchema,
147
+ period: z.string().min(1)
148
+ }).strict(),
149
+ publicData: z.object({
150
+ communityId: idSchema,
151
+ period: z.string().min(1)
152
+ }).strict()
24
153
  })
25
154
  };
26
155
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","names":[],"sources":["../../src/discussion/events.ts"],"sourcesContent":["import { commentReportSchema, commentSchema } from '../types/schemas/index.js';\nimport {\n defineEvent,\n type EventOf,\n type EventOfValues,\n type NewDomainEvent,\n} from '../shared/ports.js';\n\nexport const discussionEvents = {\n commentCreated: defineEvent({\n type: 'discussion.comment.created',\n version: 1,\n data: commentSchema,\n }),\n commentPublished: defineEvent({\n type: 'discussion.comment.published',\n version: 1,\n data: commentSchema,\n }),\n commentRemoved: defineEvent({\n type: 'discussion.comment.removed',\n version: 1,\n data: commentSchema,\n }),\n commentReported: defineEvent({\n type: 'discussion.comment.reported',\n version: 1,\n data: commentReportSchema,\n }),\n};\n\nexport type CommentCreated = EventOf<typeof discussionEvents.commentCreated>;\nexport type CommentPublished = EventOf<typeof discussionEvents.commentPublished>;\nexport type CommentRemoved = EventOf<typeof discussionEvents.commentRemoved>;\nexport type CommentReported = EventOf<typeof discussionEvents.commentReported>;\nexport type CommentEvent = EventOfValues<typeof discussionEvents>;\nexport type NewDiscussionEvent = NewDomainEvent<CommentEvent>;\n"],"mappings":";;;AAQA,MAAa,mBAAmB;CAC9B,gBAAgB,YAAY;EAC1B,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,kBAAkB,YAAY;EAC5B,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,gBAAgB,YAAY;EAC1B,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,iBAAiB,YAAY;EAC3B,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;AACH"}
1
+ {"version":3,"file":"events.js","names":[],"sources":["../../src/discussion/events.ts"],"sourcesContent":["import { z } from 'zod';\nimport {\n chatSchema,\n commentReportSchema,\n commentSchema,\n idSchema,\n messageFlagSchema,\n messageSchema,\n postFlagSchema,\n postSchema,\n} from '../types/schemas/index.js';\nimport {\n defineEvent,\n type EventOf,\n type EventOfValues,\n type NewDomainEvent,\n} from '../shared/ports.js';\n\nconst publicComment = commentSchema\n .pick({\n id: true,\n orgId: true,\n activityId: true,\n postId: true,\n communityId: true,\n parentId: true,\n orgUserId: true,\n body: true,\n status: true,\n removedBy: true,\n createdAt: true,\n updatedAt: true,\n })\n .strip();\n\nconst reportedComment = commentReportSchema.extend({ communityId: idSchema.nullable() });\nconst publicCommentReport = reportedComment\n .pick({\n id: true,\n orgId: true,\n communityId: true,\n commentId: true,\n orgUserId: true,\n reason: true,\n resolvedAt: true,\n createdAt: true,\n updatedAt: true,\n })\n .strip();\nconst reportedPost = postFlagSchema.extend({ communityId: idSchema });\n\nconst chatEventSchema = chatSchema.extend({\n participantIds: z.array(idSchema),\n});\n\nconst publicChat = chatEventSchema\n .pick({\n id: true,\n orgId: true,\n communityId: true,\n kind: true,\n status: true,\n createdBy: true,\n participantIds: true,\n })\n .strip();\n\nconst participantAddedSchema = z\n .object({\n chatId: idSchema,\n communityId: idSchema,\n orgUserId: idSchema,\n addedBy: idSchema,\n })\n .strict();\n\nconst publicMessage = messageSchema.omit({ body: true }).strip();\nconst publicMessageFlag = messageFlagSchema.omit({ reason: true }).strip();\n\nexport const discussionEvents = {\n commentCreated: defineEvent({\n type: 'discussion.comment.created',\n version: 1,\n data: commentSchema,\n publicData: publicComment,\n }),\n commentPublished: defineEvent({\n type: 'discussion.comment.published',\n version: 1,\n data: commentSchema,\n publicData: publicComment,\n }),\n commentRemoved: defineEvent({\n type: 'discussion.comment.removed',\n version: 1,\n data: commentSchema,\n publicData: publicComment,\n }),\n commentReported: defineEvent({\n type: 'discussion.comment.reported',\n version: 1,\n data: reportedComment,\n publicData: publicCommentReport,\n }),\n postCreated: defineEvent({\n type: 'discussion.post.created',\n version: 1,\n data: postSchema,\n publicData: postSchema,\n }),\n postUpdated: defineEvent({\n type: 'discussion.post.updated',\n version: 1,\n data: postSchema,\n publicData: postSchema,\n }),\n postPublished: defineEvent({\n type: 'discussion.post.published',\n version: 1,\n data: postSchema,\n publicData: postSchema,\n }),\n postRemoved: defineEvent({\n type: 'discussion.post.removed',\n version: 1,\n data: postSchema,\n publicData: postSchema,\n }),\n postReported: defineEvent({\n type: 'discussion.post.reported',\n version: 1,\n data: reportedPost,\n publicData: reportedPost,\n }),\n chatCreated: defineEvent({\n type: 'discussion.chat.created',\n version: 1,\n data: chatEventSchema,\n publicData: publicChat,\n }),\n chatUpdated: defineEvent({\n type: 'discussion.chat.updated',\n version: 1,\n data: chatEventSchema,\n publicData: publicChat,\n }),\n chatParticipantAdded: defineEvent({\n type: 'discussion.chat.participant.added',\n version: 1,\n data: participantAddedSchema,\n publicData: participantAddedSchema,\n }),\n messageSent: defineEvent({\n type: 'discussion.message.sent',\n version: 1,\n data: messageSchema,\n publicData: publicMessage,\n }),\n messageDeleted: defineEvent({\n type: 'discussion.message.deleted',\n version: 1,\n data: messageSchema,\n publicData: publicMessage,\n }),\n messageReported: defineEvent({\n type: 'discussion.message.reported',\n version: 1,\n data: messageFlagSchema,\n publicData: publicMessageFlag,\n }),\n digestDue: defineEvent({\n type: 'discussion.digest.due',\n version: 1,\n data: z.object({ communityId: idSchema, period: z.string().min(1) }).strict(),\n publicData: z.object({ communityId: idSchema, period: z.string().min(1) }).strict(),\n }),\n};\n\nexport type CommentCreated = EventOf<typeof discussionEvents.commentCreated>;\nexport type CommentPublished = EventOf<typeof discussionEvents.commentPublished>;\nexport type CommentRemoved = EventOf<typeof discussionEvents.commentRemoved>;\nexport type CommentReported = EventOf<typeof discussionEvents.commentReported>;\nexport type DiscussionEvent = EventOfValues<typeof discussionEvents>;\nexport type PostCreated = EventOf<typeof discussionEvents.postCreated>;\nexport type PostUpdated = EventOf<typeof discussionEvents.postUpdated>;\nexport type PostPublished = EventOf<typeof discussionEvents.postPublished>;\nexport type PostRemoved = EventOf<typeof discussionEvents.postRemoved>;\nexport type PostReported = EventOf<typeof discussionEvents.postReported>;\nexport type ChatCreated = EventOf<typeof discussionEvents.chatCreated>;\nexport type ChatUpdated = EventOf<typeof discussionEvents.chatUpdated>;\nexport type ChatParticipantAdded = EventOf<typeof discussionEvents.chatParticipantAdded>;\nexport type MessageSent = EventOf<typeof discussionEvents.messageSent>;\nexport type MessageDeleted = EventOf<typeof discussionEvents.messageDeleted>;\nexport type MessageReported = EventOf<typeof discussionEvents.messageReported>;\nexport type NewDiscussionEvent = NewDomainEvent<DiscussionEvent>;\n"],"mappings":";;;;;AAkBA,MAAM,gBAAgB,cACnB,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,YAAY;CACZ,QAAQ;CACR,aAAa;CACb,UAAU;CACV,WAAW;CACX,MAAM;CACN,QAAQ;CACR,WAAW;CACX,WAAW;CACX,WAAW;AACb,CAAC,CAAC,CACD,MAAM;AAET,MAAM,kBAAkB,oBAAoB,OAAO,EAAE,aAAa,SAAS,SAAS,EAAE,CAAC;AACvF,MAAM,sBAAsB,gBACzB,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,aAAa;CACb,WAAW;CACX,WAAW;CACX,QAAQ;CACR,YAAY;CACZ,WAAW;CACX,WAAW;AACb,CAAC,CAAC,CACD,MAAM;AACT,MAAM,eAAe,eAAe,OAAO,EAAE,aAAa,SAAS,CAAC;AAEpE,MAAM,kBAAkB,WAAW,OAAO,EACxC,gBAAgB,EAAE,MAAM,QAAQ,EAClC,CAAC;AAED,MAAM,aAAa,gBAChB,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,aAAa;CACb,MAAM;CACN,QAAQ;CACR,WAAW;CACX,gBAAgB;AAClB,CAAC,CAAC,CACD,MAAM;AAET,MAAM,yBAAyB,EAC5B,OAAO;CACN,QAAQ;CACR,aAAa;CACb,WAAW;CACX,SAAS;AACX,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,gBAAgB,cAAc,KAAK,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM;AAC/D,MAAM,oBAAoB,kBAAkB,KAAK,EAAE,QAAQ,KAAK,CAAC,CAAC,CAAC,MAAM;AAEzE,MAAa,mBAAmB;CAC9B,gBAAgB,YAAY;EAC1B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,kBAAkB,YAAY;EAC5B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,gBAAgB,YAAY;EAC1B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,iBAAiB,YAAY;EAC3B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,aAAa,YAAY;EACvB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,aAAa,YAAY;EACvB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,eAAe,YAAY;EACzB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,aAAa,YAAY;EACvB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,cAAc,YAAY;EACxB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,aAAa,YAAY;EACvB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,aAAa,YAAY;EACvB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,sBAAsB,YAAY;EAChC,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,aAAa,YAAY;EACvB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,gBAAgB,YAAY;EAC1B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,iBAAiB,YAAY;EAC3B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,WAAW,YAAY;EACrB,MAAM;EACN,SAAS;EACT,MAAM,EAAE,OAAO;GAAE,aAAa;GAAU,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EAAE,CAAC,CAAC,CAAC,OAAO;EAC5E,YAAY,EAAE,OAAO;GAAE,aAAa;GAAU,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EAAE,CAAC,CAAC,CAAC,OAAO;CACpF,CAAC;AACH"}
@@ -1,8 +1,12 @@
1
1
  import { CommentListItem, CommentReaction, CommentReportSummary, CommentSettings, CommentStatus, CommentView, CommentsConfig, ListCommentsQuery, ReactionCounts, ReactionEmoji } from "../types/schemas/discussion.js";
2
2
  import { Comment, CommentAuthor, CommentReport } from "../types/discussion.js";
3
- import { CommentEvent, discussionEvents } from "./events.js";
3
+ import { Actor } from "../shared/actor.js";
4
4
  import "./model.js";
5
5
  import "./types.js";
6
- import { ActivityComments, Actor, AuthorRecord, CommentReactions, CommentWithContext, CourseAccessReader, DiscussionRepository, DiscussionService, DiscussionUnitOfWork, DiscussionWriteScope, PostCommentInput } from "./ports.js";
6
+ import { ActivityComments, AuthorProfileReader, AuthorRecord, AuthorRoleReader, BookmarkQuery, ChatListItem, ChatRepository, ChatService, ChatUnitOfWork, ChatWriteScope, CommentReactions, CommentWithContext, ContentAccessReader, CreatePostInput, DiscussionRepository, DiscussionService, DiscussionUnitOfWork, DiscussionWriteScope, FeedQuery, MessageQueue, MessageReactions, PageQuery, PostCommentInput, PostCommentReader, PostPatch, PostReactions, PostRepository, PostService, PostThreadsQuery, PostUnitOfWork, PostWriteScope, SendMessageInput, SpaceModerationQueue, StartDirectInput, StartGroupInput, UpdatePostInput } from "./ports.js";
7
+ import { authorView } from "./authors.js";
8
+ import { ChatServiceImpl } from "./chats.js";
9
+ import { DiscussionEvent, discussionEvents } from "./events.js";
7
10
  import { DEFAULT_SETTINGS, DiscussionServiceImpl } from "./service.js";
8
- export { type ActivityComments, type Actor, type AuthorRecord, type Comment, type CommentAuthor, type CommentEvent, type CommentListItem, type CommentReaction, type CommentReactions, type CommentReport, type CommentReportSummary, type CommentSettings, type CommentStatus, type CommentView, type CommentWithContext, type CommentsConfig, type CourseAccessReader, DEFAULT_SETTINGS, type DiscussionRepository, type DiscussionService, DiscussionServiceImpl, type DiscussionUnitOfWork, type DiscussionWriteScope, type ListCommentsQuery, type PostCommentInput, type ReactionCounts, type ReactionEmoji, discussionEvents };
11
+ import { PostServiceImpl } from "./posts.js";
12
+ export { type ActivityComments, type Actor, type AuthorProfileReader, type AuthorRecord, type AuthorRoleReader, type BookmarkQuery, type ChatListItem, type ChatRepository, type ChatService, ChatServiceImpl, type ChatUnitOfWork, type ChatWriteScope, type Comment, type CommentAuthor, type CommentListItem, type CommentReaction, type CommentReactions, type CommentReport, type CommentReportSummary, type CommentSettings, type CommentStatus, type CommentView, type CommentWithContext, type CommentsConfig, type ContentAccessReader, type CreatePostInput, DEFAULT_SETTINGS, type DiscussionEvent, type DiscussionRepository, type DiscussionService, DiscussionServiceImpl, type DiscussionUnitOfWork, type DiscussionWriteScope, type FeedQuery, type ListCommentsQuery, type MessageQueue, type MessageReactions, type PageQuery, type PostCommentInput, type PostCommentReader, type PostPatch, type PostReactions, type PostRepository, type PostService, PostServiceImpl, type PostThreadsQuery, type PostUnitOfWork, type PostWriteScope, type ReactionCounts, type ReactionEmoji, type SendMessageInput, type SpaceModerationQueue, type StartDirectInput, type StartGroupInput, type UpdatePostInput, authorView, discussionEvents };
@@ -1,3 +1,6 @@
1
1
  import { discussionEvents } from "./events.js";
2
+ import { authorView } from "./authors.js";
2
3
  import { DEFAULT_SETTINGS, DiscussionServiceImpl } from "./service.js";
3
- export { DEFAULT_SETTINGS, DiscussionServiceImpl, discussionEvents };
4
+ import { PostServiceImpl } from "./posts.js";
5
+ import { ChatServiceImpl } from "./chats.js";
6
+ export { ChatServiceImpl, DEFAULT_SETTINGS, DiscussionServiceImpl, PostServiceImpl, authorView, discussionEvents };
@@ -1,5 +1,4 @@
1
- import { ActivityCommentsRule } from "../types/schemas/content.js";
2
- import { CommentReaction, CommentSettings, CommentStatus } from "../types/schemas/discussion.js";
1
+ import { ActivityCommentsRule, CommentReaction, CommentSettings, CommentStatus } from "../types/schemas/discussion.js";
3
2
  import { Comment, CommentAuthor, CommentReport } from "../types/discussion.js";
4
3
  import "../types/index.js";
5
4
  export type { ActivityCommentsRule, Comment, CommentAuthor, CommentReaction, CommentReport, CommentSettings, CommentStatus };
@@ -1,10 +1,13 @@
1
- import { Page } from "../types/shared.js";
1
+ import { JsonValue, Page } from "../types/shared.js";
2
+ import { Activity, SpaceDetail } from "../types/schemas/content.js";
2
3
  import { Role } from "../types/schemas/organizations.js";
3
- import { Activity } from "../types/schemas/content.js";
4
- import { CommentListItem, CommentView, CommentsConfig, ListCommentsQuery, ReactionCounts, ReactionEmoji } from "../types/schemas/discussion.js";
5
- import { Comment, CommentAuthor, CommentReport } from "../types/discussion.js";
4
+ import { Chat, ChatLastMessage, ChatUser, CommentListItem, CommentView, CommentsConfig, FlaggedComment, ListCommentsQuery, Message, MessageFlag, MessageFlagResolution, MessageView, Post, PostFlag, PostFlagResolution, PostStatus, PostView, ReactionCounts, ReactionEmoji } from "../types/schemas/discussion.js";
5
+ import { Comment, CommentReport } from "../types/discussion.js";
6
6
  import "../types/index.js";
7
7
  import { OutboxAppender, UnitOfWork } from "../shared/ports.js";
8
+ import { Actor } from "../shared/actor.js";
9
+ import "../content/index.js";
10
+ import "../organizations/index.js";
8
11
  import "./model.js";
9
12
  import "./types.js";
10
13
  //#region src/discussion/ports.d.ts
@@ -23,27 +26,33 @@ interface CommentWithContext {
23
26
  courseId: string;
24
27
  activityTitle: string;
25
28
  }
26
- /**
27
- * Who is acting, and the role they hold in this org right now.
28
- *
29
- * The role is resolved at the HTTP edge from the session's active-org
30
- * org user and handed in — read fresh on every request, never stored on a
31
- * comment. Core does not look a role up to authorise.
32
- */
33
- interface Actor {
34
- id: string;
35
- role: Role;
36
- }
37
29
  type PostCommentInput = {
38
30
  actor: Actor;
39
- activityId: string;
40
31
  parentId: string | null;
41
32
  body: string;
42
- };
33
+ } & ({
34
+ activityId: string;
35
+ postId?: undefined;
36
+ } | {
37
+ postId: string;
38
+ activityId?: undefined;
39
+ });
43
40
  /** A profile row as the repository loads it, keyed by `org_users.id`. `email`
44
41
  * is stripped before comments are served and kept only for the staff list. */
45
- interface AuthorRecord extends CommentAuthor {
42
+ interface AuthorRecord {
43
+ id: string;
44
+ firstName: string | null;
45
+ lastName: string | null;
46
46
  email: string;
47
+ image: string | null;
48
+ role: Role;
49
+ displayName: string | null;
50
+ headline: string | null;
51
+ imageAssetOrgId: string | null;
52
+ imageAssetId: string | null;
53
+ }
54
+ interface AuthorProfileReader {
55
+ authorsOf(orgId: string, orgUserIds: string[]): Promise<Record<string, AuthorRecord>>;
47
56
  }
48
57
  interface DiscussionService {
49
58
  /** Post a root comment or a reply. Lands pending where review is required and
@@ -52,15 +61,17 @@ interface DiscussionService {
52
61
  /** Author-only. Throws ForbiddenError for anyone else, staff included. */
53
62
  edit(orgId: string, commentId: string, actor: Actor, body: string): Promise<CommentView>;
54
63
  /** The author, or anyone whose role is staff. */
55
- remove(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
64
+ remove(orgId: string, commentId: string, actor: Actor, communityId?: string): Promise<CommentView>;
56
65
  /** Staff only. Returns the comment to published. */
57
- restore(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
66
+ restore(orgId: string, commentId: string, actor: Actor, communityId?: string): Promise<CommentView>;
58
67
  /** Staff only. Publishes a pending comment. */
59
68
  approve(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
60
69
  /** Make a comment published, whichever state it is in. Staff only. */
61
70
  publish(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
62
71
  /** The activity's comments as this reader may see them. */
63
72
  activityComments(orgId: string, activityId: string, actor: Actor): Promise<ActivityComments>;
73
+ /** One page of top-level comments, oldest first, each with its replies. */
74
+ postComments(orgId: string, postId: string, actor: Actor, query: PageQuery): Promise<Page<CommentView>>;
64
75
  /**
65
76
  * The org's comments, filtered. Staff-scoped: rows carry the author's email
66
77
  * and a removed comment's body, neither of which a learner may see, so the
@@ -71,33 +82,39 @@ interface DiscussionService {
71
82
  */
72
83
  listComments(orgId: string, query: ListCommentsQuery): Promise<Page<CommentListItem>>;
73
84
  setReaction(orgId: string, commentId: string, actor: Actor, emoji: ReactionEmoji | null): Promise<CommentReactions>;
74
- resolveReports(orgId: string, commentId: string, actor: Actor): Promise<void>;
85
+ resolveReports(orgId: string, commentId: string, actor: Actor, communityId?: string): Promise<void>;
75
86
  /** Accepted even on locked comments — a locked activity can still hold
76
87
  * something a moderator needs to see. */
77
88
  reportComment(orgId: string, commentId: string, actor: Actor, reason: string): Promise<CommentReport>;
78
89
  /** Plain read of one comment — no rules applied. */
79
90
  getComment(orgId: string, commentId: string): Promise<Comment | null>;
91
+ sendDigest(orgId: string, now: Date): Promise<void>;
80
92
  }
81
- interface CourseAccessReader {
82
- hasCourseAccess(orgId: string, orgUserId: string, courseId: string): Promise<boolean>;
93
+ interface ContentAccessReader {
94
+ hasAccess(orgId: string, orgUserId: string, contentId: string): Promise<boolean>;
83
95
  }
84
96
  interface ActivityGetter {
85
97
  getActivity(orgId: string, activityId: string): Promise<Activity | null>;
86
98
  }
87
- interface DiscussionRepository {
99
+ interface DiscussionRepository extends PostCommentReader, AuthorProfileReader {
88
100
  insertComment(orgId: string, comment: Comment): Promise<Comment>;
89
101
  findComment(orgId: string, id: string): Promise<Comment | null>;
90
102
  updateComment(orgId: string, id: string, patch: Partial<Pick<Comment, 'body' | 'status' | 'removedBy' | 'updatedAt'>>): Promise<Comment | null>;
91
103
  /** Every comment on the activity, oldest first, including removed ones. */
92
104
  listByActivity(orgId: string, activityId: string): Promise<Comment[]>;
105
+ /** A page of the post's top-level threads the viewer can see, oldest first, with their replies. `total` counts threads. */
106
+ listThreadsByPost(orgId: string, postId: string, query: PostThreadsQuery): Promise<Page<Comment>>;
93
107
  reactionsOf(orgId: string, commentIds: string[], viewerId: string): Promise<Record<string, CommentReactions>>;
94
108
  setReaction(orgId: string, commentId: string, orgUserId: string, emoji: ReactionEmoji | null): Promise<void>;
95
109
  /** Returns null when this person has already reported this comment. */
96
110
  insertReport(orgId: string, report: CommentReport): Promise<CommentReport | null>;
97
111
  /** Every unresolved report against the given comments. */
98
112
  listOpenReports(orgId: string, commentIds: string[]): Promise<CommentReport[]>;
99
- resolveReportsFor(orgId: string, commentId: string, resolvedAt: Date): Promise<void>;
100
- authorsOf(orgId: string, orgUserIds: string[]): Promise<Record<string, AuthorRecord>>;
113
+ resolveReportsFor(orgId: string, commentId: string, resolved: {
114
+ resolvedAt: Date;
115
+ resolvedBy: string;
116
+ resolution: 'dismissed' | 'removed';
117
+ }): Promise<void>;
101
118
  listComments(orgId: string, query: ListCommentsQuery): Promise<Page<CommentWithContext>>;
102
119
  }
103
120
  /** Writes that emit events run through this scope so the row and the outbox
@@ -107,6 +124,250 @@ interface DiscussionWriteScope {
107
124
  outbox: OutboxAppender;
108
125
  }
109
126
  type DiscussionUnitOfWork = UnitOfWork<DiscussionWriteScope>;
127
+ interface AuthorRoleReader {
128
+ roleOf(orgId: string, orgUserId: string): Promise<Role | null>;
129
+ rolesOf(orgId: string, orgUserIds: string[]): Promise<Record<string, Role>>;
130
+ }
131
+ type PostMode = 'draft' | 'submit' | 'schedule';
132
+ interface CreatePostInput {
133
+ communityId: string;
134
+ spaceId: string;
135
+ title: string;
136
+ body: string;
137
+ topicId: string | null;
138
+ extra: JsonValue;
139
+ coverAssetId: string | null;
140
+ mode: PostMode;
141
+ scheduledAt: Date | null;
142
+ }
143
+ interface UpdatePostInput {
144
+ title?: string;
145
+ body?: string;
146
+ topicId?: string | null;
147
+ extra?: JsonValue;
148
+ coverAssetId?: string | null;
149
+ }
150
+ type PostPatch = Partial<Pick<Post, 'title' | 'body' | 'topicId' | 'extra' | 'coverAssetId' | 'status' | 'scheduledAt' | 'publishedAt' | 'removedBy' | 'pinned' | 'commentsClosed' | 'reactionsEnabled'>>;
151
+ interface FeedQuery {
152
+ page: number;
153
+ pageSize: number;
154
+ topicId?: string;
155
+ }
156
+ interface PostReactions {
157
+ reactions: ReactionCounts;
158
+ viewerReaction?: ReactionEmoji;
159
+ }
160
+ type PageQuery = Pick<FeedQuery, 'page' | 'pageSize'>;
161
+ interface PostThreadsQuery extends PageQuery {
162
+ viewerId: string;
163
+ seesHeld: boolean;
164
+ }
165
+ interface BookmarkQuery extends PageQuery {
166
+ visibleStatuses: PostStatus[];
167
+ }
168
+ declare const MODERATION_QUEUE_LIMIT = 100;
169
+ interface SpaceModerationQueue {
170
+ pending: PostView[];
171
+ flags: PostFlag[];
172
+ commentFlags: FlaggedComment[];
173
+ }
174
+ interface PostCommentReader {
175
+ listOpenFlagsForSpace(orgId: string, spaceId: string, limit: number): Promise<FlaggedComment[]>;
176
+ publishedCommentCounts(orgId: string, postIds: string[]): Promise<Record<string, number>>;
177
+ }
178
+ interface PostService {
179
+ visibleTitles(orgId: string, actor: Actor, postIds: string[]): Promise<Record<string, string>>;
180
+ create(orgId: string, actor: Actor, input: CreatePostInput): Promise<PostView>;
181
+ update(orgId: string, postId: string, actor: Actor, patch: UpdatePostInput): Promise<PostView>;
182
+ submit(orgId: string, postId: string, actor: Actor): Promise<PostView>;
183
+ schedule(orgId: string, postId: string, actor: Actor, scheduledAt: Date): Promise<PostView>;
184
+ approve(orgId: string, postId: string, actor: Actor, communityId?: string): Promise<PostView>;
185
+ remove(orgId: string, postId: string, actor: Actor, communityId?: string): Promise<PostView>;
186
+ restore(orgId: string, postId: string, actor: Actor, communityId?: string): Promise<PostView>;
187
+ pin(orgId: string, postId: string, actor: Actor): Promise<PostView>;
188
+ unpin(orgId: string, postId: string, actor: Actor): Promise<PostView>;
189
+ closeComments(orgId: string, postId: string, actor: Actor): Promise<PostView>;
190
+ openComments(orgId: string, postId: string, actor: Actor): Promise<PostView>;
191
+ setReactions(orgId: string, postId: string, actor: Actor, enabled: boolean): Promise<PostView>;
192
+ setReaction(orgId: string, postId: string, actor: Actor, emoji: ReactionEmoji | null): Promise<PostReactions>;
193
+ follow(orgId: string, postId: string, actor: Actor): Promise<void>;
194
+ unfollow(orgId: string, postId: string, actor: Actor): Promise<void>;
195
+ bookmark(orgId: string, postId: string, actor: Actor): Promise<void>;
196
+ unbookmark(orgId: string, postId: string, actor: Actor): Promise<void>;
197
+ flag(orgId: string, postId: string, actor: Actor, reason: string): Promise<PostFlag>;
198
+ resolveFlags(orgId: string, postId: string, actor: Actor, resolution: Extract<PostFlagResolution, 'dismissed'>, communityId?: string): Promise<void>;
199
+ spaceFeed(orgId: string, actor: Actor, communityId: string, spaceId: string, query: FeedQuery): Promise<Page<PostView>>;
200
+ memberFeed(orgId: string, actor: Actor, communityId: string, query: Pick<FeedQuery, 'page' | 'pageSize'>): Promise<Page<PostView>>;
201
+ listOwn(orgId: string, actor: Actor, communityId: string, query: PageQuery): Promise<Page<PostView>>;
202
+ listBookmarked(orgId: string, actor: Actor, communityId: string, query: PageQuery): Promise<Page<PostView>>;
203
+ /** Signed URL of the post's cover, for whoever can read the post. */
204
+ coverFile(orgId: string, actor: Actor, postId: string): Promise<string | null>;
205
+ getPost(orgId: string, actor: Actor, postId: string): Promise<PostView>;
206
+ visible(orgId: string, actor: Actor, postId: string): Promise<{
207
+ post: Post;
208
+ space: SpaceDetail;
209
+ }>;
210
+ find(orgId: string, postId: string): Promise<Post | null>;
211
+ followerIds(orgId: string, postId: string): Promise<string[]>;
212
+ moderationQueue(orgId: string, actor: Actor, communityId: string, spaceId: string): Promise<SpaceModerationQueue>;
213
+ publishDue(orgId: string, now: Date): Promise<void>;
214
+ hasDue(orgId: string, now: Date): Promise<boolean>;
215
+ }
216
+ interface PostRepository {
217
+ insert(orgId: string, post: Post): Promise<Post>;
218
+ update(orgId: string, id: string, patch: PostPatch): Promise<Post | null>;
219
+ find(orgId: string, id: string): Promise<Post | null>;
220
+ findMany(orgId: string, ids: string[]): Promise<Post[]>;
221
+ listPublished(orgId: string, spaceIds: string[], query: FeedQuery): Promise<Page<Post>>;
222
+ listByAuthor(orgId: string, orgUserId: string, spaceIds: string[], query: PageQuery): Promise<Page<Post>>;
223
+ listBookmarked(orgId: string, orgUserId: string, spaceIds: string[], query: BookmarkQuery): Promise<Page<Post>>;
224
+ listPending(orgId: string, spaceId: string, limit: number): Promise<Post[]>;
225
+ /** Due scheduled posts in id order, after `afterId` when given. */
226
+ listDue(orgId: string, now: Date, limit: number, afterId?: string): Promise<Post[]>;
227
+ hasDue(orgId: string, now: Date): Promise<boolean>;
228
+ reactionsOf(orgId: string, postIds: string[], viewerId: string): Promise<Record<string, PostReactions>>;
229
+ setReaction(orgId: string, postId: string, orgUserId: string, emoji: ReactionEmoji | null): Promise<void>;
230
+ follow(orgId: string, postId: string, orgUserId: string): Promise<void>;
231
+ unfollow(orgId: string, postId: string, orgUserId: string): Promise<void>;
232
+ followerIds(orgId: string, postId: string): Promise<string[]>;
233
+ followedAmong(orgId: string, postIds: string[], orgUserId: string): Promise<string[]>;
234
+ bookmark(orgId: string, postId: string, orgUserId: string): Promise<void>;
235
+ unbookmark(orgId: string, postId: string, orgUserId: string): Promise<void>;
236
+ bookmarkedAmong(orgId: string, postIds: string[], orgUserId: string): Promise<string[]>;
237
+ insertFlag(orgId: string, flag: PostFlag): Promise<PostFlag | null>;
238
+ findFlag(orgId: string, postId: string, orgUserId: string): Promise<PostFlag | null>;
239
+ listOpenFlags(orgId: string, spaceId: string, limit: number): Promise<PostFlag[]>;
240
+ resolveFlags(orgId: string, postId: string, resolved: {
241
+ resolvedAt: Date;
242
+ resolvedBy: string;
243
+ resolution: PostFlagResolution;
244
+ }): Promise<void>;
245
+ }
246
+ interface PostWriteScope {
247
+ posts: PostRepository;
248
+ outbox: OutboxAppender;
249
+ }
250
+ type PostUnitOfWork = UnitOfWork<PostWriteScope>;
251
+ interface StartDirectInput {
252
+ communityId: string;
253
+ orgUserId: string;
254
+ body: string | null;
255
+ assetIds: string[];
256
+ }
257
+ interface StartGroupInput {
258
+ communityId: string;
259
+ orgUserIds: string[];
260
+ }
261
+ interface SendMessageInput {
262
+ body: string;
263
+ replyToId: string | null;
264
+ assetIds: string[];
265
+ }
266
+ interface ChatListItem {
267
+ chat: Chat;
268
+ participantIds: string[];
269
+ lastReadMessageId: string | null;
270
+ muted: boolean;
271
+ mutedUntil: Date | null;
272
+ unread: number;
273
+ lastMessage: ChatLastMessage | null;
274
+ }
275
+ interface MessageReactions {
276
+ reactions: ReactionCounts;
277
+ viewerReaction?: ReactionEmoji;
278
+ }
279
+ interface ChatSummary {
280
+ chat: Chat;
281
+ participantIds: string[];
282
+ }
283
+ interface MessageQueueEntry {
284
+ message: MessageView;
285
+ flags: MessageFlag[];
286
+ chat: Chat;
287
+ participantIds: string[];
288
+ }
289
+ interface MessageQueue {
290
+ entries: MessageQueueEntry[];
291
+ }
292
+ interface ChatService {
293
+ startDirect(orgId: string, actor: Actor, input: StartDirectInput): Promise<Chat>;
294
+ startGroup(orgId: string, actor: Actor, input: StartGroupInput): Promise<Chat>;
295
+ addParticipant(orgId: string, actor: Actor, chatId: string, orgUserId: string): Promise<Chat>;
296
+ leave(orgId: string, actor: Actor, chatId: string): Promise<Chat>;
297
+ accept(orgId: string, actor: Actor, chatId: string): Promise<Chat>;
298
+ send(orgId: string, actor: Actor, chatId: string, input: SendMessageInput): Promise<MessageView>;
299
+ editMessage(orgId: string, actor: Actor, messageId: string, body: string): Promise<MessageView>;
300
+ deleteMessage(orgId: string, actor: Actor, messageId: string): Promise<MessageView>;
301
+ setReaction(orgId: string, actor: Actor, messageId: string, emoji: ReactionEmoji | null): Promise<MessageReactions>;
302
+ markRead(orgId: string, actor: Actor, chatId: string, messageId: string): Promise<void>;
303
+ mute(orgId: string, actor: Actor, chatId: string, until?: Date): Promise<void>;
304
+ unmute(orgId: string, actor: Actor, chatId: string): Promise<void>;
305
+ block(orgId: string, actor: Actor, communityId: string, orgUserId: string): Promise<void>;
306
+ unblock(orgId: string, actor: Actor, communityId: string, orgUserId: string): Promise<void>;
307
+ flagMessage(orgId: string, actor: Actor, messageId: string, reason: string): Promise<MessageFlag>;
308
+ resolveMessageFlags(orgId: string, actor: Actor, messageId: string, resolution: Extract<MessageFlagResolution, 'dismissed'>, communityId?: string): Promise<void>;
309
+ lock(orgId: string, actor: Actor, chatId: string, communityId?: string): Promise<Chat>;
310
+ unlock(orgId: string, actor: Actor, chatId: string, communityId?: string): Promise<Chat>;
311
+ listChats(orgId: string, actor: Actor, communityId: string, query: PageQuery): Promise<Page<ChatListItem>>;
312
+ chatSummary(orgId: string, chatId: string): Promise<{
313
+ chat: Chat;
314
+ participants: ChatUser[];
315
+ } | null>;
316
+ latestMessageBody(orgId: string, chatId: string): Promise<string | null>;
317
+ isBlocked(orgId: string, communityId: string, a: string, b: string): Promise<boolean>;
318
+ titlesFor(orgId: string, actor: Actor, chatIds: string[]): Promise<Record<string, string>>;
319
+ messages(orgId: string, actor: Actor, chatId: string, query: Pick<FeedQuery, 'page' | 'pageSize'>): Promise<Page<MessageView>>;
320
+ /** Signed URL of a message attachment: for the chat's participants while the
321
+ * message stands (staff also after deletion), and for staff while it is flagged. */
322
+ attachmentFile(orgId: string, actor: Actor, chatId: string, messageId: string, assetId: string): Promise<string | null>;
323
+ messageQueue(orgId: string, actor: Actor, communityId: string): Promise<MessageQueue>;
324
+ }
325
+ interface ChatRepository {
326
+ lockDirectPair(orgId: string, communityId: string, orgUserId: string, otherOrgUserId: string): Promise<void>;
327
+ findDirect(orgId: string, communityId: string, orgUserId: string, otherOrgUserId: string): Promise<Chat | null>;
328
+ insertChat(orgId: string, chat: Chat): Promise<Chat>;
329
+ updateChat(orgId: string, id: string, patch: Partial<Pick<Chat, 'status' | 'lockedAt' | 'lockedBy'>>): Promise<Chat | null>;
330
+ findChat(orgId: string, id: string): Promise<Chat | null>;
331
+ listForUser(orgId: string, communityId: string, orgUserId: string, query: PageQuery): Promise<Page<ChatListItem>>;
332
+ participants(orgId: string, chatId: string): Promise<ChatUser[]>;
333
+ join(orgId: string, user: ChatUser): Promise<void>;
334
+ markLeft(orgId: string, chatId: string, orgUserId: string, leftAt: Date): Promise<void>;
335
+ setRead(orgId: string, chatId: string, orgUserId: string, messageId: string): Promise<void>;
336
+ setMuted(orgId: string, chatId: string, orgUserId: string, muted: boolean, mutedUntil: Date | null): Promise<void>;
337
+ insertMessage(orgId: string, message: Message): Promise<Message>;
338
+ updateMessage(orgId: string, id: string, patch: Partial<Pick<Message, 'body' | 'editedAt' | 'deletedAt'>>): Promise<Message | null>;
339
+ findMessage(orgId: string, id: string): Promise<Message | null>;
340
+ listMessages(orgId: string, chatId: string, query: Pick<FeedQuery, 'page' | 'pageSize'>): Promise<Page<Message>>;
341
+ attach(orgId: string, communityId: string, messageId: string, assetIds: string[]): Promise<void>;
342
+ attachmentsOf(orgId: string, messageIds: string[]): Promise<Record<string, string[]>>;
343
+ blockedWith(orgId: string, communityId: string, orgUserId: string, otherIds: string[]): Promise<string[]>;
344
+ setReaction(orgId: string, communityId: string, messageId: string, orgUserId: string, emoji: ReactionEmoji | null): Promise<void>;
345
+ reactionsOf(orgId: string, messageIds: string[], viewerId: string): Promise<Record<string, MessageReactions>>;
346
+ block(orgId: string, communityId: string, blockerOrgUserId: string, blockedOrgUserId: string): Promise<void>;
347
+ unblock(orgId: string, communityId: string, blockerOrgUserId: string, blockedOrgUserId: string): Promise<void>;
348
+ isBlocked(orgId: string, communityId: string, a: string, b: string): Promise<boolean>;
349
+ anyBlockedAmong(orgId: string, communityId: string, orgUserIds: string[]): Promise<boolean>;
350
+ insertFlag(orgId: string, flag: MessageFlag): Promise<MessageFlag | null>;
351
+ findFlag(orgId: string, messageId: string, orgUserId: string): Promise<MessageFlag | null>;
352
+ listOpenFlags(orgId: string, communityId: string, limit?: number): Promise<MessageFlag[]>;
353
+ messagesByIds(orgId: string, ids: string[]): Promise<Message[]>;
354
+ chatSummaries(orgId: string, chatIds: string[]): Promise<ChatSummary[]>;
355
+ resolveFlags(orgId: string, messageId: string, resolved: {
356
+ resolvedAt: Date;
357
+ resolvedBy: string;
358
+ resolution: MessageFlagResolution;
359
+ }): Promise<void>;
360
+ resolveOpenFlagsForChat(orgId: string, chatId: string, resolved: {
361
+ resolvedAt: Date;
362
+ resolvedBy: string;
363
+ resolution: MessageFlagResolution;
364
+ }): Promise<void>;
365
+ }
366
+ interface ChatWriteScope {
367
+ chats: ChatRepository;
368
+ outbox: OutboxAppender;
369
+ }
370
+ type ChatUnitOfWork = UnitOfWork<ChatWriteScope>;
110
371
  //#endregion
111
- export { ActivityComments, ActivityGetter, Actor, AuthorRecord, CommentReactions, CommentWithContext, CourseAccessReader, DiscussionRepository, DiscussionService, DiscussionUnitOfWork, DiscussionWriteScope, PostCommentInput };
372
+ export { ActivityComments, ActivityGetter, type Actor, AuthorProfileReader, AuthorRecord, AuthorRoleReader, BookmarkQuery, ChatListItem, ChatRepository, ChatService, ChatSummary, ChatUnitOfWork, ChatWriteScope, CommentReactions, CommentWithContext, ContentAccessReader, CreatePostInput, DiscussionRepository, DiscussionService, DiscussionUnitOfWork, DiscussionWriteScope, FeedQuery, MODERATION_QUEUE_LIMIT, MessageQueue, MessageQueueEntry, MessageReactions, PageQuery, PostCommentInput, PostCommentReader, PostMode, PostPatch, PostReactions, PostRepository, PostService, PostThreadsQuery, PostUnitOfWork, PostWriteScope, SendMessageInput, SpaceModerationQueue, StartDirectInput, StartGroupInput, UpdatePostInput };
112
373
  //# sourceMappingURL=ports.d.ts.map
@@ -1 +1,6 @@
1
- export {};
1
+ //#region src/discussion/ports.ts
2
+ const MODERATION_QUEUE_LIMIT = 100;
3
+ //#endregion
4
+ export { MODERATION_QUEUE_LIMIT };
5
+
6
+ //# sourceMappingURL=ports.js.map