Continue phase 2 device ops and dynamic QR lifecycle

This commit is contained in:
2026-05-26 21:25:07 +07:00
parent 5624b92872
commit e0b8f9af9a
22 changed files with 1050 additions and 92 deletions

37
dist/shared/services/dynamicQrExpiry.js vendored Normal file
View File

@ -0,0 +1,37 @@
import { listDueDynamicQrTransactions, toTransactionPayload, updateTransactionStatus } from "../store/transactionStore";
export async function expireDueDynamicQrTransactions(input) {
const due = await listDueDynamicQrTransactions(input?.limit || 100);
const expired = [];
const skipped = [];
const sweptAt = new Date().toISOString();
for (const tx of due) {
try {
const updated = await updateTransactionStatus(tx.id, "expired", {
source: input?.source || "system",
expired_at: tx.expired_at || sweptAt,
eventContext: {
reason: "dynamic_qr_expired",
expired_at: tx.expired_at,
swept_at: sweptAt,
request_id: input?.request_id
}
});
expired.push(toTransactionPayload(updated));
}
catch (error) {
skipped.push({
transaction_id: tx.id,
partner_reference: tx.partner_reference,
reason: error instanceof Error ? error.message : "UNKNOWN_ERROR"
});
}
}
return {
scanned: due.length,
expired_count: expired.length,
skipped_count: skipped.length,
swept_at: sweptAt,
expired,
skipped
};
}