add from to notification model (#14102)

This commit is contained in:
Pedro Guzman
2025-11-24 09:24:38 +01:00
committed by GitHub
parent 0cb12021ef
commit f67bfb9f92
9 changed files with 83 additions and 15 deletions

View File

@@ -0,0 +1,7 @@
---
"@medusajs/notification": patch
"@medusajs/core-flows": patch
"@medusajs/types": patch
---
add from to notification model

View File

@@ -1,4 +1,8 @@
import type { Attachment, INotificationModuleService, NotificationContent } from "@medusajs/framework/types"
import type {
Attachment,
INotificationModuleService,
NotificationContent,
} from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
@@ -11,6 +15,11 @@ export type SendNotificationsStepInput = {
* the channel. For example, the email address for the email channel.
*/
to: string
/**
* The address to send the notification from, depending on
* the channel. For example, the email address for the email channel.
*/
from?: string | null
/**
* The channel to send the notification through. For example, `email`.
*/

View File

@@ -147,6 +147,10 @@ export interface FilterableNotificationProps
* Filter based on the recipient of the notification.
*/
to?: string | string[] | OperatorMap<string | string[]>
/**
* Filter based on the recipient of the notification.
*/
from?: string | string[] | OperatorMap<string | string[]>
/**
* Filter based on the channel through which the notification is sent, such as 'email' or 'sms'
*/

View File

@@ -11,6 +11,10 @@ export interface CreateNotificationDTO {
* The recipient of the notification. It can be email, phone number, or username, depending on the channel.
*/
to: string
/**
* The sender of the notification. It can be email, phone number, or username, depending on the channel.
*/
from?: string | null
/**
* The channel through which the notification is sent, such as `email` or `sms`.
*/

View File

@@ -1,4 +1,7 @@
import { INotificationModuleService } from "@medusajs/framework/types"
import {
CreateNotificationDTO,
INotificationModuleService,
} from "@medusajs/framework/types"
import {
CommonEvents,
composeMessage,
@@ -74,19 +77,27 @@ moduleIntegrationTestRunner<INotificationModuleService>({
it("should send a notification and stores it in the database", async () => {
const notification = {
to: "admin@medusa.com",
from: "sender@verified.com",
template: "some-template",
channel: "email",
data: {},
}
} as CreateNotificationDTO
const result = await service.createNotifications(notification)
expect(result).toEqual(
expect.objectContaining({
provider_id: "test-provider",
external_id: "external_id",
status: NotificationStatus.SUCCESS,
})
)
const retrieved = await service.retrieveNotification(result.id)
const expected = {
to: "admin@medusa.com",
from: "sender@verified.com",
template: "some-template",
channel: "email",
data: {},
provider_id: "test-provider",
external_id: "external_id",
status: NotificationStatus.SUCCESS,
}
expect(result).toEqual(expect.objectContaining(expected))
expect(retrieved).toEqual(expect.objectContaining(expected))
})
it("should send a notification and don't store the content in the database", async () => {

View File

@@ -14,6 +14,7 @@ const successMedusaCloudEmailResponse = {
const testNotification = {
to: "customer@test.com",
from: "sender@verified.com",
template: "some-template",
channel: "email",
data: {
@@ -50,6 +51,13 @@ moduleIntegrationTestRunner<INotificationModuleService>({
const result = await service.createNotifications(testNotification)
expect(result).toEqual(
expect.objectContaining({
to: "customer@test.com",
from: "sender@verified.com",
template: "some-template",
channel: "email",
data: {
link: "https://test.com",
},
provider_id: "cloud",
external_id: "external_id_1",
status: NotificationStatus.SUCCESS,
@@ -66,6 +74,7 @@ moduleIntegrationTestRunner<INotificationModuleService>({
)
expect(JSON.parse(request.body)).toEqual({
to: "customer@test.com",
from: "sender@verified.com",
template: "some-template",
data: {
link: "https://test.com",

View File

@@ -96,7 +96,7 @@
"constraint": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_notification_provider_deleted_at\" ON \"notification_provider\" (deleted_at) WHERE deleted_at IS NULL"
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_notification_provider_deleted_at\" ON \"notification_provider\" (\"deleted_at\") WHERE deleted_at IS NULL"
},
{
"keyName": "notification_provider_pkey",
@@ -133,6 +133,15 @@
"nullable": false,
"mappedType": "text"
},
"from": {
"name": "from",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"channel": {
"name": "channel",
"type": "text",
@@ -290,7 +299,7 @@
"constraint": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_notification_receiver_id\" ON \"notification\" (receiver_id) WHERE deleted_at IS NULL"
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_notification_receiver_id\" ON \"notification\" (\"receiver_id\") WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_notification_idempotency_key_unique",
@@ -299,7 +308,7 @@
"constraint": false,
"primary": false,
"unique": false,
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_notification_idempotency_key_unique\" ON \"notification\" (idempotency_key) WHERE deleted_at IS NULL"
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_notification_idempotency_key_unique\" ON \"notification\" (\"idempotency_key\") WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_notification_provider_id",
@@ -308,7 +317,7 @@
"constraint": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_notification_provider_id\" ON \"notification\" (provider_id) WHERE deleted_at IS NULL"
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_notification_provider_id\" ON \"notification\" (\"provider_id\") WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_notification_deleted_at",
@@ -317,7 +326,7 @@
"constraint": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_notification_deleted_at\" ON \"notification\" (deleted_at) WHERE deleted_at IS NULL"
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_notification_deleted_at\" ON \"notification\" (\"deleted_at\") WHERE deleted_at IS NULL"
},
{
"keyName": "notification_pkey",

View File

@@ -0,0 +1,13 @@
import { Migration } from '@mikro-orm/migrations';
export class Migration20251121123942 extends Migration {
override async up(): Promise<void> {
this.addSql(`alter table if exists "notification" add column if not exists "from" text null;`);
}
override async down(): Promise<void> {
this.addSql(`alter table if exists "notification" drop column if exists "from";`);
}
}

View File

@@ -6,6 +6,8 @@ export const Notification = model.define("notification", {
id: model.id({ prefix: "noti" }).primaryKey(),
// This can be an email, phone number, or username, depending on the channel.
to: model.text().searchable(),
// This can be an email, phone number, or username, depending on the channel.
from: model.text().searchable().nullable(),
channel: model.text(),
// The template name in the provider's system.
template: model.text().nullable(),