Skip to content

Commit 614bf04

Browse files
committed
feat: added the webhooks
1 parent 7d4b6bc commit 614bf04

5 files changed

Lines changed: 105 additions & 1 deletion

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { Webhook } from '../../infrastructure/persistence/mongoose/webhook.schema';
2+
3+
export interface IWebhookRepository {
4+
createWebhook(url: string, event: string, ownerId: string): Promise<Webhook>;
5+
findByOwnerId(ownerId: string): Promise<Webhook[]>;
6+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
2+
import { Document } from 'mongoose';
3+
4+
@Schema({ timestamps: true })
5+
export class Webhook extends Document {
6+
@Prop({ required: true })
7+
url: string;
8+
9+
@Prop({ required: true })
10+
event: string; // e.g., 'notification.sent', 'notification.failed'
11+
12+
@Prop({ required: true })
13+
ownerId: string; // e.g., user or system ID
14+
15+
@Prop({ default: true })
16+
active: boolean;
17+
}
18+
19+
export const WebhookSchema = SchemaFactory.createForClass(Webhook);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { InjectModel } from '@nestjs/mongoose';
3+
import { Model } from 'mongoose';
4+
import { Webhook } from '../persistence/mongoose/webhook.schema';
5+
import { IWebhookRepository } from '../../domain/interfaces/webhook-repository.interface';
6+
7+
@Injectable()
8+
export class WebhookRepository implements IWebhookRepository {
9+
constructor(
10+
@InjectModel('Webhook')
11+
private readonly webhookModel: Model<Webhook>,
12+
) {}
13+
14+
async createWebhook(
15+
url: string,
16+
event: string,
17+
ownerId: string,
18+
): Promise<Webhook> {
19+
const webhook = new this.webhookModel({ url, event, ownerId });
20+
return webhook.save();
21+
}
22+
23+
async findByOwnerId(ownerId: string): Promise<Webhook[]> {
24+
return this.webhookModel.find({ ownerId, active: true }).exec();
25+
}
26+
}

src/notification/notification.module.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { Module } from '@nestjs/common';
22
import { MongooseModule } from '@nestjs/mongoose';
33
import { NotificationController } from './presentation/controllers/notification.controller';
4+
import { WebhookController } from './presentation/controllers/webhook.controller';
45
import { LogController } from './presentation/controllers/log.controller';
56
import { NotificationRepository } from './infrastructure/repositories/notification.repository';
7+
import { WebhookRepository } from './infrastructure/repositories/webhook.repository';
68
import { NotificationSchema } from './infrastructure/persistence/mongoose/notification.schema';
9+
import { WebhookSchema } from './infrastructure/persistence/mongoose/webhook.schema';
710
import { NotificationFactory } from './application/factories/notification.factory';
811
import { EmailNotificationStrategy } from './application/strategies/email-notification.strategy';
912
import { SMSNotificationStrategy } from './application/strategies/sms-notification.strategy';
@@ -13,15 +16,20 @@ import { LoggerModule } from '../logger/logger.module';
1316
imports: [
1417
MongooseModule.forFeature([
1518
{ name: 'Notification', schema: NotificationSchema },
19+
{ name: 'Webhook', schema: WebhookSchema }, // Register Webhook schema
1620
]),
1721
LoggerModule,
1822
],
19-
controllers: [NotificationController, LogController],
23+
controllers: [NotificationController, WebhookController, LogController],
2024
providers: [
2125
{
2226
provide: 'INotificationRepository',
2327
useClass: NotificationRepository,
2428
},
29+
{
30+
provide: 'IWebhookRepository',
31+
useClass: WebhookRepository,
32+
},
2533
NotificationFactory,
2634
EmailNotificationStrategy,
2735
SMSNotificationStrategy,
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Body, Controller, Get, HttpStatus, Post, Query } from '@nestjs/common';
2+
import { Inject } from '@nestjs/common';
3+
import { IWebhookRepository } from '../../domain/interfaces/webhook-repository.interface';
4+
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
5+
6+
class CreateWebhookDto {
7+
url: string;
8+
event: string;
9+
ownerId: string;
10+
}
11+
12+
@ApiTags('Webhooks')
13+
@Controller('api/webhooks')
14+
export class WebhookController {
15+
constructor(
16+
@Inject('IWebhookRepository')
17+
private readonly webhookRepository: IWebhookRepository,
18+
) {}
19+
20+
@Post()
21+
@ApiOperation({ summary: 'Create a webhook subscription' })
22+
@ApiResponse({
23+
status: HttpStatus.CREATED,
24+
description: 'Webhook created successfully',
25+
})
26+
async createWebhook(@Body() dto: CreateWebhookDto) {
27+
const webhook = await this.webhookRepository.createWebhook(
28+
dto.url,
29+
dto.event,
30+
dto.ownerId,
31+
);
32+
return { message: 'Webhook created successfully', data: webhook };
33+
}
34+
35+
@Get()
36+
@ApiOperation({ summary: 'Get webhooks for an owner' })
37+
@ApiResponse({
38+
status: HttpStatus.OK,
39+
description: 'Webhooks retrieved successfully',
40+
})
41+
async getWebhooks(@Query('ownerId') ownerId: string) {
42+
const webhooks = await this.webhookRepository.findByOwnerId(ownerId);
43+
return { data: webhooks };
44+
}
45+
}

0 commit comments

Comments
 (0)