feat: 优化签名热力图与金额展示

This commit is contained in:
hectorzhao
2026-08-12 11:41:47 +08:00
parent e64b5e23fe
commit 0cd353450a
33 changed files with 344 additions and 121 deletions
@@ -0,0 +1,58 @@
#!/usr/bin/env node
require('../../api/node_modules/reflect-metadata');
const { PrismaService } = require('../../api/dist/prisma/prisma.service');
const { SignatureRetirementService } = require('../../api/dist/signature-retirement/signature-retirement.service');
const DAY_MS = 86_400_000;
const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
function parseDateKey(value, name) {
if (!DATE_PATTERN.test(value || '')) throw new Error(`${name} must use YYYY-MM-DD`);
const date = new Date(`${value}T00:00:00.000Z`);
if (Number.isNaN(date.getTime()) || date.toISOString().slice(0, 10) !== value) throw new Error(`${name} is invalid`);
return date;
}
function dateKey(date) {
return date.toISOString().slice(0, 10);
}
async function main() {
const [fromValue, toValue] = process.argv.slice(2);
const from = parseDateKey(fromValue, 'from');
const to = parseDateKey(toValue, 'to');
const days = Math.round((to.getTime() - from.getTime()) / DAY_MS) + 1;
if (days < 1 || days > 31) throw new Error('date range must contain 1 to 31 days');
const prisma = new PrismaService();
const service = new SignatureRetirementService(prisma);
await prisma.$connect();
try {
const before = await Promise.all([
prisma.signatureRetirementMessage.count(),
prisma.signatureRetirementWebhookDelivery.count(),
]);
for (let offset = 0; offset < days; offset += 1) {
const current = new Date(from.getTime() + offset * DAY_MS);
const result = await service.runDetection(dateKey(current));
process.stdout.write(`${dateKey(current)} ${JSON.stringify(result)}\n`);
}
const after = await Promise.all([
prisma.signatureRetirementMessage.count(),
prisma.signatureRetirementWebhookDelivery.count(),
]);
if (before[0] !== after[0] || before[1] !== after[1]) {
throw new Error(`notification side effect detected: messages ${before[0]} -> ${after[0]}, webhook deliveries ${before[1]} -> ${after[1]}`);
}
process.stdout.write(`notification side effects: none (messages=${after[0]}, webhookDeliveries=${after[1]})\n`);
} finally {
await prisma.$disconnect();
}
}
main().catch((error) => {
process.stderr.write(`${error.stack || error.message || error}\n`);
process.exitCode = 1;
});