feat(notifications): R8.1 Stringee SMS adapter + rate limiting (TEC-2764)
- Add NotificationChannelPort domain port for SMS/transactional channels. - Refactor StringeeSmsService to implement the port; routes OTP template keys through the tighter otp bucket and transactional keys through the wider bucket. - Add SmsRateLimiterService using a Redis sorted-set sliding window with per-minute + per-hour limits per phone; fails open on Redis errors. - Rate-limit violations throw DomainException(TOO_MANY_REQUESTS, 429) with retryAfterSeconds in the details payload. - Cover adapter + rate limiter with unit tests (22 specs); all 148 notifications tests still green. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -24,12 +24,14 @@ import { SubscriptionExpiringListener } from './application/listeners/subscripti
|
||||
import { SubscriptionRenewedListener } from './application/listeners/subscription-renewed.listener';
|
||||
import { UserKycUpdatedListener } from './application/listeners/user-kyc-updated.listener';
|
||||
import { UserRegisteredListener } from './application/listeners/user-registered.listener';
|
||||
import { SMS_NOTIFICATION_CHANNEL } from './domain/ports/notification-channel.port';
|
||||
import { NOTIFICATION_PREFERENCE_REPOSITORY } from './domain/repositories/notification-preference.repository';
|
||||
import { NOTIFICATION_REPOSITORY } from './domain/repositories/notification.repository';
|
||||
import { PrismaNotificationPreferenceRepository } from './infrastructure/repositories/prisma-notification-preference.repository';
|
||||
import { PrismaNotificationRepository } from './infrastructure/repositories/prisma-notification.repository';
|
||||
import { EmailService } from './infrastructure/services/email.service';
|
||||
import { FcmService } from './infrastructure/services/fcm.service';
|
||||
import { SmsRateLimiterService } from './infrastructure/services/sms-rate-limiter.service';
|
||||
import { StringeeSmsService } from './infrastructure/services/stringee-sms.service';
|
||||
import { TemplateService } from './infrastructure/services/template.service';
|
||||
import { ZaloOaService } from './infrastructure/services/zalo-oa.service';
|
||||
@@ -72,7 +74,9 @@ const EventListeners = [
|
||||
// Services
|
||||
EmailService,
|
||||
FcmService,
|
||||
SmsRateLimiterService,
|
||||
StringeeSmsService,
|
||||
{ provide: SMS_NOTIFICATION_CHANNEL, useExisting: StringeeSmsService },
|
||||
ZaloOaService,
|
||||
TemplateService,
|
||||
|
||||
@@ -85,6 +89,15 @@ const EventListeners = [
|
||||
// Event Listeners
|
||||
...EventListeners,
|
||||
],
|
||||
exports: [EmailService, FcmService, StringeeSmsService, ZaloOaService, TemplateService, NotificationsGateway],
|
||||
exports: [
|
||||
EmailService,
|
||||
FcmService,
|
||||
SmsRateLimiterService,
|
||||
StringeeSmsService,
|
||||
SMS_NOTIFICATION_CHANNEL,
|
||||
ZaloOaService,
|
||||
TemplateService,
|
||||
NotificationsGateway,
|
||||
],
|
||||
})
|
||||
export class NotificationsModule {}
|
||||
|
||||
Reference in New Issue
Block a user