@headless-lms/core 0.1.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.
- package/LICENSE +21 -0
- package/dist/assets/events.d.ts +81 -0
- package/dist/assets/events.js +24 -0
- package/dist/assets/events.js.map +1 -0
- package/dist/assets/index.d.ts +7 -0
- package/dist/assets/index.js +3 -0
- package/dist/assets/model.d.ts +4 -0
- package/dist/assets/model.js +1 -0
- package/dist/assets/ports.d.ts +34 -0
- package/dist/assets/ports.js +1 -0
- package/dist/assets/service.d.ts +29 -0
- package/dist/assets/service.js +130 -0
- package/dist/assets/service.js.map +1 -0
- package/dist/automations/actions.d.ts +24 -0
- package/dist/automations/actions.js +59 -0
- package/dist/automations/actions.js.map +1 -0
- package/dist/automations/catalog.d.ts +12 -0
- package/dist/automations/catalog.js +224 -0
- package/dist/automations/catalog.js.map +1 -0
- package/dist/automations/events.d.ts +264 -0
- package/dist/automations/events.js +54 -0
- package/dist/automations/events.js.map +1 -0
- package/dist/automations/index.d.ts +9 -0
- package/dist/automations/index.js +4 -0
- package/dist/automations/model.d.ts +12 -0
- package/dist/automations/model.js +14 -0
- package/dist/automations/model.js.map +1 -0
- package/dist/automations/ports.d.ts +56 -0
- package/dist/automations/ports.js +1 -0
- package/dist/automations/service.d.ts +53 -0
- package/dist/automations/service.js +225 -0
- package/dist/automations/service.js.map +1 -0
- package/dist/automations/types.d.ts +3 -0
- package/dist/automations/types.js +1 -0
- package/dist/content/events.d.ts +410 -0
- package/dist/content/events.js +105 -0
- package/dist/content/events.js.map +1 -0
- package/dist/content/index.d.ts +8 -0
- package/dist/content/index.js +3 -0
- package/dist/content/model.d.ts +3 -0
- package/dist/content/model.js +1 -0
- package/dist/content/ports.d.ts +85 -0
- package/dist/content/ports.js +1 -0
- package/dist/content/service.d.ts +54 -0
- package/dist/content/service.js +479 -0
- package/dist/content/service.js.map +1 -0
- package/dist/content/types.d.ts +4 -0
- package/dist/content/types.js +1 -0
- package/dist/discussion/events.d.ts +101 -0
- package/dist/discussion/events.js +29 -0
- package/dist/discussion/events.js.map +1 -0
- package/dist/discussion/index.d.ts +8 -0
- package/dist/discussion/index.js +3 -0
- package/dist/discussion/model.d.ts +5 -0
- package/dist/discussion/model.js +1 -0
- package/dist/discussion/ports.d.ts +112 -0
- package/dist/discussion/ports.js +1 -0
- package/dist/discussion/service.d.ts +67 -0
- package/dist/discussion/service.js +343 -0
- package/dist/discussion/service.js.map +1 -0
- package/dist/discussion/types.d.ts +4 -0
- package/dist/discussion/types.js +1 -0
- package/dist/entitlements/events.d.ts +89 -0
- package/dist/entitlements/events.js +29 -0
- package/dist/entitlements/events.js.map +1 -0
- package/dist/entitlements/index.d.ts +7 -0
- package/dist/entitlements/index.js +3 -0
- package/dist/entitlements/model.d.ts +4 -0
- package/dist/entitlements/model.js +1 -0
- package/dist/entitlements/ports.d.ts +34 -0
- package/dist/entitlements/ports.js +1 -0
- package/dist/entitlements/service.d.ts +27 -0
- package/dist/entitlements/service.js +60 -0
- package/dist/entitlements/service.js.map +1 -0
- package/dist/identity/events.d.ts +63 -0
- package/dist/identity/events.js +24 -0
- package/dist/identity/events.js.map +1 -0
- package/dist/identity/index.d.ts +8 -0
- package/dist/identity/index.js +3 -0
- package/dist/identity/model.d.ts +3 -0
- package/dist/identity/model.js +1 -0
- package/dist/identity/ports.d.ts +58 -0
- package/dist/identity/ports.js +1 -0
- package/dist/identity/service.d.ts +38 -0
- package/dist/identity/service.js +79 -0
- package/dist/identity/service.js.map +1 -0
- package/dist/identity/types.d.ts +4 -0
- package/dist/identity/types.js +1 -0
- package/dist/integrations/events.d.ts +70 -0
- package/dist/integrations/events.js +24 -0
- package/dist/integrations/events.js.map +1 -0
- package/dist/integrations/index.d.ts +9 -0
- package/dist/integrations/index.js +6 -0
- package/dist/integrations/model.d.ts +28 -0
- package/dist/integrations/model.js +45 -0
- package/dist/integrations/model.js.map +1 -0
- package/dist/integrations/ports.d.ts +62 -0
- package/dist/integrations/ports.js +1 -0
- package/dist/integrations/registry.d.ts +7 -0
- package/dist/integrations/registry.js +16 -0
- package/dist/integrations/registry.js.map +1 -0
- package/dist/integrations/service.d.ts +47 -0
- package/dist/integrations/service.js +184 -0
- package/dist/integrations/service.js.map +1 -0
- package/dist/integrations/zod.d.ts +29 -0
- package/dist/integrations/zod.js +40 -0
- package/dist/integrations/zod.js.map +1 -0
- package/dist/organizations/events.d.ts +197 -0
- package/dist/organizations/events.js +59 -0
- package/dist/organizations/events.js.map +1 -0
- package/dist/organizations/index.d.ts +11 -0
- package/dist/organizations/index.js +5 -0
- package/dist/organizations/members.d.ts +32 -0
- package/dist/organizations/members.js +12 -0
- package/dist/organizations/members.js.map +1 -0
- package/dist/organizations/model.d.ts +3 -0
- package/dist/organizations/model.js +1 -0
- package/dist/organizations/ports.d.ts +127 -0
- package/dist/organizations/ports.js +1 -0
- package/dist/organizations/roles.d.ts +23 -0
- package/dist/organizations/roles.js +70 -0
- package/dist/organizations/roles.js.map +1 -0
- package/dist/organizations/service.d.ts +58 -0
- package/dist/organizations/service.js +359 -0
- package/dist/organizations/service.js.map +1 -0
- package/dist/organizations/types.d.ts +39 -0
- package/dist/organizations/types.js +1 -0
- package/dist/progress/events.d.ts +55 -0
- package/dist/progress/events.js +19 -0
- package/dist/progress/events.js.map +1 -0
- package/dist/progress/index.d.ts +8 -0
- package/dist/progress/index.js +3 -0
- package/dist/progress/model.d.ts +3 -0
- package/dist/progress/model.js +1 -0
- package/dist/progress/ports.d.ts +37 -0
- package/dist/progress/ports.js +1 -0
- package/dist/progress/service.d.ts +33 -0
- package/dist/progress/service.js +181 -0
- package/dist/progress/service.js.map +1 -0
- package/dist/progress/types.d.ts +4 -0
- package/dist/progress/types.js +1 -0
- package/dist/reporting/dashboard/index.d.ts +4 -0
- package/dist/reporting/dashboard/index.js +2 -0
- package/dist/reporting/dashboard/model.d.ts +14 -0
- package/dist/reporting/dashboard/model.js +1 -0
- package/dist/reporting/dashboard/ports.d.ts +13 -0
- package/dist/reporting/dashboard/ports.js +1 -0
- package/dist/reporting/dashboard/service.d.ts +19 -0
- package/dist/reporting/dashboard/service.js +20 -0
- package/dist/reporting/dashboard/service.js.map +1 -0
- package/dist/reporting/learn/index.d.ts +5 -0
- package/dist/reporting/learn/index.js +2 -0
- package/dist/reporting/learn/model.d.ts +23 -0
- package/dist/reporting/learn/model.js +1 -0
- package/dist/reporting/learn/ports.d.ts +42 -0
- package/dist/reporting/learn/ports.js +1 -0
- package/dist/reporting/learn/service.d.ts +48 -0
- package/dist/reporting/learn/service.js +111 -0
- package/dist/reporting/learn/service.js.map +1 -0
- package/dist/reporting/students/index.d.ts +4 -0
- package/dist/reporting/students/index.js +2 -0
- package/dist/reporting/students/model.d.ts +31 -0
- package/dist/reporting/students/model.js +1 -0
- package/dist/reporting/students/ports.d.ts +13 -0
- package/dist/reporting/students/ports.js +1 -0
- package/dist/reporting/students/service.d.ts +19 -0
- package/dist/reporting/students/service.js +20 -0
- package/dist/reporting/students/service.js.map +1 -0
- package/dist/shared/errors.d.ts +22 -0
- package/dist/shared/errors.js +34 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/events.d.ts +31 -0
- package/dist/shared/events.js +75 -0
- package/dist/shared/events.js.map +1 -0
- package/dist/shared/id.d.ts +44 -0
- package/dist/shared/id.js +53 -0
- package/dist/shared/id.js.map +1 -0
- package/dist/shared/invite-token.d.ts +9 -0
- package/dist/shared/invite-token.js +16 -0
- package/dist/shared/invite-token.js.map +1 -0
- package/dist/shared/logger.d.ts +19 -0
- package/dist/shared/logger.js +44 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/mailer.d.ts +23 -0
- package/dist/shared/mailer.js +27 -0
- package/dist/shared/mailer.js.map +1 -0
- package/dist/shared/ports.d.ts +62 -0
- package/dist/shared/ports.js +2 -0
- package/dist/shared/settings.d.ts +25 -0
- package/dist/shared/settings.js +21 -0
- package/dist/shared/settings.js.map +1 -0
- package/dist/types/assets.d.ts +2 -0
- package/dist/types/assets.js +1 -0
- package/dist/types/automations.d.ts +23 -0
- package/dist/types/automations.js +1 -0
- package/dist/types/content.d.ts +2 -0
- package/dist/types/content.js +1 -0
- package/dist/types/discussion.d.ts +36 -0
- package/dist/types/discussion.js +1 -0
- package/dist/types/email-templates.d.ts +57 -0
- package/dist/types/email-templates.js +1 -0
- package/dist/types/entitlements.d.ts +3 -0
- package/dist/types/entitlements.js +1 -0
- package/dist/types/events.d.ts +25 -0
- package/dist/types/events.js +1 -0
- package/dist/types/identity.d.ts +37 -0
- package/dist/types/identity.js +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.js +1 -0
- package/dist/types/integrations.d.ts +45 -0
- package/dist/types/integrations.js +1 -0
- package/dist/types/organizations.d.ts +15 -0
- package/dist/types/organizations.js +1 -0
- package/dist/types/ports.d.ts +57 -0
- package/dist/types/ports.js +1 -0
- package/dist/types/progress.d.ts +6 -0
- package/dist/types/progress.js +1 -0
- package/dist/types/schemas/assets.d.ts +109 -0
- package/dist/types/schemas/assets.js +49 -0
- package/dist/types/schemas/assets.js.map +1 -0
- package/dist/types/schemas/automations.d.ts +118 -0
- package/dist/types/schemas/automations.js +73 -0
- package/dist/types/schemas/automations.js.map +1 -0
- package/dist/types/schemas/content.d.ts +216 -0
- package/dist/types/schemas/content.js +138 -0
- package/dist/types/schemas/content.js.map +1 -0
- package/dist/types/schemas/credentials.d.ts +15 -0
- package/dist/types/schemas/credentials.js +15 -0
- package/dist/types/schemas/credentials.js.map +1 -0
- package/dist/types/schemas/discussion.d.ts +192 -0
- package/dist/types/schemas/discussion.js +100 -0
- package/dist/types/schemas/discussion.js.map +1 -0
- package/dist/types/schemas/entitlements.d.ts +50 -0
- package/dist/types/schemas/entitlements.js +38 -0
- package/dist/types/schemas/entitlements.js.map +1 -0
- package/dist/types/schemas/identity.d.ts +37 -0
- package/dist/types/schemas/identity.js +34 -0
- package/dist/types/schemas/identity.js.map +1 -0
- package/dist/types/schemas/index.d.ts +14 -0
- package/dist/types/schemas/index.js +14 -0
- package/dist/types/schemas/integrations.d.ts +36 -0
- package/dist/types/schemas/integrations.js +30 -0
- package/dist/types/schemas/integrations.js.map +1 -0
- package/dist/types/schemas/organizations.d.ts +135 -0
- package/dist/types/schemas/organizations.js +90 -0
- package/dist/types/schemas/organizations.js.map +1 -0
- package/dist/types/schemas/outbox.d.ts +19 -0
- package/dist/types/schemas/outbox.js +18 -0
- package/dist/types/schemas/outbox.js.map +1 -0
- package/dist/types/schemas/progress.d.ts +53 -0
- package/dist/types/schemas/progress.js +37 -0
- package/dist/types/schemas/progress.js.map +1 -0
- package/dist/types/schemas/settings.d.ts +16 -0
- package/dist/types/schemas/settings.js +15 -0
- package/dist/types/schemas/settings.js.map +1 -0
- package/dist/types/schemas/shared.d.ts +13 -0
- package/dist/types/schemas/shared.js +28 -0
- package/dist/types/schemas/shared.js.map +1 -0
- package/dist/types/shared.d.ts +25 -0
- package/dist/types/shared.js +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { NewDomainEvent } from "../types/shared.js";
|
|
2
|
+
import { EventOf, EventOfValues, RuntimeEventDefinition, VersionedDomainEvent } from "../shared/events.js";
|
|
3
|
+
import "../shared/ports.js";
|
|
4
|
+
//#region src/discussion/events.d.ts
|
|
5
|
+
declare const discussionEvents: {
|
|
6
|
+
commentCreated: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
7
|
+
id: string;
|
|
8
|
+
orgId: string;
|
|
9
|
+
activityId: string;
|
|
10
|
+
parentId: string | null;
|
|
11
|
+
orgUserId: string;
|
|
12
|
+
body: string;
|
|
13
|
+
status: "pending" | "published" | "removed";
|
|
14
|
+
removedBy: string | null;
|
|
15
|
+
createdAt: Date;
|
|
16
|
+
updatedAt: Date;
|
|
17
|
+
}, "discussion.comment.created", 1>, {
|
|
18
|
+
id: string;
|
|
19
|
+
orgId: string;
|
|
20
|
+
activityId: string;
|
|
21
|
+
parentId: string | null;
|
|
22
|
+
orgUserId: string;
|
|
23
|
+
body: string;
|
|
24
|
+
status: "pending" | "published" | "removed";
|
|
25
|
+
removedBy: string | null;
|
|
26
|
+
createdAt: unknown;
|
|
27
|
+
updatedAt: unknown;
|
|
28
|
+
}>;
|
|
29
|
+
commentPublished: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
30
|
+
id: string;
|
|
31
|
+
orgId: string;
|
|
32
|
+
activityId: string;
|
|
33
|
+
parentId: string | null;
|
|
34
|
+
orgUserId: string;
|
|
35
|
+
body: string;
|
|
36
|
+
status: "pending" | "published" | "removed";
|
|
37
|
+
removedBy: string | null;
|
|
38
|
+
createdAt: Date;
|
|
39
|
+
updatedAt: Date;
|
|
40
|
+
}, "discussion.comment.published", 1>, {
|
|
41
|
+
id: string;
|
|
42
|
+
orgId: string;
|
|
43
|
+
activityId: string;
|
|
44
|
+
parentId: string | null;
|
|
45
|
+
orgUserId: string;
|
|
46
|
+
body: string;
|
|
47
|
+
status: "pending" | "published" | "removed";
|
|
48
|
+
removedBy: string | null;
|
|
49
|
+
createdAt: unknown;
|
|
50
|
+
updatedAt: unknown;
|
|
51
|
+
}>;
|
|
52
|
+
commentRemoved: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
53
|
+
id: string;
|
|
54
|
+
orgId: string;
|
|
55
|
+
activityId: string;
|
|
56
|
+
parentId: string | null;
|
|
57
|
+
orgUserId: string;
|
|
58
|
+
body: string;
|
|
59
|
+
status: "pending" | "published" | "removed";
|
|
60
|
+
removedBy: string | null;
|
|
61
|
+
createdAt: Date;
|
|
62
|
+
updatedAt: Date;
|
|
63
|
+
}, "discussion.comment.removed", 1>, {
|
|
64
|
+
id: string;
|
|
65
|
+
orgId: string;
|
|
66
|
+
activityId: string;
|
|
67
|
+
parentId: string | null;
|
|
68
|
+
orgUserId: string;
|
|
69
|
+
body: string;
|
|
70
|
+
status: "pending" | "published" | "removed";
|
|
71
|
+
removedBy: string | null;
|
|
72
|
+
createdAt: unknown;
|
|
73
|
+
updatedAt: unknown;
|
|
74
|
+
}>;
|
|
75
|
+
commentReported: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
76
|
+
id: string;
|
|
77
|
+
orgId: string;
|
|
78
|
+
commentId: string;
|
|
79
|
+
orgUserId: string;
|
|
80
|
+
reason: string;
|
|
81
|
+
resolvedAt: Date | null;
|
|
82
|
+
createdAt: Date;
|
|
83
|
+
}, "discussion.comment.reported", 1>, {
|
|
84
|
+
id: string;
|
|
85
|
+
orgId: string;
|
|
86
|
+
commentId: string;
|
|
87
|
+
orgUserId: string;
|
|
88
|
+
reason: string;
|
|
89
|
+
resolvedAt: unknown;
|
|
90
|
+
createdAt: unknown;
|
|
91
|
+
}>;
|
|
92
|
+
};
|
|
93
|
+
type CommentCreated = EventOf<typeof discussionEvents.commentCreated>;
|
|
94
|
+
type CommentPublished = EventOf<typeof discussionEvents.commentPublished>;
|
|
95
|
+
type CommentRemoved = EventOf<typeof discussionEvents.commentRemoved>;
|
|
96
|
+
type CommentReported = EventOf<typeof discussionEvents.commentReported>;
|
|
97
|
+
type CommentEvent = EventOfValues<typeof discussionEvents>;
|
|
98
|
+
type NewDiscussionEvent = NewDomainEvent<CommentEvent>;
|
|
99
|
+
//#endregion
|
|
100
|
+
export { CommentCreated, CommentEvent, CommentPublished, CommentRemoved, CommentReported, NewDiscussionEvent, discussionEvents };
|
|
101
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { commentReportSchema, commentSchema } from "../types/schemas/discussion.js";
|
|
2
|
+
import { defineEvent } from "../shared/events.js";
|
|
3
|
+
//#region src/discussion/events.ts
|
|
4
|
+
const discussionEvents = {
|
|
5
|
+
commentCreated: defineEvent({
|
|
6
|
+
type: "discussion.comment.created",
|
|
7
|
+
version: 1,
|
|
8
|
+
data: commentSchema
|
|
9
|
+
}),
|
|
10
|
+
commentPublished: defineEvent({
|
|
11
|
+
type: "discussion.comment.published",
|
|
12
|
+
version: 1,
|
|
13
|
+
data: commentSchema
|
|
14
|
+
}),
|
|
15
|
+
commentRemoved: defineEvent({
|
|
16
|
+
type: "discussion.comment.removed",
|
|
17
|
+
version: 1,
|
|
18
|
+
data: commentSchema
|
|
19
|
+
}),
|
|
20
|
+
commentReported: defineEvent({
|
|
21
|
+
type: "discussion.comment.reported",
|
|
22
|
+
version: 1,
|
|
23
|
+
data: commentReportSchema
|
|
24
|
+
})
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { discussionEvents };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CommentListItem, CommentReaction, CommentReportSummary, CommentSettings, CommentStatus, CommentView, CommentsConfig, ListCommentsQuery, ReactionCounts, ReactionEmoji } from "../types/schemas/discussion.js";
|
|
2
|
+
import { Comment, CommentAuthor, CommentReport } from "../types/discussion.js";
|
|
3
|
+
import { CommentEvent, discussionEvents } from "./events.js";
|
|
4
|
+
import "./model.js";
|
|
5
|
+
import "./types.js";
|
|
6
|
+
import { ActivityComments, Actor, AuthorRecord, CommentReactions, CommentWithContext, CourseAccessReader, DiscussionRepository, DiscussionService, DiscussionUnitOfWork, DiscussionWriteScope, PostCommentInput } from "./ports.js";
|
|
7
|
+
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 };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ActivityCommentsRule } from "../types/schemas/content.js";
|
|
2
|
+
import { CommentReaction, CommentSettings, CommentStatus } from "../types/schemas/discussion.js";
|
|
3
|
+
import { Comment, CommentAuthor, CommentReport } from "../types/discussion.js";
|
|
4
|
+
import "../types/index.js";
|
|
5
|
+
export type { ActivityCommentsRule, Comment, CommentAuthor, CommentReaction, CommentReport, CommentSettings, CommentStatus };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Page } from "../types/shared.js";
|
|
2
|
+
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";
|
|
6
|
+
import "../types/index.js";
|
|
7
|
+
import { OutboxAppender, UnitOfWork } from "../shared/ports.js";
|
|
8
|
+
import "./model.js";
|
|
9
|
+
import "./types.js";
|
|
10
|
+
//#region src/discussion/ports.d.ts
|
|
11
|
+
/** An activity's comments as this reader may see them, with the config that
|
|
12
|
+
* decided it. */
|
|
13
|
+
interface ActivityComments {
|
|
14
|
+
config: CommentsConfig;
|
|
15
|
+
comments: CommentView[];
|
|
16
|
+
}
|
|
17
|
+
interface CommentReactions {
|
|
18
|
+
reactions: ReactionCounts;
|
|
19
|
+
viewerReaction?: ReactionEmoji;
|
|
20
|
+
}
|
|
21
|
+
interface CommentWithContext {
|
|
22
|
+
comment: Comment;
|
|
23
|
+
courseId: string;
|
|
24
|
+
activityTitle: string;
|
|
25
|
+
}
|
|
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
|
+
type PostCommentInput = {
|
|
38
|
+
actor: Actor;
|
|
39
|
+
activityId: string;
|
|
40
|
+
parentId: string | null;
|
|
41
|
+
body: string;
|
|
42
|
+
};
|
|
43
|
+
/** A profile row as the repository loads it, keyed by `org_users.id`. `email`
|
|
44
|
+
* is stripped before comments are served and kept only for the staff list. */
|
|
45
|
+
interface AuthorRecord extends CommentAuthor {
|
|
46
|
+
email: string;
|
|
47
|
+
}
|
|
48
|
+
interface DiscussionService {
|
|
49
|
+
/** Post a root comment or a reply. Lands pending where review is required and
|
|
50
|
+
* the poster is not staff. */
|
|
51
|
+
postComment(orgId: string, input: PostCommentInput): Promise<CommentView>;
|
|
52
|
+
/** Author-only. Throws ForbiddenError for anyone else, staff included. */
|
|
53
|
+
edit(orgId: string, commentId: string, actor: Actor, body: string): Promise<CommentView>;
|
|
54
|
+
/** The author, or anyone whose role is staff. */
|
|
55
|
+
remove(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
|
|
56
|
+
/** Staff only. Returns the comment to published. */
|
|
57
|
+
restore(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
|
|
58
|
+
/** Staff only. Publishes a pending comment. */
|
|
59
|
+
approve(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
|
|
60
|
+
/** Make a comment published, whichever state it is in. Staff only. */
|
|
61
|
+
publish(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
|
|
62
|
+
/** The activity's comments as this reader may see them. */
|
|
63
|
+
activityComments(orgId: string, activityId: string, actor: Actor): Promise<ActivityComments>;
|
|
64
|
+
/**
|
|
65
|
+
* The org's comments, filtered. Staff-scoped: rows carry the author's email
|
|
66
|
+
* and a removed comment's body, neither of which a learner may see, so the
|
|
67
|
+
* edge admits only staff.
|
|
68
|
+
*
|
|
69
|
+
* No rule is applied beyond the filters — this is what exists, not what
|
|
70
|
+
* someone is allowed to read.
|
|
71
|
+
*/
|
|
72
|
+
listComments(orgId: string, query: ListCommentsQuery): Promise<Page<CommentListItem>>;
|
|
73
|
+
setReaction(orgId: string, commentId: string, actor: Actor, emoji: ReactionEmoji | null): Promise<CommentReactions>;
|
|
74
|
+
resolveReports(orgId: string, commentId: string, actor: Actor): Promise<void>;
|
|
75
|
+
/** Accepted even on locked comments — a locked activity can still hold
|
|
76
|
+
* something a moderator needs to see. */
|
|
77
|
+
reportComment(orgId: string, commentId: string, actor: Actor, reason: string): Promise<CommentReport>;
|
|
78
|
+
/** Plain read of one comment — no rules applied. */
|
|
79
|
+
getComment(orgId: string, commentId: string): Promise<Comment | null>;
|
|
80
|
+
}
|
|
81
|
+
interface CourseAccessReader {
|
|
82
|
+
hasCourseAccess(orgId: string, orgUserId: string, courseId: string): Promise<boolean>;
|
|
83
|
+
}
|
|
84
|
+
interface ActivityGetter {
|
|
85
|
+
getActivity(orgId: string, activityId: string): Promise<Activity | null>;
|
|
86
|
+
}
|
|
87
|
+
interface DiscussionRepository {
|
|
88
|
+
insertComment(orgId: string, comment: Comment): Promise<Comment>;
|
|
89
|
+
findComment(orgId: string, id: string): Promise<Comment | null>;
|
|
90
|
+
updateComment(orgId: string, id: string, patch: Partial<Pick<Comment, 'body' | 'status' | 'removedBy' | 'updatedAt'>>): Promise<Comment | null>;
|
|
91
|
+
/** Every comment on the activity, oldest first, including removed ones. */
|
|
92
|
+
listByActivity(orgId: string, activityId: string): Promise<Comment[]>;
|
|
93
|
+
reactionsOf(orgId: string, commentIds: string[], viewerId: string): Promise<Record<string, CommentReactions>>;
|
|
94
|
+
setReaction(orgId: string, commentId: string, orgUserId: string, emoji: ReactionEmoji | null): Promise<void>;
|
|
95
|
+
/** Returns null when this person has already reported this comment. */
|
|
96
|
+
insertReport(orgId: string, report: CommentReport): Promise<CommentReport | null>;
|
|
97
|
+
/** Every unresolved report against the given comments. */
|
|
98
|
+
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>>;
|
|
101
|
+
listComments(orgId: string, query: ListCommentsQuery): Promise<Page<CommentWithContext>>;
|
|
102
|
+
}
|
|
103
|
+
/** Writes that emit events run through this scope so the row and the outbox
|
|
104
|
+
* entry commit in one transaction. */
|
|
105
|
+
interface DiscussionWriteScope {
|
|
106
|
+
discussion: DiscussionRepository;
|
|
107
|
+
outbox: OutboxAppender;
|
|
108
|
+
}
|
|
109
|
+
type DiscussionUnitOfWork = UnitOfWork<DiscussionWriteScope>;
|
|
110
|
+
//#endregion
|
|
111
|
+
export { ActivityComments, ActivityGetter, Actor, AuthorRecord, CommentReactions, CommentWithContext, CourseAccessReader, DiscussionRepository, DiscussionService, DiscussionUnitOfWork, DiscussionWriteScope, PostCommentInput };
|
|
112
|
+
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Page } from "../types/shared.js";
|
|
2
|
+
import { Logger } from "../types/ports.js";
|
|
3
|
+
import { CommentListItem, CommentView, CommentsConfig, ListCommentsQuery, ReactionEmoji } from "../types/schemas/discussion.js";
|
|
4
|
+
import { Comment, CommentReport } from "../types/discussion.js";
|
|
5
|
+
import "../shared/ports.js";
|
|
6
|
+
import { SettingsService } from "../shared/settings.js";
|
|
7
|
+
import "./model.js";
|
|
8
|
+
import "./types.js";
|
|
9
|
+
import { ActivityComments, ActivityGetter, Actor, CommentReactions, CourseAccessReader, DiscussionRepository, DiscussionService, DiscussionUnitOfWork, PostCommentInput } from "./ports.js";
|
|
10
|
+
//#region src/discussion/service.d.ts
|
|
11
|
+
/** A course with no stored settings. Discussion is opt-in, so the common case
|
|
12
|
+
* persists no row at all and every existing course stays silent. */
|
|
13
|
+
declare const DEFAULT_SETTINGS: {
|
|
14
|
+
readonly enabled: false;
|
|
15
|
+
readonly threaded: true;
|
|
16
|
+
readonly requireReview: false;
|
|
17
|
+
readonly reactions: true;
|
|
18
|
+
};
|
|
19
|
+
type DiscussionServiceParams = {
|
|
20
|
+
repo: DiscussionRepository;
|
|
21
|
+
access: CourseAccessReader;
|
|
22
|
+
content: ActivityGetter;
|
|
23
|
+
uow: DiscussionUnitOfWork;
|
|
24
|
+
settings: SettingsService;
|
|
25
|
+
logger?: Logger;
|
|
26
|
+
};
|
|
27
|
+
declare class DiscussionServiceImpl implements DiscussionService {
|
|
28
|
+
private readonly repo;
|
|
29
|
+
private readonly access;
|
|
30
|
+
private readonly content;
|
|
31
|
+
private readonly uow;
|
|
32
|
+
private readonly settings;
|
|
33
|
+
private readonly logger;
|
|
34
|
+
constructor(params: DiscussionServiceParams);
|
|
35
|
+
resolveConfig(orgId: string, activityId: string): Promise<CommentsConfig>;
|
|
36
|
+
/** Any org user that is not a learner moderates. The role arrives from
|
|
37
|
+
* the edge already resolved; core never looks one up to authorise. */
|
|
38
|
+
private isStaff;
|
|
39
|
+
private toAuthor;
|
|
40
|
+
private toView;
|
|
41
|
+
private peopleIn;
|
|
42
|
+
private renderOne;
|
|
43
|
+
private hasAccess;
|
|
44
|
+
postComment(orgId: string, { activityId, actor, parentId, body }: PostCommentInput): Promise<CommentView>;
|
|
45
|
+
activityComments(orgId: string, activityId: string, actor: Actor): Promise<ActivityComments>;
|
|
46
|
+
edit(orgId: string, commentId: string, actor: Actor, body: string): Promise<CommentView>;
|
|
47
|
+
remove(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
|
|
48
|
+
restore(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
|
|
49
|
+
/** Load a comment together with its activity's resolved comments config,
|
|
50
|
+
* having proved the actor may reach that activity at all. Every path that
|
|
51
|
+
* acts on one comment needs the pair, and none should read the row twice. */
|
|
52
|
+
private loadWithConfig;
|
|
53
|
+
setReaction(orgId: string, commentId: string, actor: Actor, emoji: ReactionEmoji | null): Promise<CommentReactions>;
|
|
54
|
+
approve(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
|
|
55
|
+
/** Loads the comment and dispatches to whichever transition applies — the
|
|
56
|
+
* caller must not decide that itself. `approve` and `restore` still enforce
|
|
57
|
+
* their own staff check; the check here covers the third path, where a
|
|
58
|
+
* comment is already published and neither of them would run. */
|
|
59
|
+
publish(orgId: string, commentId: string, actor: Actor): Promise<Comment>;
|
|
60
|
+
resolveReports(orgId: string, commentId: string, actor: Actor): Promise<void>;
|
|
61
|
+
reportComment(orgId: string, commentId: string, actor: Actor, reason: string): Promise<CommentReport>;
|
|
62
|
+
listComments(orgId: string, query: ListCommentsQuery): Promise<Page<CommentListItem>>;
|
|
63
|
+
getComment(orgId: string, commentId: string): Promise<Comment | null>;
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { DEFAULT_SETTINGS, DiscussionServiceImpl, DiscussionServiceParams };
|
|
67
|
+
//# sourceMappingURL=service.d.ts.map
|