feat: implement comprehensive notification engine with policies, preferences, and automated dispatching services
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import mongoose, { Document, Model, Schema, model } from "mongoose";
|
||||
|
||||
export type NotificationChannel = "whatsapp" | "email" | "system";
|
||||
export type NotificationJobStatus = "pending" | "processing" | "sent" | "failed" | "cancelled";
|
||||
export type NotificationJobType = "creation" | "reminder" | "update" | "cancellation";
|
||||
|
||||
export interface NotificationJobPayload {
|
||||
email?: string;
|
||||
phoneNumber?: string;
|
||||
userId?: string;
|
||||
companyOwnerId?: string;
|
||||
subject?: string;
|
||||
message?: string;
|
||||
emailSubject?: string;
|
||||
emailMessage?: string;
|
||||
wapMessage?: string;
|
||||
systemSubject?: string;
|
||||
systemMessage?: string;
|
||||
}
|
||||
|
||||
export interface INotificationJob {
|
||||
_id: string;
|
||||
companyId: string;
|
||||
appointmentId: string;
|
||||
clientId: string;
|
||||
channel: NotificationChannel;
|
||||
type: NotificationJobType;
|
||||
scheduledAt: Date;
|
||||
status: NotificationJobStatus;
|
||||
attempts: number;
|
||||
maxAttempts: number;
|
||||
lastError?: string;
|
||||
nextRetryAt?: Date;
|
||||
providerResponse?: string;
|
||||
payload?: NotificationJobPayload;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
sentAt?: Date;
|
||||
}
|
||||
|
||||
export interface INotificationJobDocument extends Omit<INotificationJob, "_id">, Document {}
|
||||
|
||||
export class NotificationJobModel {
|
||||
schema: Schema;
|
||||
notificationJobList: Model<INotificationJobDocument>;
|
||||
|
||||
constructor() {
|
||||
this.schema = new Schema(
|
||||
{
|
||||
companyId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
required: true,
|
||||
ref: "Companie",
|
||||
},
|
||||
appointmentId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
required: true,
|
||||
ref: "Appointment",
|
||||
},
|
||||
clientId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
required: true,
|
||||
ref: "Client",
|
||||
},
|
||||
channel: {
|
||||
type: String,
|
||||
required: true,
|
||||
enum: ["whatsapp", "email", "system"],
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
enum: ["creation", "reminder", "update", "cancellation"],
|
||||
},
|
||||
scheduledAt: { type: Date, required: true },
|
||||
status: {
|
||||
type: String,
|
||||
required: true,
|
||||
enum: ["pending", "processing", "sent", "failed", "cancelled"],
|
||||
default: "pending",
|
||||
},
|
||||
attempts: { type: Number, required: true, default: 0 },
|
||||
maxAttempts: { type: Number, required: true, default: 3 },
|
||||
lastError: { type: String, required: false },
|
||||
nextRetryAt: { type: Date, required: false },
|
||||
providerResponse: { type: String, required: false },
|
||||
payload: { type: Schema.Types.Mixed, required: false },
|
||||
sentAt: { type: Date, required: false },
|
||||
},
|
||||
{
|
||||
timestamps: true,
|
||||
}
|
||||
);
|
||||
|
||||
this.schema.index({ status: 1, scheduledAt: 1 });
|
||||
this.schema.index({ status: 1, scheduledAt: 1, nextRetryAt: 1 });
|
||||
this.schema.index({ companyId: 1, status: 1 });
|
||||
this.schema.index({ appointmentId: 1 });
|
||||
|
||||
this.notificationJobList = model<INotificationJobDocument>(
|
||||
"NotificationJob",
|
||||
this.schema
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user