Skip to content

Commit

Permalink
feat: Add the basic implementation of notification module (medusajs#7282
Browse files Browse the repository at this point in the history
)

* feat: Add the basic implementation of notification module

* fix: Minor fixes and introduction of idempotency key

* fix: Changes based on PR review
  • Loading branch information
sradevski authored May 10, 2024
1 parent 6ec5ded commit 144e09e
Show file tree
Hide file tree
Showing 43 changed files with 1,666 additions and 1 deletion.
8 changes: 8 additions & 0 deletions .changeset/moody-days-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@medusajs/modules-sdk": minor
"@medusajs/types": minor
"@medusajs/utils": minor
"@medusajs/notification": patch
---

Add basic implementation of a notification module
16 changes: 16 additions & 0 deletions packages/core/modules-sdk/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export enum Modules {
STORE = "store",
CURRENCY = "currency",
FILE = "file",
NOTIFICATION = "notification",
}

export enum ModuleRegistrationName {
Expand All @@ -61,6 +62,7 @@ export enum ModuleRegistrationName {
STORE = "storeModuleService",
CURRENCY = "currencyModuleService",
FILE = "fileModuleService",
NOTIFICATION = "notificationModuleService",
}

export const MODULE_PACKAGE_NAMES = {
Expand All @@ -87,6 +89,7 @@ export const MODULE_PACKAGE_NAMES = {
[Modules.STORE]: "@medusajs/store",
[Modules.CURRENCY]: "@medusajs/currency",
[Modules.FILE]: "@medusajs/file",
[Modules.NOTIFICATION]: "@medusajs/notification",
}

export const ModulesDefinition: { [key: string | Modules]: ModuleDefinition } =
Expand Down Expand Up @@ -378,6 +381,19 @@ export const ModulesDefinition: { [key: string | Modules]: ModuleDefinition } =
resources: MODULE_RESOURCE_TYPE.SHARED,
},
},
[Modules.NOTIFICATION]: {
key: Modules.NOTIFICATION,
registrationName: ModuleRegistrationName.NOTIFICATION,
defaultPackage: false,
label: upperCaseFirst(ModuleRegistrationName.NOTIFICATION),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
},
},
}

export const MODULE_DEFINITIONS: ModuleDefinition[] =
Expand Down
1 change: 1 addition & 0 deletions packages/core/types/src/bundles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export * as StoreTypes from "./store"
export * as CurrencyTypes from "./currency"
export * as HttpTypes from "./http"
export * as FileTypes from "./file"
export * as NotificationTypes from "./notification"
1 change: 1 addition & 0 deletions packages/core/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ export * from "./transaction-base"
export * from "./user"
export * from "./workflow"
export * from "./workflows"
export * from "./notification"
138 changes: 138 additions & 0 deletions packages/core/types/src/notification/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { BaseFilterable } from "../dal"
import { OperatorMap } from "../dal/utils"

/**
* @interface
*
* A notification's data.
*/
export interface NotificationDTO {
/**
* The ID of the notification.
*/
id: string
/**
* The recipient of the notification. It can be email, phone number, or username, depending on the channel.
*/
to: string
/**
* The channel through which the notification is sent, such as 'email' or 'sms'
*/
channel: string
/**
* The template name in the provider's system.
*/
template: string
/**
* The data that gets passed over to the provider for rendering the notification.
*/
data: Record<string, unknown> | null
/**
* The event name, the workflow, or anything else that can help to identify what triggered the notification.
*/
trigger_type?: string | null
/**
* The ID of the resource this notification is for, if applicable. Useful for displaying relevant information in the UI
*/
resource_id?: string | null
/**
* The type of the resource this notification is for, if applicable, eg. "order"
*/
resource_type?: string | null
/**
* The ID of the customer this notification is for, if applicable.
*/
receiver_id?: string | null
/**
* The original notification, in case this is a retried notification.
*/
original_notification_id?: string | null
/**
* The id of the notification in the external system, if applicable
*/
external_id?: string | null
/**
* The ID of the notification provider.
*/
provider_id: string
/**
* Information about the notification provider
*/
provider: NotificationProviderDTO
/**
* The date and time the notification was created.
*/
created_at: Date
}

/**
* @interface
*
* Information about the notification provider
*/
export interface NotificationProviderDTO {
/**
* The ID of the notification provider.
*/
id: string
/**
* The handle of the notification provider.
*/
handle: string
/**
* A user-friendly name of the notification provider.
*/
name: string
/**
* The supported channels by the notification provider.
*/
channels: string[]
}

/**
* @interface
*
* The filters to apply on retrieved notifications.
*
* @prop q - Search through the notifications' attributes, such as trigger types and recipients, using this search term.
*/

export interface FilterableNotificationProps
extends BaseFilterable<FilterableNotificationProps> {
/**
* Search through the notifications' attributes, such as trigger types and recipients, using this search term.
*/
q?: string
/**
* Filter based on the recipient of the notification.
*/
to?: string | string[] | OperatorMap<string | string[]>
/**
* Filter based on the channel through which the notification is sent, such as 'email' or 'sms'
*/
channel?: string | string[] | OperatorMap<string | string[]>
/**
* Filter based on the template name.
*/
template?: string | string[] | OperatorMap<string | string[]>
/**
* Filter based on the trigger type.
*/
trigger_type?: string | string[] | OperatorMap<string | string[]>
/**
* Filter based on the resource that was the trigger for the notification.
*/
resource_id?: string | string[] | OperatorMap<string | string[]>
/**
* T* Filter based on the resource type that was the trigger for the notification.
*/
resource_type?: string | string[] | OperatorMap<string | string[]>
/**
* Filter based on the customer ID.
*/
receiver_id?: string | string[] | OperatorMap<string | string[]>
/**
* Filters a notification based on when it was sent and created in the database
*/
created_at?: OperatorMap<string>
}
5 changes: 5 additions & 0 deletions packages/core/types/src/notification/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from "./common"
export * from "./providers"
export * from "./mutations"
export * from "./service"
export * from "./provider"
48 changes: 48 additions & 0 deletions packages/core/types/src/notification/mutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @interface
*
* A notification to send and have created in the DB
*
*/
export interface CreateNotificationDTO {
/**
* The recipient of the notification. It can be email, phone number, or username, depending on the channel.
*/
to: string
/**
* The channel through which the notification is sent, such as 'email' or 'sms'
*/
channel: string
/**
* The template name in the provider's system.
*/
template: string
/**
* The data that gets passed over to the provider for rendering the notification.
*/
data?: Record<string, unknown> | null
/**
* The event name, the workflow, or anything else that can help to identify what triggered the notification.
*/
trigger_type?: string | null
/**
* The ID of the resource this notification is for, if applicable. Useful for displaying relevant information in the UI
*/
resource_id?: string | null
/**
* The type of the resource this notification is for, if applicable, eg. "order"
*/
resource_type?: string | null
/**
* The ID of the customer this notification is for, if applicable.
*/
receiver_id?: string | null
/**
* The original notification, in case this is a retried notification.
*/
original_notification_id?: string | null
/**
* An idempotency key that ensures the same notification is not sent multiple times.
*/
idempotency_key?: string | null
}
54 changes: 54 additions & 0 deletions packages/core/types/src/notification/provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @interface
*
* The details of the notification to send.
*/
export type ProviderSendNotificationDTO = {
/**
* The recipient of the notification. It can be email, phone number, or username, depending on the channel.
*/
to: string
/**
* The channel through which the notification is sent, such as 'email' or 'sms'
*/
channel: string
/**
* The template name in the provider's system.
*/
template: string
/**
* The data that gets passed over to the provider for rendering the notification.
*/
data?: Record<string, unknown> | null
}

/**
* @interface
*
* The result of sending the notification
*/
export type ProviderSendNotificationResultsDTO = {
/**
* The ID of the notification in the external system, if provided in the response
*/
id?: string
}

/**
* ## Overview
*
* Notification provider interface for the notification module.
*
*/
export interface INotificationProvider {
/**
* This method is used to send a notification.
*
* @param {ProviderSendNotificationDTO} notification - All information needed to send a notification.
* @returns {Promise<ProviderSendNotificationResultsDTO>} The result of sending the notification.
*
*/
send(
notification: ProviderSendNotificationDTO
): Promise<ProviderSendNotificationResultsDTO>
}
1 change: 1 addition & 0 deletions packages/core/types/src/notification/providers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./local"
1 change: 1 addition & 0 deletions packages/core/types/src/notification/providers/local.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export interface LocalNotificationServiceOptions {}
Loading

0 comments on commit 144e09e

Please sign in to comment.