"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AuditService = void 0; const common_1 = require("@nestjs/common"); const typeorm_1 = require("@nestjs/typeorm"); const typeorm_2 = require("typeorm"); const audit_log_entity_1 = require("../entities/audit-log.entity"); const activity_log_entity_1 = require("../entities/activity-log.entity"); let AuditService = class AuditService { constructor(auditLogRepository, activityLogRepository) { this.auditLogRepository = auditLogRepository; this.activityLogRepository = activityLogRepository; } async createAuditLog(params) { const changedFields = this.detectChangedFields(params.old_values, params.new_values); const auditLog = this.auditLogRepository.create({ ...params, changed_fields: changedFields, }); return this.auditLogRepository.save(auditLog); } async queryAuditLogs(tenantId, query) { const { user_id, action, entity_type, entity_id, from_date, to_date, page = 1, limit = 20 } = query; const queryBuilder = this.auditLogRepository .createQueryBuilder('audit') .where('audit.tenant_id = :tenantId', { tenantId }); if (user_id) { queryBuilder.andWhere('audit.user_id = :user_id', { user_id }); } if (action) { queryBuilder.andWhere('audit.action = :action', { action }); } if (entity_type) { queryBuilder.andWhere('audit.entity_type = :entity_type', { entity_type }); } if (entity_id) { queryBuilder.andWhere('audit.entity_id = :entity_id', { entity_id }); } if (from_date && to_date) { queryBuilder.andWhere('audit.created_at BETWEEN :from_date AND :to_date', { from_date, to_date, }); } else if (from_date) { queryBuilder.andWhere('audit.created_at >= :from_date', { from_date }); } else if (to_date) { queryBuilder.andWhere('audit.created_at <= :to_date', { to_date }); } queryBuilder .orderBy('audit.created_at', 'DESC') .skip((page - 1) * limit) .take(limit); const [data, total] = await queryBuilder.getManyAndCount(); return { data, total, page, limit, totalPages: Math.ceil(total / limit), }; } async getAuditLogById(tenantId, id) { return this.auditLogRepository.findOne({ where: { id, tenant_id: tenantId }, }); } async getEntityAuditHistory(tenantId, entityType, entityId) { return this.auditLogRepository.find({ where: { tenant_id: tenantId, entity_type: entityType, entity_id: entityId, }, order: { created_at: 'DESC' }, }); } async createActivityLog(tenantId, userId, dto, context) { const activityLog = this.activityLogRepository.create({ tenant_id: tenantId, user_id: userId, ...dto, ip_address: context?.ip_address, user_agent: context?.user_agent, session_id: context?.session_id, }); return this.activityLogRepository.save(activityLog); } async queryActivityLogs(tenantId, query) { const { user_id, activity_type, resource_type, from_date, to_date, page = 1, limit = 20 } = query; const queryBuilder = this.activityLogRepository .createQueryBuilder('activity') .where('activity.tenant_id = :tenantId', { tenantId }); if (user_id) { queryBuilder.andWhere('activity.user_id = :user_id', { user_id }); } if (activity_type) { queryBuilder.andWhere('activity.activity_type = :activity_type', { activity_type }); } if (resource_type) { queryBuilder.andWhere('activity.resource_type = :resource_type', { resource_type }); } if (from_date && to_date) { queryBuilder.andWhere('activity.created_at BETWEEN :from_date AND :to_date', { from_date, to_date, }); } else if (from_date) { queryBuilder.andWhere('activity.created_at >= :from_date', { from_date }); } else if (to_date) { queryBuilder.andWhere('activity.created_at <= :to_date', { to_date }); } queryBuilder .orderBy('activity.created_at', 'DESC') .skip((page - 1) * limit) .take(limit); const [data, total] = await queryBuilder.getManyAndCount(); return { data, total, page, limit, totalPages: Math.ceil(total / limit), }; } async getUserActivitySummary(tenantId, userId, days = 30) { const fromDate = new Date(); fromDate.setDate(fromDate.getDate() - days); const result = await this.activityLogRepository .createQueryBuilder('activity') .select('activity.activity_type', 'activity_type') .addSelect('COUNT(*)', 'count') .where('activity.tenant_id = :tenantId', { tenantId }) .andWhere('activity.user_id = :userId', { userId }) .andWhere('activity.created_at >= :fromDate', { fromDate }) .groupBy('activity.activity_type') .getRawMany(); return result.map((r) => ({ activity_type: r.activity_type, count: parseInt(r.count, 10), })); } async getAuditStats(tenantId, days = 7) { const fromDate = new Date(); fromDate.setDate(fromDate.getDate() - days); const [totalActions, actionsByType, topUsers] = await Promise.all([ this.auditLogRepository.count({ where: { tenant_id: tenantId, created_at: (0, typeorm_2.MoreThanOrEqual)(fromDate), }, }), this.auditLogRepository .createQueryBuilder('audit') .select('audit.action', 'action') .addSelect('COUNT(*)', 'count') .where('audit.tenant_id = :tenantId', { tenantId }) .andWhere('audit.created_at >= :fromDate', { fromDate }) .groupBy('audit.action') .getRawMany(), this.auditLogRepository .createQueryBuilder('audit') .select('audit.user_id', 'user_id') .addSelect('COUNT(*)', 'count') .where('audit.tenant_id = :tenantId', { tenantId }) .andWhere('audit.created_at >= :fromDate', { fromDate }) .andWhere('audit.user_id IS NOT NULL') .groupBy('audit.user_id') .orderBy('count', 'DESC') .limit(10) .getRawMany(), ]); return { total_actions: totalActions, actions_by_type: actionsByType.map((r) => ({ action: r.action, count: parseInt(r.count, 10), })), top_users: topUsers.map((r) => ({ user_id: r.user_id, count: parseInt(r.count, 10), })), }; } detectChangedFields(oldValues, newValues) { if (!oldValues || !newValues) return []; const changedFields = []; const allKeys = new Set([...Object.keys(oldValues), ...Object.keys(newValues)]); for (const key of allKeys) { if (JSON.stringify(oldValues[key]) !== JSON.stringify(newValues[key])) { changedFields.push(key); } } return changedFields; } }; exports.AuditService = AuditService; exports.AuditService = AuditService = __decorate([ (0, common_1.Injectable)(), __param(0, (0, typeorm_1.InjectRepository)(audit_log_entity_1.AuditLog)), __param(1, (0, typeorm_1.InjectRepository)(activity_log_entity_1.ActivityLog)), __metadata("design:paramtypes", [typeorm_2.Repository, typeorm_2.Repository]) ], AuditService); //# sourceMappingURL=audit.service.js.map