@messenger-box/platform-server 10.0.3-alpha.7 → 10.0.3-alpha.74

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 (202) hide show
  1. package/lib/config/env-config.d.ts +7 -0
  2. package/lib/config/env-config.js +20 -0
  3. package/lib/config/env-config.js.map +1 -1
  4. package/lib/containers/containers.js +9 -1
  5. package/lib/containers/containers.js.map +1 -1
  6. package/lib/containers/context-services-from-container.d.ts +1 -1
  7. package/lib/containers/context-services-from-container.js +4 -2
  8. package/lib/containers/context-services-from-container.js.map +1 -1
  9. package/lib/graphql/resolvers/ai-fragment.d.ts +3 -0
  10. package/lib/graphql/resolvers/ai-fragment.js +276 -0
  11. package/lib/graphql/resolvers/ai-fragment.js.map +1 -0
  12. package/lib/graphql/resolvers/channel-member.d.ts +3 -2
  13. package/lib/graphql/resolvers/channel-member.js +30 -5
  14. package/lib/graphql/resolvers/channel-member.js.map +1 -1
  15. package/lib/graphql/resolvers/channel.d.ts +3 -2
  16. package/lib/graphql/resolvers/channel.js +308 -53
  17. package/lib/graphql/resolvers/channel.js.map +1 -1
  18. package/lib/graphql/resolvers/extended-token-account.d.ts +3 -2
  19. package/lib/graphql/resolvers/extended-token-account.js +90 -23
  20. package/lib/graphql/resolvers/extended-token-account.js.map +1 -1
  21. package/lib/graphql/resolvers/index.d.ts +1 -1
  22. package/lib/graphql/resolvers/index.js +1 -1
  23. package/lib/graphql/resolvers/index.js.map +1 -1
  24. package/lib/graphql/resolvers/post-thread.d.ts +1 -1
  25. package/lib/graphql/resolvers/post-thread.js +294 -132
  26. package/lib/graphql/resolvers/post-thread.js.map +1 -1
  27. package/lib/graphql/resolvers/post.d.ts +2 -3
  28. package/lib/graphql/resolvers/post.js +874 -239
  29. package/lib/graphql/resolvers/post.js.map +1 -1
  30. package/lib/graphql/resolvers/reaction.d.ts +3 -2
  31. package/lib/graphql/resolvers/reaction.js +96 -14
  32. package/lib/graphql/resolvers/reaction.js.map +1 -1
  33. package/lib/graphql/schema/ai-fragment.graphql +311 -0
  34. package/lib/graphql/schema/ai-fragment.graphql.js +1 -0
  35. package/lib/graphql/schema/ai-fragment.graphql.js.map +1 -0
  36. package/lib/graphql/schema/channel-member.graphql +110 -21
  37. package/lib/graphql/schema/channel-member.graphql.js +1 -1
  38. package/lib/graphql/schema/channel.graphql +356 -38
  39. package/lib/graphql/schema/channel.graphql.js +1 -1
  40. package/lib/graphql/schema/index.js +2 -2
  41. package/lib/graphql/schema/index.js.map +1 -1
  42. package/lib/graphql/schema/post-thread.graphql +167 -21
  43. package/lib/graphql/schema/post-thread.graphql.js +1 -1
  44. package/lib/graphql/schema/post.graphql +360 -40
  45. package/lib/graphql/schema/post.graphql.js +1 -1
  46. package/lib/graphql/schema/reaction.graphql +71 -13
  47. package/lib/graphql/schema/reaction.graphql.js +1 -1
  48. package/lib/graphql/schema/services.graphql +21 -0
  49. package/lib/graphql/schema/users.graphql +76 -13
  50. package/lib/graphql/schema/users.graphql.js +1 -1
  51. package/lib/index.js +1 -1
  52. package/lib/index.js.map +1 -1
  53. package/lib/inngest/factory.d.ts +20 -0
  54. package/lib/inngest/factory.js +4 -0
  55. package/lib/inngest/factory.js.map +1 -0
  56. package/lib/inngest/functions.d.ts +235 -0
  57. package/lib/inngest/functions.js +1385 -0
  58. package/lib/inngest/functions.js.map +1 -0
  59. package/lib/inngest/index.d.ts +3 -0
  60. package/lib/inngest/prompt.d.ts +6 -0
  61. package/lib/inngest/prompt.js +871 -0
  62. package/lib/inngest/prompt.js.map +1 -0
  63. package/lib/inngest/utils.d.ts +5 -0
  64. package/lib/inngest/utils.js +32 -0
  65. package/lib/inngest/utils.js.map +1 -0
  66. package/lib/interfaces/index.d.ts +0 -1
  67. package/lib/interfaces/services.d.ts +1 -1
  68. package/lib/migrations/dbMigrations/AddPostsConfigurationsMigration.d.ts +17 -0
  69. package/lib/migrations/dbMigrations/AddPostsConfigurationsMigration.js +44 -0
  70. package/lib/migrations/dbMigrations/AddPostsConfigurationsMigration.js.map +1 -0
  71. package/lib/migrations/dbMigrations/index.d.ts +1 -0
  72. package/lib/migrations/index.d.ts +1 -0
  73. package/lib/migrations/mail-template-migration.js +1 -1
  74. package/lib/migrations/message-notification-template-migration.d.ts +1 -1
  75. package/lib/migrations/message-notification-template-migration.js +1 -1
  76. package/lib/module.js +10 -3
  77. package/lib/module.js.map +1 -1
  78. package/lib/plugins/ai-fragment-moleculer-service.d.ts +29 -0
  79. package/lib/plugins/ai-fragment-moleculer-service.js +516 -0
  80. package/lib/plugins/ai-fragment-moleculer-service.js.map +1 -0
  81. package/lib/plugins/channel-moleculer-service.d.ts +21 -1
  82. package/lib/plugins/channel-moleculer-service.js +426 -115
  83. package/lib/plugins/channel-moleculer-service.js.map +1 -1
  84. package/lib/plugins/extended-token-account-moleculer-service.d.ts +25 -1
  85. package/lib/plugins/extended-token-account-moleculer-service.js +348 -22
  86. package/lib/plugins/extended-token-account-moleculer-service.js.map +1 -1
  87. package/lib/plugins/index.d.ts +1 -0
  88. package/lib/plugins/messenger-notification-moleculer-service.d.ts +27 -3
  89. package/lib/plugins/messenger-notification-moleculer-service.js +404 -58
  90. package/lib/plugins/messenger-notification-moleculer-service.js.map +1 -1
  91. package/lib/plugins/post-moleculer-service.d.ts +85 -21
  92. package/lib/plugins/post-moleculer-service.js +1102 -256
  93. package/lib/plugins/post-moleculer-service.js.map +1 -1
  94. package/lib/plugins/post-thread-moleculer-service.d.ts +33 -1
  95. package/lib/plugins/post-thread-moleculer-service.js +326 -8
  96. package/lib/plugins/post-thread-moleculer-service.js.map +1 -1
  97. package/lib/plugins/reaction-moleculer-service.js +1 -1
  98. package/lib/plugins/reaction-moleculer-service.js.map +1 -1
  99. package/lib/preferences/settings/post-settings.d.ts +2 -0
  100. package/lib/preferences/settings/post-settings.js +47 -9
  101. package/lib/preferences/settings/post-settings.js.map +1 -1
  102. package/lib/services/ai-fragment-service.d.ts +195 -0
  103. package/lib/services/ai-fragment-service.js +631 -0
  104. package/lib/services/ai-fragment-service.js.map +1 -0
  105. package/lib/services/channel-service.d.ts +181 -33
  106. package/lib/services/channel-service.js +842 -273
  107. package/lib/services/channel-service.js.map +1 -1
  108. package/lib/services/extended-token-account-service.d.ts +130 -14
  109. package/lib/services/extended-token-account-service.js +462 -52
  110. package/lib/services/extended-token-account-service.js.map +1 -1
  111. package/lib/services/index.d.ts +3 -0
  112. package/lib/services/messenger-notification-service.d.ts +106 -13
  113. package/lib/services/messenger-notification-service.js +824 -442
  114. package/lib/services/messenger-notification-service.js.map +1 -1
  115. package/lib/services/post-service.d.ts +189 -16
  116. package/lib/services/post-service.js +949 -113
  117. package/lib/services/post-service.js.map +1 -1
  118. package/lib/services/post-thread-service.d.ts +114 -5
  119. package/lib/services/post-thread-service.js +400 -13
  120. package/lib/services/post-thread-service.js.map +1 -1
  121. package/lib/services/proxy-services/ai-fragment-microservice.d.ts +23 -0
  122. package/lib/services/proxy-services/ai-fragment-microservice.js +78 -0
  123. package/lib/services/proxy-services/ai-fragment-microservice.js.map +1 -0
  124. package/lib/services/proxy-services/channel-microservice.d.ts +6 -3
  125. package/lib/services/proxy-services/channel-microservice.js +25 -10
  126. package/lib/services/proxy-services/channel-microservice.js.map +1 -1
  127. package/lib/services/proxy-services/index.d.ts +1 -0
  128. package/lib/services/proxy-services/messenger-notification-microservice.d.ts +128 -8
  129. package/lib/services/proxy-services/messenger-notification-microservice.js +324 -29
  130. package/lib/services/proxy-services/messenger-notification-microservice.js.map +1 -1
  131. package/lib/services/proxy-services/post-microservice.d.ts +207 -12
  132. package/lib/services/proxy-services/post-microservice.js +623 -54
  133. package/lib/services/proxy-services/post-microservice.js.map +1 -1
  134. package/lib/services/proxy-services/post-thread-microservice.d.ts +134 -3
  135. package/lib/services/proxy-services/post-thread-microservice.js +388 -6
  136. package/lib/services/proxy-services/post-thread-microservice.js.map +1 -1
  137. package/lib/services/proxy-services/reaction-microservice.d.ts +161 -3
  138. package/lib/services/proxy-services/reaction-microservice.js +474 -2
  139. package/lib/services/proxy-services/reaction-microservice.js.map +1 -1
  140. package/lib/services/reaction-service.d.ts +124 -4
  141. package/lib/services/reaction-service.js +415 -3
  142. package/lib/services/reaction-service.js.map +1 -1
  143. package/lib/services/redis-cache-manager.d.ts +18 -0
  144. package/lib/services/redis-cache-manager.js +83 -0
  145. package/lib/services/redis-cache-manager.js.map +1 -0
  146. package/lib/services/sandbox-error-service.d.ts +23 -0
  147. package/lib/services/sandbox-error-service.js +422 -0
  148. package/lib/services/sandbox-error-service.js.map +1 -0
  149. package/lib/store/models/account-token-store.d.ts +1 -1
  150. package/lib/store/models/account-token-store.js.map +1 -1
  151. package/lib/store/models/ai-fragment.d.ts +4 -0
  152. package/lib/store/models/ai-fragment.js +125 -0
  153. package/lib/store/models/ai-fragment.js.map +1 -0
  154. package/lib/store/models/channel.d.ts +2 -3
  155. package/lib/store/models/channel.js +185 -71
  156. package/lib/store/models/channel.js.map +1 -1
  157. package/lib/store/models/index.d.ts +1 -0
  158. package/lib/store/models/post-thread.d.ts +3 -3
  159. package/lib/store/models/post-thread.js +96 -14
  160. package/lib/store/models/post-thread.js.map +1 -1
  161. package/lib/store/models/post.d.ts +2 -3
  162. package/lib/store/models/post.js +143 -23
  163. package/lib/store/models/post.js.map +1 -1
  164. package/lib/store/models/reaction.d.ts +2 -3
  165. package/lib/store/models/reaction.js +67 -8
  166. package/lib/store/models/reaction.js.map +1 -1
  167. package/lib/store/repositories/__tests__/__fixtures__/team-repository.d.ts +3 -3
  168. package/lib/store/repositories/ai-fragment-repository.d.ts +15 -0
  169. package/lib/store/repositories/ai-fragment-repository.js +69 -0
  170. package/lib/store/repositories/ai-fragment-repository.js.map +1 -0
  171. package/lib/store/repositories/channel-repository.d.ts +6 -6
  172. package/lib/store/repositories/channel-repository.js +5 -2
  173. package/lib/store/repositories/channel-repository.js.map +1 -1
  174. package/lib/store/repositories/index.d.ts +1 -0
  175. package/lib/store/repositories/post-repository.d.ts +6 -6
  176. package/lib/store/repositories/post-repository.js +5 -2
  177. package/lib/store/repositories/post-repository.js.map +1 -1
  178. package/lib/store/repositories/post-thread-repository.d.ts +6 -6
  179. package/lib/store/repositories/post-thread-repository.js +5 -2
  180. package/lib/store/repositories/post-thread-repository.js.map +1 -1
  181. package/lib/store/repositories/reaction-repository.d.ts +6 -6
  182. package/lib/store/repositories/reaction-repository.js +5 -2
  183. package/lib/store/repositories/reaction-repository.js.map +1 -1
  184. package/lib/templates/constants/SERVER_TYPES.ts.template +4 -4
  185. package/lib/templates/repositories/AiFragmentRepository.ts.template +4 -0
  186. package/lib/templates/repositories/ChannelRepository.ts.template +3 -3
  187. package/lib/templates/repositories/PostRepository.ts.template +3 -3
  188. package/lib/templates/repositories/PostThreadRepository.ts.template +3 -3
  189. package/lib/templates/repositories/ReactionRepository.ts.template +3 -4
  190. package/lib/templates/services/AiFragmentService.ts.template +123 -0
  191. package/lib/templates/services/ChannelService.ts.template +290 -39
  192. package/lib/templates/services/ExtendedTokenAccountService.ts.template +104 -9
  193. package/lib/templates/services/MessengerNotificationService.ts.template +94 -19
  194. package/lib/templates/services/PostService.ts.template +265 -20
  195. package/lib/templates/services/PostThreadService.ts.template +151 -6
  196. package/lib/templates/services/ReactionService.ts.template +129 -3
  197. package/lib/templates/services/RedisCacheManager.ts.template +22 -0
  198. package/lib/templates/services/SandboxErrorService.ts.template +125 -0
  199. package/package.json +14 -7
  200. package/lib/interfaces/context.d.ts +0 -14
  201. package/lib/store/models/common-options.js +0 -20
  202. package/lib/store/models/common-options.js.map +0 -1
@@ -1,272 +1,720 @@
1
- import {__decorate,__param,__metadata}from'tslib';import {inject}from'inversify';import {SERVER_TYPES,RoomType,SortEnum}from'common';import {BaseService}from'@common-stack/store-mongo';import'../constants/query.constants.js';import {DEFAULT_NOTIFY_PROPS}from'../constants/default-notify-props.js';var ChannelService_1;
2
- let ChannelService = ChannelService_1 = class ChannelService extends BaseService {
1
+ import {__decorate,__param,__metadata}from'tslib';import {injectable,inject}from'inversify';import {Emitter,DisposableCollection}from'@adminide-stack/core';import {SERVER_TYPES,RoomType,SortEnum}from'common/server';import {BaseService2}from'@common-stack/store-mongo';import'@cdm-logger/core';import {ServiceBroker}from'moleculer';import {CommonType}from'@common-stack/core';import'../constants/query.constants.js';import {DEFAULT_NOTIFY_PROPS}from'../constants/default-notify-props.js';import {config}from'../config/env-config.js';var ChannelService_1;
2
+ const CACHE_TTL = {
3
+ maxAge: 5 * 60,
4
+ scope: 'PUBLIC'
5
+ }; // 5 minutes
6
+ /**
7
+ * Modern implementation of the Channel Service
8
+ *
9
+ * This service handles comprehensive channel management within the messenger platform,
10
+ * providing operations for managing channels, their members, and related messaging workflows.
11
+ *
12
+ * Key capabilities:
13
+ * - Channel lifecycle management (creation, updates, deletion)
14
+ * - Member management (adding, removing, role assignment)
15
+ * - Direct and public channel handling
16
+ * - Message and post management within channels
17
+ * - Channel visibility and access control
18
+ * - Notification and unread message tracking
19
+ * - Team-based channel organization
20
+ * - Channel discovery and filtering
21
+ * - Redis caching for performance optimization
22
+ * - Comprehensive error handling and logging
23
+ * - Event-driven architecture with proper disposal
24
+ *
25
+ * The service layer abstracts the underlying data access operations and
26
+ * provides a cohesive API for channel-related functionality throughout
27
+ * the messaging platform, handling complex business rules and cross-cutting concerns.
28
+ */
29
+ let ChannelService = ChannelService_1 = class ChannelService extends BaseService2 {
3
30
  repository;
4
31
  postService;
5
- constructor(repository, postService) {
32
+ broker;
33
+ redisCacheManager;
34
+ redisClient;
35
+ inngestClient;
36
+ // Event emitters for channel lifecycle events
37
+ onChannelCreated = new Emitter();
38
+ onChannelUpdated = new Emitter();
39
+ onChannelDeleted = new Emitter();
40
+ onChannelRestored = new Emitter();
41
+ onMemberAdded = new Emitter();
42
+ onMemberRemoved = new Emitter();
43
+ onChannelViewed = new Emitter();
44
+ toDispose = new DisposableCollection(this.onChannelCreated, this.onChannelUpdated, this.onChannelDeleted, this.onChannelRestored, this.onMemberAdded, this.onMemberRemoved, this.onChannelViewed);
45
+ logger;
46
+ constructor(repository, postService, broker, redisCacheManager, redisClient, logger, inngestClient) {
6
47
  super(repository);
7
48
  this.repository = repository;
8
49
  this.postService = postService;
50
+ this.broker = broker;
51
+ this.redisCacheManager = redisCacheManager;
52
+ this.redisClient = redisClient;
53
+ this.inngestClient = inngestClient;
54
+ this.logger = logger?.child({
55
+ className: 'ChannelService'
56
+ }) || console;
57
+ }
58
+ /**
59
+ * Disposes of resources used by the service
60
+ */
61
+ dispose() {
62
+ this.toDispose.dispose();
63
+ }
64
+ /**
65
+ * Helper method to make service calls
66
+ * @param command - Command to execute
67
+ * @param params - Command parameters
68
+ * @param topic - Service topic
69
+ * @param opts - Call options
70
+ * @returns Command result
71
+ */
72
+ async callAction(command, params, topic, opts) {
73
+ try {
74
+ if (!this.broker) {
75
+ throw new Error('Service broker not available');
76
+ }
77
+ const actionName = topic ? `${topic}.${command}` : command;
78
+ return await this.broker.call(actionName, params, opts);
79
+ } catch (error) {
80
+ this.logger.error(`Error calling action ${command}: %o`, error);
81
+ throw error;
82
+ }
9
83
  }
84
+ /**
85
+ * Enhanced method to check if a user is a member of a specific channel
86
+ *
87
+ * @description Verifies channel membership with proper error handling and logging
88
+ *
89
+ * @param {string} channelId - The ID of the channel to check
90
+ * @param {string} user - The ID of the user
91
+ * @returns {Promise<boolean>} - True if the user is a member
92
+ */
10
93
  async isMember(channelId, user) {
11
- const channel = await this.get(channelId);
12
- return !!channel?.members?.find(member => member.user.toString() === user.toString());
13
- }
14
- static getDmNameFromIds(senderId, receiverId) {
15
- return `${senderId}__${receiverId}`;
94
+ try {
95
+ if (!channelId || !user) {
96
+ this.logger.warn('Channel ID and user ID are required for membership check');
97
+ return false;
98
+ }
99
+ this.logger.debug('Checking channel membership', {
100
+ channelId,
101
+ userId: user
102
+ });
103
+ const channel = await this.get(channelId);
104
+ if (!channel?.members) {
105
+ this.logger.debug('Channel not found or has no members', {
106
+ channelId
107
+ });
108
+ return false;
109
+ }
110
+ const isMember = !!channel.members.find(member => member.user && member.user.toString() === user.toString());
111
+ this.logger.debug('Channel membership check result', {
112
+ channelId,
113
+ userId: user,
114
+ isMember
115
+ });
116
+ return isMember;
117
+ } catch (error) {
118
+ this.logger.error('Error checking channel membership: %o', error);
119
+ return false;
120
+ }
16
121
  }
122
+ /**
123
+ * Enhanced method to get default notification properties
124
+ *
125
+ * @description Retrieves default notification settings with extensibility
126
+ *
127
+ * @returns {INotificationProps} - Default notification properties
128
+ */
17
129
  get defaultNotifyProps() {
18
- // #Todo: To be moved to settings
19
- return DEFAULT_NOTIFY_PROPS;
130
+ try {
131
+ // Future enhancement: Load from user preferences or organization settings
132
+ return DEFAULT_NOTIFY_PROPS;
133
+ } catch (error) {
134
+ this.logger.error('Error getting default notification props: %o', error);
135
+ return DEFAULT_NOTIFY_PROPS;
136
+ }
20
137
  }
21
- static getMaxChannelsPerTeam(teamId) {
22
- // #Todo: Get Max Channel per team from Team settings
23
- return Promise.resolve(10);
138
+ /**
139
+ * Enhanced method to get maximum channels per team with configuration support
140
+ *
141
+ * @description Retrieves channel limit with future configuration support
142
+ *
143
+ * @param {string} teamId - The ID of the team
144
+ * @returns {Promise<number>} - Maximum number of channels allowed
145
+ */
146
+ static async getMaxChannelsPerTeam(teamId) {
147
+ try {
148
+ // Future enhancement: Get from team settings or organization configuration
149
+ return Promise.resolve(100); // Default max channels per team
150
+ } catch (error) {
151
+ console.error('Error getting max channels per team:', error);
152
+ return Promise.resolve(10); // Fallback value
153
+ }
24
154
  }
155
+ /**
156
+ * Enhanced method to get current channel count per team
157
+ *
158
+ * @description Counts active channels for a team with proper error handling
159
+ *
160
+ * @param {string} team - The team identifier
161
+ * @returns {Promise<number>} - Current channel count
162
+ */
25
163
  async getCurrentChannelCountPerTeam(team) {
26
- return this.repository.count({
27
- team,
28
- type: RoomType.Channel
29
- });
164
+ try {
165
+ if (!team) {
166
+ this.logger.warn('Team ID is required for channel count');
167
+ return 0;
168
+ }
169
+ const count = await this.repository.count({
170
+ team,
171
+ type: RoomType.Channel,
172
+ deletedAt: {
173
+ $exists: false
174
+ } // Only count non-deleted channels
175
+ });
176
+ this.logger.debug('Current channel count for team', {
177
+ team,
178
+ count
179
+ });
180
+ return count;
181
+ } catch (error) {
182
+ this.logger.error('Error getting current channel count per team: %o', error);
183
+ return 0;
184
+ }
185
+ }
186
+ /**
187
+ * Enhanced method to generate DM name from user IDs
188
+ *
189
+ * @description Creates a standardized direct message channel name
190
+ *
191
+ * @param {string} senderId - The sender's user ID
192
+ * @param {string} receiverId - The receiver's user ID
193
+ * @returns {string} - Generated DM name
194
+ */
195
+ static getDmNameFromIds(senderId, receiverId) {
196
+ try {
197
+ if (!senderId || !receiverId) {
198
+ throw new Error('Both sender and receiver IDs are required');
199
+ }
200
+ // Sort IDs to ensure consistent naming regardless of order
201
+ const [id1, id2] = [senderId, receiverId].sort();
202
+ return `${id1}__${id2}`;
203
+ } catch (error) {
204
+ console.error('Error generating DM name:', error);
205
+ return `${senderId}__${receiverId}`;
206
+ }
30
207
  }
208
+ /**
209
+ * Enhanced method to create a direct channel between users
210
+ *
211
+ * @description Creates direct channels with comprehensive validation and error handling
212
+ *
213
+ * @param {ICreateDirectChannelParams} data - The direct channel creation parameters
214
+ * @returns {Promise<AsDomainType<IChannelModel> | Error>} - The created channel or error
215
+ */
31
216
  async createDirectChannel(data) {
32
- const {
33
- sender,
34
- receiver,
35
- displayName,
36
- orgName,
37
- channelOptions
38
- } = data;
39
- const chlMember = [{
40
- user: sender,
41
- schemeAdmin: channelOptions?.schemeAdmin || false,
42
- notifyProps: this.defaultNotifyProps
43
- }];
44
- receiver.forEach(re => {
45
- if (re != sender) {
46
- chlMember.push({
47
- user: re,
48
- schemeAdmin: channelOptions?.schemeAdmin || false,
49
- notifyProps: this.defaultNotifyProps
217
+ try {
218
+ this.logger.debug('Creating direct channel', {
219
+ sender: data.sender,
220
+ receiverCount: data.receiver?.length || 0,
221
+ orgName: data.orgName
222
+ });
223
+ const {
224
+ sender,
225
+ receiver,
226
+ displayName,
227
+ orgName,
228
+ channelOptions
229
+ } = data;
230
+ if (!sender) {
231
+ return new Error('Sender ID is required');
232
+ }
233
+ if (!receiver || receiver.length === 0) {
234
+ return new Error('At least one receiver is required');
235
+ }
236
+ // Check for duplicate direct channel
237
+ const existingChannelName = ChannelService_1.getDmNameFromIds(sender, receiver[0]);
238
+ const existingChannel = await this.getByName(existingChannelName);
239
+ if (existingChannel) {
240
+ this.logger.debug('Direct channel already exists', {
241
+ channelName: existingChannelName
50
242
  });
243
+ return existingChannel;
51
244
  }
52
- });
53
- const channelPayload = {
54
- title: sender.split('').reverse().join(''),
55
- orgName,
56
- type: RoomType.Direct,
57
- creator: sender,
58
- members: chlMember,
59
- displayName
60
- };
61
- return this.saveDirectChannel(channelPayload);
245
+ // Build channel members
246
+ const channelMembers = [{
247
+ user: sender,
248
+ schemeAdmin: channelOptions?.schemeAdmin || false,
249
+ notifyProps: this.defaultNotifyProps
250
+ }];
251
+ receiver.forEach(receiverId => {
252
+ if (receiverId !== sender) {
253
+ channelMembers.push({
254
+ user: receiverId,
255
+ schemeAdmin: channelOptions?.schemeAdmin || false,
256
+ notifyProps: this.defaultNotifyProps
257
+ });
258
+ }
259
+ });
260
+ const channelPayload = {
261
+ title: displayName || ChannelService_1.getDmNameFromIds(sender, receiver[0]),
262
+ orgName,
263
+ organization: orgName,
264
+ type: RoomType.Direct,
265
+ creator: sender,
266
+ members: channelMembers,
267
+ displayName: displayName || `Direct chat`,
268
+ _id: undefined // Allow repository to generate
269
+ };
270
+ const result = await this.saveDirectChannel(channelPayload);
271
+ if (!(result instanceof Error)) {
272
+ this.onChannelCreated.fire({
273
+ channel: result,
274
+ userContext: {
275
+ accountId: sender,
276
+ tenantId: orgName
277
+ }
278
+ });
279
+ }
280
+ return result;
281
+ } catch (error) {
282
+ this.logger.error('Error creating direct channel: %o', error);
283
+ return error instanceof Error ? error : new Error('Unknown error occurred while creating direct channel');
284
+ }
62
285
  }
286
+ /**
287
+ * Enhanced method to save a direct channel
288
+ *
289
+ * @description Saves direct channels with comprehensive validation
290
+ *
291
+ * @param {ISaveDirectChannelParams} channel - The direct channel parameters
292
+ * @returns {Promise<AsDomainType<IChannelModel> | Error>} - The created channel or error
293
+ */
63
294
  async saveDirectChannel(channel) {
64
- const {
65
- type,
66
- deletedAt
67
- } = channel;
68
- if (deletedAt) {
69
- throw new Error('Deleted Channel can not be saved');
70
- }
71
- if (type !== RoomType.Direct) {
72
- throw new Error('Only direct channels are allowed');
295
+ try {
296
+ this.logger.debug('Saving direct channel', {
297
+ type: channel.type,
298
+ creator: channel.creator,
299
+ memberCount: channel.members?.length || 0
300
+ });
301
+ const {
302
+ type,
303
+ deletedAt
304
+ } = channel;
305
+ if (deletedAt) {
306
+ return new Error('Deleted channels cannot be saved');
307
+ }
308
+ if (type !== RoomType.Direct) {
309
+ return new Error('Only direct channels are allowed in this method');
310
+ }
311
+ const result = await this.repository.create(channel);
312
+ this.logger.debug('Direct channel saved successfully', {
313
+ channelId: result.id,
314
+ type: result.type
315
+ });
316
+ return result;
317
+ } catch (error) {
318
+ this.logger.error('Error saving direct channel: %o', error);
319
+ return error instanceof Error ? error : new Error('Unknown error occurred while saving direct channel');
73
320
  }
74
- return this.repository.create(channel);
75
321
  }
322
+ /**
323
+ * Enhanced method to add a member to a channel
324
+ *
325
+ * @description Adds a single member to a channel with comprehensive validation and event firing
326
+ *
327
+ * @param {string} channelId - The ID of the channel
328
+ * @param {string} memberId - The ID of the member to add
329
+ * @returns {Promise<AsDomainType<IChannelModel> | Error>} - The updated channel or error
330
+ */
76
331
  async addMemberToChannel(channelId, memberId) {
77
- // const { channelId, memberId } = data;
78
- // console.log('==============================', channelId);
79
- const resData = await this.repository.get({
80
- id: channelId
81
- }).then(async res => {
82
- const mebs = res.members;
83
- mebs.push({
84
- id: '',
85
- user: memberId,
86
- schemeAdmin: false,
87
- notifyProps: this.defaultNotifyProps
332
+ try {
333
+ this.logger.debug('Adding member to channel', {
334
+ channelId,
335
+ memberId
88
336
  });
89
- const objToUpdate = res;
90
- objToUpdate.members = mebs;
91
- const finalResult = await this.repository.update({
337
+ if (!channelId || !memberId) {
338
+ return new Error('Channel ID and member ID are required');
339
+ }
340
+ // Check if member is already in channel
341
+ const isMember = await this.isMember(channelId, memberId);
342
+ if (isMember) {
343
+ this.logger.debug('Member already exists in channel', {
344
+ channelId,
345
+ memberId
346
+ });
347
+ return await this.get(channelId);
348
+ }
349
+ const resData = await this.repository.get({
92
350
  id: channelId
93
- }, objToUpdate, {
94
- overwrite: true
95
- }).then(response => response).catch(error => error);
96
- return finalResult;
97
- }).catch(err => err);
98
- return resData;
351
+ }).then(async res => {
352
+ if (!res) {
353
+ throw new Error(`Channel ${channelId} not found`);
354
+ }
355
+ const members = res.members || [];
356
+ members.push({
357
+ user: memberId,
358
+ schemeAdmin: false,
359
+ notifyProps: this.defaultNotifyProps
360
+ });
361
+ const objToUpdate = {
362
+ ...res,
363
+ members
364
+ };
365
+ const finalResult = await this.repository.update({
366
+ id: channelId
367
+ }, objToUpdate, {
368
+ overwrite: true
369
+ });
370
+ return finalResult;
371
+ }).catch(err => {
372
+ this.logger.error('Error in addMemberToChannel operation: %o', err);
373
+ return err;
374
+ });
375
+ if (resData instanceof Error) {
376
+ return resData;
377
+ }
378
+ // Fire member added event
379
+ this.onMemberAdded.fire({
380
+ channelId,
381
+ memberId,
382
+ userContext: {
383
+ accountId: memberId
384
+ }
385
+ });
386
+ this.logger.debug('Member added to channel successfully', {
387
+ channelId,
388
+ memberId
389
+ });
390
+ return resData;
391
+ } catch (error) {
392
+ this.logger.error('Error adding member to channel: %o', error);
393
+ return error instanceof Error ? error : new Error('Unknown error occurred while adding member to channel');
394
+ }
99
395
  }
100
396
  async saveMembersToChannel(data) {
101
- const {
102
- channelId,
103
- membersIds
104
- } = data;
105
- const resData = await this.repository.get({
106
- id: channelId
107
- }).then(async res => {
108
- let mebs = res.members;
109
- if (Array.isArray(membersIds)) {
110
- if (membersIds?.length) {
111
- membersIds.forEach(mid => {
112
- mebs.push({
113
- id: '',
114
- user: mid,
115
- schemeAdmin: false,
116
- notifyProps: this.defaultNotifyProps
397
+ try {
398
+ const {
399
+ channelId,
400
+ membersIds
401
+ } = data;
402
+ const resData = await this.repository.get({
403
+ id: channelId
404
+ }).then(async res => {
405
+ let mebs = res.members || [];
406
+ if (Array.isArray(membersIds)) {
407
+ if (membersIds?.length) {
408
+ membersIds.forEach(mid => {
409
+ mebs.push({
410
+ user: mid,
411
+ schemeAdmin: false,
412
+ notifyProps: this.defaultNotifyProps
413
+ });
117
414
  });
118
- });
415
+ }
119
416
  }
417
+ const objToUpdate = res;
418
+ objToUpdate.members = mebs;
419
+ const finalResult = await this.repository.update({
420
+ id: channelId
421
+ }, objToUpdate, {
422
+ overwrite: true
423
+ });
424
+ return finalResult;
425
+ }).catch(err => err);
426
+ if (resData instanceof Error) {
427
+ return resData;
120
428
  }
121
- const objToUpdate = res;
122
- objToUpdate.members = mebs;
123
- const finalResult = await this.repository.update({
124
- id: channelId
125
- }, objToUpdate, {
126
- overwrite: true
127
- });
128
- return finalResult;
129
- }).catch(err => err);
130
- return resData;
429
+ return resData;
430
+ } catch (error) {
431
+ this.logger.error('Error saving members to channel: %o', error);
432
+ return error instanceof Error ? error : new Error('Unknown error occurred');
433
+ }
131
434
  }
132
435
  async saveChannel(data) {
133
- const {
134
- type,
135
- team,
136
- creator
137
- } = data;
138
- if (type === RoomType.Direct) {
139
- throw new Error('Invalid Channel Type');
140
- }
141
- if (team) {
142
- const maxChannels = await ChannelService_1.getMaxChannelsPerTeam(team);
143
- const currentChannels = await this.getCurrentChannelCountPerTeam(team);
144
- const canAddNewChannel = currentChannels < maxChannels;
145
- if (!canAddNewChannel) {
146
- throw Error(`Only max of ${maxChannels} allowed`);
436
+ try {
437
+ const {
438
+ type,
439
+ team,
440
+ creator
441
+ } = data;
442
+ if (type === RoomType.Direct) {
443
+ return new Error('Invalid Channel Type');
444
+ }
445
+ if (team) {
446
+ const maxChannels = await ChannelService_1.getMaxChannelsPerTeam(team);
447
+ const currentChannels = await this.getCurrentChannelCountPerTeam(team);
448
+ const canAddNewChannel = currentChannels < maxChannels;
449
+ if (!canAddNewChannel) {
450
+ return new Error(`Only max of ${maxChannels} allowed`);
451
+ }
147
452
  }
453
+ const channelPayload = {
454
+ ...data,
455
+ members: [{
456
+ user: creator,
457
+ schemeAdmin: false,
458
+ notifyProps: this.defaultNotifyProps
459
+ }]
460
+ };
461
+ const result = await this.repository.create(channelPayload);
462
+ return result;
463
+ } catch (error) {
464
+ this.logger.error('Error saving channel: %o', error);
465
+ return error instanceof Error ? error : new Error('Unknown error occurred');
148
466
  }
149
- const channelPayload = {
150
- ...data,
151
- members: [{
152
- user: creator,
153
- schemeAdmin: false,
154
- notifyProps: this.defaultNotifyProps
155
- }]
156
- };
157
- return this.repository.create(channelPayload);
158
467
  }
159
468
  async savePublicChannel(data) {
160
- const {
161
- type
162
- } = data;
163
- if (type !== RoomType.Public) {
164
- throw new Error('Invalid Channel Type');
469
+ try {
470
+ const {
471
+ type
472
+ } = data;
473
+ if (type !== RoomType.Public) {
474
+ return new Error('Invalid Channel Type');
475
+ }
476
+ const result = await this.repository.create(data);
477
+ return result;
478
+ } catch (error) {
479
+ this.logger.error('Error saving public channel: %o', error);
480
+ return error instanceof Error ? error : new Error('Unknown error occurred');
165
481
  }
166
- return this.repository.create(data);
167
482
  }
168
483
  async getChannelUnread(channelId, userId) {
169
- const channel = await this.repository.get({
170
- id: channelId,
171
- members: {
172
- user: userId
484
+ try {
485
+ const channel = await this.repository.get({
486
+ id: channelId,
487
+ members: {
488
+ user: userId
489
+ }
490
+ }); // Type assertion to handle the interface mismatch
491
+ const {
492
+ members,
493
+ team,
494
+ id
495
+ } = channel;
496
+ const member = members?.find(i => i.user && i.user.toString() === userId);
497
+ if (!member) {
498
+ return {
499
+ channelId: id,
500
+ teamId: team ? team.toString() : '',
501
+ msgCount: 0,
502
+ msgCountRoot: 0,
503
+ mentionCount: 0,
504
+ notifyProps: this.defaultNotifyProps,
505
+ mentionCountRoot: 0
506
+ };
173
507
  }
174
- });
175
- const {
176
- members,
177
- team,
178
- id
179
- } = channel;
180
- const member = members.find(i => i.user.toString() === userId);
181
- const msgCount = channel.totalMsgCount - member.msgCount;
182
- const msgCountRoot = channel.totalMsgCountRoot - member.msgCountRoot;
183
- const {
184
- notifyProps,
185
- mentionCountRoot,
186
- mentionCount
187
- } = member;
188
- return {
189
- channelId: id,
190
- teamId: team.toString(),
191
- msgCount,
192
- msgCountRoot,
193
- mentionCount,
194
- notifyProps,
195
- mentionCountRoot
196
- };
508
+ const msgCount = (channel.totalMsgCount || 0) - (member.msgCount || 0);
509
+ const msgCountRoot = (channel.totalMsgCountRoot || 0) - (member.msgCountRoot || 0);
510
+ const {
511
+ notifyProps,
512
+ mentionCountRoot,
513
+ mentionCount
514
+ } = member;
515
+ return {
516
+ channelId: id,
517
+ teamId: team ? team.toString() : '',
518
+ msgCount,
519
+ msgCountRoot,
520
+ mentionCount: mentionCount || 0,
521
+ notifyProps: notifyProps || this.defaultNotifyProps,
522
+ mentionCountRoot: mentionCountRoot || 0
523
+ };
524
+ } catch (error) {
525
+ this.logger.error('Error getting channel unread: %o', error);
526
+ return error instanceof Error ? error : new Error('Unknown error occurred');
527
+ }
197
528
  }
198
529
  async getPinnedPosts(channelId) {
199
- const posts = await this.postService.getAll({
200
- criteria: {
201
- channelId,
202
- isPinned: true
203
- },
204
- sort: {
205
- key: 'CreatAt',
206
- value: SortEnum.Asc
207
- }
208
- });
209
- const replyCounts = await Promise.all(posts.map(post => this.postService.count({
210
- rootId: post.rootId || post.id
211
- })));
212
- return posts.reduce((acc, curr, index) => [...acc, {
213
- ...curr,
214
- replyCount: replyCounts[index]
215
- }], []);
216
- }
217
- restore(channelId, time) {
218
- return this.repository.update({
219
- id: channelId
220
- }, {
221
- deletedAt: time
222
- });
223
- }
224
- // getByName(team: string, title: string): Promise<IChannel> {
225
- // return this.get({
226
- // team,
227
- // title,
228
- // });
229
- // }
230
- getByName(title) {
231
- return this.get({
232
- title
233
- });
234
- }
235
- getByNameIncludeDeleted(team, title) {
236
- return this.get({
237
- team,
238
- title,
239
- deletedAt: true
240
- });
530
+ try {
531
+ const posts = await this.postService.getAll({
532
+ criteria: {
533
+ channelId,
534
+ isPinned: true
535
+ },
536
+ sort: {
537
+ key: 'CreatAt',
538
+ value: SortEnum.Asc
539
+ }
540
+ });
541
+ const replyCounts = await Promise.all(posts.map(post => this.postService.count({
542
+ rootId: post.rootId || post._id
543
+ })));
544
+ return posts.reduce((acc, curr, index) => [...acc, {
545
+ ...curr,
546
+ replyCount: replyCounts[index]
547
+ }], []);
548
+ } catch (error) {
549
+ this.logger.error('Error getting pinned posts: %o', error);
550
+ return error instanceof Error ? error : new Error('Unknown error occurred');
551
+ }
241
552
  }
242
- getByNames(team, titles) {
243
- return this.getAll({
244
- criteria: {
245
- team,
246
- title: {
247
- $in: titles
553
+ async getFromMaster(id) {
554
+ try {
555
+ // Try Redis cache first
556
+ if (this.redisCacheManager && id) {
557
+ try {
558
+ const cacheKey = `${config.APP_NAME}:getChannelById`;
559
+ const variables = {
560
+ id
561
+ };
562
+ const cacheCtx = {
563
+ userId: 'system'
564
+ };
565
+ const cached = await this.redisCacheManager.get(cacheKey, variables, cacheCtx);
566
+ if (cached) {
567
+ this.logger.debug(`Cache hit for channel ID: ${id}`);
568
+ return cached;
569
+ }
570
+ } catch (cacheError) {
571
+ this.logger.warn(`Redis cache error for getFromMaster(${id}): ${cacheError?.message}`);
572
+ }
573
+ }
574
+ const result = await this.get({
575
+ id
576
+ });
577
+ // Set cache
578
+ if (this.redisCacheManager && result) {
579
+ try {
580
+ const cacheKey = `${config.APP_NAME}:getChannelById`;
581
+ const variables = {
582
+ id
583
+ };
584
+ const cacheCtx = {
585
+ userId: 'system'
586
+ };
587
+ await this.redisCacheManager.set(cacheKey, variables, result, cacheCtx, CACHE_TTL);
588
+ } catch (cacheError) {
589
+ this.logger.warn(`Failed to cache channel by id: ${cacheError?.message}`);
248
590
  }
249
591
  }
250
- });
592
+ return result;
593
+ } catch (error) {
594
+ this.logger.error('Error getting channel from master: %o', error);
595
+ return error instanceof Error ? error : new Error('Unknown error occurred');
596
+ }
251
597
  }
252
- getChannelCounts(team, user) {
253
- return this.count({
254
- team,
255
- members: {
256
- user
598
+ async restore(channelId, time) {
599
+ try {
600
+ await this.repository.update({
601
+ id: channelId
602
+ }, {
603
+ deletedAt: time
604
+ });
605
+ } catch (error) {
606
+ this.logger.error('Error restoring channel: %o', error);
607
+ throw error;
608
+ }
609
+ }
610
+ // @ts-ignore - Type compatibility issue with base class method
611
+ async getByName(title) {
612
+ try {
613
+ if (!title) {
614
+ this.logger.warn('Empty channel title provided');
615
+ return null;
257
616
  }
258
- });
617
+ // Try Redis cache first
618
+ if (this.redisCacheManager) {
619
+ try {
620
+ const cacheKey = `${config.APP_NAME}:getChannelByName`;
621
+ const variables = {
622
+ name: title
623
+ };
624
+ const cacheCtx = {
625
+ userId: 'system'
626
+ };
627
+ const cached = await this.redisCacheManager.get(cacheKey, variables, cacheCtx);
628
+ if (cached) {
629
+ this.logger.debug(`Cache hit for channel name: ${title}`);
630
+ return cached;
631
+ }
632
+ } catch (cacheError) {
633
+ this.logger.warn(`Redis cache error for getByName(${title}): ${cacheError?.message}`);
634
+ }
635
+ }
636
+ const result = await this.get({
637
+ title
638
+ });
639
+ // Cache the result
640
+ if (this.redisCacheManager && result) {
641
+ try {
642
+ const cacheKey = `${config.APP_NAME}:getChannelByName`;
643
+ const variables = {
644
+ name: title
645
+ };
646
+ const cacheCtx = {
647
+ userId: 'system'
648
+ };
649
+ await this.redisCacheManager.set(cacheKey, variables, result, cacheCtx, CACHE_TTL);
650
+ } catch (cacheError) {
651
+ this.logger.warn(`Failed to cache channel by name: ${cacheError?.message}`);
652
+ }
653
+ }
654
+ return result;
655
+ } catch (error) {
656
+ this.logger.error('Error getting channel by name: %o', error);
657
+ throw error;
658
+ }
259
659
  }
260
- getChannels(team, user, includeDeleted, lastDeleteAt, orgName) {
261
- return this.repository.getAll({
262
- criteria: this.generateCriteria({
263
- team,
264
- user,
265
- includeDeleted,
266
- lastDeleteAt,
267
- orgName
268
- })
269
- });
660
+ async getByNameIncludeDeleted(teamId, name) {
661
+ try {
662
+ const result = await this.get({
663
+ team: teamId,
664
+ title: name,
665
+ deletedAt: true
666
+ });
667
+ return result;
668
+ } catch (error) {
669
+ this.logger.error('Error getting channel by name including deleted: %o', error);
670
+ return error instanceof Error ? error : new Error('Unknown error occurred');
671
+ }
672
+ }
673
+ async getByNames(teamId, names) {
674
+ try {
675
+ const result = await this.getAll({
676
+ criteria: {
677
+ team: teamId,
678
+ title: {
679
+ $in: names
680
+ }
681
+ }
682
+ });
683
+ return result;
684
+ } catch (error) {
685
+ this.logger.error('Error getting channels by names: %o', error);
686
+ return error instanceof Error ? error : new Error('Unknown error occurred');
687
+ }
688
+ }
689
+ async getChannelCounts(teamId, userId) {
690
+ try {
691
+ return await this.count({
692
+ team: teamId,
693
+ members: {
694
+ user: userId
695
+ }
696
+ });
697
+ } catch (error) {
698
+ this.logger.error('Error getting channel counts: %o', error);
699
+ return error instanceof Error ? error : new Error('Unknown error occurred');
700
+ }
701
+ }
702
+ async getChannels(teamId, userId, includeDeleted, lastDeleteAt, orgId) {
703
+ try {
704
+ const result = await this.repository.getAll({
705
+ criteria: this.generateCriteria({
706
+ team: teamId,
707
+ user: userId,
708
+ includeDeleted,
709
+ lastDeleteAt,
710
+ orgName: orgId
711
+ })
712
+ });
713
+ return result;
714
+ } catch (error) {
715
+ this.logger.error('Error getting channels: %o', error);
716
+ return error instanceof Error ? error : new Error('Unknown error occurred');
717
+ }
270
718
  }
271
719
  generateCriteria(options) {
272
720
  const {
@@ -323,72 +771,193 @@ let ChannelService = ChannelService_1 = class ChannelService extends BaseService
323
771
  }
324
772
  return criteria;
325
773
  }
326
- deleteChannel(id) {
327
- return this.repository.delete({
328
- id
329
- });
774
+ async deleteChannel(id) {
775
+ try {
776
+ return await this.repository.delete({
777
+ id
778
+ });
779
+ } catch (error) {
780
+ this.logger.error('Error deleting channel: %o', error);
781
+ return error instanceof Error ? error : new Error('Unknown error occurred');
782
+ }
330
783
  }
331
- getDeleted(teamId, offset, limit, userId) {
332
- return Promise.resolve(undefined);
784
+ async getDeleted(teamId, offset, limit, userId) {
785
+ try {
786
+ // Implementation would go here to get deleted channels
787
+ return [];
788
+ } catch (error) {
789
+ this.logger.error('Error getting deleted channels: %o', error);
790
+ return error instanceof Error ? error : new Error('Unknown error occurred');
791
+ }
333
792
  }
334
- getDeletedByName(teamId, name) {
335
- return Promise.resolve(undefined);
793
+ async getDeletedByName(teamId, name) {
794
+ try {
795
+ // Implementation would go here
796
+ return null;
797
+ } catch (error) {
798
+ this.logger.error('Error getting deleted channel by name: %o', error);
799
+ return error instanceof Error ? error : new Error('Unknown error occurred');
800
+ }
336
801
  }
337
- getFromMaster(id) {
338
- return Promise.resolve(undefined);
802
+ async getMoreChannels(teamId, userId, offset, limit) {
803
+ try {
804
+ // Implementation would go here
805
+ return [];
806
+ } catch (error) {
807
+ this.logger.error('Error getting more channels: %o', error);
808
+ return error instanceof Error ? error : new Error('Unknown error occurred');
809
+ }
339
810
  }
340
- getMoreChannels(teamId, userId, offset, limit) {
341
- return Promise.resolve(undefined);
811
+ async getPrivateChannelsForTeam(teamId, offset, limit) {
812
+ try {
813
+ // Implementation would go here
814
+ return [];
815
+ } catch (error) {
816
+ this.logger.error('Error getting private channels for team: %o', error);
817
+ return error instanceof Error ? error : new Error('Unknown error occurred');
818
+ }
342
819
  }
343
- getPrivateChannelsForTeam(teamId, offset, limit) {
344
- return Promise.resolve(undefined);
820
+ async getPublicChannelsByIdsForTeam(teamId, channelsIds) {
821
+ try {
822
+ // Implementation would go here
823
+ return [];
824
+ } catch (error) {
825
+ this.logger.error('Error getting public channels by IDs for team: %o', error);
826
+ return error instanceof Error ? error : new Error('Unknown error occurred');
827
+ }
345
828
  }
346
- getPublicChannelsByIdsForTeam(teamId, channelsIds) {
347
- return Promise.resolve(undefined);
829
+ async getPublicChannelsForTeam(teamId, offset, limit) {
830
+ try {
831
+ // Implementation would go here
832
+ return [];
833
+ } catch (error) {
834
+ this.logger.error('Error getting public channels for team: %o', error);
835
+ return error instanceof Error ? error : new Error('Unknown error occurred');
836
+ }
348
837
  }
349
- getPublicChannelsForTeam(teamId, offset, limit) {
350
- return Promise.resolve(undefined);
838
+ async getTeamChannels(teamId) {
839
+ try {
840
+ // Implementation would go here
841
+ return [];
842
+ } catch (error) {
843
+ this.logger.error('Error getting team channels: %o', error);
844
+ return error instanceof Error ? error : new Error('Unknown error occurred');
845
+ }
351
846
  }
352
- getTeamChannels(teamId) {
353
- return Promise.resolve(undefined);
847
+ async hideChannel(id) {
848
+ try {
849
+ // Implementation would go here
850
+ return false;
851
+ } catch (error) {
852
+ this.logger.error('Error hiding channel: %o', error);
853
+ return false;
854
+ }
354
855
  }
355
- hideChannel(id) {
356
- return Promise.resolve(false);
856
+ async leaveChannel(id) {
857
+ try {
858
+ // Implementation would go here
859
+ return false;
860
+ } catch (error) {
861
+ this.logger.error('Error leaving channel: %o', error);
862
+ return false;
863
+ }
357
864
  }
358
- invalidateChannelByName(teamId, name) {
359
- return Promise.resolve();
865
+ async viewChannel(id, user) {
866
+ try {
867
+ // Accessing private property
868
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
869
+ // @ts-ignore
870
+ if (id) {
871
+ await this.repository.model.updateOne({
872
+ _id: id
873
+ }, {
874
+ 'members.$[elem].lastViewedAt': new Date()
875
+ }, {
876
+ arrayFilters: [{
877
+ 'elem.user': user
878
+ }]
879
+ });
880
+ }
881
+ return true;
882
+ } catch (error) {
883
+ this.logger.error('Error viewing channel: %o', error);
884
+ return false;
885
+ }
360
886
  }
361
- leaveChannel(id) {
362
- return Promise.resolve(false);
887
+ async permanentDelete(channelId) {
888
+ try {
889
+ // Implementation would go here for permanent deletion
890
+ this.logger.debug(`Permanently deleting channel ${channelId}`);
891
+ } catch (error) {
892
+ this.logger.error('Error permanently deleting channel: %o', error);
893
+ return error instanceof Error ? error : new Error('Unknown error occurred');
894
+ }
363
895
  }
364
- async viewChannel(id, user) {
365
- // Accessing private property
366
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
367
- // @ts-ignore
368
- if (id) {
369
- await this.repository.model.updateOne({
370
- _id: id
371
- }, {
372
- 'members.$[elem].lastViewedAt': new Date()
373
- }, {
374
- arrayFilters: [{
375
- 'elem.user': user
376
- }]
377
- });
896
+ async permanentDeleteByTeam(teamId) {
897
+ try {
898
+ // Implementation would go here for permanent team deletion
899
+ this.logger.debug(`Permanently deleting all channels for team ${teamId}`);
900
+ } catch (error) {
901
+ this.logger.error('Error permanently deleting channels by team: %o', error);
902
+ return error instanceof Error ? error : new Error('Unknown error occurred');
378
903
  }
379
- return true;
380
904
  }
381
- permanentDelete(channelId) {
382
- return undefined;
905
+ async permanentDeleteMembersByChannel(channelId) {
906
+ try {
907
+ // Implementation would go here for permanent member deletion
908
+ this.logger.debug(`Permanently deleting all members for channel ${channelId}`);
909
+ } catch (error) {
910
+ this.logger.error('Error permanently deleting members by channel: %o', error);
911
+ return error instanceof Error ? error : new Error('Unknown error occurred');
912
+ }
383
913
  }
384
- permanentDeleteByTeam(teamId) {
385
- return undefined;
914
+ async saveMultipleMembers(members) {
915
+ try {
916
+ // Implementation would go here
917
+ return [];
918
+ } catch (error) {
919
+ this.logger.error('Error saving multiple members: %o', error);
920
+ return error instanceof Error ? error : new Error('Unknown error occurred');
921
+ }
386
922
  }
387
- permanentDeleteMembersByChannel(channelId) {
388
- return undefined;
923
+ async invalidateChannelByName(teamId, name) {
924
+ try {
925
+ if (!this.redisCacheManager) {
926
+ return;
927
+ }
928
+ // Invalidate name-based cache
929
+ await this.redisCacheManager.del(`${config.APP_NAME}:getChannelByName`, {
930
+ name
931
+ }, {
932
+ userId: 'system'
933
+ }, true);
934
+ // If we have team-specific variations in future, consider invalidating those keys as well
935
+ this.logger.debug(`Invalidated channel cache for name ${name} (team: ${teamId || 'n/a'})`);
936
+ } catch (error) {
937
+ this.logger.warn(`Error invalidating channel cache: ${error?.message}`);
938
+ }
389
939
  }
390
- saveMultipleMembers(members) {
391
- return Promise.resolve(undefined);
940
+ async createChannelWithProjectId(projectId, channelInput) {
941
+ try {
942
+ if (!this.inngestClient) {
943
+ return false;
944
+ }
945
+ const result = await this.inngestClient.send({
946
+ name: 'channel-with-project-id.create',
947
+ data: {
948
+ projectId,
949
+ channelInput
950
+ }
951
+ });
952
+ // Inngest send() typically returns an object with dispatched ids
953
+ const ok = !!result?.ids?.length;
954
+ return ok;
955
+ } catch (error) {
956
+ this.logger.error('Error creating channel with project ID: %o', error);
957
+ return false;
958
+ }
392
959
  }
393
960
  };
394
- ChannelService = ChannelService_1 = __decorate([__param(0, inject(SERVER_TYPES.ChannelRepository)), __param(1, inject(SERVER_TYPES.PostService)), __metadata("design:paramtypes", [Object, Object])], ChannelService);export{ChannelService};//# sourceMappingURL=channel-service.js.map
961
+ ChannelService = ChannelService_1 = __decorate([injectable()
962
+ // @ts-ignore - Type compatibility issue between BaseService2 and IChannelService
963
+ , __param(0, inject(SERVER_TYPES.ChannelRepository)), __param(1, inject(SERVER_TYPES.PostService)), __param(2, inject(CommonType.MOLECULER_BROKER)), __param(3, inject(SERVER_TYPES.IRedisCacheManager)), __param(4, inject(CommonType.REDIS_CLIENT)), __param(5, inject('Logger')), __param(6, inject(CommonType.INNGEST_CLIENT)), __metadata("design:paramtypes", [Object, Object, ServiceBroker, Object, Function, Object, Object])], ChannelService);export{ChannelService};//# sourceMappingURL=channel-service.js.map