Files
lislgosms/api/tools/verify-receipt-api.ts

57 lines
3.5 KiB
TypeScript

import { PrismaService } from '../src/prisma/prisma.service';
const prisma = new PrismaService();
const mode = process.argv[2];
const channelA = 'it-receipt-channel-a';
const channelB = 'it-receipt-channel-b';
const recordA = 'it-receipt-record-a';
const recordB = 'it-receipt-record-b';
async function cleanup() {
await prisma.smsReceiptRecord.deleteMany({ where: { messageRecordId: { in: [recordA, recordB] } } });
await prisma.smsSubmitRecord.deleteMany({ where: { messageRecordId: { in: [recordA, recordB] } } });
await prisma.smsMessageRecord.deleteMany({ where: { id: { in: [recordA, recordB] } } });
await prisma.smsChannel.deleteMany({ where: { id: { in: [channelA, channelB] } } });
}
async function main() {
if (mode === 'seed') {
await cleanup();
await prisma.smsChannel.createMany({ data: [
{ id: channelA, code: 'IT-RECEIPT-A', name: '回执验证通道A', gatewayHost: '127.0.0.1', gatewayPort: 17890, account: 'shared-account', passwordCipher: 'test-password-a', srcId: '10690000' },
{ id: channelB, code: 'IT-RECEIPT-B', name: '回执验证通道B', gatewayHost: '127.0.0.1', gatewayPort: 17891, account: 'shared-account', passwordCipher: 'test-password-b', srcId: '10690001' },
] });
await prisma.smsMessageRecord.createMany({ data: [
{ id: recordA, messageId: 'IT-RECEIPT-MSG-A', phoneNumber: '13800000001', content: '回执验证A', channelId: channelA, submitId: 'IT-RECEIPT-SUB-A', gatewayMessageId: 'SHARED-UPSTREAM-MSG-ID', status: 'submitted', submitStatus: 'accepted', submittedAt: new Date('2026-07-20T08:00:00.000Z') },
{ id: recordB, messageId: 'IT-RECEIPT-MSG-B', phoneNumber: '13800000002', content: '回执验证B', channelId: channelB, submitId: 'IT-RECEIPT-SUB-B', gatewayMessageId: 'SHARED-UPSTREAM-MSG-ID', status: 'submitted', submitStatus: 'accepted', submittedAt: new Date('2026-07-20T08:00:00.000Z') },
] });
await prisma.smsSubmitRecord.createMany({ data: [
{ id: 'it-receipt-submit-a', messageRecordId: recordA, channelId: channelA, submitId: 'IT-RECEIPT-SUB-A', gatewayMessageId: 'SHARED-UPSTREAM-MSG-ID', submitStatus: 'accepted', submittedAt: new Date('2026-07-20T08:00:00.000Z') },
{ id: 'it-receipt-submit-b', messageRecordId: recordB, channelId: channelB, submitId: 'IT-RECEIPT-SUB-B', gatewayMessageId: 'SHARED-UPSTREAM-MSG-ID', submitStatus: 'accepted', submittedAt: new Date('2026-07-20T08:00:00.000Z') },
] });
console.log(JSON.stringify({ ok: true, mode }));
return;
}
if (mode === 'verify') {
const [a, b, receipts] = await Promise.all([
prisma.smsMessageRecord.findUnique({ where: { id: recordA } }),
prisma.smsMessageRecord.findUnique({ where: { id: recordB } }),
prisma.smsReceiptRecord.findMany({ where: { messageRecordId: { in: [recordA, recordB] } } }),
]);
const evidence = { a, b, receiptCount: receipts.length, receipts };
const valid = a?.status === 'submitted' && a.receiptStatus === null
&& b?.status === 'delivered' && b.receiptStatus === 'delivered' && b.channelId === channelB
&& b.receiptRawStatus === 'DELIVRD' && receipts.length === 1 && receipts[0]?.messageRecordId === recordB;
console.log(JSON.stringify({ ok: valid, evidence }, (_key, value) => typeof value === 'bigint' ? value.toString() : value));
await cleanup();
if (!valid) throw new Error('receipt API identity assertion failed');
return;
}
throw new Error('usage: verify-receipt-api.ts seed|verify');
}
void main().finally(() => prisma.$disconnect()).catch((error) => {
console.error(error);
process.exitCode = 1;
});