@develit-services/bank 0.3.44 → 0.3.46

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.
Files changed (37) hide show
  1. package/dist/database/schema.cjs +4 -4
  2. package/dist/database/schema.d.cts +1 -1
  3. package/dist/database/schema.d.mts +1 -1
  4. package/dist/database/schema.d.ts +1 -1
  5. package/dist/database/schema.mjs +4 -4
  6. package/dist/export/worker.cjs +201 -183
  7. package/dist/export/worker.d.cts +51 -20
  8. package/dist/export/worker.d.mts +51 -20
  9. package/dist/export/worker.d.ts +51 -20
  10. package/dist/export/worker.mjs +161 -143
  11. package/dist/export/workflows.cjs +214 -18
  12. package/dist/export/workflows.mjs +207 -12
  13. package/dist/export/wrangler.d.cts +1 -2
  14. package/dist/export/wrangler.d.mts +1 -2
  15. package/dist/export/wrangler.d.ts +1 -2
  16. package/dist/shared/{bank.DFRS9oN5.mjs → bank.B1Gpn3ht.mjs} +9 -172
  17. package/dist/shared/{bank.D8wUOeOK.d.cts → bank.BEL1HIxZ.d.cts} +20 -1
  18. package/dist/shared/{bank.D8wUOeOK.d.mts → bank.BEL1HIxZ.d.mts} +20 -1
  19. package/dist/shared/{bank.D8wUOeOK.d.ts → bank.BEL1HIxZ.d.ts} +20 -1
  20. package/dist/shared/bank.BUEmFxS8.mjs +174 -0
  21. package/dist/shared/{bank.C335-raZ.cjs → bank.CPYfE-Ei.cjs} +9 -197
  22. package/dist/shared/bank.CpwLFudl.cjs +198 -0
  23. package/dist/shared/bank.D-3fzX63.mjs +170 -0
  24. package/dist/shared/bank.D0a-MZon.cjs +184 -0
  25. package/dist/shared/{bank.BchnXQDL.d.cts → bank.Dh_H_5rC.d.cts} +0 -1
  26. package/dist/shared/{bank.BchnXQDL.d.mts → bank.Dh_H_5rC.d.mts} +0 -1
  27. package/dist/shared/{bank.BchnXQDL.d.ts → bank.Dh_H_5rC.d.ts} +0 -1
  28. package/dist/types.cjs +14 -14
  29. package/dist/types.d.cts +3 -6
  30. package/dist/types.d.mts +3 -6
  31. package/dist/types.d.ts +3 -6
  32. package/dist/types.mjs +5 -5
  33. package/package.json +1 -1
  34. package/dist/shared/bank.Cj-oB02_.mjs +0 -392
  35. package/dist/shared/bank.ClRIj2Ma.cjs +0 -11
  36. package/dist/shared/bank.DhPfZ6b_.mjs +0 -9
  37. package/dist/shared/bank.DwyrLcKu.cjs +0 -402
@@ -1,19 +1,18 @@
1
1
  import { uuidv4, bankAccountMetadataSchema, workflowInstanceStatusSchema, develitWorker, createInternalError, first, action, service } from '@develit-io/backend-sdk';
2
2
  import { WorkerEntrypoint } from 'cloudflare:workers';
3
3
  import { drizzle } from 'drizzle-orm/d1';
4
- import { t as tables, c as INSTRUCTION_PRIORITIES, C as CHARGE_BEARERS, P as PAYMENT_TYPES, g as CONNECTOR_KEYS, B as BATCH_STATUSES, d as PAYMENT_STATUSES, e as PAYMENT_DIRECTIONS, i as accountInsertSchema, M as MockConnector, F as FinbricksConnector, E as ErsteConnector } from '../shared/bank.DFRS9oN5.mjs';
5
- import 'jose';
6
- import { CURRENCY_CODES } from '@develit-io/general-codes';
4
+ import { t as tables } from '../shared/bank.B1Gpn3ht.mjs';
7
5
  import { z } from 'zod';
8
- import { e as encrypt, P as PROCESS_BATCH_WORKFLOW_EVENTS, i as importAesKey, a as getCredentialsByAccountId, b as initiateConnector, u as upsertBatchCommand, c as createPaymentCommand, g as getAccountByIdQuery } from '../shared/bank.Cj-oB02_.mjs';
6
+ import { I as INSTRUCTION_PRIORITIES, C as CHARGE_BEARERS, P as PAYMENT_TYPES, d as CONNECTOR_KEYS, B as BATCH_STATUSES, a as PAYMENT_STATUSES, b as PAYMENT_DIRECTIONS, f as accountInsertSchema } from '../shared/bank.D-3fzX63.mjs';
7
+ import { CURRENCY_CODES } from '@develit-io/general-codes';
8
+ import 'date-fns';
9
9
  import { eq, inArray, and, sql, asc, desc, gte, lte } from 'drizzle-orm';
10
+ import 'jose';
11
+ import 'node:crypto';
12
+ import { f as encrypt, i as importAesKey, a as getCredentialsByAccountId, b as initiateConnector, u as upsertBatchCommand, d as getBatchByIdQuery, c as createPaymentCommand, g as getAccountByIdQuery } from '../shared/bank.BUEmFxS8.mjs';
10
13
  import 'drizzle-orm/sqlite-core';
11
- import 'date-fns';
12
- import 'drizzle-zod';
13
14
  import 'drizzle-orm/relations';
14
- import 'node:crypto';
15
- import 'cloudflare:workflows';
16
- import '../shared/bank.DhPfZ6b_.mjs';
15
+ import 'drizzle-zod';
17
16
 
18
17
  const upsertAccountCommand = (db, { account }) => {
19
18
  const id = account.id || uuidv4();
@@ -259,7 +258,9 @@ const getAuthUriInputSchema = z.object({
259
258
 
260
259
  const authorizeAccountInputSchema = z.object({
261
260
  ott: z.string(),
262
- urlParams: z.string()
261
+ urlParams: z.string(),
262
+ syncIntervalS: z.number().int().positive().optional(),
263
+ startSync: z.boolean().optional()
263
264
  });
264
265
 
265
266
  const simulateDepositInputSchema = z.object({
@@ -313,20 +314,12 @@ z.object({
313
314
  details: workflowInstanceStatusSchema
314
315
  });
315
316
 
316
- const batchAuthorizedEventPayloadSchema = z.object({
317
- authorized: z.boolean()
318
- });
319
- const processBatchEventInputSchema = z.discriminatedUnion("eventType", [
320
- z.object({
321
- batchId: z.uuid(),
322
- eventType: z.literal(PROCESS_BATCH_WORKFLOW_EVENTS.batchAuthorized),
323
- payload: batchAuthorizedEventPayloadSchema
324
- })
325
- // Future event types can be added here as new objects in the array
326
- ]);
317
+ const updateBatchStatusesInputSchema = z.object({
318
+ batchId: z.uuid().optional()
319
+ }).optional();
327
320
  z.object({
328
- success: z.boolean(),
329
- message: z.string()
321
+ processed: z.number(),
322
+ statusChanged: z.number()
330
323
  });
331
324
 
332
325
  const ALLOWED_PAYMENT_FILTERS = {
@@ -414,9 +407,13 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
414
407
  async _getAccounts() {
415
408
  return await getAllAccountsQuery(this.db);
416
409
  }
410
+ async _getConnectedAccounts() {
411
+ const accounts = await this._getAccounts();
412
+ return accounts.filter((acc) => acc.status !== "DISABLED");
413
+ }
417
414
  async _initiateBankConnector({
418
415
  connectorKey,
419
- withAuth
416
+ skipAccounts
420
417
  }) {
421
418
  if (!this.allowedProviders.includes(connectorKey)) {
422
419
  throw createInternalError(null, {
@@ -425,55 +422,45 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
425
422
  status: 400
426
423
  });
427
424
  }
428
- const accounts = await this._getAccounts();
429
- const accountsForConnector = accounts.filter(
430
- (acc) => acc.connectorKey === connectorKey && acc.status !== "DISABLED"
431
- );
432
- const encryptionKey = await importAesKey(this.env.ENCRYPTION_KEY);
433
- const accountsWithCredentials = await Promise.all(
434
- accountsForConnector.map(async (acc) => {
435
- const credentials = await getCredentialsByAccountId(
436
- this.db,
437
- encryptionKey,
438
- {
439
- accountId: acc.id
425
+ let connectedAccounts = [];
426
+ if (!skipAccounts) {
427
+ const encryptionKey = await importAesKey(this.env.ENCRYPTION_KEY);
428
+ const accounts = await this._getConnectedAccounts();
429
+ const accountsForConnector = accounts.filter(
430
+ (acc) => acc.connectorKey === connectorKey
431
+ );
432
+ connectedAccounts = await Promise.all(
433
+ accountsForConnector.map(async (acc) => {
434
+ const credentials = await getCredentialsByAccountId(
435
+ this.db,
436
+ encryptionKey,
437
+ {
438
+ accountId: acc.id
439
+ }
440
+ );
441
+ if (!credentials) {
442
+ throw createInternalError(null, {
443
+ message: `No credentials found for account ${acc.id}`,
444
+ code: "DB-B-001",
445
+ status: 404
446
+ });
440
447
  }
441
- );
442
- if (!credentials) {
443
- throw createInternalError(null, {
444
- message: `No credentials found for account ${acc.id}`,
445
- code: "DB-B-001",
446
- status: 404
447
- });
448
- }
449
- return {
450
- currency: acc.currency,
451
- iban: acc.iban,
452
- token: credentials.value,
453
- id: acc.id,
454
- connectorKey: acc.connectorKey
455
- };
456
- })
457
- );
458
- this.bankConnector = initiateConnector({
448
+ return {
449
+ currency: acc.currency,
450
+ iban: acc.iban,
451
+ token: credentials.value,
452
+ id: acc.id,
453
+ connectorKey: acc.connectorKey
454
+ };
455
+ })
456
+ );
457
+ }
458
+ const connector = initiateConnector({
459
459
  bank: connectorKey,
460
- connectedAccounts: accountsWithCredentials,
460
+ connectedAccounts,
461
461
  env: this.env
462
462
  });
463
- if (!withAuth) return;
464
- await this.bankConnector.authenticate();
465
- }
466
- _accountFetchInterval(connectorKey) {
467
- switch (connectorKey) {
468
- case "ERSTE":
469
- return ErsteConnector.FETCH_INTERVAL;
470
- case "FINBRICKS":
471
- return FinbricksConnector.FETCH_INTERVAL;
472
- case "MOCK":
473
- return MockConnector.FETCH_INTERVAL;
474
- default:
475
- return 0;
476
- }
463
+ return connector;
477
464
  }
478
465
  async getPayments(input) {
479
466
  return this.handleAction(
@@ -561,65 +548,97 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
561
548
  await this.updateBatchStatuses();
562
549
  }
563
550
  }
564
- async updateBatchStatuses() {
565
- const pendingBatches = await getAllPendingBatchesQuery(this.db);
566
- const uniqueConnectors = /* @__PURE__ */ new Set();
567
- const accounts = await this._getAccounts();
568
- for (const batch of pendingBatches) {
569
- const connectorKey = accounts.find(
570
- (acc) => acc.id === batch.accountId
571
- ).connectorKey;
572
- if (!uniqueConnectors.has(connectorKey)) {
573
- uniqueConnectors.add(connectorKey);
574
- }
551
+ async _resolveSingleBatch(batch, connector) {
552
+ const previousStatus = batch.status;
553
+ const currentStatus = await connector.getBatchStatus({
554
+ batchId: batch.id
555
+ });
556
+ let statusChanged = false;
557
+ if (previousStatus !== currentStatus) {
558
+ await upsertBatchCommand(this.db, {
559
+ batch: {
560
+ ...batch,
561
+ status: currentStatus
562
+ }
563
+ }).command.execute();
564
+ statusChanged = true;
575
565
  }
576
- const finalBatches = [];
577
- for (const connectorKey of uniqueConnectors) {
578
- const accs = accounts.filter((acc) => acc.connectorKey === connectorKey);
579
- const updatedBatches = await Promise.all(
580
- accs.map(async (account) => {
581
- const batch = pendingBatches.find((acc) => acc.id === account.id);
582
- const newStatus = await this.bankConnector.getBatchStatus({
583
- batchId: batch.id
566
+ return {
567
+ batchId: batch.id,
568
+ previousStatus,
569
+ currentStatus,
570
+ statusChanged
571
+ // eventSent,
572
+ };
573
+ }
574
+ async updateBatchStatuses(input) {
575
+ return this.handleAction(
576
+ { data: input, schema: updateBatchStatusesInputSchema },
577
+ { successMessage: "Batch statuses updated" },
578
+ async (validatedInput) => {
579
+ let pendingBatches;
580
+ if (validatedInput?.batchId) {
581
+ const batch = await getBatchByIdQuery(this.db, {
582
+ batchId: validatedInput.batchId
584
583
  });
585
- return {
586
- ...batch,
587
- status: newStatus
588
- };
589
- })
590
- );
591
- finalBatches.push(...updatedBatches);
592
- }
593
- const updateBatchesCommands = finalBatches.map((batch) => {
594
- const { command } = upsertBatchCommand(this.db, {
595
- batch: {
596
- ...batch
584
+ if (!batch) {
585
+ throw createInternalError(null, {
586
+ message: `Batch not found: ${validatedInput.batchId}`,
587
+ code: "DB-B-007",
588
+ status: 404
589
+ });
590
+ }
591
+ pendingBatches = [batch];
592
+ } else {
593
+ pendingBatches = await getAllPendingBatchesQuery(this.db);
597
594
  }
598
- });
599
- return command;
600
- });
601
- await this.db.batch([
602
- updateBatchesCommands[0],
603
- ...updateBatchesCommands.slice(1)
604
- ]);
605
- for (const batch of finalBatches) {
606
- try {
607
- const instance = await this.env.PROCESS_BATCH_WORKFLOW.get(batch.id);
608
- if (batch.status === "SIGNED" || batch.status === "SIGNATURE_FAILED") {
609
- instance.sendEvent({
610
- type: PROCESS_BATCH_WORKFLOW_EVENTS.batchAuthorized,
611
- payload: {
612
- authorized: batch.status === "SIGNED"
613
- }
595
+ const accounts = await this._getConnectedAccounts();
596
+ console.log(`Processing ${pendingBatches.length} pending batche(s)`);
597
+ const batchesByConnector = /* @__PURE__ */ new Map();
598
+ for (const batch of pendingBatches) {
599
+ const account = accounts.find((acc) => acc.id === batch.accountId);
600
+ if (!account) {
601
+ this.logError({
602
+ message: `Account not found for batch ${batch.id}, skipping`
603
+ });
604
+ await upsertBatchCommand(this.db, {
605
+ batch: {
606
+ ...batch,
607
+ status: "FAILED",
608
+ statusReason: "ACCOUNT_NOT_FOUND"
609
+ }
610
+ }).command.execute();
611
+ continue;
612
+ }
613
+ const batches = batchesByConnector.get(account.connectorKey) || [];
614
+ batches.push(batch);
615
+ batchesByConnector.set(account.connectorKey, batches);
616
+ }
617
+ const allResults = [];
618
+ for (const [connectorKey, batches] of batchesByConnector) {
619
+ console.log(
620
+ `Initializing ${connectorKey} connector for ${batches.length} batches`
621
+ );
622
+ const connector = await this._initiateBankConnector({
623
+ connectorKey
614
624
  });
625
+ for (const batch of batches) {
626
+ const result = await this._resolveSingleBatch(batch, connector);
627
+ if (result) {
628
+ allResults.push(result);
629
+ }
630
+ }
615
631
  }
616
- } catch (_) {
632
+ const changedCount = allResults.filter((r) => r.statusChanged).length;
617
633
  console.log(
618
- `No workflow instance found for batch ${batch.id}, skipping.`
634
+ `Batch update completed: ${changedCount} status change(s) detected`
619
635
  );
636
+ return {
637
+ processed: allResults.length,
638
+ statusChanged: changedCount
639
+ };
620
640
  }
621
- }
622
- console.log("Batch update completed");
641
+ );
623
642
  }
624
643
  async addPaymentsToBatch({
625
644
  paymentsToBatch
@@ -762,23 +781,6 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
762
781
  }
763
782
  );
764
783
  }
765
- async processBatchEvent(input) {
766
- return this.handleAction(
767
- { data: input, schema: processBatchEventInputSchema },
768
- { successMessage: "Event sent to batch processing workflow" },
769
- async ({ batchId, eventType, payload }) => {
770
- const instance = await this.env.PROCESS_BATCH_WORKFLOW.get(batchId);
771
- await instance.sendEvent({
772
- type: eventType,
773
- payload
774
- });
775
- return {
776
- success: true,
777
- message: `Event '${eventType}' sent to workflow instance ${batchId}`
778
- };
779
- }
780
- );
781
- }
782
784
  async queue(b) {
783
785
  await this.handleAction(
784
786
  null,
@@ -797,7 +799,10 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
797
799
  { data: input, schema: getAuthUriInputSchema },
798
800
  { successMessage: "Auth URI obtained." },
799
801
  async ({ connectorKey }) => {
800
- await this._initiateBankConnector({ connectorKey, withAuth: false });
802
+ const connector = await this._initiateBankConnector({
803
+ connectorKey,
804
+ skipAccounts: true
805
+ });
801
806
  const ott = uuidv4();
802
807
  const { command: createOneTimeToken } = createOneTimeTokenCommand(
803
808
  this.db,
@@ -808,7 +813,7 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
808
813
  }
809
814
  );
810
815
  await createOneTimeToken.execute();
811
- const uri = await this.bankConnector.getAuthUri({ ott });
816
+ const uri = await connector.getAuthUri({ ott });
812
817
  return { uri };
813
818
  }
814
819
  );
@@ -817,7 +822,7 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
817
822
  return this.handleAction(
818
823
  { data: input, schema: authorizeAccountInputSchema },
819
824
  { successMessage: "Erste code saved." },
820
- async ({ ott, urlParams }) => {
825
+ async ({ ott, urlParams, syncIntervalS, startSync }) => {
821
826
  const ottRow = await getOttQuery(this.db, {
822
827
  ott
823
828
  });
@@ -835,10 +840,10 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
835
840
  status: 400
836
841
  });
837
842
  }
838
- await this._initiateBankConnector({
843
+ const connector = await this._initiateBankConnector({
839
844
  connectorKey: ottRow.refId
840
845
  });
841
- const { credentials, accounts } = await this.bankConnector.authorizeAccount({
846
+ const { credentials, accounts } = await connector.authorizeAccount({
842
847
  urlParams
843
848
  });
844
849
  console.log("Bank connector initiated");
@@ -847,7 +852,7 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
847
852
  );
848
853
  const upsertAccounts = accounts.map(
849
854
  (acc) => upsertAccountCommand(this.db, {
850
- account: acc
855
+ account: syncIntervalS ? { ...acc, syncIntervalS } : acc
851
856
  }).command
852
857
  );
853
858
  const deleteCredentials = alreadyExistingAccounts.map(
@@ -879,6 +884,19 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
879
884
  code: "DB-B-003",
880
885
  status: 404
881
886
  });
887
+ if (startSync) {
888
+ for (const account of fetchedAccounts) {
889
+ const { error } = await this.syncAccount({
890
+ accountId: account.id
891
+ });
892
+ if (error) {
893
+ this.logError({
894
+ message: `Failed to auto-start sync workflow for account ${account.id}`,
895
+ error
896
+ });
897
+ }
898
+ }
899
+ }
882
900
  return {
883
901
  accounts: fetchedAccounts
884
902
  };