Skip to content

Commit 7d4b6bc

Browse files
committed
fix: added the logger controller
1 parent 205760c commit 7d4b6bc

6 files changed

Lines changed: 163 additions & 2 deletions

File tree

src/logger/domain/interfaces/log-repository.interface.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
export interface ILogRepository {
2+
findLogById(_id: string): any;
3+
findLogsByFilter(
4+
level: string,
5+
context: string | undefined,
6+
page: number,
7+
limit: number,
8+
): Promise<any[]>;
29
saveLog(log: {
310
level: string;
411
message: string;

src/logger/infrastructure/repositories/log.repository.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,26 @@ export class LogRepository implements ILogRepository {
1010
@InjectModel(Logger.name)
1111
private readonly loggerModel: Model<Logger>,
1212
) {}
13+
async findLogById(_id: string): Promise<Logger | null> {
14+
return await this.loggerModel.findById(_id).exec();
15+
}
16+
async findLogsByFilter(
17+
level: string,
18+
context: string | undefined,
19+
page: number,
20+
limit: number,
21+
): Promise<any[]> {
22+
const filter: { level: string; context?: string } = { level };
23+
if (context) {
24+
filter.context = context;
25+
}
26+
const logs = await this.loggerModel
27+
.find(filter)
28+
.skip((page - 1) * limit)
29+
.limit(limit)
30+
.exec();
31+
return logs;
32+
}
1333

1434
async saveLog(log: {
1535
level: string;

src/logger/services/logger.service.db.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,31 @@ export class LoggerServiceDb {
2525
timestamp: new Date(),
2626
});
2727
}
28+
async getLogsByFilter(
29+
level: string,
30+
context: string | undefined,
31+
page: number,
32+
limit: number,
33+
) {
34+
const logs = await this.logRepository.findLogsByFilter(
35+
level,
36+
context,
37+
page,
38+
limit,
39+
);
40+
if (!logs || logs.length === 0) {
41+
throw new Error(
42+
`No logs found. Level: ${level}, Context: ${context}, Page: ${page}, Limit: ${limit}`,
43+
);
44+
}
45+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
46+
return logs;
47+
}
48+
async getLogById(id: string) {
49+
const log = await this.logRepository.findLogById(id);
50+
if (!log) {
51+
throw new Error(`Log with ID: ${id} not found`);
52+
}
53+
return log;
54+
}
2855
}

src/notification/notification.module.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Module } from '@nestjs/common';
22
import { MongooseModule } from '@nestjs/mongoose';
33
import { NotificationController } from './presentation/controllers/notification.controller';
4+
import { LogController } from './presentation/controllers/log.controller';
45
import { NotificationRepository } from './infrastructure/repositories/notification.repository';
56
import { NotificationSchema } from './infrastructure/persistence/mongoose/notification.schema';
67
import { NotificationFactory } from './application/factories/notification.factory';
@@ -15,7 +16,7 @@ import { LoggerModule } from '../logger/logger.module';
1516
]),
1617
LoggerModule,
1718
],
18-
controllers: [NotificationController],
19+
controllers: [NotificationController, LogController],
1920
providers: [
2021
{
2122
provide: 'INotificationRepository',
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { Controller, Get, HttpStatus, Param, Query } from '@nestjs/common';
2+
import { LoggerServiceDb } from '../../../logger/services/logger.service.db';
3+
import { ApiOperation, ApiResponse, ApiQuery, ApiTags } from '@nestjs/swagger';
4+
5+
@ApiTags('Logs')
6+
@Controller('api/logs')
7+
export class LogController {
8+
constructor(private readonly logService: LoggerServiceDb) {}
9+
10+
@Get()
11+
@ApiOperation({ summary: 'Get logs by filter' })
12+
@ApiResponse({
13+
status: HttpStatus.OK,
14+
description: 'Logs retrieved successfully',
15+
})
16+
@ApiQuery({
17+
name: 'level',
18+
required: true,
19+
description: 'Log level (e.g., info, error)',
20+
})
21+
@ApiQuery({
22+
name: 'context',
23+
required: false,
24+
description: 'Context (e.g., NotificationController)',
25+
})
26+
@ApiQuery({
27+
name: 'page',
28+
required: false,
29+
type: Number,
30+
description: 'Page number (default: 1)',
31+
})
32+
@ApiQuery({
33+
name: 'limit',
34+
required: false,
35+
type: Number,
36+
description: 'Items per page (default: 10)',
37+
})
38+
getLogs(
39+
@Query('level') level: string,
40+
@Query('context') context?: string,
41+
@Query('page') page = 1,
42+
@Query('limit') limit = 10,
43+
) {
44+
const logs = this.logService.getLogsByFilter(level, context, page, limit);
45+
return logs;
46+
}
47+
48+
@Get(':id')
49+
@ApiOperation({ summary: 'Get log by ID' })
50+
@ApiResponse({
51+
status: HttpStatus.OK,
52+
description: 'Log retrieved successfully',
53+
})
54+
async getLogById(@Param('id') id: string) {
55+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
56+
const log = await this.logService.getLogById(id);
57+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
58+
return { data: log };
59+
}
60+
}

src/notification/presentation/controllers/notification.controller.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,16 @@ import {
55
HttpCode,
66
HttpStatus,
77
Inject,
8+
Get,
9+
Query,
810
} from '@nestjs/common';
9-
import { ApiTags, ApiOperation, ApiResponse, ApiBody } from '@nestjs/swagger';
11+
import {
12+
ApiTags,
13+
ApiOperation,
14+
ApiResponse,
15+
ApiBody,
16+
ApiQuery,
17+
} from '@nestjs/swagger';
1018
import { NotificationFactory } from '../../application/factories/notification.factory';
1119
import { NotificationValidator } from '../../application/validators/notification.validator';
1220
import { SendNotificationDto } from '../dtos/send-notification.dto';
@@ -15,10 +23,12 @@ import { INotificationStrategy } from '../../domain/interfaces/notification-stra
1523
import { INotificationRepository } from '../../domain/interfaces/notification-repository.interface';
1624
import { LoggerServiceFile } from '../../../logger/services/logger.service.file';
1725
import { LoggerServiceDb } from '../../../logger/services/logger.service.db';
26+
import { number } from 'joi';
1827

1928
@ApiTags('Notifications')
2029
@Controller('api/notifications')
2130
export class NotificationController {
31+
notificationModel: import('mongoose').Model<Notification>;
2232
constructor(
2333
private readonly notificationFactory: NotificationFactory,
2434
@Inject('INotificationRepository')
@@ -76,4 +86,40 @@ export class NotificationController {
7686
);
7787
await this.loggerDb.error(`Exception occurred while sending notification`);
7888
}
89+
@Get('history')
90+
@ApiResponse({
91+
status: HttpStatus.OK,
92+
description: 'Notification history retrieved',
93+
})
94+
@ApiQuery({
95+
name: 'page',
96+
required: false,
97+
type: Number,
98+
description: 'Page number (default: 1)',
99+
})
100+
@ApiQuery({
101+
name: 'limit',
102+
required: false,
103+
type: Number,
104+
description: 'Items per page (default: 10)',
105+
})
106+
async getNotificationHistory(
107+
@Query('page') page = 1,
108+
@Query('limit') limit = 10,
109+
) {
110+
const skip = (page - 1) * limit;
111+
const notifications = await this.notificationModel
112+
.find()
113+
.sort({ createdAt: -1 })
114+
.skip(skip)
115+
.limit(limit)
116+
.exec();
117+
const total = await this.notificationModel.countDocuments().exec();
118+
return {
119+
data: notifications,
120+
total: number,
121+
page: number,
122+
totalPages: Math.ceil(total / limit),
123+
};
124+
}
79125
}

0 commit comments

Comments
 (0)