Просмотр исходного кода

refactor: update GlobalNotificationService and related types for improved type safety and consistency

Yuki Takei 2 месяцев назад
Родитель
Сommit
245e135b91

+ 3 - 3
apps/app/src/server/crowi/index.ts

@@ -670,9 +670,9 @@ class Crowi {
    * setup GlobalNotificationService
    */
   async setUpGlobalNotification(): Promise<void> {
-    const GlobalNotificationService = (
-      await import('../service/global-notification')
-    ).default;
+    const { GlobalNotificationService } = await import(
+      '../service/global-notification'
+    );
     if (this.globalNotificationService == null) {
       this.globalNotificationService = new GlobalNotificationService(this);
     }

+ 19 - 0
apps/app/src/server/models/GlobalNotificationSetting/index.ts

@@ -4,10 +4,13 @@ import mongoose from 'mongoose';
 
 import type Crowi from '~/server/crowi';
 
+import type { GlobalNotificationSettingType } from './consts';
 import type {
   GlobalNotificationSettingDocument,
   GlobalNotificationSettingModel,
+  IGlobalNotificationMailSetting,
   IGlobalNotificationSetting,
+  IGlobalNotificationSlackSetting,
 } from './types';
 
 /**
@@ -123,6 +126,22 @@ class GlobalNotificationSetting {
   /**
    * find a list of notification settings by path and a list of events
    */
+  static async findSettingByPathAndEvent(
+    this: GlobalNotificationSettingModel,
+    event: string,
+    path: string,
+    type: typeof GlobalNotificationSettingType.SLACK,
+  ): Promise<
+    (GlobalNotificationSettingDocument & IGlobalNotificationSlackSetting)[]
+  >;
+  static async findSettingByPathAndEvent(
+    this: GlobalNotificationSettingModel,
+    event: string,
+    path: string,
+    type: typeof GlobalNotificationSettingType.MAIL,
+  ): Promise<
+    (GlobalNotificationSettingDocument & IGlobalNotificationMailSetting)[]
+  >;
   static async findSettingByPathAndEvent(
     this: GlobalNotificationSettingModel,
     event: string,

+ 13 - 2
apps/app/src/server/models/GlobalNotificationSetting/types.d.ts

@@ -2,6 +2,8 @@ import type { HydratedDocument, Model } from 'mongoose';
 
 import type Crowi from '~/server/crowi';
 
+import type { GlobalNotificationSettingType } from './consts';
+
 export interface IGlobalNotificationSetting {
   isEnabled: boolean;
   triggerPath: string;
@@ -19,8 +21,17 @@ export interface GlobalNotificationSettingModel
   findSettingByPathAndEvent(
     event: string,
     path: string,
-    type: string,
-  ): Promise<GlobalNotificationSettingDocument[]>;
+    type: typeof GlobalNotificationSettingType.SLACK,
+  ): Promise<
+    (GlobalNotificationSettingDocument & IGlobalNotificationSlackSetting)[]
+  >;
+  findSettingByPathAndEvent(
+    event: string,
+    path: string,
+    type: typeof GlobalNotificationSettingType.MAIL,
+  ): Promise<
+    (GlobalNotificationSettingDocument & IGlobalNotificationMailSetting)[]
+  >;
 }
 
 export interface IGlobalNotificationMailSetting

+ 16 - 12
apps/app/src/server/service/global-notification/global-notification-mail.ts

@@ -1,9 +1,10 @@
+import nodePath from 'node:path';
 import type { IUser } from '@growi/core/dist/interfaces';
-import nodePath from 'path';
 
 import type Crowi from '~/server/crowi';
 import {
   GlobalNotificationSettingEvent,
+  type GlobalNotificationSettingModel,
   GlobalNotificationSettingType,
 } from '~/server/models/GlobalNotificationSetting';
 import type { PageDocument } from '~/server/models/page';
@@ -49,20 +50,23 @@ class GlobalNotificationMailService {
   ): Promise<void> {
     const { mailService } = this.crowi;
 
-    const { GlobalNotificationSetting } = this.crowi.models;
-    const notifications = await (
-      GlobalNotificationSetting as any
-    ).findSettingByPathAndEvent(
-      event,
-      page.path,
-      GlobalNotificationSettingType.MAIL,
-    );
+    const GlobalNotificationSetting = this.crowi.models
+      .GlobalNotificationSetting as GlobalNotificationSettingModel;
+    const notifications =
+      await GlobalNotificationSetting.findSettingByPathAndEvent(
+        event,
+        page.path,
+        GlobalNotificationSettingType.MAIL,
+      );
 
     const option = this.generateOption(event, page, triggeredBy, vars);
 
     await Promise.all(
-      notifications.map((notification: { toEmail: string }) => {
-        return mailService?.send({ ...option, to: notification.toEmail });
+      notifications.map((notification) => {
+        return mailService?.send({
+          ...option,
+          to: notification.toEmail,
+        });
       }),
     );
   }
@@ -171,4 +175,4 @@ class GlobalNotificationMailService {
   }
 }
 
-export default GlobalNotificationMailService;
+export { GlobalNotificationMailService };

+ 17 - 16
apps/app/src/server/service/global-notification/global-notification-slack.ts

@@ -1,10 +1,12 @@
 import type { IUser } from '@growi/core/dist/interfaces';
 import { pagePathUtils } from '@growi/core/dist/utils';
+import type { ChatPostMessageArguments } from '@slack/web-api';
 import urljoin from 'url-join';
 
 import type Crowi from '~/server/crowi';
 import {
   GlobalNotificationSettingEvent,
+  type GlobalNotificationSettingModel,
   GlobalNotificationSettingType,
 } from '~/server/models/GlobalNotificationSetting';
 import loggerFactory from '~/utils/logger';
@@ -17,10 +19,6 @@ const _logger = loggerFactory('growi:service:GlobalNotificationSlackService');
 
 const { encodeSpaces } = pagePathUtils;
 
-interface GlobalNotificationSlackSetting {
-  slackChannels: string;
-}
-
 /**
  * sub service class of GlobalNotificationSetting
  */
@@ -53,14 +51,14 @@ class GlobalNotificationSlackService {
   ): Promise<void> {
     const { appService, slackIntegrationService } = this.crowi;
 
-    const { GlobalNotificationSetting } = this.crowi.models;
-    const notifications = (
-      GlobalNotificationSetting as any
-    ).findSettingByPathAndEvent(
-      event,
-      path,
-      GlobalNotificationSettingType.SLACK,
-    );
+    const GlobalNotificationSetting = this.crowi.models
+      .GlobalNotificationSetting as GlobalNotificationSettingModel;
+    const notifications =
+      await GlobalNotificationSetting.findSettingByPathAndEvent(
+        event,
+        path,
+        GlobalNotificationSettingType.SLACK,
+      );
 
     const messageBody = this.generateMessageBody(
       event,
@@ -80,15 +78,16 @@ class GlobalNotificationSlackService {
     const appTitle = appService.getAppTitle();
 
     await Promise.all(
-      notifications.map((notification: GlobalNotificationSlackSetting) => {
+      notifications.map((notification) => {
         const messageObj = prepareSlackMessageForGlobalNotification(
           messageBody,
           attachmentBody,
           appTitle,
           notification.slackChannels,
         );
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
-        return slackIntegrationService.postMessage(messageObj as any);
+        return slackIntegrationService.postMessage(
+          messageObj as unknown as ChatPostMessageArguments,
+        );
       }),
     );
   }
@@ -106,6 +105,7 @@ class GlobalNotificationSlackService {
    *
    * @return slack message body
    */
+  // biome-ignore lint/nursery/useMaxParams: event vars needed for different notification types
   generateMessageBody(
     event: string,
     id: string,
@@ -170,6 +170,7 @@ class GlobalNotificationSlackService {
    *
    * @return slack attachment body
    */
+  // biome-ignore lint/nursery/useMaxParams: event vars needed for different notification types
   generateAttachmentBody(
     _event: string,
     _id: string,
@@ -203,4 +204,4 @@ class GlobalNotificationSlackService {
   }
 }
 
-export default GlobalNotificationSlackService;
+export { GlobalNotificationSlackService };

+ 3 - 3
apps/app/src/server/service/global-notification/index.ts

@@ -5,8 +5,8 @@ import type Crowi from '~/server/crowi';
 import type { PageDocument } from '~/server/models/page';
 import loggerFactory from '~/utils/logger';
 
-import GlobalNotificationMailService from './global-notification-mail';
-import GlobalNotificationSlackService from './global-notification-slack';
+import { GlobalNotificationMailService } from './global-notification-mail';
+import { GlobalNotificationSlackService } from './global-notification-slack';
 import type { GlobalNotificationEventVars } from './types';
 
 const logger = loggerFactory('growi:service:GlobalNotificationService');
@@ -111,4 +111,4 @@ class GlobalNotificationService {
   }
 }
 
-export default GlobalNotificationService;
+export { GlobalNotificationService };