feat(subscriptions): implement subscription quota enforcement
- Apply QuotaGuard + @RequireQuota to listing creation and analytics endpoints - Add QuotaExceeded domain event emitted when quota is exceeded - Create ListingCreatedUsageHandler to auto-meter usage on listing creation - Create QuotaExceededListener to send email notifications on quota exceeded - Add maxAnalyticsQueries and maxMediaUploads fields to Plan model - Add quota.exceeded email notification template - Define quota limits per plan tier in seed data - Add 15 unit tests covering guard, event handler, listener, and event Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -26,6 +26,8 @@ import { CurrentUser } from '@modules/auth/presentation/decorators/current-user.
|
||||
import { Roles } from '@modules/auth/presentation/decorators/roles.decorator';
|
||||
import { JwtAuthGuard } from '@modules/auth/presentation/guards/jwt-auth.guard';
|
||||
import { RolesGuard } from '@modules/auth/presentation/guards/roles.guard';
|
||||
import { QuotaGuard } from '@modules/subscriptions/presentation/guards/quota.guard';
|
||||
import { RequireQuota } from '@modules/subscriptions/presentation/decorators/require-quota.decorator';
|
||||
import { FileValidationPipe, type UploadedFile as ValidatedFile } from '@modules/shared/infrastructure/pipes/file-validation.pipe';
|
||||
import { CreateListingCommand } from '../../application/commands/create-listing/create-listing.command';
|
||||
import { type CreateListingResult } from '../../application/commands/create-listing/create-listing.handler';
|
||||
@@ -55,7 +57,9 @@ export class ListingsController {
|
||||
@ApiResponse({ status: 201, description: 'Listing created successfully' })
|
||||
@ApiResponse({ status: 400, description: 'Validation error' })
|
||||
@ApiResponse({ status: 401, description: 'Unauthorized' })
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiResponse({ status: 403, description: 'Quota exceeded' })
|
||||
@UseGuards(JwtAuthGuard, QuotaGuard)
|
||||
@RequireQuota('listings_created')
|
||||
@Post()
|
||||
async createListing(
|
||||
@Body() dto: CreateListingDto,
|
||||
|
||||
Reference in New Issue
Block a user