@memberjunction/server 6.2.0-edge.1 → 6.2.0-edge.3

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 (220) hide show
  1. package/README.md +30 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/config.d.ts +2189 -71
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +123 -3
  6. package/dist/config.js.map +1 -1
  7. package/dist/context.d.ts.map +1 -1
  8. package/dist/context.js +11 -23
  9. package/dist/context.js.map +1 -1
  10. package/dist/generated/graphql-schemas/__mj.d.ts +2143 -205
  11. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  12. package/dist/generated/graphql-schemas/__mj.js +24441 -14433
  13. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  14. package/dist/generic/FireAndForgetHeartbeat.d.ts +15 -1
  15. package/dist/generic/FireAndForgetHeartbeat.d.ts.map +1 -1
  16. package/dist/generic/FireAndForgetHeartbeat.js +16 -2
  17. package/dist/generic/FireAndForgetHeartbeat.js.map +1 -1
  18. package/dist/generic/OrphanedConversationDetailReconciler.d.ts +31 -0
  19. package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -0
  20. package/dist/generic/OrphanedConversationDetailReconciler.js +215 -0
  21. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -0
  22. package/dist/generic/PushStatusResolver.d.ts +38 -0
  23. package/dist/generic/PushStatusResolver.d.ts.map +1 -1
  24. package/dist/generic/PushStatusResolver.js +84 -1
  25. package/dist/generic/PushStatusResolver.js.map +1 -1
  26. package/dist/generic/ResolverBase.d.ts +56 -4
  27. package/dist/generic/ResolverBase.d.ts.map +1 -1
  28. package/dist/generic/ResolverBase.js +191 -74
  29. package/dist/generic/ResolverBase.js.map +1 -1
  30. package/dist/generic/RunViewResolver.d.ts +4 -0
  31. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  32. package/dist/generic/RunViewResolver.js +33 -1
  33. package/dist/generic/RunViewResolver.js.map +1 -1
  34. package/dist/index.d.ts +4 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +204 -50
  37. package/dist/index.js.map +1 -1
  38. package/dist/postgresqlCompat.d.ts +8 -0
  39. package/dist/postgresqlCompat.d.ts.map +1 -0
  40. package/dist/postgresqlCompat.js +19 -0
  41. package/dist/postgresqlCompat.js.map +1 -0
  42. package/dist/postgresqlPoolSettings.d.ts +108 -0
  43. package/dist/postgresqlPoolSettings.d.ts.map +1 -0
  44. package/dist/postgresqlPoolSettings.js +134 -0
  45. package/dist/postgresqlPoolSettings.js.map +1 -0
  46. package/dist/resolvers/AdhocQueryResolver.d.ts +23 -18
  47. package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
  48. package/dist/resolvers/AdhocQueryResolver.js +77 -167
  49. package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
  50. package/dist/resolvers/AgentRunStatusPublisher.d.ts +55 -0
  51. package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -0
  52. package/dist/resolvers/AgentRunStatusPublisher.js +141 -0
  53. package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -0
  54. package/dist/resolvers/ConversationRunEventsResolver.d.ts +90 -0
  55. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -0
  56. package/dist/resolvers/ConversationRunEventsResolver.js +283 -0
  57. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -0
  58. package/dist/resolvers/DuplicateEntryCheckResolver.d.ts +98 -0
  59. package/dist/resolvers/DuplicateEntryCheckResolver.d.ts.map +1 -0
  60. package/dist/resolvers/DuplicateEntryCheckResolver.js +227 -0
  61. package/dist/resolvers/DuplicateEntryCheckResolver.js.map +1 -0
  62. package/dist/resolvers/EntityRecordNameResolver.d.ts +7 -23
  63. package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
  64. package/dist/resolvers/EntityRecordNameResolver.js +9 -47
  65. package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
  66. package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
  67. package/dist/resolvers/FetchEntityVectorsResolver.js +2 -1
  68. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  69. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  70. package/dist/resolvers/GetDataResolver.js +9 -0
  71. package/dist/resolvers/GetDataResolver.js.map +1 -1
  72. package/dist/resolvers/HumanHandoffResolver.d.ts +107 -0
  73. package/dist/resolvers/HumanHandoffResolver.d.ts.map +1 -0
  74. package/dist/resolvers/HumanHandoffResolver.js +324 -0
  75. package/dist/resolvers/HumanHandoffResolver.js.map +1 -0
  76. package/dist/resolvers/MeetingResolver.d.ts +69 -0
  77. package/dist/resolvers/MeetingResolver.d.ts.map +1 -0
  78. package/dist/resolvers/MeetingResolver.js +381 -0
  79. package/dist/resolvers/MeetingResolver.js.map +1 -0
  80. package/dist/resolvers/MergeRecordsResolver.d.ts +7 -0
  81. package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
  82. package/dist/resolvers/MergeRecordsResolver.js +16 -2
  83. package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
  84. package/dist/resolvers/RealtimeBridgeResolver.d.ts +34 -1
  85. package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
  86. package/dist/resolvers/RealtimeBridgeResolver.js +202 -7
  87. package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
  88. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +45 -89
  89. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  90. package/dist/resolvers/RealtimeClientSessionResolver.js +94 -240
  91. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  92. package/dist/resolvers/RunAIAgentResolver.d.ts +0 -16
  93. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  94. package/dist/resolvers/RunAIAgentResolver.js +23 -153
  95. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  96. package/dist/resolvers/RunDecisionResolver.d.ts +149 -0
  97. package/dist/resolvers/RunDecisionResolver.d.ts.map +1 -0
  98. package/dist/resolvers/RunDecisionResolver.js +396 -0
  99. package/dist/resolvers/RunDecisionResolver.js.map +1 -0
  100. package/dist/resolvers/VectorizeEntityResolver.d.ts +1 -1
  101. package/dist/resolvers/VectorizeEntityResolver.d.ts.map +1 -1
  102. package/dist/resolvers/VectorizeEntityResolver.js +14 -10
  103. package/dist/resolvers/VectorizeEntityResolver.js.map +1 -1
  104. package/dist/resolvers/adhocTimeout.d.ts +7 -0
  105. package/dist/resolvers/adhocTimeout.d.ts.map +1 -0
  106. package/dist/resolvers/adhocTimeout.js +12 -0
  107. package/dist/resolvers/adhocTimeout.js.map +1 -0
  108. package/dist/resolvers/meetings/index.d.ts +5 -0
  109. package/dist/resolvers/meetings/index.d.ts.map +1 -0
  110. package/dist/resolvers/meetings/index.js +5 -0
  111. package/dist/resolvers/meetings/index.js.map +1 -0
  112. package/dist/resolvers/meetings/meetingHelpers.d.ts +17 -0
  113. package/dist/resolvers/meetings/meetingHelpers.d.ts.map +1 -0
  114. package/dist/resolvers/meetings/meetingHelpers.js +212 -0
  115. package/dist/resolvers/meetings/meetingHelpers.js.map +1 -0
  116. package/dist/resolvers/meetings/meetingMutations.d.ts +12 -0
  117. package/dist/resolvers/meetings/meetingMutations.d.ts.map +1 -0
  118. package/dist/resolvers/meetings/meetingMutations.js +418 -0
  119. package/dist/resolvers/meetings/meetingMutations.js.map +1 -0
  120. package/dist/resolvers/meetings/meetingQueries.d.ts +7 -0
  121. package/dist/resolvers/meetings/meetingQueries.d.ts.map +1 -0
  122. package/dist/resolvers/meetings/meetingQueries.js +113 -0
  123. package/dist/resolvers/meetings/meetingQueries.js.map +1 -0
  124. package/dist/resolvers/meetings/meetingTypes.d.ts +89 -0
  125. package/dist/resolvers/meetings/meetingTypes.d.ts.map +1 -0
  126. package/dist/resolvers/meetings/meetingTypes.js +345 -0
  127. package/dist/resolvers/meetings/meetingTypes.js.map +1 -0
  128. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  129. package/dist/rest/ViewOperationsHandler.js +8 -5
  130. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  131. package/dist/services/TaskGraphActionRunner.d.ts +8 -0
  132. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  133. package/dist/services/TaskGraphActionRunner.js +27 -1
  134. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  135. package/dist/services/WorkQueueHostService.d.ts +36 -0
  136. package/dist/services/WorkQueueHostService.d.ts.map +1 -0
  137. package/dist/services/WorkQueueHostService.js +97 -0
  138. package/dist/services/WorkQueueHostService.js.map +1 -0
  139. package/dist/services/workQueueConfig.d.ts +103 -0
  140. package/dist/services/workQueueConfig.d.ts.map +1 -0
  141. package/dist/services/workQueueConfig.js +48 -0
  142. package/dist/services/workQueueConfig.js.map +1 -0
  143. package/dist/types.d.ts +5 -0
  144. package/dist/types.d.ts.map +1 -1
  145. package/dist/types.js.map +1 -1
  146. package/package.json +95 -92
  147. package/src/__tests__/AdhocQueryResolver.bugs.test.ts +14 -35
  148. package/src/__tests__/AdhocQueryResolver.pagination.test.ts +6 -2
  149. package/src/__tests__/AdhocQueryResolver.scopeGuard.test.ts +3 -3
  150. package/src/__tests__/AgentRunStatusPublisher.test.ts +175 -0
  151. package/src/__tests__/DuplicateEntryCheckResolver.test.ts +300 -0
  152. package/src/__tests__/EntityRecordNameResolver.fieldSecurity.test.ts +27 -72
  153. package/src/__tests__/HumanHandoffResolver.test.ts +233 -0
  154. package/src/__tests__/MeetingResolver.test.ts +374 -0
  155. package/src/__tests__/RealtimeBridgeResolver.test.ts +240 -2
  156. package/src/__tests__/RealtimeClientSessionResolver.test.ts +216 -2
  157. package/src/__tests__/RemoteBrowserActionRecovery.test.ts +7 -1
  158. package/src/__tests__/RemoteBrowserAudioStream.test.ts +7 -1
  159. package/src/__tests__/RemoteBrowserSnapshot.test.ts +7 -1
  160. package/src/__tests__/ResolverBase.adhocReadScope.test.ts +96 -0
  161. package/src/__tests__/ResolverBase.clientOldValues.test.ts +52 -0
  162. package/src/__tests__/ResolverBase.filterEscaping.test.ts +21 -2
  163. package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +291 -0
  164. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +182 -12
  165. package/src/__tests__/RunAIAgentResolver.streaming.test.ts +18 -27
  166. package/src/__tests__/RunDecisionResolver.test.ts +699 -0
  167. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +43 -0
  168. package/src/__tests__/VectorizeEntityResolver.test.ts +106 -0
  169. package/src/__tests__/WorkQueueHostService.test.ts +133 -0
  170. package/src/__tests__/adhocTimeoutClamp.test.ts +26 -0
  171. package/src/__tests__/conversationRunEvents.test.ts +399 -0
  172. package/src/__tests__/orphanedConversationDetailReconciler.test.ts +283 -0
  173. package/src/__tests__/postgresqlPoolSettings.test.ts +131 -0
  174. package/src/__tests__/pushStatusFanOut.test.ts +206 -0
  175. package/src/__tests__/translateBracketsToPG.test.ts +20 -0
  176. package/src/auth/__tests__/backward-compatibility.test.ts +1 -0
  177. package/src/config.ts +130 -3
  178. package/src/context.ts +11 -24
  179. package/src/generated/graphql-schemas/__mj.ts +24183 -17182
  180. package/src/generic/FireAndForgetHeartbeat.ts +16 -2
  181. package/src/generic/OrphanedConversationDetailReconciler.ts +267 -0
  182. package/src/generic/PushStatusResolver.ts +97 -1
  183. package/src/generic/ResolverBase.ts +220 -76
  184. package/src/generic/RunViewResolver.ts +33 -2
  185. package/src/index.ts +228 -51
  186. package/src/postgresqlCompat.ts +21 -0
  187. package/src/postgresqlPoolSettings.ts +213 -0
  188. package/src/resolvers/AdhocQueryResolver.ts +88 -188
  189. package/src/resolvers/AgentRunStatusPublisher.ts +175 -0
  190. package/src/resolvers/ConversationRunEventsResolver.ts +308 -0
  191. package/src/resolvers/DuplicateEntryCheckResolver.ts +232 -0
  192. package/src/resolvers/EntityRecordNameResolver.ts +9 -51
  193. package/src/resolvers/FetchEntityVectorsResolver.ts +2 -1
  194. package/src/resolvers/GetDataResolver.ts +10 -0
  195. package/src/resolvers/HumanHandoffResolver.ts +304 -0
  196. package/src/resolvers/MeetingResolver.ts +438 -0
  197. package/src/resolvers/MergeRecordsResolver.ts +14 -2
  198. package/src/resolvers/RealtimeBridgeResolver.ts +227 -13
  199. package/src/resolvers/RealtimeClientSessionResolver.ts +99 -287
  200. package/src/resolvers/RunAIAgentResolver.ts +28 -174
  201. package/src/resolvers/RunDecisionResolver.ts +435 -0
  202. package/src/resolvers/VectorizeEntityResolver.ts +16 -11
  203. package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +93 -0
  204. package/src/resolvers/adhocTimeout.ts +12 -0
  205. package/src/resolvers/meetings/index.ts +4 -0
  206. package/src/resolvers/meetings/meetingHelpers.ts +307 -0
  207. package/src/resolvers/meetings/meetingMutations.ts +535 -0
  208. package/src/resolvers/meetings/meetingQueries.ts +172 -0
  209. package/src/resolvers/meetings/meetingTypes.ts +238 -0
  210. package/src/rest/ViewOperationsHandler.ts +8 -5
  211. package/src/services/TaskGraphActionRunner.ts +29 -1
  212. package/src/services/WorkQueueHostService.ts +129 -0
  213. package/src/services/workQueueConfig.ts +52 -0
  214. package/src/types.ts +5 -0
  215. package/dist/resolvers/adhoc-query-helpers.d.ts +0 -33
  216. package/dist/resolvers/adhoc-query-helpers.d.ts.map +0 -1
  217. package/dist/resolvers/adhoc-query-helpers.js +0 -50
  218. package/dist/resolvers/adhoc-query-helpers.js.map +0 -1
  219. package/src/__tests__/adhoc-query-helpers.test.ts +0 -50
  220. package/src/resolvers/adhoc-query-helpers.ts +0 -67
@@ -0,0 +1,212 @@
1
+ import { LogError, RunView, } from '@memberjunction/core';
2
+ import { EscapeSQLString, UUIDsEqual } from '@memberjunction/global';
3
+ import { MeetingDialInService } from '@memberjunction/livekit-room-server';
4
+ import { NotificationEngine } from '@memberjunction/notifications';
5
+ export async function LoadMeetingEntity(id, user, provider) {
6
+ const rv = provider ? RunView.FromMetadataProvider(provider) : new RunView();
7
+ const escapedID = EscapeSQLString(id.trim());
8
+ const res = await rv.RunView({
9
+ EntityName: 'MJ: Meetings',
10
+ ExtraFilter: `ID = '${escapedID}'`,
11
+ ResultType: 'entity_object',
12
+ }, user);
13
+ if (res.Success && res.Results && res.Results.length > 0) {
14
+ return res.Results[0];
15
+ }
16
+ return null;
17
+ }
18
+ export async function LoadParticipants(meetingID, user, provider) {
19
+ const rv = provider ? RunView.FromMetadataProvider(provider) : new RunView();
20
+ const escapedID = EscapeSQLString(meetingID.trim());
21
+ const res = await rv.RunView({
22
+ EntityName: 'MJ: Meeting Participants',
23
+ ExtraFilter: `MeetingID = '${escapedID}'`,
24
+ ResultType: 'entity_object',
25
+ }, user);
26
+ if (!res.Success || !res.Results) {
27
+ return [];
28
+ }
29
+ return res.Results.map((p) => MapParticipantToType(p));
30
+ }
31
+ export async function IsUserHostOrCoHost(meeting, user, provider) {
32
+ if (UUIDsEqual(meeting.HostUserID, user.ID)) {
33
+ return true;
34
+ }
35
+ const rv = provider ? RunView.FromMetadataProvider(provider) : new RunView();
36
+ const escapedID = EscapeSQLString(meeting.ID);
37
+ const escapedUserID = EscapeSQLString(user.ID);
38
+ const res = await rv.RunView({
39
+ EntityName: 'MJ: Meeting Participants',
40
+ ExtraFilter: `MeetingID = '${escapedID}' AND UserID = '${escapedUserID}' AND Role IN ('Host', 'CoHost')`,
41
+ ResultType: 'entity_object',
42
+ }, user);
43
+ return Boolean(res.Success && res.Results && res.Results.length > 0);
44
+ }
45
+ export async function ResolveDefaultPhoneNumber(user, provider) {
46
+ const rv = provider ? RunView.FromMetadataProvider(provider) : new RunView();
47
+ const res = await rv.RunView({
48
+ EntityName: 'MJ: Phone Numbers',
49
+ ExtraFilter: "Status = 'Active'",
50
+ OrderBy: '__mj_CreatedAt ASC',
51
+ ResultType: 'entity_object',
52
+ }, user);
53
+ if (res.Success && res.Results && res.Results.length > 0) {
54
+ return res.Results[0];
55
+ }
56
+ return null;
57
+ }
58
+ export async function GenerateUniqueDialInCode(phoneNumberID, user, provider) {
59
+ return MeetingDialInService.Instance.GenerateUniqueDialInCode(phoneNumberID, user, provider);
60
+ }
61
+ export async function EnsureMeetingInteraction(meeting, user, provider) {
62
+ try {
63
+ const rv = provider ? RunView.FromMetadataProvider(provider) : new RunView();
64
+ const escapedRoom = EscapeSQLString(meeting.RoomName);
65
+ const existing = await rv.RunView({
66
+ EntityName: 'MJ: Interactions',
67
+ ExtraFilter: `RoomName = '${escapedRoom}'`,
68
+ ResultType: 'entity_object',
69
+ }, user);
70
+ if (existing.Success && existing.Results && existing.Results.length > 0) {
71
+ return existing.Results[0];
72
+ }
73
+ const entity = await provider.GetEntityObject('MJ: Interactions', user);
74
+ entity.Channel = 'Meeting';
75
+ entity.Direction = 'Inbound';
76
+ entity.Status = 'Active';
77
+ entity.RoomName = meeting.RoomName;
78
+ entity.StartedAt = new Date();
79
+ entity.AnsweredAt = new Date();
80
+ entity.RecordingEnabled = meeting.RecordingPolicy === 'Automatic' || meeting.RecordingPolicy === 'Allowed';
81
+ if (await entity.Save()) {
82
+ await RecordInteractionEvent(entity.ID, 'Created', user, provider, { MeetingID: meeting.ID, RoomName: meeting.RoomName });
83
+ await RecordInteractionEvent(entity.ID, 'Answered', user, provider);
84
+ return entity;
85
+ }
86
+ return null;
87
+ }
88
+ catch (err) {
89
+ LogError(`[MeetingResolver] ensureMeetingInteraction failed: ${err instanceof Error ? err.message : String(err)}`);
90
+ return null;
91
+ }
92
+ }
93
+ export async function RecordInteractionEvent(interactionID, eventType, user, provider, details) {
94
+ try {
95
+ const eventEntity = await provider.GetEntityObject('MJ: Interaction Events', user);
96
+ eventEntity.InteractionID = interactionID;
97
+ eventEntity.EventType = eventType;
98
+ eventEntity.ActorUserID = user.ID;
99
+ eventEntity.OccurredAt = new Date();
100
+ if (details) {
101
+ eventEntity.Details = JSON.stringify(details);
102
+ }
103
+ await eventEntity.Save();
104
+ }
105
+ catch (err) {
106
+ LogError(`[MeetingResolver] recordInteractionEvent (${eventType}) failed: ${err instanceof Error ? err.message : String(err)}`);
107
+ }
108
+ }
109
+ export async function CloseMeetingInteraction(roomName, user, provider) {
110
+ try {
111
+ const rv = provider ? RunView.FromMetadataProvider(provider) : new RunView();
112
+ const escapedRoom = EscapeSQLString(roomName);
113
+ const res = await rv.RunView({
114
+ EntityName: 'MJ: Interactions',
115
+ ExtraFilter: `RoomName = '${escapedRoom}' AND Status = 'Active'`,
116
+ ResultType: 'entity_object',
117
+ }, user);
118
+ if (res.Success && res.Results && res.Results.length > 0) {
119
+ const interaction = res.Results[0];
120
+ interaction.Status = 'Ended';
121
+ interaction.EndedAt = new Date();
122
+ await interaction.Save();
123
+ await RecordInteractionEvent(interaction.ID, 'Ended', user, provider);
124
+ }
125
+ }
126
+ catch (err) {
127
+ LogError(`[MeetingResolver] closeMeetingInteraction failed: ${err instanceof Error ? err.message : String(err)}`);
128
+ }
129
+ }
130
+ export async function SendMeetingInviteNotification(meeting, targetUserID, contextUser, provider) {
131
+ try {
132
+ await NotificationEngine.Instance.Config(false, contextUser, provider);
133
+ const inviter = contextUser.Name?.trim() || contextUser.Email || 'Someone';
134
+ await NotificationEngine.Instance.SendNotification({
135
+ userId: targetUserID,
136
+ typeNameOrId: 'Meeting Invitation',
137
+ title: `Invitation: ${meeting.Title}`,
138
+ message: `${inviter} invited you to the meeting "${meeting.Title}".`,
139
+ resourceConfiguration: { type: 'meeting', meetingID: meeting.ID, roomName: meeting.RoomName },
140
+ }, contextUser);
141
+ }
142
+ catch (err) {
143
+ LogError(`[MeetingResolver] sendMeetingInviteNotification failed for user ${targetUserID}: ${err instanceof Error ? err.message : String(err)}`);
144
+ }
145
+ }
146
+ export function NormalizeParticipantRole(roleInput, defaultRole = 'Attendee') {
147
+ switch (roleInput?.trim().toLowerCase()) {
148
+ case 'host':
149
+ return 'Host';
150
+ case 'cohost':
151
+ return 'CoHost';
152
+ case 'agent':
153
+ return 'Agent';
154
+ case 'attendee':
155
+ default:
156
+ return defaultRole;
157
+ }
158
+ }
159
+ export function NormalizeRecordingPolicy(policyInput) {
160
+ switch (policyInput?.trim().toLowerCase()) {
161
+ case 'allowed':
162
+ return 'Allowed';
163
+ case 'automatic':
164
+ return 'Automatic';
165
+ case 'off':
166
+ default:
167
+ return 'Off';
168
+ }
169
+ }
170
+ export function MapMeetingToType(m, participants) {
171
+ return {
172
+ ID: m.ID,
173
+ Title: m.Title,
174
+ Description: m.Description ?? undefined,
175
+ HostUserID: m.HostUserID,
176
+ HostUserName: m.HostUser ?? undefined,
177
+ RoomName: m.RoomName,
178
+ Status: m.Status,
179
+ ScheduledStartAt: m.ScheduledStartAt ?? undefined,
180
+ ScheduledEndAt: m.ScheduledEndAt ?? undefined,
181
+ StartedAt: m.StartedAt ?? undefined,
182
+ EndedAt: m.EndedAt ?? undefined,
183
+ AllowPhoneDialIn: m.AllowPhoneDialIn,
184
+ DialInPhoneNumberID: m.DialInPhoneNumberID ?? undefined,
185
+ DialInPhoneNumber: m.DialInPhoneNumber ?? undefined,
186
+ DialInCode: m.DialInCode ?? undefined,
187
+ RecordingPolicy: m.RecordingPolicy,
188
+ ConversationID: m.ConversationID ?? undefined,
189
+ Participants: participants,
190
+ CreatedAt: m.__mj_CreatedAt,
191
+ UpdatedAt: m.__mj_UpdatedAt,
192
+ };
193
+ }
194
+ export function MapParticipantToType(p, userNameFallback, userEmailFallback) {
195
+ return {
196
+ ID: p.ID,
197
+ MeetingID: p.MeetingID,
198
+ UserID: p.UserID ?? undefined,
199
+ UserName: p.User ?? userNameFallback ?? undefined,
200
+ UserEmail: userEmailFallback ?? undefined,
201
+ AgentID: p.AgentID ?? undefined,
202
+ AgentName: p.Agent ?? undefined,
203
+ ExternalName: p.ExternalName ?? undefined,
204
+ ExternalEmail: p.ExternalEmail ?? undefined,
205
+ ExternalPhone: p.ExternalPhone ?? undefined,
206
+ Role: p.Role,
207
+ InviteStatus: p.InviteStatus,
208
+ JoinedAt: p.JoinedAt ?? undefined,
209
+ LeftAt: p.LeftAt ?? undefined,
210
+ };
211
+ }
212
+ //# sourceMappingURL=meetingHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meetingHelpers.js","sourceRoot":"","sources":["../../../src/resolvers/meetings/meetingHelpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { IMetadataProvider, UserInfo } from '@memberjunction/core';
2
+ import { SessionManager } from '../../agentSessions/SessionManager.js';
3
+ import { MeetingResult, StartMeetingResult, CreateMeetingInput, UpdateMeetingInput, RSVPMeetingInput } from './meetingTypes.js';
4
+ import * as defaultHelpers from './meetingHelpers.js';
5
+ export type MeetingHelpers = typeof defaultHelpers;
6
+ export declare function ExecuteCreateMeeting(provider: IMetadataProvider, user: UserInfo, input: CreateMeetingInput, helpers?: Partial<MeetingHelpers>): Promise<MeetingResult>;
7
+ export declare function ExecuteUpdateMeeting(provider: IMetadataProvider, user: UserInfo, input: UpdateMeetingInput, helpers?: Partial<MeetingHelpers>): Promise<MeetingResult>;
8
+ export declare function ExecuteStartMeeting(provider: IMetadataProvider, user: UserInfo, meetingID: string, sessionManager: SessionManager, helpers?: Partial<MeetingHelpers>): Promise<StartMeetingResult>;
9
+ export declare function ExecuteEndMeeting(provider: IMetadataProvider, user: UserInfo, meetingID: string, helpers?: Partial<MeetingHelpers>): Promise<MeetingResult>;
10
+ export declare function ExecuteCancelMeeting(provider: IMetadataProvider, user: UserInfo, meetingID: string, helpers?: Partial<MeetingHelpers>): Promise<MeetingResult>;
11
+ export declare function ExecuteRSVPMeeting(provider: IMetadataProvider, user: UserInfo, input: RSVPMeetingInput, helpers?: Partial<MeetingHelpers>): Promise<MeetingResult>;
12
+ //# sourceMappingURL=meetingMutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meetingMutations.d.ts","sourceRoot":"","sources":["../../../src/resolvers/meetings/meetingMutations.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EAGjB,QAAQ,EACT,MAAM,sBAAsB,CAAC;AAY9B,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvE,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAEjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AAEtD,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC;AAMnD,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,kBAAkB,EACzB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,CAoHxB;AAED,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,kBAAkB,EACzB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,CA6IxB;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,cAAc,EAC9B,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAmF7B;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,CAwCxB;AAED,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,CA4BxB;AAED,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,gBAAgB,EACvB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,CAiDxB"}
@@ -0,0 +1,418 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { LogError, RunView, } from '@memberjunction/core';
3
+ import { EscapeSQLString, UUIDsEqual } from '@memberjunction/global';
4
+ import { LiveKitTokenService, LiveKitAgentRoomCoordinator, LiveKitEgressService, LiveKitUserIdentity, } from '@memberjunction/livekit-room-server';
5
+ import { CorrelateRecordingStart } from '../meetingRecordingRegistration.js';
6
+ import * as defaultHelpers from './meetingHelpers.js';
7
+ function resolveHelpers(overrides) {
8
+ return { ...defaultHelpers, ...overrides };
9
+ }
10
+ export async function ExecuteCreateMeeting(provider, user, input, helpers) {
11
+ const h = resolveHelpers(helpers);
12
+ try {
13
+ const trimmedTitle = input.Title?.trim();
14
+ if (!trimmedTitle) {
15
+ return { Success: false, ErrorMessage: 'Meeting title is required.' };
16
+ }
17
+ if (input.ScheduledStartAt && input.ScheduledEndAt && input.ScheduledEndAt <= input.ScheduledStartAt) {
18
+ return { Success: false, ErrorMessage: 'Scheduled end time must be after scheduled start time.' };
19
+ }
20
+ const allowDialIn = input.AllowPhoneDialIn ?? false;
21
+ let dialInPhoneNumberID = input.DialInPhoneNumberID?.trim();
22
+ let dialInCode;
23
+ if (allowDialIn) {
24
+ if (!dialInPhoneNumberID) {
25
+ // Select default active phone number
26
+ const defaultNumber = await h.ResolveDefaultPhoneNumber(user, provider);
27
+ if (!defaultNumber) {
28
+ return {
29
+ Success: false,
30
+ ErrorMessage: 'Cannot allow phone dial-in: no active phone numbers are configured in the system.',
31
+ };
32
+ }
33
+ dialInPhoneNumberID = defaultNumber.ID;
34
+ }
35
+ // Generate a random unique dial-in code (6 digits)
36
+ dialInCode = await h.GenerateUniqueDialInCode(dialInPhoneNumberID, user, provider);
37
+ if (!dialInCode) {
38
+ return { Success: false, ErrorMessage: 'Failed to generate a unique dial-in code for this phone number.' };
39
+ }
40
+ }
41
+ // Room name is always unguessable and generated: mj-mtg-<uuid>
42
+ const roomName = `mj-mtg-${randomUUID()}`;
43
+ const meeting = await provider.GetEntityObject('MJ: Meetings', user);
44
+ meeting.Title = trimmedTitle;
45
+ meeting.Description = input.Description?.trim() || null;
46
+ meeting.HostUserID = user.ID;
47
+ meeting.RoomName = roomName;
48
+ meeting.Status = 'Scheduled';
49
+ meeting.ScheduledStartAt = input.ScheduledStartAt ?? null;
50
+ meeting.ScheduledEndAt = input.ScheduledEndAt ?? null;
51
+ meeting.AllowPhoneDialIn = allowDialIn;
52
+ meeting.DialInPhoneNumberID = allowDialIn ? dialInPhoneNumberID : null;
53
+ meeting.DialInCode = allowDialIn ? dialInCode : null;
54
+ meeting.RecordingPolicy = h.NormalizeRecordingPolicy(input.RecordingPolicy);
55
+ if (!(await meeting.Save())) {
56
+ const err = meeting.LatestResult?.CompleteMessage ?? 'Failed to save meeting.';
57
+ LogError(`[MeetingResolver] CreateMeeting save failed: ${err}`);
58
+ return { Success: false, ErrorMessage: err };
59
+ }
60
+ // Add Host as accepted participant
61
+ const hostParticipant = await provider.GetEntityObject('MJ: Meeting Participants', user);
62
+ hostParticipant.MeetingID = meeting.ID;
63
+ hostParticipant.UserID = user.ID;
64
+ hostParticipant.Role = 'Host';
65
+ hostParticipant.InviteStatus = 'Accepted';
66
+ await hostParticipant.Save();
67
+ // Add other participants
68
+ const participants = [h.MapParticipantToType(hostParticipant, user.Name, user.Email)];
69
+ if (input.Participants && input.Participants.length > 0) {
70
+ for (const pInput of input.Participants) {
71
+ // Skip if duplicate of host
72
+ if (pInput.UserID && UUIDsEqual(pInput.UserID, user.ID)) {
73
+ continue;
74
+ }
75
+ const participant = await provider.GetEntityObject('MJ: Meeting Participants', user);
76
+ participant.MeetingID = meeting.ID;
77
+ if (pInput.AgentID && pInput.AgentID.trim()) {
78
+ participant.AgentID = pInput.AgentID.trim();
79
+ participant.Role = 'Agent';
80
+ participant.InviteStatus = 'Accepted';
81
+ }
82
+ else if (pInput.UserID && pInput.UserID.trim()) {
83
+ participant.UserID = pInput.UserID.trim();
84
+ participant.Role = h.NormalizeParticipantRole(pInput.Role, 'Attendee');
85
+ participant.InviteStatus = 'Invited';
86
+ }
87
+ else {
88
+ // External guest
89
+ participant.ExternalName = pInput.ExternalName?.trim() || null;
90
+ participant.ExternalEmail = pInput.ExternalEmail?.trim() || null;
91
+ participant.ExternalPhone = pInput.ExternalPhone?.trim() || null;
92
+ participant.Role = h.NormalizeParticipantRole(pInput.Role, 'Attendee');
93
+ participant.InviteStatus = 'Invited';
94
+ }
95
+ if (await participant.Save()) {
96
+ participants.push(h.MapParticipantToType(participant));
97
+ // Send notification for internal users
98
+ if (participant.UserID) {
99
+ void h.SendMeetingInviteNotification(meeting, participant.UserID, user, provider);
100
+ }
101
+ }
102
+ }
103
+ }
104
+ return {
105
+ Success: true,
106
+ Meeting: h.MapMeetingToType(meeting, participants),
107
+ };
108
+ }
109
+ catch (error) {
110
+ const msg = error instanceof Error ? error.message : String(error);
111
+ LogError(`[MeetingResolver] CreateMeeting exception: ${msg}`);
112
+ return { Success: false, ErrorMessage: msg };
113
+ }
114
+ }
115
+ export async function ExecuteUpdateMeeting(provider, user, input, helpers) {
116
+ const h = resolveHelpers(helpers);
117
+ try {
118
+ const meeting = await h.LoadMeetingEntity(input.MeetingID, user, provider);
119
+ if (!meeting) {
120
+ return { Success: false, ErrorMessage: 'Meeting not found.' };
121
+ }
122
+ // Check authorization (host or co-host)
123
+ const authorized = await h.IsUserHostOrCoHost(meeting, user, provider);
124
+ if (!authorized) {
125
+ return { Success: false, ErrorMessage: 'Unauthorized: only the host or co-host may modify this meeting.' };
126
+ }
127
+ if (meeting.Status === 'Ended' || meeting.Status === 'Cancelled') {
128
+ return { Success: false, ErrorMessage: `Cannot modify a meeting with status '${meeting.Status}'.` };
129
+ }
130
+ if (input.Title !== undefined) {
131
+ const trimmedTitle = input.Title.trim();
132
+ if (!trimmedTitle) {
133
+ return { Success: false, ErrorMessage: 'Meeting title cannot be empty.' };
134
+ }
135
+ meeting.Title = trimmedTitle;
136
+ }
137
+ if (input.Description !== undefined) {
138
+ meeting.Description = input.Description?.trim() || null;
139
+ }
140
+ if (input.ScheduledStartAt !== undefined) {
141
+ meeting.ScheduledStartAt = input.ScheduledStartAt;
142
+ }
143
+ if (input.ScheduledEndAt !== undefined) {
144
+ meeting.ScheduledEndAt = input.ScheduledEndAt;
145
+ }
146
+ if (meeting.ScheduledStartAt && meeting.ScheduledEndAt && meeting.ScheduledEndAt <= meeting.ScheduledStartAt) {
147
+ return { Success: false, ErrorMessage: 'Scheduled end time must be after scheduled start time.' };
148
+ }
149
+ if (input.RecordingPolicy !== undefined) {
150
+ meeting.RecordingPolicy = h.NormalizeRecordingPolicy(input.RecordingPolicy);
151
+ }
152
+ if (input.AllowPhoneDialIn !== undefined) {
153
+ meeting.AllowPhoneDialIn = input.AllowPhoneDialIn;
154
+ if (meeting.AllowPhoneDialIn && !meeting.DialInCode) {
155
+ let phoneID = input.DialInPhoneNumberID?.trim() || meeting.DialInPhoneNumberID;
156
+ if (!phoneID) {
157
+ const defPhone = await h.ResolveDefaultPhoneNumber(user, provider);
158
+ phoneID = defPhone?.ID;
159
+ }
160
+ if (phoneID) {
161
+ meeting.DialInPhoneNumberID = phoneID;
162
+ meeting.DialInCode = await h.GenerateUniqueDialInCode(phoneID, user, provider);
163
+ }
164
+ }
165
+ }
166
+ if (input.DialInPhoneNumberID !== undefined && input.DialInPhoneNumberID.trim()) {
167
+ meeting.DialInPhoneNumberID = input.DialInPhoneNumberID.trim();
168
+ }
169
+ if (!(await meeting.Save())) {
170
+ const err = meeting.LatestResult?.CompleteMessage ?? 'Failed to update meeting.';
171
+ return { Success: false, ErrorMessage: err };
172
+ }
173
+ // If participants specified in update, sync participants (upsert by UserID/AgentID/ExternalEmail)
174
+ if (input.Participants !== undefined) {
175
+ const existing = await h.LoadParticipants(meeting.ID, user, provider);
176
+ for (const pInput of input.Participants) {
177
+ const isSelf = pInput.UserID && UUIDsEqual(pInput.UserID, user.ID);
178
+ const match = existing.find((e) => (pInput.UserID && e.UserID && UUIDsEqual(e.UserID, pInput.UserID)) ||
179
+ (pInput.AgentID && e.AgentID && UUIDsEqual(e.AgentID, pInput.AgentID)) ||
180
+ (pInput.ExternalEmail && e.ExternalEmail && e.ExternalEmail.toLowerCase() === pInput.ExternalEmail.toLowerCase()));
181
+ if (match) {
182
+ if (!isSelf && pInput.Role) {
183
+ const rv = provider ? RunView.FromMetadataProvider(provider) : new RunView();
184
+ const escapedPID = EscapeSQLString(match.ID);
185
+ const partRes = await rv.RunView({
186
+ EntityName: 'MJ: Meeting Participants',
187
+ ExtraFilter: `ID = '${escapedPID}'`,
188
+ ResultType: 'entity_object',
189
+ }, user);
190
+ if (partRes.Success && partRes.Results && partRes.Results.length > 0) {
191
+ const part = partRes.Results[0];
192
+ part.Role = h.NormalizeParticipantRole(pInput.Role, part.Role);
193
+ await part.Save();
194
+ }
195
+ }
196
+ }
197
+ else {
198
+ // New participant
199
+ const newPart = await provider.GetEntityObject('MJ: Meeting Participants', user);
200
+ newPart.MeetingID = meeting.ID;
201
+ if (pInput.AgentID && pInput.AgentID.trim()) {
202
+ newPart.AgentID = pInput.AgentID.trim();
203
+ newPart.Role = 'Agent';
204
+ newPart.InviteStatus = 'Accepted';
205
+ }
206
+ else if (pInput.UserID && pInput.UserID.trim()) {
207
+ newPart.UserID = pInput.UserID.trim();
208
+ newPart.Role = h.NormalizeParticipantRole(pInput.Role, 'Attendee');
209
+ newPart.InviteStatus = 'Invited';
210
+ }
211
+ else {
212
+ newPart.ExternalName = pInput.ExternalName?.trim() || null;
213
+ newPart.ExternalEmail = pInput.ExternalEmail?.trim() || null;
214
+ newPart.ExternalPhone = pInput.ExternalPhone?.trim() || null;
215
+ newPart.Role = h.NormalizeParticipantRole(pInput.Role, 'Attendee');
216
+ newPart.InviteStatus = 'Invited';
217
+ }
218
+ if (await newPart.Save()) {
219
+ if (newPart.UserID) {
220
+ void h.SendMeetingInviteNotification(meeting, newPart.UserID, user, provider);
221
+ }
222
+ }
223
+ }
224
+ }
225
+ }
226
+ const updatedParticipants = await h.LoadParticipants(meeting.ID, user, provider);
227
+ return {
228
+ Success: true,
229
+ Meeting: h.MapMeetingToType(meeting, updatedParticipants),
230
+ };
231
+ }
232
+ catch (error) {
233
+ const msg = error instanceof Error ? error.message : String(error);
234
+ LogError(`[MeetingResolver] UpdateMeeting exception: ${msg}`);
235
+ return { Success: false, ErrorMessage: msg };
236
+ }
237
+ }
238
+ export async function ExecuteStartMeeting(provider, user, meetingID, sessionManager, helpers) {
239
+ const h = resolveHelpers(helpers);
240
+ try {
241
+ const meeting = await h.LoadMeetingEntity(meetingID, user, provider);
242
+ if (!meeting) {
243
+ return { Success: false, ErrorMessage: 'Meeting not found.' };
244
+ }
245
+ const authorized = await h.IsUserHostOrCoHost(meeting, user, provider);
246
+ if (!authorized) {
247
+ return { Success: false, ErrorMessage: 'Unauthorized: only the host or co-host may start this meeting.' };
248
+ }
249
+ if (meeting.Status === 'Ended' || meeting.Status === 'Cancelled') {
250
+ return { Success: false, ErrorMessage: `Meeting cannot be started because its status is '${meeting.Status}'.` };
251
+ }
252
+ const now = new Date();
253
+ meeting.Status = 'Live';
254
+ meeting.StartedAt = meeting.StartedAt ?? now;
255
+ if (!(await meeting.Save())) {
256
+ return { Success: false, ErrorMessage: meeting.LatestResult?.CompleteMessage ?? 'Failed to update meeting status to Live.' };
257
+ }
258
+ // 1. Create or get Interaction row for this meeting
259
+ const interaction = await h.EnsureMeetingInteraction(meeting, user, provider);
260
+ // 2. Start all AI agent participants
261
+ const participants = await h.LoadParticipants(meeting.ID, user, provider);
262
+ const agentParticipants = participants.filter((p) => p.Role === 'Agent' && p.AgentID);
263
+ for (const ap of agentParticipants) {
264
+ try {
265
+ const createdSession = await sessionManager.CreateSession({ agentID: ap.AgentID, userID: user.ID }, user, provider);
266
+ await LiveKitAgentRoomCoordinator.Instance.StartAgentRoomSession({
267
+ AgentSessionID: createdSession.ID,
268
+ RoomName: meeting.RoomName,
269
+ AgentID: ap.AgentID,
270
+ ContextUser: user,
271
+ MetadataProvider: provider,
272
+ TurnMode: 'Active',
273
+ TurnAddressing: 'Auto',
274
+ });
275
+ }
276
+ catch (agentErr) {
277
+ LogError(`[MeetingResolver] Failed to start agent participant ${ap.AgentID} in room ${meeting.RoomName}: ${agentErr instanceof Error ? agentErr.message : String(agentErr)}`);
278
+ }
279
+ }
280
+ // 3. Initiate recording if RecordingPolicy is 'Automatic'
281
+ if (meeting.RecordingPolicy === 'Automatic') {
282
+ try {
283
+ const egress = await new LiveKitEgressService().StartRoomRecording({ RoomName: meeting.RoomName });
284
+ if (egress && egress.EgressID) {
285
+ void CorrelateRecordingStart(meeting.RoomName, egress.EgressID, user, provider);
286
+ if (interaction) {
287
+ await h.RecordInteractionEvent(interaction.ID, 'RecordingStarted', user, provider, { EgressID: egress.EgressID });
288
+ }
289
+ }
290
+ }
291
+ catch (recErr) {
292
+ LogError(`[MeetingResolver] Automatic recording initiation failed for room ${meeting.RoomName}: ${recErr instanceof Error ? recErr.message : String(recErr)}`);
293
+ }
294
+ }
295
+ // 4. Mint LiveKit client token for the caller
296
+ const tokenService = new LiveKitTokenService();
297
+ const identity = LiveKitUserIdentity(user.ID);
298
+ const mintedToken = await tokenService.MintClientToken(meeting.RoomName, identity, user.Name ?? user.Email);
299
+ return {
300
+ Success: true,
301
+ Meeting: h.MapMeetingToType(meeting, participants),
302
+ RoomName: meeting.RoomName,
303
+ ClientToken: mintedToken.Token,
304
+ };
305
+ }
306
+ catch (error) {
307
+ const msg = error instanceof Error ? error.message : String(error);
308
+ LogError(`[MeetingResolver] StartMeeting exception: ${msg}`);
309
+ return { Success: false, ErrorMessage: msg };
310
+ }
311
+ }
312
+ export async function ExecuteEndMeeting(provider, user, meetingID, helpers) {
313
+ const h = resolveHelpers(helpers);
314
+ try {
315
+ const meeting = await h.LoadMeetingEntity(meetingID, user, provider);
316
+ if (!meeting) {
317
+ return { Success: false, ErrorMessage: 'Meeting not found.' };
318
+ }
319
+ const authorized = await h.IsUserHostOrCoHost(meeting, user, provider);
320
+ if (!authorized) {
321
+ return { Success: false, ErrorMessage: 'Unauthorized: only the host or co-host may end this meeting.' };
322
+ }
323
+ const now = new Date();
324
+ meeting.Status = 'Ended';
325
+ meeting.EndedAt = now;
326
+ if (!(await meeting.Save())) {
327
+ return { Success: false, ErrorMessage: meeting.LatestResult?.CompleteMessage ?? 'Failed to update meeting status to Ended.' };
328
+ }
329
+ // 1. Stop all AI agents in room
330
+ try {
331
+ await LiveKitAgentRoomCoordinator.Instance.StopAllAgentsInRoom(meeting.RoomName, 'Explicit', user, provider);
332
+ }
333
+ catch (err) {
334
+ LogError(`[MeetingResolver] Error stopping agents for room ${meeting.RoomName}: ${err instanceof Error ? err.message : String(err)}`);
335
+ }
336
+ // 2. Close Interaction record if exists
337
+ await h.CloseMeetingInteraction(meeting.RoomName, user, provider);
338
+ const participants = await h.LoadParticipants(meeting.ID, user, provider);
339
+ return {
340
+ Success: true,
341
+ Meeting: h.MapMeetingToType(meeting, participants),
342
+ };
343
+ }
344
+ catch (error) {
345
+ const msg = error instanceof Error ? error.message : String(error);
346
+ LogError(`[MeetingResolver] EndMeeting exception: ${msg}`);
347
+ return { Success: false, ErrorMessage: msg };
348
+ }
349
+ }
350
+ export async function ExecuteCancelMeeting(provider, user, meetingID, helpers) {
351
+ const h = resolveHelpers(helpers);
352
+ try {
353
+ const meeting = await h.LoadMeetingEntity(meetingID, user, provider);
354
+ if (!meeting) {
355
+ return { Success: false, ErrorMessage: 'Meeting not found.' };
356
+ }
357
+ const authorized = await h.IsUserHostOrCoHost(meeting, user, provider);
358
+ if (!authorized) {
359
+ return { Success: false, ErrorMessage: 'Unauthorized: only the host or co-host may cancel this meeting.' };
360
+ }
361
+ meeting.Status = 'Cancelled';
362
+ if (!(await meeting.Save())) {
363
+ return { Success: false, ErrorMessage: meeting.LatestResult?.CompleteMessage ?? 'Failed to cancel meeting.' };
364
+ }
365
+ const participants = await h.LoadParticipants(meeting.ID, user, provider);
366
+ return {
367
+ Success: true,
368
+ Meeting: h.MapMeetingToType(meeting, participants),
369
+ };
370
+ }
371
+ catch (error) {
372
+ const msg = error instanceof Error ? error.message : String(error);
373
+ LogError(`[MeetingResolver] CancelMeeting exception: ${msg}`);
374
+ return { Success: false, ErrorMessage: msg };
375
+ }
376
+ }
377
+ export async function ExecuteRSVPMeeting(provider, user, input, helpers) {
378
+ const h = resolveHelpers(helpers);
379
+ try {
380
+ const rv = provider ? RunView.FromMetadataProvider(provider) : new RunView();
381
+ const validStatuses = ['Accepted', 'Declined', 'Tentative'];
382
+ const statusInput = input.InviteStatus.trim();
383
+ const matchedStatus = validStatuses.find((s) => s.toLowerCase() === statusInput.toLowerCase());
384
+ if (!matchedStatus) {
385
+ return { Success: false, ErrorMessage: `Invalid RSVP status: '${statusInput}'. Expected Accepted, Declined, or Tentative.` };
386
+ }
387
+ const escapedMeetingID = EscapeSQLString(input.MeetingID.trim());
388
+ const escapedUserID = EscapeSQLString(user.ID);
389
+ const pResult = await rv.RunView({
390
+ EntityName: 'MJ: Meeting Participants',
391
+ ExtraFilter: `MeetingID = '${escapedMeetingID}' AND UserID = '${escapedUserID}'`,
392
+ ResultType: 'entity_object',
393
+ }, user);
394
+ if (!pResult.Success || !pResult.Results || pResult.Results.length === 0) {
395
+ return { Success: false, ErrorMessage: 'Participant record not found for the caller in this meeting.' };
396
+ }
397
+ const participant = pResult.Results[0];
398
+ participant.InviteStatus = matchedStatus;
399
+ if (!(await participant.Save())) {
400
+ return { Success: false, ErrorMessage: participant.LatestResult?.CompleteMessage ?? 'Failed to save RSVP response.' };
401
+ }
402
+ const meeting = await h.LoadMeetingEntity(input.MeetingID, user, provider);
403
+ if (!meeting) {
404
+ return { Success: false, ErrorMessage: 'Meeting not found.' };
405
+ }
406
+ const participants = await h.LoadParticipants(meeting.ID, user, provider);
407
+ return {
408
+ Success: true,
409
+ Meeting: h.MapMeetingToType(meeting, participants),
410
+ };
411
+ }
412
+ catch (error) {
413
+ const msg = error instanceof Error ? error.message : String(error);
414
+ LogError(`[MeetingResolver] RSVPMeeting exception: ${msg}`);
415
+ return { Success: false, ErrorMessage: msg };
416
+ }
417
+ }
418
+ //# sourceMappingURL=meetingMutations.js.map