|
|
@@ -1,537 +0,0 @@
|
|
|
-"use strict";
|
|
|
-// oms/src/services/messageRecordService.ts
|
|
|
-Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
-exports.MessageRecordService = void 0;
|
|
|
-const messageRecordModel_1 = require("../models/messageRecordModel");
|
|
|
-class MessageRecordService {
|
|
|
- /**
|
|
|
- * Creates a new message push record.
|
|
|
- * @param recordData Message record data.
|
|
|
- * @returns The newly created message record object.
|
|
|
- */
|
|
|
- async createMessageRecord(recordData) {
|
|
|
- const newRecord = new messageRecordModel_1.MessageRecord(recordData);
|
|
|
- return await newRecord.save();
|
|
|
- }
|
|
|
- /**
|
|
|
- * Gets paginated message records with filtering and sorting support.
|
|
|
- * @param page Page number.
|
|
|
- * @param limit Number of records per page.
|
|
|
- * @param filters Filter conditions.
|
|
|
- * @param sortField Field to sort by.
|
|
|
- * @param sortOrder Sort order ('asc' or 'desc').
|
|
|
- * @returns An object containing records and the total count.
|
|
|
- */
|
|
|
- async getPaginatedRecords(page = 1, limit = 10, filters = {}, sortField = "createdAt", sortOrder = "desc") {
|
|
|
- // Build the query conditions
|
|
|
- const query = {};
|
|
|
- if (filters.uid) {
|
|
|
- query.uid = filters.uid;
|
|
|
- }
|
|
|
- if (filters.activityName) {
|
|
|
- query.activityName = filters.activityName;
|
|
|
- }
|
|
|
- if (filters.templateName) {
|
|
|
- query.templateName = filters.templateName;
|
|
|
- }
|
|
|
- if (filters.status !== undefined) {
|
|
|
- query.status = filters.status;
|
|
|
- }
|
|
|
- const sort = {};
|
|
|
- sort[sortField] = sortOrder === "asc" ? 1 : -1;
|
|
|
- const skip = (page - 1) * limit;
|
|
|
- const records = await messageRecordModel_1.MessageRecord.find(query).sort(sort).skip(skip).limit(limit);
|
|
|
- const total = await messageRecordModel_1.MessageRecord.countDocuments(query);
|
|
|
- return { records, total };
|
|
|
- }
|
|
|
- /**
|
|
|
- * Gets all message records for a specific user UID.
|
|
|
- * @param uid User UID.
|
|
|
- * @returns A list of message records.
|
|
|
- */
|
|
|
- async getRecordsByUid(uid) {
|
|
|
- return await messageRecordModel_1.MessageRecord.find({ uid }).sort({ createdAt: -1 });
|
|
|
- }
|
|
|
- /**
|
|
|
- * Gets all message records related to a specific activity ID.
|
|
|
- * @param activityId Message activity ID.
|
|
|
- * @returns A list of message records.
|
|
|
- */
|
|
|
- async getRecordsByActivityId(activityId) {
|
|
|
- return await messageRecordModel_1.MessageRecord.find({ activityId }).sort({ createdAt: -1 });
|
|
|
- }
|
|
|
- /**
|
|
|
- * Gets a single message record by ID.
|
|
|
- * @param recordId Message record ID.
|
|
|
- * @returns The message record object or null.
|
|
|
- */
|
|
|
- async getSingleRecord(recordId) {
|
|
|
- return await messageRecordModel_1.MessageRecord.findById(recordId);
|
|
|
- }
|
|
|
- /**
|
|
|
- * Updates the status of a message record.
|
|
|
- * @param recordId Message record ID.
|
|
|
- * @param updateData Data to update.
|
|
|
- * @returns The updated message record object.
|
|
|
- */
|
|
|
- async updateMessageRecord(recordId, updateData) {
|
|
|
- return await messageRecordModel_1.MessageRecord.findByIdAndUpdate(recordId, updateData, { new: true });
|
|
|
- }
|
|
|
- /**
|
|
|
- * Gets overall message push statistics.
|
|
|
- */
|
|
|
- async getOverallStatistics() {
|
|
|
- try {
|
|
|
- const result = await messageRecordModel_1.MessageRecord.aggregate([
|
|
|
- // 1. Group messages by status
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: "$status",
|
|
|
- count: { $sum: 1 },
|
|
|
- },
|
|
|
- },
|
|
|
- // 2. Transform the result into a more manageable format
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: null,
|
|
|
- total_records: { $sum: "$count" },
|
|
|
- status_counts: {
|
|
|
- $push: {
|
|
|
- k: { $toString: "$_id" },
|
|
|
- v: "$count",
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- // 3. Reformat the output and calculate all rates
|
|
|
- {
|
|
|
- $project: {
|
|
|
- _id: 0,
|
|
|
- totalRecords: "$total_records",
|
|
|
- sent: {
|
|
|
- $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "1"] }] }, 0],
|
|
|
- },
|
|
|
- delivered: {
|
|
|
- $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "2"] }] }, 0],
|
|
|
- },
|
|
|
- opened: {
|
|
|
- $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "3"] }] }, 0],
|
|
|
- },
|
|
|
- failed: {
|
|
|
- $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "-1"] }] }, 0],
|
|
|
- },
|
|
|
- // Sent success rate = (sent + delivered + opened) / total
|
|
|
- sentSuccessRate: {
|
|
|
- $cond: [
|
|
|
- { $eq: ["$total_records", 0] },
|
|
|
- 0,
|
|
|
- {
|
|
|
- $divide: [
|
|
|
- {
|
|
|
- $sum: [
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "1"] }] }, 0] },
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "2"] }] }, 0] },
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "3"] }] }, 0] },
|
|
|
- ],
|
|
|
- },
|
|
|
- "$total_records",
|
|
|
- ],
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
- // Delivered rate = delivered / (sent + delivered)
|
|
|
- deliveredRate: {
|
|
|
- $cond: [
|
|
|
- {
|
|
|
- $eq: [
|
|
|
- {
|
|
|
- $sum: [
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "1"] }] }, 0] },
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "2"] }] }, 0] },
|
|
|
- ],
|
|
|
- },
|
|
|
- 0,
|
|
|
- ],
|
|
|
- },
|
|
|
- 0,
|
|
|
- {
|
|
|
- $divide: [
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "2"] }] }, 0] },
|
|
|
- {
|
|
|
- $sum: [
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "1"] }] }, 0] },
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "2"] }] }, 0] },
|
|
|
- ],
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
- // Opened rate = opened / (delivered + opened)
|
|
|
- openedRate: {
|
|
|
- $cond: [
|
|
|
- {
|
|
|
- $eq: [
|
|
|
- {
|
|
|
- $sum: [
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "2"] }] }, 0] },
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "3"] }] }, 0] },
|
|
|
- ],
|
|
|
- },
|
|
|
- 0,
|
|
|
- ],
|
|
|
- },
|
|
|
- 0,
|
|
|
- {
|
|
|
- $divide: [
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "3"] }] }, 0] },
|
|
|
- {
|
|
|
- $sum: [
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "2"] }] }, 0] },
|
|
|
- { $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "3"] }] }, 0] },
|
|
|
- ],
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
- // Token invalidation rate
|
|
|
- tokenInvalidationRate: {
|
|
|
- $cond: [{ $eq: ["$total_records", 0] }, 0, { $divide: [{ $ifNull: [{ $arrayElemAt: ["$status_counts.v", { $indexOfArray: ["$status_counts.k", "-1"] }] }, 0] }, "$total_records"] }],
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- ]);
|
|
|
- return result[0];
|
|
|
- }
|
|
|
- catch (error) {
|
|
|
- console.error("Error fetching overall statistics:", error);
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
- /**
|
|
|
- * Gets message statistics grouped by activity.
|
|
|
- */
|
|
|
- async getStatisticsByActivity() {
|
|
|
- try {
|
|
|
- const results = await messageRecordModel_1.MessageRecord.aggregate([
|
|
|
- // 1. Group by both activityId and status
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: { activityId: "$activityId", activityName: "$activityName", status: "$status" },
|
|
|
- count: { $sum: 1 },
|
|
|
- },
|
|
|
- },
|
|
|
- // 2. Regroup by activityId to summarize counts and get the activityName
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: "$_id.activityId", // Group by the ID
|
|
|
- activityName: { $first: "$_id.activityName" }, // Keep the name
|
|
|
- total_sent: { $sum: "$count" },
|
|
|
- sent_count: { $sum: { $cond: [{ $eq: ["$_id.status", 1] }, "$count", 0] } },
|
|
|
- delivered_count: {
|
|
|
- $sum: { $cond: [{ $eq: ["$_id.status", 2] }, "$count", 0] },
|
|
|
- },
|
|
|
- opened_count: {
|
|
|
- $sum: { $cond: [{ $eq: ["$_id.status", 3] }, "$count", 0] },
|
|
|
- },
|
|
|
- failed_count: {
|
|
|
- $sum: { $cond: [{ $eq: ["$_id.status", -1] }, "$count", 0] },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- // 3. Calculate rates and format the output
|
|
|
- {
|
|
|
- $project: {
|
|
|
- _id: 0,
|
|
|
- activityId: "$_id",
|
|
|
- activityName: "$activityName",
|
|
|
- totalSent: "$total_sent",
|
|
|
- sent: "$sent_count",
|
|
|
- delivered: "$delivered_count",
|
|
|
- opened: "$opened_count",
|
|
|
- failed: "$failed_count",
|
|
|
- sentSuccessRate: {
|
|
|
- $cond: [{ $eq: ["$total_sent", 0] }, 0, { $divide: [{ $sum: ["$sent_count", "$delivered_count", "$opened_count"] }, "$total_sent"] }],
|
|
|
- },
|
|
|
- tokenInvalidationRate: {
|
|
|
- $cond: [{ $eq: ["$total_sent", 0] }, 0, { $divide: ["$failed_count", "$total_sent"] }],
|
|
|
- },
|
|
|
- deliveredRate: {
|
|
|
- $cond: [{ $eq: [{ $sum: ["$sent_count", "$delivered_count"] }, 0] }, 0, { $divide: ["$delivered_count", { $sum: ["$sent_count", "$delivered_count"] }] }],
|
|
|
- },
|
|
|
- openedRate: {
|
|
|
- $cond: [{ $eq: [{ $sum: ["$delivered_count", "$opened_count"] }, 0] }, 0, { $divide: ["$opened_count", { $sum: ["$delivered_count", "$opened_count"] }] }],
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- // 4. Sort by deliveredRate in descending order
|
|
|
- {
|
|
|
- $sort: { deliveredRate: -1 },
|
|
|
- },
|
|
|
- ]);
|
|
|
- return results;
|
|
|
- }
|
|
|
- catch (error) {
|
|
|
- console.error("Error fetching statistics by activity:", error);
|
|
|
- return [];
|
|
|
- }
|
|
|
- }
|
|
|
- /**
|
|
|
- * Gets message statistics grouped by strategy.
|
|
|
- */
|
|
|
- async getStatisticsByStrategy() {
|
|
|
- try {
|
|
|
- const results = await messageRecordModel_1.MessageRecord.aggregate([
|
|
|
- // 1. Group by both strategyId and status
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: { strategyId: "$strategyId", strategyName: "$strategyName", status: "$status" },
|
|
|
- count: { $sum: 1 },
|
|
|
- },
|
|
|
- },
|
|
|
- // 2. Regroup by strategyId to summarize counts and get the strategyName
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: "$_id.strategyId",
|
|
|
- strategyName: { $first: "$_id.strategyName" },
|
|
|
- total_sent: { $sum: "$count" },
|
|
|
- sent_count: { $sum: { $cond: [{ $eq: ["$_id.status", 1] }, "$count", 0] } },
|
|
|
- delivered_count: {
|
|
|
- $sum: { $cond: [{ $eq: ["$_id.status", 2] }, "$count", 0] },
|
|
|
- },
|
|
|
- opened_count: {
|
|
|
- $sum: { $cond: [{ $eq: ["$_id.status", 3] }, "$count", 0] },
|
|
|
- },
|
|
|
- failed_count: {
|
|
|
- $sum: { $cond: [{ $eq: ["$_id.status", -1] }, "$count", 0] },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- // 3. Calculate rates and format the output
|
|
|
- {
|
|
|
- $project: {
|
|
|
- _id: 0,
|
|
|
- strategyId: "$_id",
|
|
|
- strategyName: "$strategyName",
|
|
|
- totalSent: "$total_sent",
|
|
|
- sent: "$sent_count",
|
|
|
- delivered: "$delivered_count",
|
|
|
- opened: "$opened_count",
|
|
|
- failed: "$failed_count",
|
|
|
- sentSuccessRate: {
|
|
|
- $cond: [{ $eq: ["$total_sent", 0] }, 0, { $divide: [{ $sum: ["$sent_count", "$delivered_count", "$opened_count"] }, "$total_sent"] }],
|
|
|
- },
|
|
|
- tokenInvalidationRate: {
|
|
|
- $cond: [{ $eq: ["$total_sent", 0] }, 0, { $divide: ["$failed_count", "$total_sent"] }],
|
|
|
- },
|
|
|
- deliveredRate: {
|
|
|
- $cond: [{ $eq: [{ $sum: ["$sent_count", "$delivered_count"] }, 0] }, 0, { $divide: ["$delivered_count", { $sum: ["$sent_count", "$delivered_count"] }] }],
|
|
|
- },
|
|
|
- openedRate: {
|
|
|
- $cond: [{ $eq: [{ $sum: ["$delivered_count", "$opened_count"] }, 0] }, 0, { $divide: ["$opened_count", { $sum: ["$delivered_count", "$opened_count"] }] }],
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- // 4. Sort by deliveredRate in descending order
|
|
|
- {
|
|
|
- $sort: { deliveredRate: -1 },
|
|
|
- },
|
|
|
- ]);
|
|
|
- return results;
|
|
|
- }
|
|
|
- catch (error) {
|
|
|
- console.error("Error fetching statistics by strategy:", error);
|
|
|
- return [];
|
|
|
- }
|
|
|
- }
|
|
|
- /**
|
|
|
- * Gets message statistics grouped by template.
|
|
|
- */
|
|
|
- async getStatisticsByTemplate() {
|
|
|
- try {
|
|
|
- const results = await messageRecordModel_1.MessageRecord.aggregate([
|
|
|
- // 1. Group by both templateId and status
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: { templateId: "$templateId", templateName: "$templateName", status: "$status" },
|
|
|
- count: { $sum: 1 },
|
|
|
- },
|
|
|
- },
|
|
|
- // 2. Regroup by templateId to summarize counts and get the templateName
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: "$_id.templateId",
|
|
|
- templateName: { $first: "$_id.templateName" },
|
|
|
- total_sent: { $sum: "$count" },
|
|
|
- sent_count: { $sum: { $cond: [{ $eq: ["$_id.status", 1] }, "$count", 0] } },
|
|
|
- delivered_count: {
|
|
|
- $sum: { $cond: [{ $eq: ["$_id.status", 2] }, "$count", 0] },
|
|
|
- },
|
|
|
- opened_count: {
|
|
|
- $sum: { $cond: [{ $eq: ["$_id.status", 3] }, "$count", 0] },
|
|
|
- },
|
|
|
- failed_count: {
|
|
|
- $sum: { $cond: [{ $eq: ["$_id.status", -1] }, "$count", 0] },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- // 3. Calculate rates and format the output
|
|
|
- {
|
|
|
- $project: {
|
|
|
- _id: 0,
|
|
|
- templateId: "$_id",
|
|
|
- templateName: "$templateName",
|
|
|
- totalSent: "$total_sent",
|
|
|
- sent: "$sent_count",
|
|
|
- delivered: "$delivered_count",
|
|
|
- opened: "$opened_count",
|
|
|
- failed: "$failed_count",
|
|
|
- sentSuccessRate: {
|
|
|
- $cond: [{ $eq: ["$total_sent", 0] }, 0, { $divide: [{ $sum: ["$sent_count", "$delivered_count", "$opened_count"] }, "$total_sent"] }],
|
|
|
- },
|
|
|
- tokenInvalidationRate: {
|
|
|
- $cond: [{ $eq: ["$total_sent", 0] }, 0, { $divide: ["$failed_count", "$total_sent"] }],
|
|
|
- },
|
|
|
- deliveredRate: {
|
|
|
- $cond: [{ $eq: [{ $sum: ["$sent_count", "$delivered_count"] }, 0] }, 0, { $divide: ["$delivered_count", { $sum: ["$sent_count", "$delivered_count"] }] }],
|
|
|
- },
|
|
|
- openedRate: {
|
|
|
- $cond: [{ $eq: [{ $sum: ["$delivered_count", "$opened_count"] }, 0] }, 0, { $divide: ["$opened_count", { $sum: ["$delivered_count", "$opened_count"] }] }],
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- // 4. Sort by deliveredRate in descending order
|
|
|
- {
|
|
|
- $sort: { deliveredRate: -1 },
|
|
|
- },
|
|
|
- ]);
|
|
|
- return results;
|
|
|
- }
|
|
|
- catch (error) {
|
|
|
- console.error("Error fetching statistics by template:", error);
|
|
|
- return [];
|
|
|
- }
|
|
|
- }
|
|
|
- /**
|
|
|
- * Gets daily message sending trends.
|
|
|
- */
|
|
|
- async getDailySentTrends() {
|
|
|
- try {
|
|
|
- const results = await messageRecordModel_1.MessageRecord.aggregate([
|
|
|
- // 1. Truncate actualSendAt to the day, ignoring time
|
|
|
- {
|
|
|
- $project: {
|
|
|
- _id: 0,
|
|
|
- date: {
|
|
|
- $dateTrunc: { date: "$actualSendAt", unit: "day", timezone: "America/Los_Angeles" },
|
|
|
- },
|
|
|
- status: "$status",
|
|
|
- },
|
|
|
- },
|
|
|
- // 2. Group by date and status
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: { date: "$date", status: "$status" },
|
|
|
- count: { $sum: 1 },
|
|
|
- },
|
|
|
- },
|
|
|
- // 3. Regroup to summarize counts by date
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: "$_id.date",
|
|
|
- totalSent: { $sum: "$count" },
|
|
|
- sent: { $sum: { $cond: [{ $eq: ["$_id.status", 1] }, "$count", 0] } },
|
|
|
- delivered: { $sum: { $cond: [{ $eq: ["$_id.status", 2] }, "$count", 0] } },
|
|
|
- opened: { $sum: { $cond: [{ $eq: ["$_id.status", 3] }, "$count", 0] } },
|
|
|
- failed: { $sum: { $cond: [{ $eq: ["$_id.status", -1] }, "$count", 0] } },
|
|
|
- },
|
|
|
- },
|
|
|
- // 4. Calculate rates and format the output
|
|
|
- {
|
|
|
- $project: {
|
|
|
- _id: 0,
|
|
|
- date: "$_id",
|
|
|
- totalSent: "$totalSent",
|
|
|
- sent: "$sent",
|
|
|
- delivered: "$delivered",
|
|
|
- opened: "$opened",
|
|
|
- failed: "$failed",
|
|
|
- // Sent success rate = (sent + delivered + opened) / total
|
|
|
- sentSuccessRate: {
|
|
|
- $cond: [{ $eq: ["$totalSent", 0] }, 0, { $divide: [{ $sum: ["$sent", "$delivered", "$opened"] }, "$totalSent"] }],
|
|
|
- },
|
|
|
- // Delivered rate = delivered / (sent + delivered)
|
|
|
- deliveredRate: {
|
|
|
- $cond: [{ $eq: [{ $sum: ["$sent", "$delivered"] }, 0] }, 0, { $divide: ["$delivered", { $sum: ["$sent", "$delivered"] }] }],
|
|
|
- },
|
|
|
- // Opened rate = opened / (delivered + opened)
|
|
|
- openedRate: {
|
|
|
- $cond: [{ $eq: [{ $sum: ["$delivered", "$opened"] }, 0] }, 0, { $divide: ["$opened", { $sum: ["$delivered", "$opened"] }] }],
|
|
|
- },
|
|
|
- // Token invalidation rate
|
|
|
- tokenInvalidationRate: {
|
|
|
- $cond: [{ $eq: ["$totalSent", 0] }, 0, { $divide: ["$failed", "$totalSent"] }],
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- // 5. Sort by date in ascending order
|
|
|
- {
|
|
|
- $sort: { date: 1 },
|
|
|
- },
|
|
|
- ]);
|
|
|
- return results;
|
|
|
- }
|
|
|
- catch (error) {
|
|
|
- console.error("Error fetching daily sent trends:", error);
|
|
|
- return [];
|
|
|
- }
|
|
|
- }
|
|
|
- /**
|
|
|
- * Calculates the average delivery time.
|
|
|
- */
|
|
|
- async getAverageDeliveryTime() {
|
|
|
- try {
|
|
|
- const result = await messageRecordModel_1.MessageRecord.aggregate([
|
|
|
- // 1. Filter for delivered messages (status 2 or 3) with existing timestamps
|
|
|
- {
|
|
|
- $match: {
|
|
|
- status: { $in: [2, 3] },
|
|
|
- actualSendAt: { $exists: true, $ne: null },
|
|
|
- deliveredAt: { $exists: true, $ne: null },
|
|
|
- },
|
|
|
- },
|
|
|
- // 2. Calculate the time difference (in milliseconds) from send to delivery
|
|
|
- {
|
|
|
- $addFields: {
|
|
|
- time_to_deliver: {
|
|
|
- $subtract: ["$deliveredAt", "$actualSendAt"],
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- // 3. Calculate the average time
|
|
|
- {
|
|
|
- $group: {
|
|
|
- _id: null,
|
|
|
- avg_time_to_deliver_ms: { $avg: "$time_to_deliver" },
|
|
|
- },
|
|
|
- },
|
|
|
- // 4. Convert to seconds for readability
|
|
|
- {
|
|
|
- $project: {
|
|
|
- _id: 0,
|
|
|
- averageTimeToDeliverInSeconds: {
|
|
|
- $divide: ["$avg_time_to_deliver_ms", 1000],
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- ]);
|
|
|
- return result[0];
|
|
|
- }
|
|
|
- catch (error) {
|
|
|
- console.error("Error calculating average delivery time:", error);
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-exports.MessageRecordService = MessageRecordService;
|