All files / src/platform/audit audit-log.service.ts

0% Statements 0/23
0% Branches 0/40
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98                                                                                                                                                                                                   
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { AuditLog } from './schemas/audit-log.schema';
 
@Injectable()
export class AuditLogService {
  constructor(
    @InjectModel(AuditLog.name) private readonly auditLogModel: Model<AuditLog>,
  ) {}
 
  async log(params: {
    tenantId: string;
    userId?: string;
    action: string;
    resource: string;
    resourceId?: string;
    oldValues?: any;
    newValues?: any;
    changedFields?: string[];
    ipAddress?: string;
    userAgent?: string;
    correlationId?: string;
    requestId?: string;
    source?: string;
    moduleName?: string;
    severity?: string;
    metadata?: any;
  }): Promise<any> {
    return this.auditLogModel.create({
      tenantId: params.tenantId,
      userId: params.userId || null,
      action: params.action,
      resource: params.resource,
      resourceId: params.resourceId || null,
      oldValues: params.oldValues || null,
      newValues: params.newValues || null,
      changedFields: params.changedFields || [],
      ipAddress: params.ipAddress || null,
      userAgent: params.userAgent || null,
      correlationId: params.correlationId || null,
      requestId: params.requestId || null,
      source: params.source || 'WEB',
      moduleName: params.moduleName || null,
      severity: params.severity || 'INFO',
      metadata: params.metadata || null,
    });
  }
 
  async getLogs(
    tenantId: string,
    filters: {
      userId?: string;
      resource?: string;
      action?: 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 };
    if (filters.userId) where.userId = filters.userId;
    if (filters.resource) where.resource = filters.resource;
    if (filters.action) where.action = filters.action;
 
    const [data, total] = await Promise.all([
      this.auditLogModel
        .find(where)
        .skip(skip)
        .limit(limit)
        .sort({ createdAt: -1 })
        .lean()
        .exec(),
      this.auditLogModel.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 getEntityLogs(
    tenantId: string,
    entityType: string,
    entityId: string,
  ): Promise<any> {
    return this.auditLogModel
      .find({ tenantId, resource: entityType, resourceId: entityId })
      .sort({ createdAt: -1 })
      .lean()
      .exec();
  }
}