forked from novuhq/novu
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(api): create topic use case and endpoint
- Loading branch information
1 parent
32a79ed
commit 3be1c62
Showing
18 changed files
with
226 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; | ||
import { IsDefined, IsString } from 'class-validator'; | ||
|
||
import { TopicDto } from './topic.dto'; | ||
|
||
export class CreateTopicResponseDto implements Pick<TopicDto, '_id'> {} | ||
|
||
export class CreateTopicRequestDto { | ||
@ApiProperty({ | ||
description: | ||
'User defined custom key and provided by the user that will be an unique identifier for the Topic created.', | ||
}) | ||
@IsString() | ||
@IsDefined() | ||
key: string; | ||
|
||
@ApiProperty({ | ||
description: 'User defined custom name and provided by the user that will name the Topic created.', | ||
}) | ||
@IsString() | ||
@IsDefined() | ||
name: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; | ||
|
||
export class TopicDto { | ||
@ApiProperty() | ||
_id?: string; | ||
|
||
@ApiProperty() | ||
_organizationId: string; | ||
|
||
@ApiProperty() | ||
_environmentId: string; | ||
|
||
@ApiProperty() | ||
_userId: string; | ||
|
||
@ApiProperty() | ||
key: string; | ||
|
||
@ApiProperty() | ||
name: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { UserSession } from '@novu/testing'; | ||
import * as jwt from 'jsonwebtoken'; | ||
import { expect } from 'chai'; | ||
import { IJwtPayload, MemberRoleEnum } from '@novu/shared'; | ||
|
||
const URL = '/v1/topics'; | ||
|
||
describe('Topic creation - /topics (POST)', async () => { | ||
let session: UserSession; | ||
|
||
before(async () => { | ||
session = new UserSession(); | ||
await session.initialize(); | ||
}); | ||
|
||
it('should throw validation error for missing request payload information', async () => { | ||
const { body } = await session.testAgent.post(URL).send({}); | ||
|
||
expect(body.statusCode).to.equal(400); | ||
expect(body.message.find((i) => i.includes('key'))).to.be.ok; | ||
expect(body.message.find((i) => i.includes('name'))).to.be.ok; | ||
expect(body.message).to.eql([ | ||
'key should not be null or undefined', | ||
'key must be a string', | ||
'name should not be null or undefined', | ||
'name must be a string', | ||
]); | ||
}); | ||
|
||
it('should create a new topic successfully', async () => { | ||
const topicKey = 'topic-key'; | ||
const topicName = 'topic-name'; | ||
const response = await session.testAgent.post(URL).send({ | ||
key: topicKey, | ||
name: topicName, | ||
}); | ||
|
||
expect(response.statusCode).to.eql(201); | ||
|
||
const { body } = response; | ||
expect(body.data._id).to.exist; | ||
expect(body.data._id).to.be.string; | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { Body, Controller, Inject, Post, UseGuards } from '@nestjs/common'; | ||
import { ApiExcludeController, ApiOkResponse, ApiTags } from '@nestjs/swagger'; | ||
import { IJwtPayload } from '@novu/shared'; | ||
|
||
import { CreateTopicRequestDto, CreateTopicResponseDto } from './dtos/create-topic.dto'; | ||
import { CreateTopicCommand, CreateTopicUseCase } from './use-cases'; | ||
|
||
import { JwtAuthGuard } from '../auth/framework/auth.guard'; | ||
import { ExternalApiAccessible } from '../auth/framework/external-api.decorator'; | ||
import { UserSession } from '../shared/framework/user.decorator'; | ||
import { AnalyticsService } from '../shared/services/analytics/analytics.service'; | ||
import { ANALYTICS_SERVICE } from '../shared/shared.module'; | ||
|
||
@Controller('/topics') | ||
@ApiTags('Topics') | ||
@UseGuards(JwtAuthGuard) | ||
export class TopicsController { | ||
constructor( | ||
private createTopicUseCase: CreateTopicUseCase, | ||
@Inject(ANALYTICS_SERVICE) private analyticsService: AnalyticsService | ||
) {} | ||
|
||
@ExternalApiAccessible() | ||
@ApiOkResponse({ | ||
type: CreateTopicResponseDto, | ||
}) | ||
@Post('/') | ||
async createTopic( | ||
@UserSession() user: IJwtPayload, | ||
@Body() body: CreateTopicRequestDto | ||
): Promise<CreateTopicResponseDto> { | ||
const topic = await this.createTopicUseCase.execute( | ||
CreateTopicCommand.create({ | ||
environmentId: user.environmentId, | ||
key: body.key, | ||
name: body.name, | ||
organizationId: user.organizationId, | ||
userId: user._id, | ||
}) | ||
); | ||
|
||
return { | ||
_id: topic._id, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Module } from '@nestjs/common'; | ||
|
||
import { USE_CASES } from './use-cases'; | ||
import { TopicsController } from './topics.controller'; | ||
|
||
import { SharedModule } from '../shared/shared.module'; | ||
import { AuthModule } from '../auth/auth.module'; | ||
|
||
@Module({ | ||
imports: [SharedModule, AuthModule], | ||
providers: [...USE_CASES], | ||
exports: [...USE_CASES], | ||
controllers: [TopicsController], | ||
}) | ||
export class TopicsModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { EnvironmentId, OrganizationId, TopicId, TopicKey, UserId } from '@novu/dal'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { TopicKey } from '@novu/dal'; | ||
import { IsDefined, IsString } from 'class-validator'; | ||
|
||
import { EnvironmentWithUserCommand } from '../../shared/commands/project.command'; | ||
|
||
export class CreateTopicCommand extends EnvironmentWithUserCommand { | ||
@IsString() | ||
@IsDefined() | ||
key: TopicKey; | ||
|
||
@IsString() | ||
@IsDefined() | ||
name: string; | ||
} |
33 changes: 33 additions & 0 deletions
33
apps/api/src/app/topics/use-cases/create-topic.use-case.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { EnvironmentId, OrganizationId, TopicEntity, TopicKey, TopicRepository, UserId } from '@novu/dal'; | ||
|
||
import { CreateTopicCommand } from './create-topic.command'; | ||
|
||
import { TopicDto } from '../dtos/topic.dto'; | ||
|
||
const mapFromCommandToRepository = (command: CreateTopicCommand) => ({ | ||
_environmentId: command.environmentId as unknown as EnvironmentId, | ||
_organizationId: command.organizationId as unknown as OrganizationId, | ||
_userId: command.userId as unknown as UserId, | ||
key: command.key as TopicKey, | ||
name: command.name, | ||
}); | ||
|
||
const mapFromEntityToDto = (topic: TopicEntity): TopicDto => ({ | ||
...topic, | ||
_id: topic._id as unknown as string, | ||
_organizationId: topic._organizationId as unknown as string, | ||
_environmentId: topic._environmentId as unknown as string, | ||
_userId: topic._userId as unknown as string, | ||
}); | ||
|
||
@Injectable() | ||
export class CreateTopicUseCase { | ||
constructor(private topicRepository: TopicRepository) {} | ||
|
||
async execute(command: CreateTopicCommand) { | ||
const topic = await this.topicRepository.create(mapFromCommandToRepository(command)); | ||
|
||
return mapFromEntityToDto(topic); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { CreateTopicUseCase } from './create-topic.use-case'; | ||
|
||
export * from './create-topic.command'; | ||
export * from './create-topic.use-case'; | ||
|
||
export const USE_CASES = [CreateTopicUseCase]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
libs/dal/src/repositories/topic/topic-subscribers.repository.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { Schema } from 'mongoose'; | ||
|
||
export type EnvironmentId = Schema.Types.ObjectId; | ||
export type OrganizationId = Schema.Types.ObjectId; | ||
export type TopicId = Schema.Types.ObjectId; | ||
export type TopicKey = string; | ||
export type UserId = Schema.Types.ObjectId; |