Skip to content

Commit 6242bfa

Browse files
committed
file loging and email sending is working
1 parent e153312 commit 6242bfa

27 files changed

Lines changed: 222 additions & 99 deletions
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export interface ILogRepository {
2+
saveLog(log: {
3+
level: string;
4+
message: string;
5+
trace?: string;
6+
metadata?: {
7+
recipient?: string;
8+
notificationType?: string;
9+
mediaType?: string;
10+
context?: string;
11+
};
12+
timestamp: Date;
13+
}): Promise<void>;
14+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
2+
import { Document } from 'mongoose';
3+
4+
@Schema({ collection: 'logger', timestamps: true })
5+
export class Logger extends Document {
6+
@Prop({ required: true, enum: ['info', 'error'] })
7+
level: string;
8+
9+
@Prop({ required: true })
10+
message: string;
11+
12+
@Prop()
13+
trace?: string;
14+
15+
@Prop({ type: Object })
16+
metadata?: {
17+
recipient?: string;
18+
notificationType?: string;
19+
mediaType?: string;
20+
context?: string;
21+
};
22+
23+
@Prop({ default: Date.now })
24+
timestamp: Date;
25+
}
26+
27+
export const LoggerSchema = SchemaFactory.createForClass(Logger);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { InjectModel } from '@nestjs/mongoose';
3+
import { Model } from 'mongoose';
4+
import { ILogRepository } from '../../domain/interfaces/log-repository.interface';
5+
import { Logger } from '../persistence/mongoose/logger.schema';
6+
7+
@Injectable()
8+
export class LogRepository implements ILogRepository {
9+
constructor(
10+
@InjectModel(Logger.name)
11+
private readonly loggerModel: Model<Logger>,
12+
) {}
13+
14+
async saveLog(log: {
15+
level: string;
16+
message: string;
17+
trace?: string;
18+
metadata?: {
19+
recipient?: string;
20+
notificationType?: string;
21+
mediaType?: string;
22+
context?: string;
23+
};
24+
timestamp: Date;
25+
}): Promise<void> {
26+
const logEntry = new this.loggerModel(log);
27+
await logEntry.save();
28+
}
29+
}

src/logger/logger.module.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
import { Module } from '@nestjs/common';
2+
import { MongooseModule } from '@nestjs/mongoose';
23
import { LoggerService } from './services/logger.service';
4+
import { LogRepository } from './infrastructure/repositories/log.repository';
5+
import {
6+
Logger,
7+
LoggerSchema,
8+
} from './infrastructure/persistence/mongoose/logger.schema';
39

410
@Module({
5-
providers: [LoggerService],
6-
exports: [LoggerService],
11+
imports: [
12+
MongooseModule.forFeature([{ name: Logger.name, schema: LoggerSchema }]),
13+
],
14+
providers: [
15+
LoggerService,
16+
LogRepository,
17+
{
18+
provide: 'ILogRepository',
19+
useClass: LogRepository,
20+
},
21+
],
22+
exports: [LoggerService, 'ILogRepository', LogRepository],
723
})
824
export class LoggerModule {}

src/main.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,25 @@ import { NestFactory } from '@nestjs/core';
22
import { AppModule } from './app.module';
33
import { AllExceptionsFilter } from './filters/all-exceptions.filter';
44
import { LoggerService } from './logger/services/logger.service';
5+
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
56

67
async function bootstrap() {
78
const app = await NestFactory.create(AppModule);
89
const logger = app.get(LoggerService);
910
app.useGlobalFilters(new AllExceptionsFilter(logger));
11+
12+
// Configure Swagger
13+
const config = new DocumentBuilder()
14+
.setTitle('SmartEduHub Utility API')
15+
.setDescription('API for sending notifications via email or SMS')
16+
.setVersion('1.0')
17+
.build();
18+
const document = SwaggerModule.createDocument(app, config);
19+
SwaggerModule.setup('api', app, document);
20+
1021
await app.listen(3000);
1122
logger.log('Application run successfully');
1223
}
1324
bootstrap().catch((error) => {
14-
console.error('Error during application bootstrap:', error);
25+
console.log('Error during application bootstrap:', error);
1526
});

src/notification/application/factories/common/notification.factory.ts

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { NotificationChannel } from '../../../config/notification.config';
3+
import { INotificationStrategy } from '../../domain/interfaces/notification-strategy.interface';
4+
import { EmailNotificationStrategy } from '../strategies/email-notification.strategy';
5+
import { SMSNotificationStrategy } from '../strategies/sms-notification.strategy';
6+
import { UnsupportedMediaTypeError } from '../../domain/errors/unsupported-media-type.error';
7+
8+
@Injectable()
9+
export class NotificationFactory {
10+
constructor(
11+
private readonly emailStrategy: EmailNotificationStrategy,
12+
private readonly smsStrategy: SMSNotificationStrategy,
13+
) {}
14+
15+
createStrategy(mediaType: NotificationChannel): INotificationStrategy {
16+
switch (mediaType) {
17+
case NotificationChannel.EMAIL:
18+
return this.emailStrategy;
19+
case NotificationChannel.SMS:
20+
return this.smsStrategy;
21+
default:
22+
throw new UnsupportedMediaTypeError(mediaType);
23+
}
24+
}
25+
}

src/notification/application/strategies/email-notification.strategy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { INotificationStrategy } from '../../domain/interfaces/common/notification-strategy.interface';
2-
import { Notification } from '../../domain/entities/common/notification.entity';
1+
import { INotificationStrategy } from '../../domain/interfaces/notification-strategy.interface';
2+
import { Notification } from '../../domain/entities/notification.entity';
33

44
export class EmailNotificationStrategy implements INotificationStrategy {
55
constructor(private emailClient?: any) {

src/notification/application/strategies/sms-notification.strategy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { INotificationStrategy } from '../../domain/interfaces/common/notification-strategy.interface';
2-
import { Notification } from '../../domain/entities/common/notification.entity';
1+
import { INotificationStrategy } from '../../domain/interfaces/notification-strategy.interface';
2+
import { Notification } from '../../domain/entities/notification.entity';
33

44
export class SMSNotificationStrategy implements INotificationStrategy {
55
constructor(private smsClient?: any) {

src/notification/application/use-cases/send-notification.use-case.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { Injectable } from '@nestjs/common';
2-
import { Notification } from '../../domain/entities/common/notification.entity';
3-
import { INotificationStrategy } from '../../domain/interfaces/common/notification-strategy.interface';
2+
import { Notification } from '../../domain/entities/notification.entity';
3+
import { INotificationStrategy } from '../../domain/interfaces/notification-strategy.interface';
44
import { NotificationFactory } from '../../infrastructure/factories/notification.factory';
55
import { NotificationChannel } from '../../../config/notification.config';
66
import { NotificationRepository } from '../../infrastructure/repositories/notification.repository';
77
import { NotificationValidator } from '../validators/notification.validator';
8+
import { NotificationType } from '../../presentation/dtos/send-notification.dto';
89

910
@Injectable()
1011
export class SendNotificationUseCase {
@@ -25,6 +26,7 @@ export class SendNotificationUseCase {
2526
subject,
2627
body,
2728
mediaType,
29+
notificationType: NotificationType.ADMISSION_ID,
2830
});
2931
// Check for validation errors
3032
const error = validationResult.error;

0 commit comments

Comments
 (0)