/* * Copyright © 2024 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). */ import { ModelDefinition, Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import { BaseSchema } from '@/utils/generics/base-schema'; import { LifecycleHookManager } from '@/utils/generics/lifecycle-hook-manager'; import { THydratedDocument } from '@/utils/types/filter.types'; export enum BotStatsType { outgoing = 'outgoing', new_users = 'new_users', all_messages = 'all_messages', incoming = 'incoming', existing_conversations = 'existing_conversations', popular = 'popular', new_conversations = 'new_conversations', returning_users = 'returning_users', retention = 'retention', } export type ToLinesType = { id: number; name: BotStatsType; values: any[]; }; @Schema({ timestamps: true }) export class BotStats extends BaseSchema { /** * Type of the captured insight. */ @Prop({ type: String, required: true, }) type: BotStatsType; /** * Day based granularity for the captured insights. */ @Prop({ type: Date, required: true, }) day: Date; /** * Total value of the insight for the whole chosen granularity. */ @Prop({ type: Number, default: 0 }) value: number; /** * name of the insight (e.g: incoming messages). */ @Prop({ type: String, required: true }) name: string; /** * Converts bot statistics data into an line chart data format. * * @param stats - The array of bot statistics. * @param types - The array of bot statistics types. * @returns An array of data representing the bot statistics data. */ static toLines(stats: BotStats[], types: BotStatsType[]): ToLinesType[] { const data = types.map((type, index) => { return { id: index + 1, name: type, values: [], } as ToLinesType; }); const index: { [dataName: string]: number } = data.reduce( (acc, curr, i) => { acc[curr.name] = i; return acc; }, {}, ); const result = stats.reduce((acc, stat: BotStats & { date: Date }) => { stat.date = stat.day; acc[index[stat.type]].values.push(stat); return acc; }, data); return result; } /** * Converts fetched stats to a bar chart compatible data format * * @param stats - Array of objects, each contaning at least an id and a value * @returns BarChart compatible data */ static toBars( stats: { id: string; value: number }[], ): { id: string; name: string; value: number }[] { return stats.map((stat) => { return { ...stat, name: stat.id, }; }); } } export type BotStatsDocument = THydratedDocument; export const BotStatsModel: ModelDefinition = LifecycleHookManager.attach({ name: BotStats.name, schema: SchemaFactory.createForClass(BotStats), }); export default BotStatsModel.schema;