@astralibx/email-analytics 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors/index.ts","../src/validation/config.schema.ts","../src/constants/index.ts","../src/schemas/email-event.schema.ts","../src/schemas/analytics-stats.schema.ts","../src/services/event-recorder.ts","../src/services/aggregator.ts","../src/services/query.service.ts","../src/controllers/analytics.controller.ts","../src/routes/index.ts","../src/index.ts"],"names":["Schema","Types"],"mappings":"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","file":"index.mjs","sourcesContent":["import { AlxError } from '@astralibx/core';\n\nexport class AlxAnalyticsError extends AlxError {\n constructor(message: string, public readonly code: string) {\n super(message, code);\n this.name = 'AlxAnalyticsError';\n }\n}\n\nexport { ConfigValidationError } from '@astralibx/core';\n\nexport class InvalidDateRangeError extends AlxAnalyticsError {\n constructor(\n public readonly startDate: string,\n public readonly endDate: string,\n ) {\n super(\n `Invalid date range: ${startDate} to ${endDate}`,\n 'INVALID_DATE_RANGE',\n );\n this.name = 'InvalidDateRangeError';\n }\n}\n\nexport class AggregationError extends AlxAnalyticsError {\n constructor(\n public readonly pipeline: string,\n public readonly originalError: Error,\n ) {\n super(\n `Aggregation pipeline failed (${pipeline}): ${originalError.message}`,\n 'AGGREGATION_FAILED',\n );\n this.name = 'AggregationError';\n }\n}\n","import { z } from 'zod';\nimport { loggerSchema, baseDbSchema } from '@astralibx/core';\nimport { ConfigValidationError } from '../errors';\n\nconst configSchema = z.object({\n db: baseDbSchema,\n logger: loggerSchema.optional(),\n options: z.object({\n eventTTLDays: z.number().int().positive().optional(),\n timezone: z.string().optional(),\n aggregationSchedule: z.array(\n z.enum(['daily', 'weekly', 'monthly']),\n ).optional(),\n }).optional(),\n});\n\nexport function validateConfig(raw: unknown): void {\n const result = configSchema.safeParse(raw);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` ${i.path.join('.')}: ${i.message}`)\n .join('\\n');\n throw new ConfigValidationError(\n `Invalid EmailAnalyticsConfig:\\n${issues}`,\n result.error.issues[0]?.path.join('.') ?? '',\n );\n }\n}\n","export const EVENT_TYPE = {\n Sent: 'sent',\n Delivered: 'delivered',\n Bounced: 'bounced',\n Complained: 'complained',\n Opened: 'opened',\n Clicked: 'clicked',\n Unsubscribed: 'unsubscribed',\n Failed: 'failed',\n} as const;\n\nexport type EventType = (typeof EVENT_TYPE)[keyof typeof EVENT_TYPE];\n\nexport const AGGREGATION_INTERVAL = {\n Daily: 'daily',\n Weekly: 'weekly',\n Monthly: 'monthly',\n} as const;\n\nexport type AggregationInterval = (typeof AGGREGATION_INTERVAL)[keyof typeof AGGREGATION_INTERVAL];\n\nexport const STATS_GROUP_BY = {\n Account: 'account',\n Rule: 'rule',\n Template: 'template',\n} as const;\n\nexport type StatsGroupBy = (typeof STATS_GROUP_BY)[keyof typeof STATS_GROUP_BY];\n","import { Schema, Model, Types, HydratedDocument } from 'mongoose';\nimport type { EventType } from '../constants';\nimport { EVENT_TYPE } from '../constants';\n\nexport interface IEmailEvent {\n type: EventType;\n accountId: Types.ObjectId;\n ruleId?: Types.ObjectId;\n templateId?: Types.ObjectId;\n recipientEmail: string;\n identifierId?: Types.ObjectId;\n metadata?: Record<string, unknown>;\n timestamp: Date;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport type EmailEventDocument = HydratedDocument<IEmailEvent>;\n\nexport interface EmailEventStatics {\n record(event: {\n type: EventType;\n accountId: string;\n ruleId?: string;\n templateId?: string;\n recipientEmail: string;\n identifierId?: string;\n metadata?: Record<string, unknown>;\n timestamp?: Date;\n }): Promise<EmailEventDocument>;\n findByDateRange(\n start: Date,\n end: Date,\n filters?: { type?: EventType; accountId?: string; ruleId?: string; templateId?: string },\n ): Promise<EmailEventDocument[]>;\n}\n\nexport type EmailEventModel = Model<IEmailEvent> & EmailEventStatics;\n\nexport interface CreateEmailEventSchemaOptions {\n collectionName?: string;\n eventTTLDays?: number;\n}\n\nexport function createEmailEventSchema(options?: CreateEmailEventSchemaOptions) {\n const eventTypeValues = Object.values(EVENT_TYPE);\n\n const schema = new Schema<IEmailEvent>(\n {\n type: { type: String, required: true, enum: eventTypeValues, index: true },\n accountId: { type: Schema.Types.ObjectId, required: true, index: true },\n ruleId: { type: Schema.Types.ObjectId, index: true },\n templateId: { type: Schema.Types.ObjectId, index: true },\n recipientEmail: { type: String, required: true },\n identifierId: { type: Schema.Types.ObjectId },\n metadata: { type: Schema.Types.Mixed },\n timestamp: { type: Date, required: true, default: () => new Date() },\n },\n {\n timestamps: true,\n collection: options?.collectionName || 'email_events',\n\n statics: {\n record(event: {\n type: EventType;\n accountId: string;\n ruleId?: string;\n templateId?: string;\n recipientEmail: string;\n identifierId?: string;\n metadata?: Record<string, unknown>;\n timestamp?: Date;\n }) {\n return this.create({\n type: event.type,\n accountId: new Types.ObjectId(event.accountId),\n ruleId: event.ruleId ? new Types.ObjectId(event.ruleId) : undefined,\n templateId: event.templateId ? new Types.ObjectId(event.templateId) : undefined,\n recipientEmail: event.recipientEmail,\n identifierId: event.identifierId ? new Types.ObjectId(event.identifierId) : undefined,\n metadata: event.metadata,\n timestamp: event.timestamp || new Date(),\n });\n },\n\n findByDateRange(\n start: Date,\n end: Date,\n filters?: { type?: EventType; accountId?: string; ruleId?: string; templateId?: string },\n ) {\n const query: Record<string, unknown> = {\n timestamp: { $gte: start, $lte: end },\n };\n\n if (filters?.type) query.type = filters.type;\n if (filters?.accountId) query.accountId = new Types.ObjectId(filters.accountId);\n if (filters?.ruleId) query.ruleId = new Types.ObjectId(filters.ruleId);\n if (filters?.templateId) query.templateId = new Types.ObjectId(filters.templateId);\n\n return this.find(query).sort({ timestamp: -1 });\n },\n },\n },\n );\n\n const ttlDays = options?.eventTTLDays ?? 90;\n schema.index({ timestamp: 1 }, { expireAfterSeconds: ttlDays * 24 * 60 * 60 });\n schema.index({ type: 1, timestamp: -1 });\n schema.index({ accountId: 1, timestamp: -1 });\n schema.index({ ruleId: 1, timestamp: -1 });\n\n return schema;\n}\n","import { Schema, Model, Types, HydratedDocument } from 'mongoose';\nimport type { AggregationInterval } from '../constants';\nimport { AGGREGATION_INTERVAL } from '../constants';\n\nexport interface IAnalyticsStats {\n date: string;\n interval: AggregationInterval;\n accountId: Types.ObjectId | null;\n ruleId: Types.ObjectId | null;\n templateId: Types.ObjectId | null;\n sent: number;\n delivered: number;\n bounced: number;\n complained: number;\n opened: number;\n clicked: number;\n unsubscribed: number;\n failed: number;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport type AnalyticsStatsDocument = HydratedDocument<IAnalyticsStats>;\n\nexport interface AnalyticsStatsStatics {\n upsertStats(\n date: string,\n interval: AggregationInterval,\n dimensions: { accountId?: string; ruleId?: string; templateId?: string },\n increments: Partial<Record<'sent' | 'delivered' | 'bounced' | 'complained' | 'opened' | 'clicked' | 'unsubscribed' | 'failed', number>>,\n ): Promise<AnalyticsStatsDocument>;\n}\n\nexport type AnalyticsStatsModel = Model<IAnalyticsStats> & AnalyticsStatsStatics;\n\nexport interface CreateAnalyticsStatsSchemaOptions {\n collectionName?: string;\n}\n\nexport function createAnalyticsStatsSchema(options?: CreateAnalyticsStatsSchemaOptions) {\n const intervalValues = Object.values(AGGREGATION_INTERVAL);\n\n const schema = new Schema<IAnalyticsStats>(\n {\n date: { type: String, required: true, index: true },\n interval: { type: String, required: true, enum: intervalValues },\n accountId: { type: Schema.Types.ObjectId, default: null },\n ruleId: { type: Schema.Types.ObjectId, default: null },\n templateId: { type: Schema.Types.ObjectId, default: null },\n sent: { type: Number, default: 0 },\n delivered: { type: Number, default: 0 },\n bounced: { type: Number, default: 0 },\n complained: { type: Number, default: 0 },\n opened: { type: Number, default: 0 },\n clicked: { type: Number, default: 0 },\n unsubscribed: { type: Number, default: 0 },\n failed: { type: Number, default: 0 },\n },\n {\n timestamps: true,\n collection: options?.collectionName || 'analytics_stats',\n\n statics: {\n upsertStats(\n date: string,\n interval: AggregationInterval,\n dimensions: { accountId?: string; ruleId?: string; templateId?: string },\n increments: Partial<Record<string, number>>,\n ) {\n const filter: Record<string, unknown> = { date, interval };\n\n filter.accountId = dimensions.accountId ? new Types.ObjectId(dimensions.accountId) : null;\n filter.ruleId = dimensions.ruleId ? new Types.ObjectId(dimensions.ruleId) : null;\n filter.templateId = dimensions.templateId ? new Types.ObjectId(dimensions.templateId) : null;\n\n const $inc: Record<string, number> = {};\n for (const [key, value] of Object.entries(increments)) {\n if (value) $inc[key] = value;\n }\n\n return this.findOneAndUpdate(\n filter,\n { $inc },\n { upsert: true, new: true },\n );\n },\n },\n },\n );\n\n schema.index({ date: 1, interval: 1, accountId: 1, ruleId: 1, templateId: 1 }, { unique: true });\n schema.index({ date: 1, interval: 1 });\n\n return schema;\n}\n","import type { FilterQuery } from 'mongoose';\nimport type { EmailEventModel } from '../schemas/email-event.schema';\nimport type { LogAdapter } from '@astralibx/core';\nimport type { EmailEvent, CreateEventInput } from '../types/event.types';\n\nexport interface EventQueryFilters {\n dateFrom: Date;\n dateTo: Date;\n type?: string;\n accountId?: string;\n ruleId?: string;\n recipientEmail?: string;\n}\n\nexport interface PaginatedEvents {\n events: EmailEvent[];\n total: number;\n}\n\nexport class EventRecorderService {\n constructor(\n private EmailEvent: EmailEventModel,\n private logger: LogAdapter,\n ) {}\n\n async record(event: CreateEventInput): Promise<void> {\n await this.EmailEvent.record(event);\n this.logger.info('Event recorded', { type: event.type, accountId: event.accountId });\n }\n\n async recordBatch(events: CreateEventInput[]): Promise<void> {\n if (events.length === 0) return;\n\n const docs = events.map((e) => ({\n ...e,\n timestamp: e.timestamp || new Date(),\n }));\n\n await this.EmailEvent.insertMany(docs, { ordered: false });\n this.logger.info('Batch events recorded', { count: events.length });\n }\n\n async getEvents(\n filters: EventQueryFilters,\n page = 1,\n limit = 50,\n ): Promise<PaginatedEvents> {\n const query: FilterQuery<EmailEvent> = {\n timestamp: { $gte: filters.dateFrom, $lte: filters.dateTo },\n };\n\n if (filters.type) query.type = filters.type;\n if (filters.accountId) query.accountId = filters.accountId;\n if (filters.ruleId) query.ruleId = filters.ruleId;\n if (filters.recipientEmail) query.recipientEmail = filters.recipientEmail;\n\n const skip = (page - 1) * limit;\n\n const [events, total] = await Promise.all([\n this.EmailEvent.find(query)\n .sort({ timestamp: -1 })\n .skip(skip)\n .limit(limit)\n .lean<EmailEvent[]>(),\n this.EmailEvent.countDocuments(query),\n ]);\n\n return { events, total };\n }\n\n async purgeOldEvents(olderThanDays: number): Promise<number> {\n const cutoff = new Date();\n cutoff.setDate(cutoff.getDate() - olderThanDays);\n\n const result = await this.EmailEvent.deleteMany({\n timestamp: { $lt: cutoff },\n });\n\n const count = result.deletedCount || 0;\n this.logger.info('Purged old events', { olderThanDays, deleted: count });\n return count;\n }\n}\n","import type { EmailEventModel } from '../schemas/email-event.schema';\nimport type { AnalyticsStatsModel } from '../schemas/analytics-stats.schema';\nimport type { LogAdapter } from '@astralibx/core';\nimport { EVENT_TYPE, AGGREGATION_INTERVAL } from '../constants';\nimport { InvalidDateRangeError, AggregationError } from '../errors';\n\nconst METRIC_CONDS = {\n sent: { $cond: [{ $eq: ['$type', EVENT_TYPE.Sent] }, 1, 0] },\n failed: { $cond: [{ $eq: ['$type', EVENT_TYPE.Failed] }, 1, 0] },\n delivered: { $cond: [{ $eq: ['$type', EVENT_TYPE.Delivered] }, 1, 0] },\n bounced: { $cond: [{ $eq: ['$type', EVENT_TYPE.Bounced] }, 1, 0] },\n complained: { $cond: [{ $eq: ['$type', EVENT_TYPE.Complained] }, 1, 0] },\n opened: { $cond: [{ $eq: ['$type', EVENT_TYPE.Opened] }, 1, 0] },\n clicked: { $cond: [{ $eq: ['$type', EVENT_TYPE.Clicked] }, 1, 0] },\n unsubscribed: { $cond: [{ $eq: ['$type', EVENT_TYPE.Unsubscribed] }, 1, 0] },\n};\n\nfunction buildSumGroup() {\n return {\n sent: { $sum: METRIC_CONDS.sent },\n failed: { $sum: METRIC_CONDS.failed },\n delivered: { $sum: METRIC_CONDS.delivered },\n bounced: { $sum: METRIC_CONDS.bounced },\n complained: { $sum: METRIC_CONDS.complained },\n opened: { $sum: METRIC_CONDS.opened },\n clicked: { $sum: METRIC_CONDS.clicked },\n unsubscribed: { $sum: METRIC_CONDS.unsubscribed },\n };\n}\n\nexport class AggregatorService {\n constructor(\n private EmailEvent: EmailEventModel,\n private AnalyticsStats: AnalyticsStatsModel,\n private timezone: string,\n private logger: LogAdapter,\n ) {}\n\n async aggregateDaily(date?: Date): Promise<void> {\n const targetDate = date || new Date();\n const dayStart = this.getDayStart(targetDate);\n const dayEnd = this.getDayEnd(targetDate);\n const dateKey = this.toDateKey(dayStart);\n\n this.logger.info('Running daily aggregation', { date: dateKey });\n\n await this.aggregateByAccount(dayStart, dayEnd, dateKey);\n await this.aggregateByRule(dayStart, dayEnd, dateKey);\n await this.aggregateByTemplate(dayStart, dayEnd, dateKey);\n await this.aggregateOverall(dayStart, dayEnd, dateKey);\n\n this.logger.info('Daily aggregation complete', { date: dateKey });\n }\n\n async aggregateRange(from: Date, to: Date): Promise<void> {\n if (!(from instanceof Date) || isNaN(from.getTime())) {\n throw new InvalidDateRangeError(String(from), String(to));\n }\n if (!(to instanceof Date) || isNaN(to.getTime())) {\n throw new InvalidDateRangeError(String(from), String(to));\n }\n if (from > to) {\n throw new InvalidDateRangeError(from.toISOString(), to.toISOString());\n }\n\n const current = this.getDayStart(from);\n const end = this.getDayStart(to);\n\n this.logger.info('Running range aggregation', {\n from: this.toDateKey(current),\n to: this.toDateKey(end),\n });\n\n while (current <= end) {\n await this.aggregateDaily(new Date(current));\n current.setDate(current.getDate() + 1);\n }\n\n this.logger.info('Range aggregation complete');\n }\n\n private async aggregateByAccount(\n dayStart: Date,\n dayEnd: Date,\n dateKey: string,\n ): Promise<void> {\n let results: any[];\n try {\n results = await this.EmailEvent.aggregate([\n { $match: { timestamp: { $gte: dayStart, $lt: dayEnd } } },\n { $group: { _id: '$accountId', ...buildSumGroup() } },\n ]);\n } catch (error) {\n throw new AggregationError('byAccount', error instanceof Error ? error : new Error(String(error)));\n }\n\n const bulkOps = results.map((r) => ({\n updateOne: {\n filter: { date: dateKey, interval: AGGREGATION_INTERVAL.Daily, accountId: r._id, ruleId: null, templateId: null },\n update: {\n $set: {\n date: dateKey,\n interval: AGGREGATION_INTERVAL.Daily,\n accountId: r._id,\n ruleId: null,\n templateId: null,\n sent: r.sent, failed: r.failed, delivered: r.delivered,\n bounced: r.bounced, complained: r.complained, opened: r.opened,\n clicked: r.clicked, unsubscribed: r.unsubscribed,\n updatedAt: new Date(),\n },\n },\n upsert: true,\n },\n }));\n\n if (bulkOps.length > 0) {\n await this.AnalyticsStats.bulkWrite(bulkOps as any);\n }\n }\n\n private async aggregateByRule(\n dayStart: Date,\n dayEnd: Date,\n dateKey: string,\n ): Promise<void> {\n let results: any[];\n try {\n results = await this.EmailEvent.aggregate([\n { $match: { timestamp: { $gte: dayStart, $lt: dayEnd }, ruleId: { $exists: true, $ne: null } } },\n { $group: { _id: '$ruleId', ...buildSumGroup() } },\n ]);\n } catch (error) {\n throw new AggregationError('byRule', error instanceof Error ? error : new Error(String(error)));\n }\n\n const bulkOps = results.map((r) => ({\n updateOne: {\n filter: { date: dateKey, interval: AGGREGATION_INTERVAL.Daily, ruleId: r._id, accountId: null, templateId: null },\n update: {\n $set: {\n date: dateKey,\n interval: AGGREGATION_INTERVAL.Daily,\n ruleId: r._id,\n accountId: null,\n templateId: null,\n sent: r.sent, failed: r.failed, delivered: r.delivered,\n bounced: r.bounced, complained: r.complained, opened: r.opened,\n clicked: r.clicked, unsubscribed: r.unsubscribed,\n updatedAt: new Date(),\n },\n },\n upsert: true,\n },\n }));\n\n if (bulkOps.length > 0) {\n await this.AnalyticsStats.bulkWrite(bulkOps as any);\n }\n }\n\n private async aggregateByTemplate(\n dayStart: Date,\n dayEnd: Date,\n dateKey: string,\n ): Promise<void> {\n let results: any[];\n try {\n results = await this.EmailEvent.aggregate([\n { $match: { timestamp: { $gte: dayStart, $lt: dayEnd }, templateId: { $exists: true, $ne: null } } },\n { $group: { _id: '$templateId', ...buildSumGroup() } },\n ]);\n } catch (error) {\n throw new AggregationError('byTemplate', error instanceof Error ? error : new Error(String(error)));\n }\n\n const bulkOps = results.map((r) => ({\n updateOne: {\n filter: { date: dateKey, interval: AGGREGATION_INTERVAL.Daily, templateId: r._id, accountId: null, ruleId: null },\n update: {\n $set: {\n date: dateKey,\n interval: AGGREGATION_INTERVAL.Daily,\n templateId: r._id,\n accountId: null,\n ruleId: null,\n sent: r.sent, failed: r.failed, delivered: r.delivered,\n bounced: r.bounced, complained: r.complained, opened: r.opened,\n clicked: r.clicked, unsubscribed: r.unsubscribed,\n updatedAt: new Date(),\n },\n },\n upsert: true,\n },\n }));\n\n if (bulkOps.length > 0) {\n await this.AnalyticsStats.bulkWrite(bulkOps as any);\n }\n }\n\n private async aggregateOverall(\n dayStart: Date,\n dayEnd: Date,\n dateKey: string,\n ): Promise<void> {\n let results: any[];\n try {\n results = await this.EmailEvent.aggregate([\n { $match: { timestamp: { $gte: dayStart, $lt: dayEnd } } },\n { $group: { _id: null, ...buildSumGroup() } },\n ]);\n } catch (error) {\n throw new AggregationError('overall', error instanceof Error ? error : new Error(String(error)));\n }\n\n if (results.length > 0) {\n const r = results[0];\n await this.AnalyticsStats.updateOne(\n { date: dateKey, interval: AGGREGATION_INTERVAL.Daily, accountId: null, ruleId: null, templateId: null },\n {\n $set: {\n date: dateKey,\n interval: AGGREGATION_INTERVAL.Daily,\n accountId: null,\n ruleId: null,\n templateId: null,\n sent: r.sent, failed: r.failed, delivered: r.delivered,\n bounced: r.bounced, complained: r.complained, opened: r.opened,\n clicked: r.clicked, unsubscribed: r.unsubscribed,\n updatedAt: new Date(),\n },\n },\n { upsert: true },\n );\n }\n }\n\n private getDayStart(date: Date): Date {\n const formatter = new Intl.DateTimeFormat('en-CA', {\n timeZone: this.timezone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n });\n const parts = formatter.formatToParts(date);\n const year = parseInt(parts.find((p) => p.type === 'year')!.value, 10);\n const month = parseInt(parts.find((p) => p.type === 'month')!.value, 10) - 1;\n const day = parseInt(parts.find((p) => p.type === 'day')!.value, 10);\n\n const localMidnight = new Date(Date.UTC(year, month, day));\n const offsetMs = this.getTimezoneOffsetMs(localMidnight);\n return new Date(localMidnight.getTime() - offsetMs);\n }\n\n private getDayEnd(date: Date): Date {\n const dayStart = this.getDayStart(date);\n return new Date(dayStart.getTime() + 24 * 60 * 60 * 1000);\n }\n\n private getTimezoneOffsetMs(utcDate: Date): number {\n const utcStr = utcDate.toLocaleString('en-US', { timeZone: 'UTC' });\n const tzStr = utcDate.toLocaleString('en-US', { timeZone: this.timezone });\n return new Date(tzStr).getTime() - new Date(utcStr).getTime();\n }\n\n private toDateKey(date: Date): string {\n const formatter = new Intl.DateTimeFormat('en-CA', {\n timeZone: this.timezone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n });\n return formatter.format(date);\n }\n}\n","import type { AnalyticsStatsModel } from '../schemas/analytics-stats.schema';\nimport type { LogAdapter } from '@astralibx/core';\nimport type {\n OverviewStats,\n TimelineEntry,\n AccountStats,\n RuleStats,\n TemplateStats,\n} from '../types/stats.types';\nimport type { AggregationInterval } from '../constants';\n\nexport class QueryService {\n constructor(\n private AnalyticsStats: AnalyticsStatsModel,\n private logger: LogAdapter,\n ) {}\n\n async getOverview(dateFrom: Date, dateTo: Date): Promise<OverviewStats> {\n const fromKey = this.toDateKey(dateFrom);\n const toKey = this.toDateKey(dateTo);\n\n const pipeline = [\n {\n $match: {\n interval: 'daily',\n date: { $gte: fromKey, $lte: toKey },\n accountId: null,\n ruleId: null,\n templateId: null,\n },\n },\n {\n $group: {\n _id: null,\n sent: { $sum: '$sent' },\n failed: { $sum: '$failed' },\n delivered: { $sum: '$delivered' },\n bounced: { $sum: '$bounced' },\n complained: { $sum: '$complained' },\n opened: { $sum: '$opened' },\n clicked: { $sum: '$clicked' },\n unsubscribed: { $sum: '$unsubscribed' },\n },\n },\n ];\n\n const results = await this.AnalyticsStats.aggregate(pipeline);\n\n const empty = {\n startDate: fromKey,\n endDate: toKey,\n sent: 0,\n failed: 0,\n delivered: 0,\n bounced: 0,\n complained: 0,\n opened: 0,\n clicked: 0,\n unsubscribed: 0,\n };\n\n if (results.length === 0) return empty;\n\n const r = results[0];\n return {\n startDate: fromKey,\n endDate: toKey,\n sent: r.sent,\n failed: r.failed,\n delivered: r.delivered,\n bounced: r.bounced,\n complained: r.complained,\n opened: r.opened,\n clicked: r.clicked,\n unsubscribed: r.unsubscribed,\n };\n }\n\n async getTimeline(\n dateFrom: Date,\n dateTo: Date,\n interval: AggregationInterval = 'daily',\n ): Promise<TimelineEntry[]> {\n const fromKey = this.toDateKey(dateFrom);\n const toKey = this.toDateKey(dateTo);\n\n const groupId = this.buildTimeGroupId(interval);\n\n const pipeline = [\n {\n $match: {\n interval: 'daily',\n date: { $gte: fromKey, $lte: toKey },\n accountId: null,\n ruleId: null,\n templateId: null,\n },\n },\n {\n $group: {\n _id: groupId,\n sent: { $sum: '$sent' },\n failed: { $sum: '$failed' },\n delivered: { $sum: '$delivered' },\n bounced: { $sum: '$bounced' },\n complained: { $sum: '$complained' },\n opened: { $sum: '$opened' },\n clicked: { $sum: '$clicked' },\n unsubscribed: { $sum: '$unsubscribed' },\n },\n },\n { $sort: { _id: 1 as const } },\n ];\n\n const results = await this.AnalyticsStats.aggregate(pipeline);\n\n return results.map((r) => ({\n date: r._id,\n interval,\n sent: r.sent,\n failed: r.failed,\n delivered: r.delivered,\n bounced: r.bounced,\n complained: r.complained,\n opened: r.opened,\n clicked: r.clicked,\n unsubscribed: r.unsubscribed,\n }));\n }\n\n async getAccountStats(dateFrom: Date, dateTo: Date): Promise<AccountStats[]> {\n const fromKey = this.toDateKey(dateFrom);\n const toKey = this.toDateKey(dateTo);\n\n const results = await this.AnalyticsStats.aggregate([\n {\n $match: {\n interval: 'daily',\n date: { $gte: fromKey, $lte: toKey },\n accountId: { $ne: null },\n ruleId: null,\n templateId: null,\n },\n },\n {\n $group: {\n _id: '$accountId',\n sent: { $sum: '$sent' },\n failed: { $sum: '$failed' },\n delivered: { $sum: '$delivered' },\n bounced: { $sum: '$bounced' },\n complained: { $sum: '$complained' },\n opened: { $sum: '$opened' },\n clicked: { $sum: '$clicked' },\n unsubscribed: { $sum: '$unsubscribed' },\n },\n },\n { $sort: { sent: -1 as const } },\n ]);\n\n return results.map((r) => ({\n accountId: r._id.toString(),\n sent: r.sent,\n failed: r.failed,\n delivered: r.delivered,\n bounced: r.bounced,\n complained: r.complained,\n opened: r.opened,\n clicked: r.clicked,\n unsubscribed: r.unsubscribed,\n }));\n }\n\n async getRuleStats(dateFrom: Date, dateTo: Date): Promise<RuleStats[]> {\n const fromKey = this.toDateKey(dateFrom);\n const toKey = this.toDateKey(dateTo);\n\n const results = await this.AnalyticsStats.aggregate([\n {\n $match: {\n interval: 'daily',\n date: { $gte: fromKey, $lte: toKey },\n ruleId: { $ne: null },\n accountId: null,\n templateId: null,\n },\n },\n {\n $group: {\n _id: '$ruleId',\n sent: { $sum: '$sent' },\n failed: { $sum: '$failed' },\n delivered: { $sum: '$delivered' },\n bounced: { $sum: '$bounced' },\n complained: { $sum: '$complained' },\n opened: { $sum: '$opened' },\n clicked: { $sum: '$clicked' },\n unsubscribed: { $sum: '$unsubscribed' },\n },\n },\n { $sort: { sent: -1 as const } },\n ]);\n\n return results.map((r) => ({\n ruleId: r._id.toString(),\n sent: r.sent,\n failed: r.failed,\n delivered: r.delivered,\n bounced: r.bounced,\n complained: r.complained,\n opened: r.opened,\n clicked: r.clicked,\n unsubscribed: r.unsubscribed,\n }));\n }\n\n async getTemplateStats(dateFrom: Date, dateTo: Date): Promise<TemplateStats[]> {\n const fromKey = this.toDateKey(dateFrom);\n const toKey = this.toDateKey(dateTo);\n\n const results = await this.AnalyticsStats.aggregate([\n {\n $match: {\n interval: 'daily',\n date: { $gte: fromKey, $lte: toKey },\n templateId: { $ne: null },\n accountId: null,\n ruleId: null,\n },\n },\n {\n $group: {\n _id: '$templateId',\n sent: { $sum: '$sent' },\n failed: { $sum: '$failed' },\n delivered: { $sum: '$delivered' },\n bounced: { $sum: '$bounced' },\n complained: { $sum: '$complained' },\n opened: { $sum: '$opened' },\n clicked: { $sum: '$clicked' },\n unsubscribed: { $sum: '$unsubscribed' },\n },\n },\n { $sort: { sent: -1 as const } },\n ]);\n\n return results.map((r) => ({\n templateId: r._id.toString(),\n sent: r.sent,\n failed: r.failed,\n delivered: r.delivered,\n bounced: r.bounced,\n complained: r.complained,\n opened: r.opened,\n clicked: r.clicked,\n unsubscribed: r.unsubscribed,\n }));\n }\n\n private buildTimeGroupId(interval: AggregationInterval): string | Record<string, unknown> {\n switch (interval) {\n case 'weekly': {\n const dateExpr = { $dateFromString: { dateString: '$date' } };\n return {\n $concat: [\n { $substr: ['$date', 0, 4] },\n '-W',\n {\n $cond: [\n { $lt: [{ $isoWeek: dateExpr }, 10] },\n { $concat: ['0', { $toString: { $isoWeek: dateExpr } }] },\n { $toString: { $isoWeek: dateExpr } },\n ],\n },\n ],\n };\n }\n case 'monthly':\n return { $substr: ['$date', 0, 7] };\n case 'daily':\n default:\n return '$date';\n }\n }\n\n private toDateKey(date: Date): string {\n return date.toISOString().slice(0, 10);\n }\n}\n","import type { Request, Response } from 'express';\nimport type { EventRecorderService } from '../services/event-recorder';\nimport type { AggregatorService } from '../services/aggregator';\nimport type { QueryService } from '../services/query.service';\nimport { InvalidDateRangeError } from '../errors';\n\nconst MAX_AGGREGATION_RANGE_DAYS = 365;\n\nfunction parseDateRange(req: Request): { dateFrom: Date; dateTo: Date } | { error: string } {\n const now = new Date();\n const thirtyDaysAgo = new Date();\n thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);\n\n const dateFrom = req.query.from\n ? new Date(req.query.from as string)\n : thirtyDaysAgo;\n const dateTo = req.query.to\n ? new Date(req.query.to as string)\n : now;\n\n if (isNaN(dateFrom.getTime())) {\n return { error: `Invalid 'from' date: ${req.query.from}` };\n }\n if (isNaN(dateTo.getTime())) {\n return { error: `Invalid 'to' date: ${req.query.to}` };\n }\n\n return { dateFrom, dateTo };\n}\n\nexport function createAnalyticsController(\n eventRecorder: EventRecorderService,\n aggregator: AggregatorService,\n queryService: QueryService,\n) {\n return {\n async getOverview(req: Request, res: Response) {\n try {\n const parsed = parseDateRange(req);\n if ('error' in parsed) {\n return res.status(400).json({ success: false, error: parsed.error });\n }\n const data = await queryService.getOverview(parsed.dateFrom, parsed.dateTo);\n res.json({ success: true, data });\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ success: false, error: message });\n }\n },\n\n async getTimeline(req: Request, res: Response) {\n try {\n const parsed = parseDateRange(req);\n if ('error' in parsed) {\n return res.status(400).json({ success: false, error: parsed.error });\n }\n const interval = (req.query.interval as string) || 'daily';\n\n if (!['daily', 'weekly', 'monthly'].includes(interval)) {\n return res.status(400).json({\n success: false,\n error: 'interval must be daily, weekly, or monthly',\n });\n }\n\n const data = await queryService.getTimeline(\n parsed.dateFrom,\n parsed.dateTo,\n interval as 'daily' | 'weekly' | 'monthly',\n );\n res.json({ success: true, data });\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ success: false, error: message });\n }\n },\n\n async getAccountStats(req: Request, res: Response) {\n try {\n const parsed = parseDateRange(req);\n if ('error' in parsed) {\n return res.status(400).json({ success: false, error: parsed.error });\n }\n const data = await queryService.getAccountStats(parsed.dateFrom, parsed.dateTo);\n res.json({ success: true, data });\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ success: false, error: message });\n }\n },\n\n async getRuleStats(req: Request, res: Response) {\n try {\n const parsed = parseDateRange(req);\n if ('error' in parsed) {\n return res.status(400).json({ success: false, error: parsed.error });\n }\n const data = await queryService.getRuleStats(parsed.dateFrom, parsed.dateTo);\n res.json({ success: true, data });\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ success: false, error: message });\n }\n },\n\n async getTemplateStats(req: Request, res: Response) {\n try {\n const parsed = parseDateRange(req);\n if ('error' in parsed) {\n return res.status(400).json({ success: false, error: parsed.error });\n }\n const data = await queryService.getTemplateStats(parsed.dateFrom, parsed.dateTo);\n res.json({ success: true, data });\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ success: false, error: message });\n }\n },\n\n async triggerAggregation(req: Request, res: Response) {\n try {\n const { from, to } = req.body;\n\n if (from && to) {\n const fromDate = new Date(from);\n const toDate = new Date(to);\n\n if (isNaN(fromDate.getTime()) || isNaN(toDate.getTime())) {\n return res.status(400).json({\n success: false,\n error: 'Invalid date format for from/to',\n });\n }\n\n if (fromDate > toDate) {\n return res.status(400).json({\n success: false,\n error: `Invalid date range: 'from' must be before 'to'`,\n });\n }\n\n const diffDays = (toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24);\n if (diffDays > MAX_AGGREGATION_RANGE_DAYS) {\n return res.status(400).json({\n success: false,\n error: `Date range exceeds maximum of ${MAX_AGGREGATION_RANGE_DAYS} days`,\n });\n }\n\n await aggregator.aggregateRange(fromDate, toDate);\n res.json({ success: true, message: 'Range aggregation complete' });\n } else {\n let date: Date | undefined;\n if (from) {\n date = new Date(from);\n if (isNaN(date.getTime())) {\n return res.status(400).json({\n success: false,\n error: 'Invalid date format for from',\n });\n }\n }\n await aggregator.aggregateDaily(date);\n res.json({ success: true, message: 'Daily aggregation complete' });\n }\n } catch (error: unknown) {\n if (error instanceof InvalidDateRangeError) {\n return res.status(400).json({ success: false, error: error.message });\n }\n const message = error instanceof Error ? error.message : 'Unknown error';\n res.status(500).json({ success: false, error: message });\n }\n },\n };\n}\n","import { Router } from 'express';\nimport type { createAnalyticsController } from '../controllers/analytics.controller';\n\ntype AnalyticsController = ReturnType<typeof createAnalyticsController>;\n\nexport function createAnalyticsRoutes(controller: AnalyticsController): Router {\n const router = Router();\n\n router.get('/overview', controller.getOverview);\n router.get('/timeline', controller.getTimeline);\n router.get('/accounts', controller.getAccountStats);\n router.get('/rules', controller.getRuleStats);\n router.get('/templates', controller.getTemplateStats);\n router.post('/aggregate', controller.triggerAggregation);\n\n return router;\n}\n","import type { Router } from 'express';\nimport type { LogAdapter } from '@astralibx/core';\nimport type { EmailAnalyticsConfig } from './types/config.types';\nimport { validateConfig } from './validation/config.schema';\nimport { createEmailEventSchema, type EmailEventModel } from './schemas/email-event.schema';\nimport { createAnalyticsStatsSchema, type AnalyticsStatsModel } from './schemas/analytics-stats.schema';\nimport { EventRecorderService } from './services/event-recorder';\nimport { AggregatorService } from './services/aggregator';\nimport { QueryService } from './services/query.service';\nimport { createAnalyticsController } from './controllers/analytics.controller';\nimport { createAnalyticsRoutes } from './routes';\n\nexport interface EmailAnalytics {\n routes: Router;\n events: EventRecorderService;\n aggregator: AggregatorService;\n query: QueryService;\n models: {\n EmailEvent: EmailEventModel;\n AnalyticsStats: AnalyticsStatsModel;\n };\n}\n\nconst noopLogger: LogAdapter = {\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\nexport function createEmailAnalytics(config: EmailAnalyticsConfig): EmailAnalytics {\n validateConfig(config);\n\n const conn = config.db.connection;\n const prefix = config.db.collectionPrefix || '';\n const logger = config.logger || noopLogger;\n const timezone = config.options?.timezone || 'UTC';\n const ttlDays = config.options?.eventTTLDays;\n\n const EmailEvent = conn.model<any>(\n `${prefix}EmailEvent`,\n createEmailEventSchema(ttlDays ? { eventTTLDays: ttlDays } : undefined),\n ) as EmailEventModel;\n\n const AnalyticsStats = conn.model<any>(\n `${prefix}AnalyticsStats`,\n createAnalyticsStatsSchema(),\n ) as AnalyticsStatsModel;\n\n const eventRecorder = new EventRecorderService(EmailEvent, logger);\n const aggregator = new AggregatorService(EmailEvent, AnalyticsStats, timezone, logger);\n const queryService = new QueryService(AnalyticsStats, logger);\n\n const controller = createAnalyticsController(eventRecorder, aggregator, queryService);\n const routes = createAnalyticsRoutes(controller);\n\n return {\n routes,\n events: eventRecorder,\n aggregator,\n query: queryService,\n models: {\n EmailEvent,\n AnalyticsStats,\n },\n };\n}\n\nexport type { EmailAnalyticsConfig } from './types/config.types';\nexport type { EmailEvent, CreateEventInput } from './types/event.types';\nexport type { BaseMetrics, DailyStats, AccountStats, RuleStats, TemplateStats, OverviewStats, TimelineEntry } from './types/stats.types';\n\nexport { EVENT_TYPE, AGGREGATION_INTERVAL, STATS_GROUP_BY } from './constants';\nexport type { EventType, AggregationInterval, StatsGroupBy } from './constants';\n\nexport { AlxAnalyticsError, ConfigValidationError, InvalidDateRangeError, AggregationError } from './errors';\n\nexport { validateConfig } from './validation/config.schema';\n\nexport {\n createEmailEventSchema,\n type IEmailEvent, type EmailEventDocument,\n type EmailEventModel, type EmailEventStatics,\n type CreateEmailEventSchemaOptions,\n} from './schemas';\n\nexport {\n createAnalyticsStatsSchema,\n type IAnalyticsStats, type AnalyticsStatsDocument,\n type AnalyticsStatsModel, type AnalyticsStatsStatics,\n type CreateAnalyticsStatsSchemaOptions,\n} from './schemas';\n\nexport { EventRecorderService, type EventQueryFilters, type PaginatedEvents } from './services/event-recorder';\nexport { AggregatorService } from './services/aggregator';\nexport { QueryService } from './services/query.service';\nexport { createAnalyticsController } from './controllers/analytics.controller';\nexport { createAnalyticsRoutes } from './routes';\n"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@astralibx/email-analytics",
3
+ "version": "2.0.0",
4
+ "description": "Email analytics with event recording, aggregation, time-series, and querying",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.mts",
12
+ "default": "./dist/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.cjs"
17
+ }
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsup",
25
+ "dev": "tsup --watch",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest",
28
+ "test:coverage": "vitest run --coverage",
29
+ "lint": "eslint src/",
30
+ "prepublishOnly": "npm run build",
31
+ "clean": "rm -rf dist"
32
+ },
33
+ "keywords": [
34
+ "email",
35
+ "analytics",
36
+ "event-tracking",
37
+ "aggregation",
38
+ "time-series",
39
+ "statistics"
40
+ ],
41
+ "license": "MIT",
42
+ "dependencies": {
43
+ "@astralibx/core": "*",
44
+ "zod": "^3.23.0"
45
+ },
46
+ "peerDependencies": {
47
+ "express": "^4.18.0 || ^5.0.0",
48
+ "mongoose": "^7.0.0 || ^8.0.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/express": "^5.0.0",
52
+ "@types/node": "^22.0.0",
53
+ "@vitest/coverage-v8": "^3.0.0",
54
+ "express": "^5.0.0",
55
+ "mongoose": "^8.12.1",
56
+ "typescript": "^5.8.2"
57
+ }
58
+ }