File size: 3,267 Bytes
f5957a1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
99
100
import { Injectable, Logger, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { SystemError } from '../entities/system-error.entity';
import { ErrorQueryDto } from '../dto/error-query.dto';
import { UpdateErrorDto } from '../dto/update-error.dto';

@Injectable()
export class ErrorsService {
  private readonly logger = new Logger(ErrorsService.name);

  constructor(
    @InjectRepository(SystemError)
    private errorRepo: Repository<SystemError>,
  ) {}

  async getErrors(query: ErrorQueryDto) {
    const { errorType, severity, isResolved, startDate, endDate, page = 1, limit = 20 } = query;

    const qb = this.errorRepo
      .createQueryBuilder('se')
      .leftJoinAndSelect('se.user', 'user')
      .leftJoinAndSelect('se.resolver', 'resolver');

    if (errorType) qb.andWhere('se.error_type = :errorType', { errorType });
    if (severity) qb.andWhere('se.severity = :severity', { severity });
    if (isResolved !== undefined) qb.andWhere('se.is_resolved = :isResolved', { isResolved });
    if (startDate) qb.andWhere('se.created_at >= :startDate', { startDate });
    if (endDate) qb.andWhere('se.created_at <= :endDate', { endDate });

    const total = await qb.getCount();
    const data = await qb
      .orderBy('se.createdAt', 'DESC')
      .skip((page - 1) * limit)
      .take(limit)
      .getMany();

    return {
      data,
      meta: { total, page, limit, totalPages: Math.ceil(total / limit) },
    };
  }

  async getErrorDetails(id: number) {
    const error = await this.errorRepo.findOne({
      where: { errorId: id },
      relations: ['user', 'resolver'],
    });
    if (!error) {
      throw new NotFoundException(`System error #${id} not found`);
    }
    return { data: error };
  }

  async updateErrorStatus(id: number, dto: UpdateErrorDto, resolvedByUserId: number) {
    const error = await this.errorRepo.findOne({ where: { errorId: id } });
    if (!error) {
      throw new NotFoundException(`System error #${id} not found`);
    }

    if (dto.status === 'resolved') {
      error.isResolved = true;
      error.resolvedBy = resolvedByUserId;
      error.resolvedAt = new Date();
    } else if (dto.status === 'investigating') {
      error.isResolved = false;
      (error as any).resolvedBy = null;
      (error as any).resolvedAt = null;
    }

    if (dto.resolutionNotes) {
      error.resolutionNotes = dto.resolutionNotes;
    }

    const saved = await this.errorRepo.save(error);
    return { data: saved, message: `Error #${id} status updated to ${dto.status}` };
  }

  async getErrorStats() {
    const byType = await this.errorRepo
      .createQueryBuilder('se')
      .select('se.error_type', 'errorType')
      .addSelect('COUNT(*)', 'count')
      .groupBy('se.error_type')
      .getRawMany();

    const bySeverity = await this.errorRepo
      .createQueryBuilder('se')
      .select('se.severity', 'severity')
      .addSelect('COUNT(*)', 'count')
      .groupBy('se.severity')
      .getRawMany();

    const total = await this.errorRepo.count();
    const unresolved = await this.errorRepo.count({ where: { isResolved: false } });

    return { data: { total, unresolved, byType, bySeverity } };
  }
}