feat: add application queue priority routing

This commit is contained in:
hectorzhao
2026-07-07 14:49:10 +08:00
parent 72f2c010ce
commit 4c8f7dd73f
17 changed files with 392 additions and 46 deletions
+18
View File
@@ -10,6 +10,7 @@ export interface CreateSmsApplicationDto {
callbackUrl?: string;
dailyLimit?: number;
customerUnitPrice?: number;
queuePriority?: string;
maxPhonesPerTask?: number;
templateMismatchMode?: string;
ipAllowlist?: string[];
@@ -85,6 +86,9 @@ export interface ApplicationListQuery {
includeConnections?: boolean;
}
const APPLICATION_QUEUE_PRIORITIES = ['normal', 'priority'] as const;
type ApplicationQueuePriority = typeof APPLICATION_QUEUE_PRIORITIES[number];
@Injectable()
export class SmsConfigService {
constructor(private readonly prisma: PrismaService) {}
@@ -148,6 +152,7 @@ export class SmsConfigService {
createApplication(data: CreateSmsApplicationDto) {
const secret = randomBytes(24).toString('hex');
const queuePriority = normalizeApplicationQueuePriority(data.queuePriority);
return this.prisma.smsApplication.create({
data: {
tenantId: data.tenantId,
@@ -157,6 +162,7 @@ export class SmsConfigService {
secretHash: hashSecret(secret),
dailyLimit: data.dailyLimit,
customerUnitPrice: data.customerUnitPrice ?? 0,
queuePriority,
maxPhonesPerTask: data.maxPhonesPerTask ?? 1000000,
templateMismatchMode: data.templateMismatchMode ?? 'reject',
ipAllowlist: {
@@ -172,6 +178,9 @@ export class SmsConfigService {
if (!application) {
throw new NotFoundException('Application not found');
}
const queuePriority = data.queuePriority === undefined
? undefined
: normalizeApplicationQueuePriority(data.queuePriority);
return this.prisma.$transaction(async (tx) => {
if (data.ipAllowlist) {
@@ -185,6 +194,7 @@ export class SmsConfigService {
callbackUrl: data.callbackUrl,
dailyLimit: data.dailyLimit,
customerUnitPrice: data.customerUnitPrice,
queuePriority,
maxPhonesPerTask: data.maxPhonesPerTask,
templateMismatchMode: data.templateMismatchMode,
status: data.status,
@@ -738,6 +748,14 @@ function startOfToday() {
return date;
}
function normalizeApplicationQueuePriority(value?: string): ApplicationQueuePriority {
const queuePriority = value ?? 'normal';
if (!APPLICATION_QUEUE_PRIORITIES.includes(queuePriority as ApplicationQueuePriority)) {
throw new BadRequestException('queuePriority must be normal or priority');
}
return queuePriority as ApplicationQueuePriority;
}
function normalizeApplicationCmppStatus(connections: Array<{ status: string; currentConnections: number }>, applicationStatus: string) {
if (applicationStatus !== 'active') {
return 'inactive';