All files / src/platform/activity activity.service.ts

0% Statements 0/22
0% Branches 0/24
0% Functions 0/5
0% Lines 0/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80                                                                                                                                                               
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Activity } from './schemas/activity.schema';
 
@Injectable()
export class ActivityTimelineService {
  constructor(
    @InjectModel(Activity.name) private readonly activityModel: Model<Activity>,
  ) {}
 
  async log(params: {
    tenantId: string;
    entityType: string;
    entityId: string;
    actorId: string;
    activityType: string;
    title: string;
    description?: string;
    icon?: string;
    visibility?: 'INTERNAL' | 'PUBLIC';
    relatedEntity?: any;
    metadata?: any;
    occurredAt?: Date;
  }): Promise<any> {
    return this.activityModel.create({
      tenantId: params.tenantId,
      entityType: params.entityType,
      entityId: params.entityId,
      actorId: params.actorId,
      activityType: params.activityType,
      title: params.title,
      description: params.description || null,
      icon: params.icon || 'Activity',
      visibility: params.visibility || 'INTERNAL',
      relatedEntity: params.relatedEntity || null,
      metadata: params.metadata || null,
      occurredAt: params.occurredAt || new Date(),
    });
  }
 
  async getTimeline(
    tenantId: string,
    entityType: string,
    entityId: string,
    filters?: { visibility?: string; page?: number; limit?: number },
  ): Promise<any> {
    const page = filters?.page || 1;
    const limit = filters?.limit || 20;
    const skip = (page - 1) * limit;
 
    const where: any = { tenantId, entityType, entityId };
    if (filters?.visibility) where.visibility = filters.visibility;
 
    const [data, total] = await Promise.all([
      this.activityModel
        .find(where)
        .skip(skip)
        .limit(limit)
        .sort({ occurredAt: -1 })
        .lean()
        .exec(),
      this.activityModel.countDocuments(where).exec(),
    ]);
 
    return {
      data: data.map((d) => ({ ...d, id: (d as any)._id.toString() })),
      meta: { total, page, limit, totalPages: Math.ceil(total / limit) },
    };
  }
 
  async delete(id: string, tenantId: string): Promise<any> {
    const deleted = await this.activityModel
      .findOneAndDelete({ _id: id, tenantId })
      .exec();
    if (!deleted) throw new NotFoundException('Activity not found');
    return { success: true };
  }
}