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
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ echo "Running pre-commit..."

BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)

if echo "$BRANCH_NAME" | grep -qE '^(feature|bugfix|release|hotfix)\/[a-z0-9-]+$'; then
if echo "$BRANCH_NAME" | grep -qE '^(feature|bugfix|release|hotfix|refactor)\/[a-z0-9-]+$'; then
echo "✅ Valid branch name: $BRANCH_NAME"
else
echo "🚫 The branch name '$BRANCH_NAME' does not follow the Gitflow standard."
Expand Down
2 changes: 1 addition & 1 deletion .husky/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)

if echo "$BRANCH_NAME" | grep -qE '^(feature|bugfix|release|hotfix)\/[a-z0-9-]+$'; then
if echo "$BRANCH_NAME" | grep -qE '^(feature|bugfix|release|hotfix|refactor)\/[a-z0-9-]+$'; then
echo "✅ Valid branch name: $BRANCH_NAME"
else
echo "🚫 The branch name '$BRANCH_NAME' does not follow the Gitflow standard."
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ It serves as a practical study for the "adaptation" of concepts such as **Clean
**Hexagonal Architecture**, with the goal of promoting the best software design practices, ensuring clear separation of
responsibilities, and abstracting external dependencies.

![architecture-timesheet-in-transit-api](diagram/architecture-timesheet-in-transit-api.png)

## 1. Installation Requirements

To run the project, you will need the following requirements:
Expand Down Expand Up @@ -42,7 +44,7 @@ timesheet-in-transit-api/
│ │ │-- main.ts
│ │ │-- seed.module.ts
│ │ │-- seed.ts
│ │ │-- modules/
│ │ │-- entrypoint/
│ │ │ │-- config/
│ │ │ │-- consumers/
│ │ │ │-- web/
Expand Down Expand Up @@ -71,9 +73,9 @@ timesheet-in-transit-api/
│ │ │ │-- config/
```

### **modules**
### **entrypoints**

The `modules` module is responsible for managing the application's entry points, such as `web`, `jobs`, and
The `entrypoints` module is responsible for managing the application's entry points, such as `web`, `jobs`, and
`consumers`.

**Important**: **It must not contain business logic**. This module may include input data validation for request
Expand Down
8 changes: 5 additions & 3 deletions README.pt-br.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Ele funciona como um estudo prático para a "adaptação" de conceitos como **Cl
**Hexagonal Architecture**, visando promover boas práticas de design de software, garantindo uma clara
separação de responsabilidadese a abstração de dependências externas.

![architecture-timesheet-in-transit-api](diagram/architecture-timesheet-in-transit-api.png)

## 1. Requisitos de Instalação

Para rodar o projeto, você precisará dos seguintes requisitos:
Expand Down Expand Up @@ -42,7 +44,7 @@ timesheet-in-transit-api/
│ │ │-- main.ts
│ │ │-- seed.module.ts
│ │ │-- seed.ts
│ │ │-- modules/
│ │ │-- entrypoint/
│ │ │ │-- config/
│ │ │ │-- consumers/
│ │ │ │-- web/
Expand Down Expand Up @@ -71,9 +73,9 @@ timesheet-in-transit-api/
│ │ │ │-- config/
```

### **modules**
### **entrypoints**

O módulo `modules` é responsável pela gestão dos pontos de entrada da aplicação, como `web`, `jobs` e
O módulo `entrypoints` é responsável pela gestão dos pontos de entrada da aplicação, como `web`, `jobs` e
`consumers`.

**Importante**: **não deve conter regras de negócio**. Este pode ter validações de entradas de dados
Expand Down
4 changes: 2 additions & 2 deletions app/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Module } from '@nestjs/common';
import { WebModule } from '@application/web';
import { ConsumerModule } from '@src/modules/consumers';
import { WebModule } from '@entrypoints/web';
import { ConsumerModule } from '@src/entrypoints/consumers';

@Module({
imports: [WebModule, ConsumerModule],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import { Provider, Type } from '@nestjs/common';
* ```typescript
* import { Module, Provider } from '@nestjs/shared';
* import { RepositoryInfraModule } from '@infrastructure/repositories';
* import { AuthAppModule } from '@modules/web/middleware/apikey';
* import { OrdersController } from '@modules/web/controllers/orders';
* import { UsecaseProviderConfig } from '@modules/config/usecases/abstract';
* import { AuthAppModule } from '@entrypoints/web/middleware/apikey';
* import { OrdersController } from '@entrypoints/web/controllers/orders';
* import { UsecaseProviderConfig } from '@entrypoints/config/usecases/abstract';
* import { NotificationOrderRegisterUsecaseImpl } from '@core/usecases/notification/impl';
* import { SqsProducerQueueProviderImpl } from '@infrastructure/queue/sqs/impl';
* import { SqsQueueInfraModule } from '@infrastructure/queue/sqs';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Module } from '@nestjs/common';
import { WebhookIntegrationClientModule } from '@infrastructure/integrations/webhook-client';
import { SqsConsumerQueueProviderImpl } from '@infrastructure/queue/sqs/impl';
import { UsecaseProviderConfig } from '@application/config/usecases/abstract';
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 '@application/consumers/notification';
import { NotificationOrderConsumerService } from '@entrypoints/consumers/notification';
import { DiscoveryModule } from '@nestjs/core';

const notificationProvider = [UsecaseProviderConfig(NotificationSendWebhookUsecaseImpl, [WebhookIntegrationClientProviderImpl]), NotificationOrderConsumerService];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { applyDecorators, Type } from '@nestjs/common';
import { ApiBadRequestResponse, ApiInternalServerErrorResponse, ApiNoContentResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiUnauthorizedResponse } from '@nestjs/swagger';
import { ErrorResponse } from '@application/web/shared/response/error';
import { ErrorResponse } from '@entrypoints/web/shared/response/error';

export function ApiDocGenericDelete(value: string, modelType?: Type) {
return applyDecorators(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { applyDecorators, Type } from '@nestjs/common';
import { ApiBadRequestResponse, ApiInternalServerErrorResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiUnauthorizedResponse } from '@nestjs/swagger';
import { ErrorResponse } from '@application/web/shared/response/error';
import { ErrorResponse } from '@entrypoints/web/shared/response/error';

export function ApiDocGenericGetAll(value: string, modelType: Type) {
return applyDecorators(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { applyDecorators, Type } from '@nestjs/common';
import { ApiBadRequestResponse, ApiInternalServerErrorResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiUnauthorizedResponse } from '@nestjs/swagger';
import { ErrorResponse } from '@application/web/shared/response/error';
import { ErrorResponse } from '@entrypoints/web/shared/response/error';

export function ApiDocGenericGetOne(value: string, modelType: Type) {
return applyDecorators(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { applyDecorators, Type } from '@nestjs/common';
import { ApiBadRequestResponse, ApiInternalServerErrorResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiUnauthorizedResponse } from '@nestjs/swagger';
import { ErrorResponse } from '@application/web/shared/response/error';
import { ErrorResponse } from '@entrypoints/web/shared/response/error';

export function ApiDocGenericGetPagination(value: string, modelType: Type) {
return applyDecorators(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { applyDecorators, Type } from '@nestjs/common';
import { ApiBadRequestResponse, ApiInternalServerErrorResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiUnauthorizedResponse } from '@nestjs/swagger';
import { ErrorResponse } from '@application/web/shared/response/error';
import { ErrorResponse } from '@entrypoints/web/shared/response/error';

export function ApiDocGenericGet(value: string, modelType: Type) {
return applyDecorators(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
ApiOperation,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { ErrorResponse } from '@application/web/shared/response/error';
import { ErrorResponse } from '@entrypoints/web/shared/response/error';

export function ApiDocGenericPatch(value: string, description?: string, modelType?: Type) {
return applyDecorators(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
ApiOperation,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { ErrorResponse } from '@application/web/shared/response/error';
import { ErrorResponse } from '@entrypoints/web/shared/response/error';

export function ApiDocGenericPost(value: string, modelType?: Type) {
return applyDecorators(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
ApiOperation,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { ErrorResponse } from '@application/web/shared/response/error';
import { ErrorResponse } from '@entrypoints/web/shared/response/error';

export function ApiDocGenericPut(value: string, modelType?: Type) {
return applyDecorators(
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { HealthController } from '@src/modules/web/rest/health';
import { HealthController } from '@src/entrypoints/web/rest/health';
import { TerminusModule } from '@nestjs/terminus';

@Module({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Controller, Get, HttpCode } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { HealthCheck, HealthCheckService, TypeOrmHealthIndicator } from '@nestjs/terminus';
import { ApiDocGenericGet } from '@src/modules/web/config/swagger/decorators';
import { HealthCheckResultResponse } from '@src/modules/web/rest/health/response';
import { HealthCheckResultMapper } from '@src/modules/web/rest/health/mappers';
import { ApiDocGenericGet } from '@src/entrypoints/web/config/swagger/decorators';
import { HealthCheckResultResponse } from '@src/entrypoints/web/rest/health/response';
import { HealthCheckResultMapper } from '@src/entrypoints/web/rest/health/mappers';

@ApiTags('Health')
@Controller('health')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { HealthCheckResultResponse } from '@src/modules/web/rest/health/response';
import { HealthCheckResultResponse } from '@src/entrypoints/web/rest/health/response';
import { HealthCheckResult } from '@nestjs/terminus';

export class HealthCheckResultMapper {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { OrderCreationRequest } from '@src/modules/web/rest/orders/request';
import { OrderCreateResponse } from '@src/modules/web/rest/orders/response';
import { OrderCreationRequest } from '@src/entrypoints/web/rest/orders/request';
import { OrderCreateResponse } from '@src/entrypoints/web/rest/orders/response';
import { OrderCoreEntity, OrderCreationCoreEntity } from '@core/domain/entities/orders';
import { Request } from 'express';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Request } from 'express';
import { OrderEndCoreEntity } from '@core/domain/entities/orders';
import { OrderEndRequest } from '@src/modules/web/rest/orders/request';
import { OrderEndRequest } from '@src/entrypoints/web/rest/orders/request';

export class OrderEndAppMapper {
public static fromApi(id: string, object: OrderEndRequest, { userId }: Request): OrderEndCoreEntity {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Request } from 'express';
import { OrderItemsResponse } from '@src/modules/web/rest/orders/response';
import { OrderItemsResponse } from '@src/entrypoints/web/rest/orders/response';
import { OrderCoreEntity, OrderFindByIdCoreEntity } from '@core/domain/entities/orders';

export class OrderFindByIdAppMapper {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Request } from 'express';
import { OrderPaginationCoreEntity, OrderQueryCoreEntity } from '@core/domain/entities/orders';
import { PaginationCoreEntity } from '@core/domain/entities/common';
import { OrderQueryRequest } from '@src/modules/web/rest/orders/request';
import { OrderPaginationResponse, OrderTotalHoursResponse } from '@src/modules/web/rest/orders/response';
import { PaginationResponse } from '@application/web/shared/response/pagination';
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';

export class OrderQueryAppMapper {
public static fromApi(object: OrderQueryRequest, { userId }: Request): OrderQueryCoreEntity {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Request } from 'express';
import { OrderQuantityStatusResponse } from '@src/modules/web/rest/orders/response';
import { OrderQueryQuantityStatusRequest } from '@src/modules/web/rest/orders/request';
import { OrderQuantityStatusResponse } from '@src/entrypoints/web/rest/orders/response';
import { OrderQueryQuantityStatusRequest } from '@src/entrypoints/web/rest/orders/request';
import { OrderQuantityStatusEntity, OrderQueryQuantityStatusCoreEntity } from '@core/domain/entities/orders';
import { PeriodGroup } from '@core/domain/enums';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Request } from 'express';
import { OrderStartCoreEntity } from '@core/domain/entities/orders';
import { OrderStartRequest } from '@src/modules/web/rest/orders/request';
import { OrderStartRequest } from '@src/entrypoints/web/rest/orders/request';

export class OrderStartAppMapper {
public static fromApi(id: string, object: OrderStartRequest, { userId }: Request): OrderStartCoreEntity {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Module, Provider } from '@nestjs/common';
import { RepositoryInfraModule } from '@infrastructure/repositories';
import { AuthAppModule } from '@application/web/shared/middleware/apikey';
import { OrdersController } from '@src/modules/web/rest/orders';
import { UsecaseProviderConfig } from '@src/modules/config/usecases/abstract';
import { AuthAppModule } from '@entrypoints/web/shared/middleware/apikey';
import { OrdersController } from '@src/entrypoints/web/rest/orders';
import { UsecaseProviderConfig } from '@src/entrypoints/config/usecases/abstract';
import { NotificationOrderRegisterUsecaseImpl } from '@core/usecases/notification/impl';
import { SqsProducerQueueProviderImpl } from '@infrastructure/queue/sqs/impl';
import { SqsQueueInfraModule } from '@infrastructure/queue/sqs';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { Body, Controller, Get, HttpCode, Inject, Param, Patch, Post, Query, Req, UseGuards } from '@nestjs/common';
import { Request } from 'express';
import { OrderCreationUseCase, OrderEndUsecase, OrderFindByIdUsecase, OrderQueryQuantityStatusUsecase, OrderQueryUsecase, OrderStartUsecase } from '@core/usecases/orders';
import { ApiKeyGuard } from '@application/web/shared/middleware/apikey';
import { OrderCreateResponse, OrderPaginationResponse, OrderQuantityStatusResponse, OrderItemsResponse } from '@src/modules/web/rest/orders/response';
import { OrderQueryRequest, OrderCreationRequest, OrderStartRequest, OrderEndRequest, OrderQueryQuantityStatusRequest } from '@src/modules/web/rest/orders/request';
import { ApiDocGenericGetAll, ApiDocGenericGetOne, ApiDocGenericGetPagination, ApiDocGenericPatch, ApiDocGenericPost } from '@src/modules/web/config/swagger/decorators';
import { ApiKeyGuard } from '@entrypoints/web/shared/middleware/apikey';
import { OrderCreateResponse, OrderPaginationResponse, OrderQuantityStatusResponse, OrderItemsResponse } from '@src/entrypoints/web/rest/orders/response';
import { OrderQueryRequest, OrderCreationRequest, OrderStartRequest, OrderEndRequest, OrderQueryQuantityStatusRequest } from '@src/entrypoints/web/rest/orders/request';
import { ApiDocGenericGetAll, ApiDocGenericGetOne, ApiDocGenericGetPagination, ApiDocGenericPatch, ApiDocGenericPost } from '@src/entrypoints/web/config/swagger/decorators';
import { ApiSecurity, ApiTags } from '@nestjs/swagger';
import { OrderCreationAppMapper, OrderEndAppMapper, OrderFindByIdAppMapper, OrderQueryAppMapper, OrderQueryQuantityStatusAppMapper, OrderStartAppMapper } from '@src/modules/web/rest/orders/mappers';
import {
OrderCreationAppMapper,
OrderEndAppMapper,
OrderFindByIdAppMapper,
OrderQueryAppMapper,
OrderQueryQuantityStatusAppMapper,
OrderStartAppMapper,
} from '@src/entrypoints/web/rest/orders/mappers';
import { OrderCreationUseCaseImpl, OrderEndUsecaseImpl, OrderFindByIdUsecaseImpl, OrderQueryQuantityStatusUsecaseImpl, OrderQueryUsecaseImpl, OrderStartUsecaseImpl } from '@core/usecases/orders/impl';

@ApiTags('Orders')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { OrderStatus } from '@core/domain/enums/order-status.enum';
import { OrderTotalHoursResponse } from '@src/modules/web/rest/orders/response/order-total-hours.response';
import { OrderTotalHoursResponse } from '@src/entrypoints/web/rest/orders/response/order-total-hours.response';

export class OrderItemsResponse {
@ApiProperty({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { PaginationResponse } from '@application/web/shared/response/pagination/pagination.response';
import { OrderItemsResponse } from '@src/modules/web/rest/orders/response/order-items.response';
import { OrderTotalHoursResponse } from '@src/modules/web/rest/orders/response/order-total-hours.response';
import { PaginationResponse } from '@entrypoints/web/shared/response/pagination/pagination.response';
import { OrderItemsResponse } from '@src/entrypoints/web/rest/orders/response/order-items.response';
import { OrderTotalHoursResponse } from '@src/entrypoints/web/rest/orders/response/order-total-hours.response';

export class OrderPaginationResponse {
@ApiProperty({ description: 'Show pagination.', type: PaginationResponse })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Module, Provider } from '@nestjs/common';
import { RepositoryInfraModule } from '@infrastructure/repositories';
import { CheckApiKeyUsecaseImpl } from '@core/usecases/auth/impl';
import { UsecaseProviderConfig } from '@application/config/usecases/abstract';
import { UsecaseProviderConfig } from '@entrypoints/config/usecases/abstract';
import { ApiKeyApplicationRepositoryProviderImpl } from '@infrastructure/repositories/auth/impl';

const usecaseProvidersConfig: Provider[] = [UsecaseProviderConfig(CheckApiKeyUsecaseImpl, [ApiKeyApplicationRepositoryProviderImpl])];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ValidationPipe } from '@nestjs/common';
import { ValidationError } from 'class-validator';
import { CustomValidationException } from '@application/web/shared/middleware/exceptions/index';
import { CustomValidationException } from '@entrypoints/web/shared/middleware/exceptions/index';

export class CustomValidationPipe extends ValidationPipe {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';
import { WebLoggerDto } from '@application/web/shared/middleware/logger';
import { WebLoggerDto } from '@entrypoints/web/shared/middleware/logger';
import { TracerContextAudit } from '@shared/audit';
import { v4 as uuid } from 'uuid';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { ErrorItemResponse } from '@application/web/shared/response/error/error-item.response';
import { ErrorItemResponse } from '@entrypoints/web/shared/response/error/error-item.response';

export class ErrorResponse {
@ApiProperty({ type: ErrorItemResponse, isArray: true })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { HealthAppModule } from '@src/modules/web/rest/health/health-app.module';
import { OrdersAppModule } from '@src/modules/web/rest/orders/orders-app.module';
import { LoggingMiddleware } from '@application/web/shared/middleware/logger/logging.middleware';
import { HealthAppModule } from '@src/entrypoints/web/rest/health/health-app.module';
import { OrdersAppModule } from '@src/entrypoints/web/rest/orders/orders-app.module';
import { LoggingMiddleware } from '@entrypoints/web/shared/middleware/logger/logging.middleware';

@Module({
imports: [HealthAppModule, OrdersAppModule],
Expand Down
Loading
Loading