@develit-services/bank 0.8.7 → 0.8.9

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 (38) hide show
  1. package/dist/database/schema.cjs +1 -1
  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 +1 -1
  6. package/dist/export/worker.cjs +237 -277
  7. package/dist/export/worker.d.cts +25 -20
  8. package/dist/export/worker.d.mts +25 -20
  9. package/dist/export/worker.d.ts +25 -20
  10. package/dist/export/worker.mjs +238 -278
  11. package/dist/export/workflows.cjs +58 -96
  12. package/dist/export/workflows.mjs +59 -97
  13. package/dist/export/wrangler.d.cts +2 -1
  14. package/dist/export/wrangler.d.mts +2 -1
  15. package/dist/export/wrangler.d.ts +2 -1
  16. package/dist/shared/{bank.DEmzZGZW.mjs → bank.B5bZRvgq.mjs} +2 -5
  17. package/dist/shared/{bank.CQBfbG8u.d.cts → bank.BP_3WMIF.d.cts} +1 -0
  18. package/dist/shared/{bank.CQBfbG8u.d.mts → bank.BP_3WMIF.d.mts} +1 -0
  19. package/dist/shared/{bank.CQBfbG8u.d.ts → bank.BP_3WMIF.d.ts} +1 -0
  20. package/dist/shared/{bank.CA5ytXxp.mjs → bank.BoZtXQpG.mjs} +1 -1
  21. package/dist/shared/{bank.D1jqaHaF.mjs → bank.BtszLapg.mjs} +128 -20
  22. package/dist/shared/{bank.C0UN6luZ.mjs → bank.C6jjS1Pl.mjs} +0 -2
  23. package/dist/shared/{bank.BYRq3yJf.d.ts → bank.CHQ3VSEh.d.ts} +1 -1
  24. package/dist/shared/{bank.DwyCCyd0.cjs → bank.CtnsGHM8.cjs} +128 -20
  25. package/dist/shared/{bank.CO89tR9U.d.cts → bank.CwuH4spB.d.mts} +1 -1
  26. package/dist/shared/{bank.62VzK9Aj.cjs → bank.DJnDSYqE.cjs} +1 -1
  27. package/dist/shared/{bank.Dm8GHThw.cjs → bank.DT6bg8k5.cjs} +2 -5
  28. package/dist/shared/{bank.BS7fFjGA.cjs → bank.JVlyPAAb.cjs} +0 -2
  29. package/dist/shared/{bank.Cns5ss41.d.cts → bank.pgyk4j94.d.cts} +12 -25
  30. package/dist/shared/{bank.Cns5ss41.d.mts → bank.pgyk4j94.d.mts} +12 -25
  31. package/dist/shared/{bank.Cns5ss41.d.ts → bank.pgyk4j94.d.ts} +12 -25
  32. package/dist/shared/{bank.CreoSb2d.d.mts → bank.vPWD7Ce4.d.cts} +1 -1
  33. package/dist/types.cjs +3 -3
  34. package/dist/types.d.cts +10 -6
  35. package/dist/types.d.mts +10 -6
  36. package/dist/types.d.ts +10 -6
  37. package/dist/types.mjs +3 -3
  38. package/package.json +1 -1
@@ -1,18 +1,18 @@
1
1
  import { uuidv4, first, buildMultiFilterConditions as buildMultiFilterConditions$1, bankAccountMetadataSchema, workflowInstanceStatusSchema, develitWorker, createInternalError, action, service } from '@develit-io/backend-sdk';
2
- import { t as tables, h as encrypt, d as createCredentialsResolver, u as upsertBatchCommand, a as getPaymentRequestsByBatchIdQuery, e as updatePaymentRequestStatusCommand, g as getBatchByIdQuery, i as importAesKey, f as createPaymentCommand, b as getAccountByIdQuery } from '../shared/bank.DEmzZGZW.mjs';
2
+ import { t as tables, h as encrypt, d as createCredentialsResolver, u as upsertBatchCommand, a as getPaymentRequestsByBatchIdQuery, e as updatePaymentRequestStatusCommand, g as getBatchByIdQuery, i as importAesKey, f as createPaymentCommand, b as getAccountByIdQuery } from '../shared/bank.B5bZRvgq.mjs';
3
3
  import { WorkerEntrypoint } from 'cloudflare:workers';
4
4
  import { drizzle } from 'drizzle-orm/d1';
5
- import { j as initiateConnector, m as mapFinbricksTransactionStatus, g as toIncomingPayment, d as assignAccount, t as toBatchedPayment, a as FinbricksClient, F as FINBRICKS_ENDPOINTS, h as toPaymentRequestInsert } from '../shared/bank.D1jqaHaF.mjs';
5
+ import { j as initiateConnector, m as mapFinbricksTransactionStatus, g as toIncomingPayment, d as assignAccount, t as toBatchedPayment, a as FinbricksClient, F as FINBRICKS_ENDPOINTS, h as toPaymentRequestInsert } from '../shared/bank.BtszLapg.mjs';
6
6
  import 'jose';
7
7
  import { z } from 'zod';
8
- import { I as INSTRUCTION_PRIORITIES, C as CHARGE_BEARERS, e as PAYMENT_TYPES, a as CONNECTOR_KEYS, B as BATCH_STATUSES, d as PAYMENT_STATUSES, P as PAYMENT_DIRECTIONS, i as accountInsertSchema } from '../shared/bank.C0UN6luZ.mjs';
8
+ import { I as INSTRUCTION_PRIORITIES, C as CHARGE_BEARERS, e as PAYMENT_TYPES, a as CONNECTOR_KEYS, B as BATCH_STATUSES, d as PAYMENT_STATUSES, P as PAYMENT_DIRECTIONS, i as accountInsertSchema } from '../shared/bank.C6jjS1Pl.mjs';
9
9
  import { CURRENCY_CODES } from '@develit-io/general-codes';
10
10
  import 'date-fns';
11
- import { eq, sql, and, inArray, like, asc, desc, gte, lte, isNull, or, isNotNull } from 'drizzle-orm';
12
- import { unionAll } from 'drizzle-orm/sqlite-core';
11
+ import { eq, sql, and, inArray, like, asc, desc, gte, lte, isNull, count } from 'drizzle-orm';
13
12
  import 'node:crypto';
14
- import '../shared/bank.CA5ytXxp.mjs';
13
+ import '../shared/bank.BoZtXQpG.mjs';
15
14
  import 'drizzle-orm/relations';
15
+ import 'drizzle-orm/sqlite-core';
16
16
  import 'drizzle-zod';
17
17
 
18
18
  const upsertAccountCommand = (db, { account }) => {
@@ -208,7 +208,8 @@ const getPaymentsWithPaginationQuery = async (db, {
208
208
  filterPaymentMessage,
209
209
  filterPaymentCreditorIban,
210
210
  filterPaymentDebtorIban,
211
- filterPaymentBatchId
211
+ filterPaymentBatchId,
212
+ filterPaymentBankRefId
212
213
  }) => {
213
214
  const whereConditions = and(
214
215
  buildMultiFilterConditions(
@@ -240,7 +241,8 @@ const getPaymentsWithPaginationQuery = async (db, {
240
241
  filterPaymentMessage !== void 0 ? like(tables.payment.message, `%${filterPaymentMessage}%`) : void 0,
241
242
  filterPaymentCreditorIban !== void 0 ? eq(tables.payment.creditorIban, filterPaymentCreditorIban) : void 0,
242
243
  filterPaymentDebtorIban !== void 0 ? eq(tables.payment.debtorIban, filterPaymentDebtorIban) : void 0,
243
- filterPaymentBatchId !== void 0 ? eq(tables.payment.batchId, filterPaymentBatchId) : void 0
244
+ filterPaymentBatchId !== void 0 ? eq(tables.payment.batchId, filterPaymentBatchId) : void 0,
245
+ filterPaymentBankRefId !== void 0 ? eq(tables.payment.bankRefId, filterPaymentBankRefId) : void 0
244
246
  );
245
247
  const sortColumn = resolveColumn(tables.payment, sort.column);
246
248
  const [{ totalCount }] = await db.select({
@@ -285,11 +287,12 @@ const getBatchesQuery = async (db, {
285
287
  };
286
288
  };
287
289
 
288
- const getAccountOpenBatchesQuery = async (db, { accountId, paymentType }) => {
290
+ const getAccountAccumulatingBatchesQuery = async (db, { accountId, paymentType }) => {
289
291
  return await db.select().from(tables.batch).where(
290
292
  and(
291
293
  eq(tables.batch.accountId, accountId),
292
294
  eq(tables.batch.status, "OPEN"),
295
+ isNull(tables.batch.batchPaymentInitiatedAt),
293
296
  paymentType ? eq(tables.batch.paymentType, paymentType) : void 0
294
297
  )
295
298
  );
@@ -299,265 +302,60 @@ const getOttQuery = async (db, { ott }) => {
299
302
  return await db.select().from(tables.ott).where(eq(tables.ott.oneTimeToken, ott)).get();
300
303
  };
301
304
 
302
- const getPaymentRequestByIdQuery = async (db, { paymentId }) => {
303
- const prResults = await db.select().from(tables.paymentRequest).where(
305
+ const getPaymentRequestByIdQuery = async (db, { paymentRequestId }) => {
306
+ const result = await db.select().from(tables.paymentRequest).where(
304
307
  and(
305
- eq(tables.paymentRequest.id, paymentId),
308
+ eq(tables.paymentRequest.id, paymentRequestId),
306
309
  isNull(tables.paymentRequest.deletedAt)
307
310
  )
308
311
  ).limit(1);
309
- if (prResults[0]) return prResults[0];
310
- const paymentResults = await db.select().from(tables.payment).where(
311
- or(
312
- eq(tables.payment.paymentRequestId, paymentId),
313
- and(
314
- isNull(tables.payment.paymentRequestId),
315
- eq(tables.payment.id, paymentId)
316
- )
317
- )
318
- ).limit(1);
319
- if (!paymentResults[0]) return null;
320
- const p = paymentResults[0];
321
- return {
322
- ...p,
323
- id: p.paymentRequestId ?? p.id,
324
- authorizationUrl: null,
325
- sendAsSinglePayment: null,
326
- direction: p.direction ?? "OUTGOING"
327
- };
312
+ return first(result);
328
313
  };
329
314
 
330
- function isCompletedOnly(filterStatus) {
331
- if (!filterStatus) return false;
332
- const statuses = Array.isArray(filterStatus) ? filterStatus : [filterStatus];
333
- return statuses.length > 0 && statuses.every((s) => s === "COMPLETED");
334
- }
335
- function mapPaymentToPaymentRequest(p) {
336
- return {
337
- id: p.id,
338
- createdAt: p.createdAt,
339
- createdBy: p.createdBy,
340
- updatedAt: p.updatedAt,
341
- updatedBy: p.updatedBy,
342
- deletedAt: p.deletedAt,
343
- deletedBy: p.deletedBy,
344
- batchId: p.batchId,
345
- accountId: p.accountId,
346
- correlationId: p.correlationId,
347
- refId: p.refId,
348
- bankRefId: p.bankRefId,
349
- connectorKey: p.connectorKey,
350
- amount: p.amount,
351
- paymentType: p.paymentType,
352
- currency: p.currency,
353
- status: p.status,
354
- statusReason: p.statusReason,
355
- initiatedAt: p.initiatedAt,
356
- processedAt: p.processedAt,
357
- vs: p.vs,
358
- ss: p.ss,
359
- ks: p.ks,
360
- message: p.message,
361
- chargeBearer: p.chargeBearer,
362
- instructionPriority: p.instructionPriority,
363
- creditor: p.creditor,
364
- creditorIban: p.creditorIban,
365
- debtor: p.debtor,
366
- debtorIban: p.debtorIban,
367
- authorizationUrl: null,
368
- sendAsSinglePayment: null
369
- };
370
- }
371
- const getUnionColumns = () => ({
372
- id: tables.paymentRequest.id,
373
- createdAt: tables.paymentRequest.createdAt,
374
- createdBy: tables.paymentRequest.createdBy,
375
- updatedAt: tables.paymentRequest.updatedAt,
376
- updatedBy: tables.paymentRequest.updatedBy,
377
- deletedAt: tables.paymentRequest.deletedAt,
378
- deletedBy: tables.paymentRequest.deletedBy,
379
- batchId: tables.paymentRequest.batchId,
380
- accountId: tables.paymentRequest.accountId,
381
- correlationId: tables.paymentRequest.correlationId,
382
- refId: tables.paymentRequest.refId,
383
- bankRefId: tables.paymentRequest.bankRefId,
384
- connectorKey: tables.paymentRequest.connectorKey,
385
- amount: tables.paymentRequest.amount,
386
- paymentType: tables.paymentRequest.paymentType,
387
- currency: tables.paymentRequest.currency,
388
- status: tables.paymentRequest.status,
389
- statusReason: tables.paymentRequest.statusReason,
390
- authorizationUrl: tables.paymentRequest.authorizationUrl,
391
- initiatedAt: tables.paymentRequest.initiatedAt,
392
- processedAt: tables.paymentRequest.processedAt,
393
- vs: tables.paymentRequest.vs,
394
- ss: tables.paymentRequest.ss,
395
- ks: tables.paymentRequest.ks,
396
- message: tables.paymentRequest.message,
397
- chargeBearer: tables.paymentRequest.chargeBearer,
398
- instructionPriority: tables.paymentRequest.instructionPriority,
399
- creditor: tables.paymentRequest.creditor,
400
- creditorIban: tables.paymentRequest.creditorIban,
401
- debtor: tables.paymentRequest.debtor,
402
- debtorIban: tables.paymentRequest.debtorIban,
403
- sendAsSinglePayment: tables.paymentRequest.sendAsSinglePayment,
404
- // payment_request je vždy OUTGOING — typ musí být kompatibilní s payment.direction
405
- direction: sql`'OUTGOING'`.as("direction")
406
- });
407
- const getPaymentUnionColumns = () => ({
408
- id: sql`COALESCE(${tables.payment.paymentRequestId}, ${tables.payment.id})`.as(
409
- "id"
410
- ),
411
- createdAt: tables.payment.createdAt,
412
- createdBy: tables.payment.createdBy,
413
- updatedAt: tables.payment.updatedAt,
414
- updatedBy: tables.payment.updatedBy,
415
- deletedAt: tables.payment.deletedAt,
416
- deletedBy: tables.payment.deletedBy,
417
- batchId: tables.payment.batchId,
418
- accountId: tables.payment.accountId,
419
- correlationId: tables.payment.correlationId,
420
- refId: tables.payment.refId,
421
- bankRefId: tables.payment.bankRefId,
422
- connectorKey: tables.payment.connectorKey,
423
- amount: tables.payment.amount,
424
- paymentType: tables.payment.paymentType,
425
- currency: tables.payment.currency,
426
- status: tables.payment.status,
427
- statusReason: tables.payment.statusReason,
428
- authorizationUrl: sql`NULL`.as("authorization_url"),
429
- initiatedAt: tables.payment.initiatedAt,
430
- processedAt: tables.payment.processedAt,
431
- vs: tables.payment.vs,
432
- ss: tables.payment.ss,
433
- ks: tables.payment.ks,
434
- message: tables.payment.message,
435
- chargeBearer: tables.payment.chargeBearer,
436
- instructionPriority: tables.payment.instructionPriority,
437
- creditor: tables.payment.creditor,
438
- creditorIban: tables.payment.creditorIban,
439
- debtor: tables.payment.debtor,
440
- debtorIban: tables.payment.debtorIban,
441
- sendAsSinglePayment: sql`NULL`.as("send_as_single_payment"),
442
- direction: tables.payment.direction
443
- });
444
- const getPaymentRequestsWithPaginationQuery = async (db, {
445
- limit,
446
- page,
447
- sort,
448
- filterAccountId,
449
- filterStatus,
450
- filterPaymentType,
451
- filterCurrency,
452
- filterMinAmount,
453
- filterMaxAmount,
454
- filterBatchId,
455
- filterCreditorIban,
456
- filterDebtorIban,
457
- filterDateFrom,
458
- filterDateTo,
459
- filterVariableSymbol,
460
- filterSpecificSymbol,
461
- filterConstantSymbol,
462
- filterMessage,
463
- filterBankRefId,
464
- filterPaymentId,
465
- filterDirection,
466
- filterSource
467
- }) => {
468
- const offset = (page - 1) * limit;
469
- const buildPrWhereConditions = () => and(
315
+ const getPaymentRequestsQuery = async (db, params) => {
316
+ const limit = params.limit;
317
+ const offset = (params.page - 1) * params.limit;
318
+ const orderDir = params.sort.direction === "asc" ? asc : desc;
319
+ const orderCol = params.sort.column === "amount" ? tables.paymentRequest.amount : params.sort.column === "updatedAt" ? tables.paymentRequest.updatedAt : tables.paymentRequest.createdAt;
320
+ const where = and(
470
321
  isNull(tables.paymentRequest.deletedAt),
471
- buildMultiFilterConditions(
472
- tables.paymentRequest.accountId,
473
- filterAccountId
474
- ),
475
- buildMultiFilterConditions(tables.paymentRequest.status, filterStatus),
476
- buildMultiFilterConditions(
477
- tables.paymentRequest.paymentType,
478
- filterPaymentType
479
- ),
480
- buildMultiFilterConditions(
481
- tables.paymentRequest.currency,
482
- filterCurrency
483
- ),
484
- buildRangeFilterConditions(
485
- tables.paymentRequest.amount,
486
- filterMinAmount,
487
- filterMaxAmount
488
- ),
489
- filterBatchId !== void 0 ? eq(tables.paymentRequest.batchId, filterBatchId) : void 0,
490
- filterCreditorIban !== void 0 ? eq(tables.paymentRequest.creditorIban, filterCreditorIban) : void 0,
491
- filterDebtorIban !== void 0 ? eq(tables.paymentRequest.debtorIban, filterDebtorIban) : void 0,
492
- filterDateFrom !== void 0 ? gte(tables.paymentRequest.createdAt, filterDateFrom) : void 0,
493
- filterDateTo !== void 0 ? lte(tables.paymentRequest.createdAt, filterDateTo) : void 0,
494
- filterVariableSymbol !== void 0 ? eq(tables.paymentRequest.vs, filterVariableSymbol) : void 0,
495
- filterSpecificSymbol !== void 0 ? eq(tables.paymentRequest.ss, filterSpecificSymbol) : void 0,
496
- filterConstantSymbol !== void 0 ? eq(tables.paymentRequest.ks, filterConstantSymbol) : void 0,
497
- filterMessage !== void 0 ? like(tables.paymentRequest.message, `%${filterMessage}%`) : void 0,
498
- filterBankRefId !== void 0 ? eq(tables.paymentRequest.bankRefId, filterBankRefId) : void 0,
499
- filterPaymentId !== void 0 ? eq(tables.paymentRequest.id, filterPaymentId) : void 0,
500
- // payment_request is always OUTGOING — exclude branch entirely when filtering INCOMING
501
- filterDirection === "INCOMING" ? sql`0` : void 0,
502
- // payment_request is always API (has no bank-synced payments)
503
- filterSource === "BANK" ? sql`0` : void 0
322
+ params.filterAccountId ? Array.isArray(params.filterAccountId) ? inArray(tables.paymentRequest.accountId, params.filterAccountId) : eq(tables.paymentRequest.accountId, params.filterAccountId) : void 0,
323
+ params.filterStatus ? Array.isArray(params.filterStatus) ? inArray(tables.paymentRequest.status, params.filterStatus) : eq(tables.paymentRequest.status, params.filterStatus) : void 0,
324
+ params.filterPaymentType ? Array.isArray(params.filterPaymentType) ? inArray(tables.paymentRequest.paymentType, params.filterPaymentType) : eq(tables.paymentRequest.paymentType, params.filterPaymentType) : void 0,
325
+ params.filterCurrency ? Array.isArray(params.filterCurrency) ? inArray(tables.paymentRequest.currency, params.filterCurrency) : eq(tables.paymentRequest.currency, params.filterCurrency) : void 0,
326
+ params.filterBatchId ? eq(tables.paymentRequest.batchId, params.filterBatchId) : void 0,
327
+ params.filterDateFrom ? gte(tables.paymentRequest.createdAt, params.filterDateFrom) : void 0,
328
+ params.filterDateTo ? lte(tables.paymentRequest.createdAt, params.filterDateTo) : void 0,
329
+ params.filterMinAmount !== void 0 ? gte(tables.paymentRequest.amount, params.filterMinAmount) : void 0,
330
+ params.filterMaxAmount !== void 0 ? lte(tables.paymentRequest.amount, params.filterMaxAmount) : void 0,
331
+ params.filterVariableSymbol ? eq(tables.paymentRequest.vs, params.filterVariableSymbol) : void 0,
332
+ params.filterSpecificSymbol ? eq(tables.paymentRequest.ss, params.filterSpecificSymbol) : void 0,
333
+ params.filterConstantSymbol ? eq(tables.paymentRequest.ks, params.filterConstantSymbol) : void 0,
334
+ params.filterMessage ? like(tables.paymentRequest.message, `%${params.filterMessage}%`) : void 0,
335
+ params.filterBankRefId ? eq(tables.paymentRequest.bankRefId, params.filterBankRefId) : void 0,
336
+ params.filterCreditorIban ? eq(tables.paymentRequest.creditorIban, params.filterCreditorIban) : void 0,
337
+ params.filterDebtorIban ? eq(tables.paymentRequest.debtorIban, params.filterDebtorIban) : void 0,
338
+ params.ids?.length ? inArray(tables.paymentRequest.id, params.ids) : void 0
504
339
  );
505
- const buildPaymentWhereConditions = () => and(
506
- isNull(tables.payment.deletedAt),
507
- buildMultiFilterConditions(tables.payment.accountId, filterAccountId),
508
- buildMultiFilterConditions(tables.payment.status, filterStatus),
509
- buildMultiFilterConditions(tables.payment.paymentType, filterPaymentType),
510
- buildMultiFilterConditions(tables.payment.currency, filterCurrency),
511
- buildRangeFilterConditions(
512
- tables.payment.amount,
513
- filterMinAmount,
514
- filterMaxAmount
515
- ),
516
- filterBatchId !== void 0 ? eq(tables.payment.batchId, filterBatchId) : void 0,
517
- filterCreditorIban !== void 0 ? eq(tables.payment.creditorIban, filterCreditorIban) : void 0,
518
- filterDebtorIban !== void 0 ? eq(tables.payment.debtorIban, filterDebtorIban) : void 0,
519
- filterDateFrom !== void 0 ? gte(tables.payment.createdAt, filterDateFrom) : void 0,
520
- filterDateTo !== void 0 ? lte(tables.payment.createdAt, filterDateTo) : void 0,
521
- filterVariableSymbol !== void 0 ? eq(tables.payment.vs, filterVariableSymbol) : void 0,
522
- filterSpecificSymbol !== void 0 ? eq(tables.payment.ss, filterSpecificSymbol) : void 0,
523
- filterConstantSymbol !== void 0 ? eq(tables.payment.ks, filterConstantSymbol) : void 0,
524
- filterMessage !== void 0 ? like(tables.payment.message, `%${filterMessage}%`) : void 0,
525
- filterBankRefId !== void 0 ? eq(tables.payment.bankRefId, filterBankRefId) : void 0,
526
- filterPaymentId !== void 0 ? sql`COALESCE(${tables.payment.paymentRequestId}, ${tables.payment.id}) = ${filterPaymentId}` : void 0,
527
- filterDirection !== void 0 ? eq(tables.payment.direction, filterDirection) : void 0,
528
- filterSource === "BANK" ? isNull(tables.payment.paymentRequestId) : filterSource === "API" ? isNotNull(tables.payment.paymentRequestId) : void 0
529
- );
530
- const queryInFlight = !isCompletedOnly(filterStatus);
531
- const queryCompleted = true;
532
- if (!queryInFlight && queryCompleted) {
533
- const whereConditions = buildPaymentWhereConditions();
534
- const sortColumn = resolveColumn(tables.payment, sort.column);
535
- const [{ totalCount }] = await db.select({ totalCount: sql`count(*)` }).from(tables.payment).where(whereConditions);
536
- const payments = await db.select().from(tables.payment).where(whereConditions).limit(limit).offset(offset).orderBy(sort.direction === "asc" ? asc(sortColumn) : desc(sortColumn));
537
- return {
538
- paymentRequests: payments.map(mapPaymentToPaymentRequest),
539
- totalCount
540
- };
541
- }
542
- const prWhereConditions = buildPrWhereConditions();
543
- const paymentWhereConditions = buildPaymentWhereConditions();
544
- const unionColumns = getUnionColumns();
545
- const paymentUnionColumns = getPaymentUnionColumns();
546
- const sortColObj = sort.column in unionColumns ? unionColumns[sort.column] : unionColumns.updatedAt;
547
- const [{ totalCount: countPR }, { totalCount: countP }] = await Promise.all([
548
- db.select({ totalCount: sql`count(*)` }).from(tables.paymentRequest).where(prWhereConditions).then(([row]) => row),
549
- db.select({ totalCount: sql`count(*)` }).from(tables.payment).where(paymentWhereConditions).then(([row]) => row)
340
+ const [paymentRequests, [{ value: totalCount }]] = await Promise.all([
341
+ db.select().from(tables.paymentRequest).where(where).orderBy(orderDir(orderCol)).limit(limit).offset(offset),
342
+ db.select({ value: count() }).from(tables.paymentRequest).where(where)
550
343
  ]);
551
- const paymentRequests = await unionAll(
552
- db.select(unionColumns).from(tables.paymentRequest).where(prWhereConditions),
553
- db.select(paymentUnionColumns).from(tables.payment).where(paymentWhereConditions)
554
- ).orderBy(sort.direction === "asc" ? asc(sortColObj) : desc(sortColObj)).limit(limit).offset(offset);
555
- return {
556
- paymentRequests,
557
- totalCount: countPR + countP
558
- };
344
+ return { paymentRequests, totalCount };
559
345
  };
560
346
 
347
+ const NON_BATCH_CONNECTOR_KEYS = ["DBU", "CREDITAS"];
348
+ const getPendingNonBatchPaymentRequestsQuery = (db) => db.select().from(tables.paymentRequest).where(
349
+ and(
350
+ inArray(tables.paymentRequest.status, [
351
+ "PREPARED",
352
+ "SIGNED",
353
+ "PENDING"
354
+ ]),
355
+ inArray(tables.paymentRequest.connectorKey, NON_BATCH_CONNECTOR_KEYS)
356
+ )
357
+ );
358
+
561
359
  const sendPaymentInputSchema = z.object({
562
360
  correlationId: z.string().min(1),
563
361
  refId: z.string().optional(),
@@ -664,7 +462,8 @@ const ALLOWED_PAYMENT_FILTERS = {
664
462
  MESSAGE: "filterPaymentMessage",
665
463
  CREDITOR_IBAN: "filterPaymentCreditorIban",
666
464
  DEBTOR_IBAN: "filterPaymentDebtorIban",
667
- BATCH_ID: "filterPaymentBatchId"
465
+ BATCH_ID: "filterPaymentBatchId",
466
+ BANK_REF_ID: "filterPaymentBankRefId"
668
467
  };
669
468
  const getPaymentsInputSchema = z.object({
670
469
  page: z.number().positive(),
@@ -681,7 +480,7 @@ const getPaymentsInputSchema = z.object({
681
480
  [ALLOWED_PAYMENT_FILTERS.FROM]: z.date().optional(),
682
481
  [ALLOWED_PAYMENT_FILTERS.TO]: z.date().optional(),
683
482
  [ALLOWED_PAYMENT_FILTERS.STATUS]: z.union([z.enum(PAYMENT_STATUSES), z.enum(PAYMENT_STATUSES).array()]).optional(),
684
- [ALLOWED_PAYMENT_FILTERS.PAYMENT_TYPE]: z.enum(PAYMENT_TYPES).optional(),
483
+ [ALLOWED_PAYMENT_FILTERS.PAYMENT_TYPE]: z.union([z.enum(PAYMENT_TYPES), z.enum(PAYMENT_TYPES).array()]).optional(),
685
484
  [ALLOWED_PAYMENT_FILTERS.MIN_AMOUNT]: z.number().positive().optional(),
686
485
  [ALLOWED_PAYMENT_FILTERS.MAX_AMOUNT]: z.number().positive().optional(),
687
486
  [ALLOWED_PAYMENT_FILTERS.VARIABLE_SYMBOL]: z.string().regex(/^\d{1,10}$/).optional(),
@@ -690,7 +489,8 @@ const getPaymentsInputSchema = z.object({
690
489
  [ALLOWED_PAYMENT_FILTERS.MESSAGE]: z.string().optional(),
691
490
  [ALLOWED_PAYMENT_FILTERS.CREDITOR_IBAN]: z.string().optional(),
692
491
  [ALLOWED_PAYMENT_FILTERS.DEBTOR_IBAN]: z.string().optional(),
693
- [ALLOWED_PAYMENT_FILTERS.BATCH_ID]: z.uuid().optional()
492
+ [ALLOWED_PAYMENT_FILTERS.BATCH_ID]: z.uuid().optional(),
493
+ [ALLOWED_PAYMENT_FILTERS.BANK_REF_ID]: z.string().optional()
694
494
  });
695
495
 
696
496
  const syncAccountInputSchema = z.object({
@@ -774,9 +574,14 @@ const getPaymentRequestsInputSchema = z.object({
774
574
  filterConstantSymbol: z.string().optional(),
775
575
  filterMessage: z.string().optional(),
776
576
  filterBankRefId: z.string().optional(),
777
- filterPaymentId: z.uuid().optional(),
778
- filterDirection: z.enum(["INCOMING", "OUTGOING"]).optional(),
779
- filterSource: z.enum(["API", "BANK"]).optional()
577
+ ids: z.array(z.string().uuid()).optional()
578
+ // filterSource: removed — payment_request is always API
579
+ // filterDirection: removed — payment_request is always OUTGOING
580
+ });
581
+
582
+ z.object({
583
+ processed: z.number(),
584
+ statusChanged: z.number()
780
585
  });
781
586
 
782
587
  var __defProp = Object.defineProperty;
@@ -789,6 +594,7 @@ var __decorateClass = (decorators, target, key, kind) => {
789
594
  if (kind && result) __defProp(target, key, result);
790
595
  return result;
791
596
  };
597
+ const POLLING_TIMEOUT_MS = 14 * 24 * 60 * 60 * 1e3;
792
598
  let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
793
599
  constructor(ctx, env, config) {
794
600
  super(ctx, env);
@@ -942,6 +748,10 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
942
748
  console.log("Scheduled CRON batch statuses");
943
749
  await this.updateBatchStatuses();
944
750
  }
751
+ if (controller.cron === this.env.CRON_PAYMENT_STATUSES) {
752
+ console.log("Scheduled CRON payment statuses");
753
+ await this.updatePaymentStatuses();
754
+ }
945
755
  }
946
756
  async _resolveSingleBatch(batch, connector) {
947
757
  const previousStatus = batch.status;
@@ -971,14 +781,25 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
971
781
  SIGNATURE_FAILED: "FAILED"
972
782
  };
973
783
  for (const pr of paymentRequests) {
784
+ if (pr.status !== "COMPLETED" && pr.status !== "FAILED" && pr.createdAt != null && Date.now() - pr.createdAt.getTime() > POLLING_TIMEOUT_MS) {
785
+ await updatePaymentRequestStatusCommand(this.db, {
786
+ id: pr.id,
787
+ status: "FAILED",
788
+ statusReason: "Polling timeout: no final status received after 14 days",
789
+ processedAt: /* @__PURE__ */ new Date()
790
+ }).command.execute();
791
+ continue;
792
+ }
974
793
  let newStatus = pr.status;
794
+ let match;
975
795
  if (perPaymentStatuses) {
976
- const match = perPaymentStatuses.find(
796
+ match = perPaymentStatuses.find(
977
797
  (p) => p.merchantTransactionId === pr.id
978
798
  );
979
799
  if (match) {
980
800
  newStatus = mapFinbricksTransactionStatus(
981
- match.resultCode
801
+ match.resultCode,
802
+ match.finalBankStatus ?? false
982
803
  );
983
804
  }
984
805
  } else {
@@ -988,10 +809,30 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
988
809
  await updatePaymentRequestStatusCommand(this.db, {
989
810
  id: pr.id,
990
811
  status: newStatus,
812
+ ...newStatus === "FAILED" && {
813
+ statusReason: perPaymentStatuses ? match?.resultCode ?? currentStatus : currentStatus
814
+ },
991
815
  processedAt: newStatus === "COMPLETED" || newStatus === "FAILED" ? /* @__PURE__ */ new Date() : void 0
992
816
  }).command.execute();
993
817
  }
994
818
  }
819
+ if (paymentRequests.length > 0) {
820
+ const freshPRs = await getPaymentRequestsByBatchIdQuery(this.db, {
821
+ batchId: batch.id
822
+ });
823
+ const allTerminal = freshPRs.every(
824
+ (pr) => pr.status === "COMPLETED" || pr.status === "FAILED"
825
+ );
826
+ if (allTerminal && currentStatus !== "COMPLETED" && currentStatus !== "FAILED") {
827
+ const finalBatchStatus = freshPRs.some((pr) => pr.status === "FAILED") ? "FAILED" : "COMPLETED";
828
+ await upsertBatchCommand(this.db, {
829
+ batch: { ...batch, status: finalBatchStatus }
830
+ }).command.execute();
831
+ console.log(
832
+ `Batch ${batch.id} auto-closed with status ${finalBatchStatus}`
833
+ );
834
+ }
835
+ }
995
836
  }
996
837
  return {
997
838
  batchId: batch.id,
@@ -1030,13 +871,28 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1030
871
  this.logError({
1031
872
  message: `Account not found for batch ${batch.id}, skipping`
1032
873
  });
1033
- await upsertBatchCommand(this.db, {
874
+ const prs = await getPaymentRequestsByBatchIdQuery(this.db, {
875
+ batchId: batch.id
876
+ });
877
+ const prCmds = prs.filter((p) => p.status !== "FAILED").map(
878
+ (p) => updatePaymentRequestStatusCommand(this.db, {
879
+ id: p.id,
880
+ status: "FAILED",
881
+ statusReason: "ACCOUNT_NOT_FOUND",
882
+ processedAt: /* @__PURE__ */ new Date()
883
+ }).command
884
+ );
885
+ const batchCmd = upsertBatchCommand(this.db, {
1034
886
  batch: {
1035
887
  ...batch,
1036
888
  status: "FAILED",
1037
889
  statusReason: "ACCOUNT_NOT_FOUND"
1038
890
  }
1039
- }).command.execute();
891
+ }).command;
892
+ const allCmds = [batchCmd, ...prCmds];
893
+ if (allCmds.length > 0) {
894
+ await this.db.batch(allCmds);
895
+ }
1040
896
  continue;
1041
897
  }
1042
898
  const batches = batchesByConnector.get(account.connectorKey) || [];
@@ -1051,6 +907,9 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1051
907
  const connector = await this._initiateBankConnector({
1052
908
  connectorKey
1053
909
  });
910
+ if (connector.lifecycleMode === "per-payment") {
911
+ continue;
912
+ }
1054
913
  for (const batch of batches) {
1055
914
  const result = await this._resolveSingleBatch(batch, connector);
1056
915
  if (result) {
@@ -1069,6 +928,92 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1069
928
  }
1070
929
  );
1071
930
  }
931
+ async updatePaymentStatuses() {
932
+ return this.handleAction(
933
+ null,
934
+ { successMessage: "Payment statuses updated" },
935
+ async () => {
936
+ const pendingRequests = await getPendingNonBatchPaymentRequestsQuery(
937
+ this.db
938
+ );
939
+ if (pendingRequests.length === 0) {
940
+ return { processed: 0, statusChanged: 0 };
941
+ }
942
+ const requestsByConnector = /* @__PURE__ */ new Map();
943
+ for (const pr of pendingRequests) {
944
+ const list = requestsByConnector.get(pr.connectorKey) || [];
945
+ list.push(pr);
946
+ requestsByConnector.set(pr.connectorKey, list);
947
+ }
948
+ let processed = 0;
949
+ let statusChanged = 0;
950
+ for (const [connectorKey, requests] of requestsByConnector) {
951
+ let connector;
952
+ try {
953
+ connector = await this._initiateBankConnector({ connectorKey });
954
+ } catch (err) {
955
+ this.logError({
956
+ message: `[updatePaymentStatuses] Failed to init connector ${connectorKey}: ${err}`
957
+ });
958
+ continue;
959
+ }
960
+ for (const pr of requests) {
961
+ try {
962
+ if (pr.createdAt != null && Date.now() - pr.createdAt.getTime() > POLLING_TIMEOUT_MS) {
963
+ await updatePaymentRequestStatusCommand(this.db, {
964
+ id: pr.id,
965
+ status: "FAILED",
966
+ statusReason: "Polling timeout: no final status received after 14 days",
967
+ processedAt: /* @__PURE__ */ new Date()
968
+ }).command.execute();
969
+ statusChanged++;
970
+ processed++;
971
+ continue;
972
+ }
973
+ const paymentId = pr.bankRefId ?? pr.id;
974
+ const newStatus = await connector.getPaymentStatus({ paymentId });
975
+ if (newStatus !== pr.status) {
976
+ await updatePaymentRequestStatusCommand(this.db, {
977
+ id: pr.id,
978
+ status: newStatus,
979
+ processedAt: newStatus === "COMPLETED" || newStatus === "FAILED" ? /* @__PURE__ */ new Date() : void 0
980
+ }).command.execute();
981
+ statusChanged++;
982
+ }
983
+ processed++;
984
+ } catch (err) {
985
+ this.logError({
986
+ message: `Failed to get status for payment ${pr.id}: ${err}`
987
+ });
988
+ }
989
+ }
990
+ }
991
+ const affectedBatchIds = [
992
+ ...new Set(
993
+ pendingRequests.map((pr) => pr.batchId).filter((id) => id != null)
994
+ )
995
+ ];
996
+ for (const batchId of affectedBatchIds) {
997
+ const [allPRs, batch] = await Promise.all([
998
+ getPaymentRequestsByBatchIdQuery(this.db, { batchId }),
999
+ getBatchByIdQuery(this.db, { batchId })
1000
+ ]);
1001
+ if (!batch || batch.status === "COMPLETED" || batch.status === "FAILED")
1002
+ continue;
1003
+ const allTerminal = allPRs.every(
1004
+ (pr) => pr.status === "COMPLETED" || pr.status === "FAILED"
1005
+ );
1006
+ if (allTerminal && allPRs.length > 0) {
1007
+ const finalStatus = allPRs.some((pr) => pr.status === "FAILED") ? "FAILED" : "COMPLETED";
1008
+ await upsertBatchCommand(this.db, {
1009
+ batch: { ...batch, status: finalStatus }
1010
+ }).command.execute();
1011
+ }
1012
+ }
1013
+ return { processed, statusChanged };
1014
+ }
1015
+ );
1016
+ }
1072
1017
  async handleAuthorizationCallback(input) {
1073
1018
  return this.handleAction(
1074
1019
  { data: input, schema: handleAuthorizationCallbackInputSchema },
@@ -1077,7 +1022,9 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1077
1022
  let targetBatchId = null;
1078
1023
  let paymentsUpdated = 0;
1079
1024
  if (paymentId) {
1080
- const pr = await getPaymentRequestByIdQuery(this.db, { paymentId });
1025
+ const pr = await getPaymentRequestByIdQuery(this.db, {
1026
+ paymentRequestId: paymentId
1027
+ });
1081
1028
  if (!pr) {
1082
1029
  throw createInternalError(null, {
1083
1030
  message: `Payment request not found: ${paymentId}`,
@@ -1145,9 +1092,9 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1145
1092
  this.logInput({ paymentIds });
1146
1093
  const paymentRequests = (await Promise.all(
1147
1094
  paymentIds.map(
1148
- (id) => getPaymentRequestByIdQuery(this.db, { paymentId: id })
1095
+ (id) => getPaymentRequestByIdQuery(this.db, { paymentRequestId: id })
1149
1096
  )
1150
- )).filter((p) => p !== null);
1097
+ )).filter((p) => p !== void 0);
1151
1098
  const foundIds = new Set(paymentRequests.map((p) => p.id));
1152
1099
  const missingIds = paymentIds.filter((id) => !foundIds.has(id));
1153
1100
  if (missingIds.length > 0) {
@@ -1205,10 +1152,13 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1205
1152
  });
1206
1153
  }
1207
1154
  if (regularPayments.length > 0) {
1208
- const openBatches = await getAccountOpenBatchesQuery(this.db, {
1209
- accountId: acc.id,
1210
- paymentType: first2.paymentType
1211
- });
1155
+ const openBatches = await getAccountAccumulatingBatchesQuery(
1156
+ this.db,
1157
+ {
1158
+ accountId: acc.id,
1159
+ paymentType: first2.paymentType
1160
+ }
1161
+ );
1212
1162
  let batchId;
1213
1163
  let availableCount = 0;
1214
1164
  let availableBatch;
@@ -1410,8 +1360,15 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1410
1360
  secretName: "BANK_SERVICE_ENCRYPTION_KEY"
1411
1361
  })).data?.secretValue || ""
1412
1362
  );
1363
+ const remappedCredentials = credentials.map((cr) => {
1364
+ const matchingNewAccount = accounts.find((a) => a.id === cr.accountId);
1365
+ const existingAccount = matchingNewAccount ? alreadyExistingAccounts.find(
1366
+ (e) => e.iban === matchingNewAccount.iban
1367
+ ) : void 0;
1368
+ return existingAccount ? { ...cr, accountId: existingAccount.id } : cr;
1369
+ });
1413
1370
  const createAccountCredentials = (await Promise.all(
1414
- credentials.map(
1371
+ remappedCredentials.map(
1415
1372
  async (cr) => createAccountCredentialsCommand(this.db, encryptionKey, {
1416
1373
  credentials: cr
1417
1374
  })
@@ -1819,7 +1776,7 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1819
1776
  { data: input, schema: getPaymentRequestsInputSchema },
1820
1777
  { successMessage: "Payment requests fetched successfully" },
1821
1778
  async (params) => {
1822
- return await getPaymentRequestsWithPaginationQuery(this.db, params);
1779
+ return await getPaymentRequestsQuery(this.db, params);
1823
1780
  }
1824
1781
  );
1825
1782
  }
@@ -1829,11 +1786,11 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1829
1786
  { successMessage: "Payment request fetched successfully" },
1830
1787
  async () => {
1831
1788
  const paymentRequest = await getPaymentRequestByIdQuery(this.db, {
1832
- paymentId: input.paymentId
1789
+ paymentRequestId: input.paymentRequestId
1833
1790
  });
1834
1791
  if (!paymentRequest) {
1835
1792
  throw createInternalError(null, {
1836
- message: `Payment request not found: ${input.paymentId}`,
1793
+ message: `Payment request not found: ${input.paymentRequestId}`,
1837
1794
  code: "NOT-FOUND-B-001",
1838
1795
  status: 404
1839
1796
  });
@@ -1876,6 +1833,9 @@ __decorateClass([
1876
1833
  __decorateClass([
1877
1834
  action("update-batch-statuses")
1878
1835
  ], BankServiceBase.prototype, "updateBatchStatuses", 1);
1836
+ __decorateClass([
1837
+ action("update-payment-statuses")
1838
+ ], BankServiceBase.prototype, "updatePaymentStatuses", 1);
1879
1839
  __decorateClass([
1880
1840
  action("handle-authorization-callback")
1881
1841
  ], BankServiceBase.prototype, "handleAuthorizationCallback", 1);