A Ton Products API segue uma arquitetura em camadas baseada nos princípios de Clean Architecture e Domain-Driven Design, garantindo separação de responsabilidades e alta testabilidade.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Controller │────│ Service │────│ Repository │
│ │ │ │ │ │
│ • Validation │ │ • Business │ │ • Data Access │
│ • HTTP Handling │ │ Logic │ │ • ElectroDB │
│ • Auth Guards │ │ • Orchestration │ │ • DynamoDB │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
│ ┌─────────────────┐ │
└──────────────│ DTOs/Models │──────────────┘
│ │
│ • Interfaces │
│ • Validation │
│ • Type Safety │
└─────────────────┘
@Controller('products')
@UseGuards(JwtAuthGuard)
export class ProductsController {
async findAll(@Query() query: FindAllQueryDto) {
return await this.productsService.findAll(query);
}
}
@Injectable()
export class ProductsService {
constructor(private readonly repository: ProductsRepository) {}
async findAll(query: FindAllQueryDto): Promise<PaginatedResult> {
// Business logic here
return await this.repository.findAll(query);
}
}
@Injectable()
export class ProductsRepository {
async findAll(limit: number, nextKey?: string) {
return await Product.scan.go({ limit, cursor: nextKey });
}
}
@Module({
imports: [JwtModule, UsersModule],
controllers: [AuthController],
providers: [AuthService, EncryptionService],
exports: [AuthService],
})
export class AuthModule {}
@Module({
controllers: [ProductsController],
providers: [ProductsService, ProductsRepository],
exports: [ProductsService],
})
export class ProductsModule {}
@Module({
controllers: [],
providers: [UsersService, UsersRepository],
exports: [UsersService],
})
export class UsersModule {}
PK: USER#{userId}
SK: PROFILE
GSI1PK: EMAIL#{email}
GSI1SK: PROFILE
PK: PRODUCT#{productId}
SK: METADATA