feat: reconcile commerce payments

This commit is contained in:
Codex
2026-06-29 05:58:08 +08:00
parent ad8e32fa6b
commit 4c9f742b31
13 changed files with 1956 additions and 22 deletions

View File

@@ -8,7 +8,8 @@
"start": "node dist/apps/worker/src/index.js --loop",
"build": "node -e \"fs.rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",
"check": "tsc -p tsconfig.json --noEmit",
"crm:once": "tsx src/index.ts --once --job crm"
"crm:once": "tsx src/index.ts --once --job crm",
"commerce:once": "tsx src/index.ts --once --job commerce"
},
"dependencies": {
"pg": "^8.16.3"

View File

@@ -10,6 +10,9 @@ export interface WorkerConfig {
crmBackoffSeconds: number[];
crmRequestTimeoutMs: number;
crmAllowInsecureLocalhost: boolean;
commerceBatchSize: number;
commerceMinAgeSeconds: number;
commerceRequestTimeoutMs: number;
}
export const config: WorkerConfig = {
@@ -22,4 +25,7 @@ export const config: WorkerConfig = {
.filter((value: number) => Number.isFinite(value) && value > 0),
crmRequestTimeoutMs: envNumber('WORKER_CRM_REQUEST_TIMEOUT_MS', 10_000),
crmAllowInsecureLocalhost: envBoolean('WORKER_CRM_ALLOW_INSECURE_LOCALHOST', false),
commerceBatchSize: envNumber('WORKER_COMMERCE_BATCH_SIZE', 20),
commerceMinAgeSeconds: envNumber('WORKER_COMMERCE_MIN_AGE_SECONDS', 300),
commerceRequestTimeoutMs: envNumber('WORKER_COMMERCE_REQUEST_TIMEOUT_MS', 10_000),
};

View File

@@ -1,6 +1,7 @@
import { closePool } from './db.js';
import { config } from './config.js';
import { processCrmBatch } from './jobs/crm.js';
import { processCommerceBatch } from './jobs/commerce.js';
function hasArg(name: string) {
return process.argv.includes(name);
@@ -13,11 +14,21 @@ function argValue(name: string, fallback = '') {
async function runOnce() {
const job = argValue('--job', 'crm');
if (job !== 'crm') {
throw new Error(`Unsupported worker job: ${job}`);
if (job === 'crm') {
const result = await processCrmBatch();
console.log(`[worker] crm batch processed=${result.processed} sent=${result.sent} failed=${result.failed} retrying=${result.retrying} discarded=${result.discarded}`);
return;
}
const result = await processCrmBatch();
console.log(`[worker] crm batch processed=${result.processed} sent=${result.sent} failed=${result.failed} retrying=${result.retrying} discarded=${result.discarded}`);
if (job === 'commerce') {
const result = await processCommerceBatch();
console.log(
`[worker] commerce batch processed=${result.processed}`
+ ` payments=${result.payments.processed} paid=${result.payments.paid} pending=${result.payments.pending} closed=${result.payments.closed} failed=${result.payments.failed} paymentErrors=${result.payments.errors}`
+ ` refunds=${result.refunds.processed} succeeded=${result.refunds.succeeded} processing=${result.refunds.processing} refundFailed=${result.refunds.failed} refundErrors=${result.refunds.errors}`,
);
return;
}
throw new Error(`Unsupported worker job: ${job}`);
}
async function runLoop() {

File diff suppressed because it is too large Load Diff