feat: add application interface controls
This commit is contained in:
@@ -11,6 +11,8 @@ export interface CreateSmsApplicationDto {
|
||||
cmppAccount?: string;
|
||||
cmppEnterpriseCode?: string;
|
||||
passwordCipher?: string;
|
||||
interfaceEnabled?: boolean;
|
||||
interfaceType?: string;
|
||||
cmppMaxConnections?: number;
|
||||
cmppWindowSize?: number;
|
||||
dailyLimit?: number;
|
||||
@@ -64,6 +66,10 @@ export interface CreateSmsTemplateDto {
|
||||
variables?: Array<{ name: string; example?: string; required?: boolean }>;
|
||||
}
|
||||
|
||||
export interface CreateSmsTemplateOptions {
|
||||
initialAuditStatus?: string;
|
||||
}
|
||||
|
||||
export type UpdateSmsTemplateDto = Partial<Omit<CreateSmsTemplateDto, 'tenantId'>> & {
|
||||
auditStatus?: string;
|
||||
};
|
||||
@@ -93,6 +99,8 @@ export interface ApplicationListQuery {
|
||||
|
||||
const APPLICATION_QUEUE_PRIORITIES = ['normal', 'priority'] as const;
|
||||
type ApplicationQueuePriority = typeof APPLICATION_QUEUE_PRIORITIES[number];
|
||||
const APPLICATION_INTERFACE_TYPES = ['cmpp20'] as const;
|
||||
type ApplicationInterfaceType = typeof APPLICATION_INTERFACE_TYPES[number];
|
||||
|
||||
@Injectable()
|
||||
export class SmsConfigService {
|
||||
@@ -158,6 +166,7 @@ export class SmsConfigService {
|
||||
async createApplication(data: CreateSmsApplicationDto) {
|
||||
const secret = normalizeApplicationPassword(data.passwordCipher);
|
||||
const queuePriority = normalizeApplicationQueuePriority(data.queuePriority);
|
||||
const interfaceType = normalizeApplicationInterfaceType(data.interfaceType);
|
||||
const cmppAccount = data.cmppAccount ? await this.validateAndReserveCmppAccount(data.cmppAccount) : await this.generateCmppAccount();
|
||||
const cmppEnterpriseCode = await this.resolveCmppEnterpriseCode(data.cmppEnterpriseCode, data.tenantId);
|
||||
return this.prisma.smsApplication.create({
|
||||
@@ -169,6 +178,8 @@ export class SmsConfigService {
|
||||
cmppAccount,
|
||||
cmppEnterpriseCode,
|
||||
secretHash: secret,
|
||||
interfaceEnabled: data.interfaceEnabled ?? true,
|
||||
interfaceType,
|
||||
cmppMaxConnections: getPositiveInteger(data.cmppMaxConnections, 1, 'cmppMaxConnections'),
|
||||
cmppWindowSize: getPositiveInteger(data.cmppWindowSize, 16, 'cmppWindowSize'),
|
||||
dailyLimit: data.dailyLimit,
|
||||
@@ -198,6 +209,9 @@ export class SmsConfigService {
|
||||
const cmppEnterpriseCode = data.cmppEnterpriseCode === undefined
|
||||
? undefined
|
||||
: normalizeEnterpriseCode(data.cmppEnterpriseCode);
|
||||
const interfaceType = data.interfaceType === undefined
|
||||
? undefined
|
||||
: normalizeApplicationInterfaceType(data.interfaceType);
|
||||
const secretHash = data.passwordCipher === undefined
|
||||
? undefined
|
||||
: normalizeApplicationPassword(data.passwordCipher);
|
||||
@@ -215,6 +229,8 @@ export class SmsConfigService {
|
||||
cmppAccount,
|
||||
cmppEnterpriseCode,
|
||||
secretHash,
|
||||
interfaceEnabled: data.interfaceEnabled,
|
||||
interfaceType,
|
||||
cmppMaxConnections: data.cmppMaxConnections === undefined ? undefined : getPositiveInteger(data.cmppMaxConnections, 1, 'cmppMaxConnections'),
|
||||
cmppWindowSize: data.cmppWindowSize === undefined ? undefined : getPositiveInteger(data.cmppWindowSize, 16, 'cmppWindowSize'),
|
||||
dailyLimit: data.dailyLimit,
|
||||
@@ -373,10 +389,12 @@ export class SmsConfigService {
|
||||
account: application.cmppAccount,
|
||||
passwordCipher: application.secretHash,
|
||||
srcId: channel?.srcId ?? '',
|
||||
interfaceEnabled: application.interfaceEnabled,
|
||||
interfaceType: application.interfaceType,
|
||||
maxConnections: application.cmppMaxConnections,
|
||||
heartbeatSeconds: 30,
|
||||
windowSize: application.cmppWindowSize,
|
||||
protocolVersion: channel?.cmppVersion ?? '3.0',
|
||||
protocolVersion: application.interfaceType === 'cmpp20' ? 'CMPP2.0' : application.interfaceType,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -542,7 +560,7 @@ export class SmsConfigService {
|
||||
});
|
||||
}
|
||||
|
||||
createTemplate(data: CreateSmsTemplateDto) {
|
||||
createTemplate(data: CreateSmsTemplateDto, options: CreateSmsTemplateOptions = {}) {
|
||||
return this.prisma.smsTemplate.create({
|
||||
data: {
|
||||
tenantId: data.tenantId,
|
||||
@@ -551,6 +569,7 @@ export class SmsConfigService {
|
||||
name: data.name,
|
||||
content: data.content,
|
||||
category: data.category,
|
||||
auditStatus: options.initialAuditStatus,
|
||||
billingUnits: estimateBillingUnits(data.content),
|
||||
variables: {
|
||||
create: (data.variables ?? inferTemplateVariables(data.content)).map((variable: TemplateVariableInput) => ({
|
||||
@@ -833,6 +852,14 @@ function normalizeApplicationQueuePriority(value?: string): ApplicationQueuePrio
|
||||
return queuePriority as ApplicationQueuePriority;
|
||||
}
|
||||
|
||||
function normalizeApplicationInterfaceType(value?: string): ApplicationInterfaceType {
|
||||
const interfaceType = value ?? 'cmpp20';
|
||||
if (!APPLICATION_INTERFACE_TYPES.includes(interfaceType as ApplicationInterfaceType)) {
|
||||
throw new BadRequestException('interfaceType only supports cmpp20; HTTP interface is not available yet');
|
||||
}
|
||||
return interfaceType as ApplicationInterfaceType;
|
||||
}
|
||||
|
||||
function getPositiveInteger(value: number | undefined, fallback: number, fieldName: string) {
|
||||
if (value === undefined || value === null) {
|
||||
return fallback;
|
||||
|
||||
Reference in New Issue
Block a user