@festapp/banksync 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2793,6 +2793,7 @@ function yyyyMmDdDaysAgo(days) {
2793
2793
  var API_POLL_CRON = "* * * * *";
2794
2794
  var MAINTENANCE_CRON = "15 3 * * *";
2795
2795
  var API_SYNC_LEASE_S = 30;
2796
+ var RECONCILIATION_INTERVAL_MINUTES = 5;
2796
2797
  function scheduledCron(event) {
2797
2798
  const cron = event.cron;
2798
2799
  return typeof cron === "string" ? cron : null;
@@ -2805,6 +2806,14 @@ function shouldRunMaintenance(event) {
2805
2806
  const cron = scheduledCron(event);
2806
2807
  return cron === null || cron === MAINTENANCE_CRON;
2807
2808
  }
2809
+ function shouldRunReconciliation(event) {
2810
+ const cron = scheduledCron(event);
2811
+ if (cron === null) return true;
2812
+ if (cron !== API_POLL_CRON) return false;
2813
+ const scheduledTime = event.scheduledTime;
2814
+ if (typeof scheduledTime !== "number" || !Number.isFinite(scheduledTime)) return true;
2815
+ return Math.floor(scheduledTime / 6e4) % RECONCILIATION_INTERVAL_MINUTES === 0;
2816
+ }
2808
2817
  function apiSyncDelayS(env) {
2809
2818
  return Math.max(30, apiMinIntervalS(env));
2810
2819
  }
@@ -3672,6 +3681,7 @@ var cloudflare_default = {
3672
3681
  await assertSchemaVersion(env.DB);
3673
3682
  const runPolling = shouldRunApiPolling(event);
3674
3683
  const runMaintenance = shouldRunMaintenance(event);
3684
+ const runReconciliation = runPolling && shouldRunReconciliation(event);
3675
3685
  if (runMaintenance) {
3676
3686
  try {
3677
3687
  const result = await pruneRetention(env.DB);
@@ -3696,6 +3706,8 @@ var cloudflare_default = {
3696
3706
  } catch (err) {
3697
3707
  logError("outbox_process_failed", err, {});
3698
3708
  }
3709
+ }
3710
+ if (runReconciliation) {
3699
3711
  try {
3700
3712
  const swept = await createWebhookDeliveryCoordinator(env).sweep();
3701
3713
  if (swept.created > 0 || swept.considered > 0) {
@@ -3723,7 +3735,7 @@ var cloudflare_default = {
3723
3735
  logError("api_sync_tick_failed", err, {});
3724
3736
  }
3725
3737
  }
3726
- if (runPolling && env.ALERT_WEBHOOK_URL) {
3738
+ if (runReconciliation && env.ALERT_WEBHOOK_URL) {
3727
3739
  try {
3728
3740
  const alert = await runAlerterTick(env.DB, {
3729
3741
  webhookUrl: env.ALERT_WEBHOOK_URL,
@@ -3736,7 +3748,7 @@ var cloudflare_default = {
3736
3748
  logError("alerter_tick_failed", err, {});
3737
3749
  }
3738
3750
  }
3739
- if (runPolling && env.ALERT_WEBHOOK_URL) {
3751
+ if (runReconciliation && env.ALERT_WEBHOOK_URL) {
3740
3752
  try {
3741
3753
  const service = _nullishCoalesce(env.BANKSYNC_DOMAIN, () => ( "banksync"));
3742
3754
  await detectStalledIncidents(env.DB, service);
@@ -2793,6 +2793,7 @@ function yyyyMmDdDaysAgo(days) {
2793
2793
  var API_POLL_CRON = "* * * * *";
2794
2794
  var MAINTENANCE_CRON = "15 3 * * *";
2795
2795
  var API_SYNC_LEASE_S = 30;
2796
+ var RECONCILIATION_INTERVAL_MINUTES = 5;
2796
2797
  function scheduledCron(event) {
2797
2798
  const cron = event.cron;
2798
2799
  return typeof cron === "string" ? cron : null;
@@ -2805,6 +2806,14 @@ function shouldRunMaintenance(event) {
2805
2806
  const cron = scheduledCron(event);
2806
2807
  return cron === null || cron === MAINTENANCE_CRON;
2807
2808
  }
2809
+ function shouldRunReconciliation(event) {
2810
+ const cron = scheduledCron(event);
2811
+ if (cron === null) return true;
2812
+ if (cron !== API_POLL_CRON) return false;
2813
+ const scheduledTime = event.scheduledTime;
2814
+ if (typeof scheduledTime !== "number" || !Number.isFinite(scheduledTime)) return true;
2815
+ return Math.floor(scheduledTime / 6e4) % RECONCILIATION_INTERVAL_MINUTES === 0;
2816
+ }
2808
2817
  function apiSyncDelayS(env) {
2809
2818
  return Math.max(30, apiMinIntervalS(env));
2810
2819
  }
@@ -3672,6 +3681,7 @@ var cloudflare_default = {
3672
3681
  await assertSchemaVersion(env.DB);
3673
3682
  const runPolling = shouldRunApiPolling(event);
3674
3683
  const runMaintenance = shouldRunMaintenance(event);
3684
+ const runReconciliation = runPolling && shouldRunReconciliation(event);
3675
3685
  if (runMaintenance) {
3676
3686
  try {
3677
3687
  const result = await pruneRetention(env.DB);
@@ -3696,6 +3706,8 @@ var cloudflare_default = {
3696
3706
  } catch (err) {
3697
3707
  logError("outbox_process_failed", err, {});
3698
3708
  }
3709
+ }
3710
+ if (runReconciliation) {
3699
3711
  try {
3700
3712
  const swept = await createWebhookDeliveryCoordinator(env).sweep();
3701
3713
  if (swept.created > 0 || swept.considered > 0) {
@@ -3723,7 +3735,7 @@ var cloudflare_default = {
3723
3735
  logError("api_sync_tick_failed", err, {});
3724
3736
  }
3725
3737
  }
3726
- if (runPolling && env.ALERT_WEBHOOK_URL) {
3738
+ if (runReconciliation && env.ALERT_WEBHOOK_URL) {
3727
3739
  try {
3728
3740
  const alert = await runAlerterTick(env.DB, {
3729
3741
  webhookUrl: env.ALERT_WEBHOOK_URL,
@@ -3736,7 +3748,7 @@ var cloudflare_default = {
3736
3748
  logError("alerter_tick_failed", err, {});
3737
3749
  }
3738
3750
  }
3739
- if (runPolling && env.ALERT_WEBHOOK_URL) {
3751
+ if (runReconciliation && env.ALERT_WEBHOOK_URL) {
3740
3752
  try {
3741
3753
  const service = env.BANKSYNC_DOMAIN ?? "banksync";
3742
3754
  await detectStalledIncidents(env.DB, service);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@festapp/banksync",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Bank transaction ingestion for Cloudflare Workers: Czech bank email and Fio API parsing, durable deduplication, and signed webhook delivery.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.24.0",
@@ -44,19 +44,19 @@
44
44
  "prepack": "pnpm build"
45
45
  },
46
46
  "dependencies": {
47
- "postal-mime": "^2.7.5",
48
- "ulid": "^2.3.0",
47
+ "postal-mime": "^3.0.0",
48
+ "ulid": "^3.0.2",
49
49
  "valibot": "^1.2.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@cloudflare/workers-types": "^5.20260730.1",
53
53
  "@types/better-sqlite3": "^7.6.13",
54
- "better-sqlite3": "^12.11.1",
54
+ "better-sqlite3": "^13.0.3",
55
55
  "tsup": "^8.5.0",
56
56
  "typescript": "^5.9.3",
57
- "vite": "^6.4.2",
57
+ "vite": "^8.2.2",
58
58
  "vitest": "^4.1.5",
59
- "wrangler": "4.118.0"
59
+ "wrangler": "4.127.1"
60
60
  },
61
61
  "engines": {
62
62
  "node": ">=20"