import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose"; import { HydratedDocument } from "mongoose"; /** Who dispatched the SMS: external gateways, or tejaratno when sent/skipped locally. */ export enum SmsSendLogProvider { KAVENEGAR = "kavenegar", PARSIAN = "parsian", TEJARATNO = "tejaratno", } export enum SmsSendLogOperation { SEND = "send", VERIFY_LOOKUP = "verifyLookup", SKIPPED = "skipped", } export enum SmsSendLogStatus { SUCCESS = "success", FAILURE = "failure", SKIPPED = "skipped", } export enum SmsSendLogKind { OTP = "otp", TEMPLATE = "template", PLAIN = "plain", SKIPPED = "skipped", } @Schema({ collection: "smsSendLogs", timestamps: true, versionKey: false }) export class SmsSendLog { /** Destination mobile number. */ @Prop({ type: String, required: true, index: true }) receptor: string; /** SMS dispatcher: kavenegar, parsian, or tejaratno (local/skipped). */ @Prop({ type: String, required: true, enum: SmsSendLogProvider, index: true, }) provider: SmsSendLogProvider; /** Originating shortcode/number when the provider exposes one (e.g. Kavenegar). */ @Prop({ type: String, required: false }) sender?: string; @Prop({ type: String, required: true, enum: SmsSendLogOperation, index: true, }) operation: SmsSendLogOperation; @Prop({ type: String, required: true, enum: SmsSendLogStatus, index: true, }) status: SmsSendLogStatus; @Prop({ type: String, required: true, enum: SmsSendLogKind, index: true, }) kind: SmsSendLogKind; /** Full message body when known (OTP kept as plain text). */ @Prop({ type: String, required: false }) messageText?: string; /** Kavenegar/Parsian template name for verifyLookup sends. */ @Prop({ type: String, required: false, index: true }) template?: string; /** * Template tokens as sent (OTP is `token` for auth — stored plain text on purpose). */ @Prop({ type: Object, required: false }) tokens?: { token?: string; token2?: string; token3?: string; token10?: string; }; /** True when this send is an auth OTP (or a skipped fake OTP). */ @Prop({ type: Boolean, required: false, index: true }) isOtp?: boolean; /** Deployment Fanavaran tenant when known (parsian / tejaratno / moallem). */ @Prop({ type: String, required: false, index: true }) tenant?: string; /** Raw provider API response body (success or rejection). */ @Prop({ type: Object, required: false }) providerResponse?: unknown; @Prop({ type: String, required: false }) errorMessage?: string; @Prop({ type: Object, required: false }) errorDetails?: Record; @Prop({ type: Number, required: false }) durationMs?: number; } export type SmsSendLogDocument = HydratedDocument; export const SmsSendLogSchema = SchemaFactory.createForClass(SmsSendLog); SmsSendLogSchema.index({ receptor: 1, createdAt: -1 }); SmsSendLogSchema.index({ provider: 1, createdAt: -1 }); SmsSendLogSchema.index({ isOtp: 1, createdAt: -1 });