Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .env.dist
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
MONGODB_URL=mongodb://user:pass@mongodb

TYPER_ORM_SYNCHRONIZE=true

QUEUE_NOTIFICATION_ORDER=queue_notification_order

WEBHOOK_BASE_URL=

AWS_REGION=us-east-1
AWS_ACCOUNT_ID=000000000000
AWS_SQS_ENDPOINT=http://localstack-dev:4566


3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ seed:
# Generates the project's index (e.g., files or reference code) using Yarn,
# in a container defined in the yarn.cli.yml file.
generate-index:
docker compose -f yarn.cli.yml run --rm yarn generate-index
docker compose -f yarn.cli.yml run --rm yarn generate-index && \
git add .

# Creates the network defined in NETWORK_NAME (if it doesn't exist) and starts only the MongoDB
# container in the background, based on the compose.yml file.
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@ timesheet-in-transit-api/
│ │ │-- seed.module.ts
│ │ │-- seed.ts
│ │ │-- entrypoints/
│ │ │ │-- config/
│ │ │ │-- consumers/
│ │ │ │-- web/
│ │ │ │ │-- shared/
│ │ │ │ │-- config/
│ │ │ │ │-- rest/
│ │ │ │ │-- shared/
│ │ │-- core/
│ │ │ │-- domain/
│ │ │ │ │-- entities/
│ │ │ │ │-- enums/
│ │ │ │ │-- exceptions/
│ │ │ │-- providers/
│ │ │ │ │-- config-env/
│ │ │ │ │-- integrations/
│ │ │ │ │-- queue/
│ │ │ │ │-- repositories/
Expand All @@ -70,6 +70,7 @@ timesheet-in-transit-api/
│ │ │ │ │-- notification/
│ │ │ │ │-- orders/
│ │ │-- infrastructure/
│ │ │ │-- config-env/
│ │ │ │-- integrations/
│ │ │ │-- queue/
│ │ │ │-- repositories/
Expand Down
5 changes: 3 additions & 2 deletions README.pt-br.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ timesheet-in-transit-api/
│ │ │-- seed.module.ts
│ │ │-- seed.ts
│ │ │-- entrypoints/
│ │ │ │-- config/
│ │ │ │-- consumers/
│ │ │ │-- web/
│ │ │ │ │-- shared/
│ │ │ │ │-- config/
│ │ │ │ │-- rest/
│ │ │ │ │-- shared/
│ │ │-- core/
│ │ │ │-- domain/
│ │ │ │ │-- entities/
│ │ │ │ │-- enums/
│ │ │ │ │-- exceptions/
│ │ │ │-- providers/
│ │ │ │ │-- config-env/
│ │ │ │ │-- integrations/
│ │ │ │ │-- queue/
│ │ │ │ │-- repositories/
Expand All @@ -69,6 +69,7 @@ timesheet-in-transit-api/
│ │ │ │ │-- notification/
│ │ │ │ │-- orders/
│ │ │-- infrastructure/
│ │ │ │-- config-env/
│ │ │ │-- integrations/
│ │ │ │-- queue/
│ │ │ │-- repositories/
Expand Down
1 change: 1 addition & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@nestjs/common": "^10.4.15",
"@nestjs/core": "^10.4.15",
"@nestjs/platform-express": "^10.4.15",
"@nestjs/config": "^3.3.0",
"@nestjs/swagger": "^8.1.0",
"@nestjs/terminus": "^10.2.3",
"@nestjs/typeorm": "^10.0.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { OrderTotalHoursCoreEntity, OrderCoreEntity } from '@core/domain/entities/orders';
import { GenericPaginationCoreEntity, PaginationCoreEntity } from '@core/domain/entities/common';
import { GenericPaginationCoreEntity, PaginationCoreEntity } from '@core/domain/entities/shared';

export class OrderPaginationCoreEntity extends GenericPaginationCoreEntity<OrderCoreEntity> {
readonly totalHours: OrderTotalHoursCoreEntity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PaginationCoreEntity } from '@core/domain/entities/common';
import { PaginationCoreEntity } from '@core/domain/entities/shared';
import { OrderStatus } from '@core/domain/enums';

export class OrderQueryCoreEntity {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PaginationCoreEntity } from '@core/domain/entities/common';
import { PaginationCoreEntity } from '@core/domain/entities/shared';

export class GenericPaginationCoreEntity<E> {
constructor(
Expand Down
2 changes: 1 addition & 1 deletion app/src/core/domain/exceptions/custom-base.exception.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ErrorItemCoreEntity } from '@core/domain/entities/common';
import { ErrorItemCoreEntity } from '@core/domain/entities/shared';

export abstract class CustomBaseException extends Error {
protected constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CustomBaseException } from '@core/domain/exceptions';
import { ErrorItemCoreEntity } from '@core/domain/entities/common';
import { ErrorItemCoreEntity } from '@core/domain/entities/shared';

export class CustomBusinessException extends CustomBaseException {
constructor(protected readonly error: ErrorItemCoreEntity) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CustomBaseException } from '@core/domain/exceptions';
import { ErrorItemCoreEntity } from '@core/domain/entities/common';
import { ErrorItemCoreEntity } from '@core/domain/entities/shared';

export class CustomConflictException extends CustomBaseException {
constructor(protected readonly error: ErrorItemCoreEntity) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CustomBaseException } from '@core/domain/exceptions';
import { ErrorItemCoreEntity } from '@core/domain/entities/common';
import { ErrorItemCoreEntity } from '@core/domain/entities/shared';

export class CustomResourceNotFoundException extends CustomBaseException {
constructor(protected readonly error: ErrorItemCoreEntity) {
Expand Down
29 changes: 29 additions & 0 deletions app/src/core/providers/config-env/config.env.provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export interface ConfigEnvProvider {
/**
* Gets a configuration value by name of type generic.
* @param key Key name of env
* @param defaultValue Default value if the key does not exist.
*/
get<T = string>(key: string, defaultValue?: T): T;

/**
* Gets a configuration value by name of type string.
* @param key Key name of env
* @param defaultValue Default value if the key does not exist.
*/
getString(key: string, defaultValue?: string): string;

/**
* Gets a configuration value by name of type number.
* @param key Key name of env
* @param defaultValue Default value if the key does not exist.
*/
getNumber(key: string, defaultValue?: number): number;

/**
* Gets a configuration value by name of type boolean.
* @param key Key name of env
* @param defaultValue Default value if the key does not exist.
*/
getBoolean(key: string, defaultValue?: boolean): boolean;
}
1 change: 1 addition & 0 deletions app/src/core/providers/config-env/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './config.env.provider';
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { NotificationOrderCoreEntity } from '@core/domain/entities/notifications';
import { NotificationOrderRegisterUsecase } from '@core/usecases/notification';
import { ProducerQueueProvider } from '@core/providers/queue';
import { configEnv } from '@shared/config';
import { ConfigEnvProvider } from '@core/providers/config-env';

export class NotificationOrderRegisterUsecaseImpl implements NotificationOrderRegisterUsecase {
constructor(private readonly sendQueueProvider: ProducerQueueProvider) {}
constructor(
private readonly sendQueueProvider: ProducerQueueProvider,
private readonly configEnvProvider: ConfigEnvProvider,
) {}
public async execute(notificationOrderCoreEntity: Partial<NotificationOrderCoreEntity>): Promise<void> {
await this.sendQueueProvider.sendMessage(configEnv.aws.sqs.queues.queueNotificationOrder, JSON.stringify(notificationOrderCoreEntity));
const queueName = this.configEnvProvider.getString('QUEUE_NOTIFICATION_ORDER');
await this.sendQueueProvider.sendMessage(queueName, JSON.stringify(notificationOrderCoreEntity));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OrderRepositoryProvider } from '@core/providers/repositories';
import { OrderCoordsCoreEntity, OrderEndCoreEntity } from '@core/domain/entities/orders';
import { ValidateDatesCoreEntity } from '@core/domain/entities/common';
import { ValidateDatesCoreEntity } from '@core/domain/entities/shared';
import { OrderEndUsecase } from '@core/usecases/orders';
import { NotificationOrderRegisterUsecase } from '@core/usecases/notification';
import { NotificationOrderCoreEntity } from '@core/domain/entities/notifications';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OrderRepositoryProvider } from '@core/providers/repositories';
import { OrderQuantityStatusEntity, OrderQueryQuantityStatusCoreEntity } from '@core/domain/entities/orders';
import { ValidateDatesCoreEntity } from '@core/domain/entities/common';
import { ValidateDatesCoreEntity } from '@core/domain/entities/shared';
import { OrderQueryQuantityStatusUsecase } from '@core/usecases/orders';

export class OrderQueryQuantityStatusUsecaseImpl implements OrderQueryQuantityStatusUsecase {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OrderRepositoryProvider } from '@core/providers/repositories';
import { OrderPaginationCoreEntity, OrderQueryCoreEntity } from '@core/domain/entities/orders';
import { ValidateDatesCoreEntity } from '@core/domain/entities/common';
import { ValidateDatesCoreEntity } from '@core/domain/entities/shared';
import { OrderQueryUsecase } from '@core/usecases/orders';

export class OrderQueryUsecaseImpl implements OrderQueryUsecase {
Expand Down
20 changes: 13 additions & 7 deletions app/src/database.module.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { configEnv } from '@src/shared/config';
import { ConfigEnvModule } from '@infrastructure/config-env';
import { ConfigEnvProvider } from '@core/providers/config-env';
import { ConfigEnvProviderImpl } from '@infrastructure/config-env/impl';

@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mongodb',
url: configEnv.database.mongodb.url,
entities: [__dirname + '/infrastructure/repositories/**/*.entity{.ts,.js}'],
synchronize: configEnv.database.mongodb.synchronize,
logging: false,
TypeOrmModule.forRootAsync({
imports: [ConfigEnvModule],
useFactory: async (configEnvProvider: ConfigEnvProvider) => ({
type: 'mongodb',
url: configEnvProvider.getString('MONGODB_URL'),
entities: [__dirname + '/infrastructure/repositories/**/*.entity{.ts,.js}'],
synchronize: configEnvProvider.getBoolean('TYPER_ORM_SYNCHRONIZE', false),
logging: false,
}),
inject: [ConfigEnvProviderImpl.name],
}),
],
})
Expand Down
1 change: 0 additions & 1 deletion app/src/entrypoints/config/usecases/abstract/index.ts

This file was deleted.

This file was deleted.

11 changes: 4 additions & 7 deletions app/src/entrypoints/consumers/consumer.module.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { Module } from '@nestjs/common';
import { WebhookIntegrationClientModule } from '@infrastructure/integrations/webhook-client';
import { SqsConsumerQueueProviderImpl } from '@infrastructure/queue/sqs/impl';
import { UsecaseProviderConfig } from '@entrypoints/config/usecases/abstract';
import { NotificationSendWebhookUsecaseImpl } from '@core/usecases/notification/impl';
import { WebhookIntegrationClientProviderImpl } from '@infrastructure/integrations/webhook-client/impl';
import { NotificationOrderConsumerService } from '@entrypoints/consumers/notification';
import { DiscoveryModule } from '@nestjs/core';

const notificationProvider = [UsecaseProviderConfig(NotificationSendWebhookUsecaseImpl, [WebhookIntegrationClientProviderImpl]), NotificationOrderConsumerService];
import { DynamicConfigModule } from '@shared/config';
import { SqsQueueInfraModule } from '@infrastructure/queue/sqs';

@Module({
imports: [DiscoveryModule, WebhookIntegrationClientModule],
providers: [SqsConsumerQueueProviderImpl, ...notificationProvider],
imports: [SqsQueueInfraModule, WebhookIntegrationClientModule],
providers: [DynamicConfigModule.forProvider(NotificationSendWebhookUsecaseImpl, [WebhookIntegrationClientProviderImpl]), NotificationOrderConsumerService],
})
export class ConsumerModule {}
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
import { Inject, Injectable, Logger } from '@nestjs/common';
import { configEnv } from '@src/shared/config';
import { Inject, Injectable } from '@nestjs/common';
import { Message } from '@aws-sdk/client-sqs';
import { NotificationSendWebhookUsecaseImpl } from '@core/usecases/notification/impl';
import { NotificationSendWebhookUsecase } from '@core/usecases/notification';
import { SqsMessageHandler } from '@infrastructure/queue/sqs/config/decorators';

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

@Inject(NotificationSendWebhookUsecaseImpl.name)
private readonly notificationSendWebhookUsecase: NotificationSendWebhookUsecase;

@SqsMessageHandler({ queueName: configEnv.aws.sqs.queues.queueNotificationOrder, waitTimeSeconds: 5, batchSize: 10 })
@SqsMessageHandler({ queueNameEnv: 'QUEUE_NOTIFICATION_ORDER', waitTimeSeconds: 5, batchSize: 10 })
async handleMessage(message: Message) {
if (!message || !message.Body) {
this.logger.warn(`[QueueName: ${configEnv.aws.sqs.queues.queueNotificationOrder}] Empty message body received in queue.`);
return;
}
await this.notificationSendWebhookUsecase.execute(message.Body);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Request } from 'express';
import { OrderPaginationCoreEntity, OrderQueryCoreEntity } from '@core/domain/entities/orders';
import { PaginationCoreEntity } from '@core/domain/entities/common';
import { PaginationCoreEntity } from '@core/domain/entities/shared';
import { OrderQueryRequest } from '@src/entrypoints/web/rest/orders/request';
import { OrderPaginationResponse, OrderTotalHoursResponse } from '@src/entrypoints/web/rest/orders/response';
import { PaginationResponse } from '@entrypoints/web/shared/response/pagination';
Expand Down
Loading
Loading