@develit-services/ledger 0.3.2 → 0.3.4
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.
- package/README.md +318 -0
- package/dist/database/schema.cjs +2 -2
- package/dist/database/schema.d.cts +1 -1
- package/dist/database/schema.d.mts +1 -1
- package/dist/database/schema.d.ts +1 -1
- package/dist/database/schema.mjs +2 -2
- package/dist/export/worker.cjs +141 -2
- package/dist/export/worker.d.cts +3 -2
- package/dist/export/worker.d.mts +3 -2
- package/dist/export/worker.d.ts +3 -2
- package/dist/export/worker.mjs +141 -2
- package/dist/shared/{ledger.D7boja6V.d.cts → ledger.5cAlw89w.d.ts} +26 -20
- package/dist/shared/{ledger.D_uHoy5E.d.mts → ledger.B08p9mSv.d.mts} +26 -20
- package/dist/shared/{ledger.CDdw0Nyc.d.ts → ledger.BUVGgzID.d.cts} +26 -20
- package/dist/shared/{ledger.BVNtjljl.mjs → ledger.Bb6l1o9P.mjs} +17 -9
- package/dist/shared/{ledger.Dfi_K5W2.cjs → ledger.Bmi7Cafn.cjs} +19 -9
- package/dist/shared/{ledger.CLVyCzRb.d.cts → ledger.CZjiiQQk.d.cts} +534 -46
- package/dist/shared/{ledger.CLVyCzRb.d.mts → ledger.CZjiiQQk.d.mts} +534 -46
- package/dist/shared/{ledger.CLVyCzRb.d.ts → ledger.CZjiiQQk.d.ts} +534 -46
- package/dist/shared/{ledger.BGgIPMu-.mjs → ledger.DKVdStuQ.mjs} +1 -1
- package/dist/shared/{ledger.C7cMVCgk.cjs → ledger.V5SF3fcq.cjs} +1 -1
- package/dist/types.cjs +4 -2
- package/dist/types.d.cts +4 -4
- package/dist/types.d.mts +4 -4
- package/dist/types.d.ts +4 -4
- package/dist/types.mjs +1 -1
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# Ledger Service
|
|
2
|
+
|
|
3
|
+
Microsluzba pro spravu ucetnich transakci, uctu a identifikatoru. Postavena na Cloudflare Workers s D1 databazi.
|
|
4
|
+
|
|
5
|
+
## Obsah
|
|
6
|
+
|
|
7
|
+
- [Architektura](#architektura)
|
|
8
|
+
- [Zivotni cyklus transakce](#zivotni-cyklus-transakce)
|
|
9
|
+
- [Refund flow](#refund-flow)
|
|
10
|
+
- [Ucty a identifikatory](#ucty-a-identifikatory)
|
|
11
|
+
- [RPC akce](#rpc-akce)
|
|
12
|
+
- [Event system](#event-system)
|
|
13
|
+
- [Databazove schema](#databazove-schema)
|
|
14
|
+
- [Error Codes](#error-codes)
|
|
15
|
+
|
|
16
|
+
## Architektura
|
|
17
|
+
|
|
18
|
+
Sluzba se sklada z:
|
|
19
|
+
|
|
20
|
+
- **Akce (Actions)** - RPC endpointy pro spravu transakci, uctu a identifikatoru
|
|
21
|
+
- **Database commands** - Atomicke zapisy (INSERT, UPDATE, DELETE) s podporou batchovani
|
|
22
|
+
- **Database queries** - Cteni dat s paginaci, filtrovanim a razenim
|
|
23
|
+
|
|
24
|
+
Bindings:
|
|
25
|
+
- `LEDGER_D1` - Cloudflare D1 databaze
|
|
26
|
+
- `QUEUE_BUS_QUEUE` - Event bus pro ledger eventy
|
|
27
|
+
- `PAYMENTS_READY_TO_BATCH_QUEUE` - Fronta pro platby k batchovani
|
|
28
|
+
- `NOTIFICATIONS_QUEUE` - Fronta pro notifikace
|
|
29
|
+
- `SECRETS_STORE` - Service binding na secrets store
|
|
30
|
+
|
|
31
|
+
## Zivotni cyklus transakce
|
|
32
|
+
|
|
33
|
+
### Hlavni flow
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
WAITING_FOR_PAYMENT ──► MATCHED (banka potvrdila platbu, VS match)
|
|
37
|
+
WAITING_FOR_PAYMENT ──► FAILED (platba selhala)
|
|
38
|
+
WAITING_FOR_PAYMENT ──► CANCELLED (zrusena manualne)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Pokud platba neni sparovana, vytvori se UNMATCHED transakce:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
WAITING_FOR_MANUAL_PROCESSING ──► RETURNING ──► RETURNED (refund flow)
|
|
45
|
+
WAITING_FOR_MANUAL_PROCESSING ──► CANCELLED (manualni zruseni)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Stavy transakce
|
|
49
|
+
|
|
50
|
+
| Status | Popis |
|
|
51
|
+
|--------|-------|
|
|
52
|
+
| `WAITING_FOR_PAYMENT` | Ceka na bankovni platbu |
|
|
53
|
+
| `WAITING_FOR_MANUAL_PROCESSING` | Vyzaduje manualni zpracovani |
|
|
54
|
+
| `MATCHED` | Sparovana s platbou |
|
|
55
|
+
| `RETURNING` | Probiha refund |
|
|
56
|
+
| `RETURNED` | Refund dokoncen |
|
|
57
|
+
| `FAILED` | Selhala |
|
|
58
|
+
| `CANCELLED` | Zrusena |
|
|
59
|
+
| `SETTLED` | Finalne vyporadana (zatim nepouzivano) |
|
|
60
|
+
|
|
61
|
+
### Typy transakci
|
|
62
|
+
|
|
63
|
+
| Typ | Popis |
|
|
64
|
+
|-----|-------|
|
|
65
|
+
| `CLIENT_FUND_IN` | Prichozi platba od klienta |
|
|
66
|
+
| `CLIENT_FUND_OUT` | Odchozi platba klientovi |
|
|
67
|
+
| `PROVIDER_FUND_IN` | Prichozi platba od providera |
|
|
68
|
+
| `PROVIDER_FUND_OUT` | Odchozi platba providerovi |
|
|
69
|
+
| `COLLATERAL_FUND_IN` | Prichozi kolateralni platba |
|
|
70
|
+
| `COLLATERAL_FUND_OUT` | Odchozi kolateralni platba |
|
|
71
|
+
| `EXCHANGE` | Smena (budouci) |
|
|
72
|
+
| `UNMATCHED` | Nesparovana platba |
|
|
73
|
+
| `ADJUSTMENT` | Manualni korekce (budouci) |
|
|
74
|
+
| `TRANSFER` | Interni prevod mezi ucty |
|
|
75
|
+
| `REFUND` | Vraceni platby |
|
|
76
|
+
|
|
77
|
+
### Reference typy
|
|
78
|
+
|
|
79
|
+
Vazba transakce na business kontext:
|
|
80
|
+
|
|
81
|
+
| Typ | Popis |
|
|
82
|
+
|-----|-------|
|
|
83
|
+
| `PAYMENT` | Bankovni platba |
|
|
84
|
+
| `EXCHANGE` | Smena |
|
|
85
|
+
| `ORDER` | Objednavka |
|
|
86
|
+
| `INTERNAL-TRANSFER` | Interni prevod |
|
|
87
|
+
| `FORWARD` | Forward kontrakt |
|
|
88
|
+
| `TRANSACTION` | Jina ledger transakce (pouziva se u refundu) |
|
|
89
|
+
|
|
90
|
+
## Refund flow
|
|
91
|
+
|
|
92
|
+
Refund je atomicka operace na urovni ledger service - gateway vola jedinou metodu `refundTransaction()`.
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
┌─────────────────────────────────────────────────────────┐
|
|
96
|
+
│ 1. refundTransaction({ transactionId, amount?, reason })│
|
|
97
|
+
│ - Validace statusu, castky, payment metadat │
|
|
98
|
+
│ - Atomicky batch: │
|
|
99
|
+
│ a) INSERT nova REFUND transakce │
|
|
100
|
+
│ (obraceny debtor/creditor, VS zachovan) │
|
|
101
|
+
│ b) UPDATE original na RETURNING │
|
|
102
|
+
│ - Emit: LEDGER_TRANSACTION created + refunding │
|
|
103
|
+
└──────────────────────────┬──────────────────────────────┘
|
|
104
|
+
▼
|
|
105
|
+
┌─────────────────────────────────────────────────────────┐
|
|
106
|
+
│ 2. Queue Bus reaguje na REFUND TX (created) │
|
|
107
|
+
│ → vytvori odchozi platbu v bance │
|
|
108
|
+
└──────────────────────────┬──────────────────────────────┘
|
|
109
|
+
│ banka provede platbu
|
|
110
|
+
▼
|
|
111
|
+
┌─────────────────────────────────────────────────────────┐
|
|
112
|
+
│ 3. Sync flow nacte completed platbu z banky │
|
|
113
|
+
│ → emituje BANK_PAYMENT event do busu │
|
|
114
|
+
│ → Bus sparuje platbu s REFUND TX (VS + IBAN match) │
|
|
115
|
+
│ → Bus vola ledger matchTransaction() na REFUND TX │
|
|
116
|
+
│ → Emit: LEDGER_TRANSACTION matched │
|
|
117
|
+
└──────────────────────────┬──────────────────────────────┘
|
|
118
|
+
▼
|
|
119
|
+
┌─────────────────────────────────────────────────────────┐
|
|
120
|
+
│ 4. Queue Bus reaguje na matched REFUND TX │
|
|
121
|
+
│ → oznaci original TX jako RETURNED │
|
|
122
|
+
└─────────────────────────────────────────────────────────┘
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Refundovatelne statusy: `WAITING_FOR_MANUAL_PROCESSING`.
|
|
126
|
+
|
|
127
|
+
Podporuje partial refund (castka < original). Metadata obsahuje `refund.isPartialRefund` boolean.
|
|
128
|
+
|
|
129
|
+
## Ucty a identifikatory
|
|
130
|
+
|
|
131
|
+
> **Pozn.:** ⚠️ Ucty, identifikatory ani entries se zatim v produkcnim kodu nepouzivaji. Schema a akce existuji, ale zadna jina sluzba je aktualne nevola. ⚠️
|
|
132
|
+
|
|
133
|
+
Hierarchicky system uctu s vice identifikatory (IBAN, cislo uctu, crypto adresa).
|
|
134
|
+
|
|
135
|
+
### Typy uctu
|
|
136
|
+
|
|
137
|
+
| Typ | Popis |
|
|
138
|
+
|-----|-------|
|
|
139
|
+
| `INTERNAL` | Interni ucet spravovany v systemu |
|
|
140
|
+
| `EXTERNAL` | Externi klientsky ucet |
|
|
141
|
+
| `NOSTRO` | Mirror ucet u treti strany (napr. Creditas) |
|
|
142
|
+
| `TECHNICAL` | Systemovy ucet (AML, poplatky) |
|
|
143
|
+
| `SETTLEMENT` | Ucet pro settlement obchodu |
|
|
144
|
+
| `FX` | Ucet pro menovou konverzi |
|
|
145
|
+
| `FEE` | Ucet pro sber poplatku |
|
|
146
|
+
| `REVENUE` | Ucet pro prijem (z poplatku, FX) |
|
|
147
|
+
| `LOSS` | Ztratovy ucet (FX spread, refundy) |
|
|
148
|
+
| `TRANSPORT` | Docasne parkovani prostredku "in transit" |
|
|
149
|
+
| `HOLD` | Blokovane prostredky (AML hold, pending settlement) |
|
|
150
|
+
| `SYSTEM` | Interni systemovy ucet |
|
|
151
|
+
| `TEST` | Sandbox / testovaci ucty |
|
|
152
|
+
|
|
153
|
+
### Typy aktiv
|
|
154
|
+
|
|
155
|
+
- `FIAT` - CZK, EUR, USD...
|
|
156
|
+
- `CRYPTO` - BTC, ETH, USDT...
|
|
157
|
+
- `TOKEN` - Tokenizovana aktiva
|
|
158
|
+
- `STOCK` - Cenné papiry
|
|
159
|
+
- `COMMODITY` - Fyzicka aktiva (zlato, stribro)
|
|
160
|
+
- `OTHER` - Specificke pripady
|
|
161
|
+
|
|
162
|
+
### Identifikatory uctu
|
|
163
|
+
|
|
164
|
+
| Typ | Pole |
|
|
165
|
+
|-----|------|
|
|
166
|
+
| `IBAN` | `iban`, `swift` |
|
|
167
|
+
| `LOCAL_CZ` | `accountNumber`, `bankCode`, `prefix` |
|
|
168
|
+
| `SWIFT` | `swift` |
|
|
169
|
+
| `CRYPTO_ADDRESS` | `cryptoAddress`, `network` |
|
|
170
|
+
|
|
171
|
+
Ucet muze mit vice identifikatoru (M:N vazba pres `accountIdentifierMapping`).
|
|
172
|
+
|
|
173
|
+
## RPC akce
|
|
174
|
+
|
|
175
|
+
Ledger service je **RPC worker** - nema vlastni verejne HTTP endpointy. Vsechny akce jsou dostupne pouze pres Cloudflare Worker binding.
|
|
176
|
+
|
|
177
|
+
### Transakce
|
|
178
|
+
|
|
179
|
+
| Akce | Popis |
|
|
180
|
+
|------|-------|
|
|
181
|
+
| `create-transaction` | Vytvori novou transakci (idempotence pres correlationId) |
|
|
182
|
+
| `get-transaction-by-id` | Detail transakce |
|
|
183
|
+
| `get-transactions-by-reference-id` | Transakce podle referenceType + referenceId |
|
|
184
|
+
| `get-transactions` | Seznam transakci s paginaci, filtry a razenim |
|
|
185
|
+
| `update-transaction-status` | Aktualizace statusu transakce |
|
|
186
|
+
| `match-transaction` | Oznaci transakci jako MATCHED (sparovana s platbou) |
|
|
187
|
+
| `fail-transaction` | Oznaci transakci jako FAILED |
|
|
188
|
+
| `cancel-transaction` | Oznaci transakci jako CANCELLED |
|
|
189
|
+
| `refund-transaction` | Vytvori REFUND transakci a oznaci original jako RETURNING (atomicky batch) |
|
|
190
|
+
| `update-transaction-confirmation-sent-at` | Zaznam odeslani potvrzeni |
|
|
191
|
+
|
|
192
|
+
### Filtry transakci
|
|
193
|
+
|
|
194
|
+
| Filtr | Popis |
|
|
195
|
+
|-------|-------|
|
|
196
|
+
| `filterTransactionCorrelationId` | Podle correlation ID |
|
|
197
|
+
| `filterTransactionReferenceType` | Podle typu reference |
|
|
198
|
+
| `filterTransactionReferenceId` | Podle ID reference |
|
|
199
|
+
| `filterTransactionType` | Podle typu transakce |
|
|
200
|
+
| `filterTransactionDateFrom` | Od data |
|
|
201
|
+
| `filterTransactionDateTo` | Do data |
|
|
202
|
+
| `filterTransactionDescription` | Fulltextove hledani v popisu |
|
|
203
|
+
| `filterTransactionCompletedAt` | Podle data dokonceni |
|
|
204
|
+
| `filterTransactionStatus` | Podle statusu |
|
|
205
|
+
|
|
206
|
+
### Ucty
|
|
207
|
+
|
|
208
|
+
| Akce | Popis |
|
|
209
|
+
|------|-------|
|
|
210
|
+
| `create-account` | Vytvori ucet (volitelne s identifikatorem) |
|
|
211
|
+
| `get-account` | Detail uctu vcetne identifikatoru |
|
|
212
|
+
| `get-accounts-by-owner` | Ucty podle vlastnika |
|
|
213
|
+
| `list-accounts` | Seznam uctu s filtry (owner, typ, asset, mena, parent) |
|
|
214
|
+
| `update-account` | Aktualizace uctu |
|
|
215
|
+
| `delete-account` | Smazani uctu a vazeb na identifikatory (batch) |
|
|
216
|
+
| `get-account-balance` | Zustatek uctu |
|
|
217
|
+
|
|
218
|
+
### Identifikatory uctu
|
|
219
|
+
|
|
220
|
+
| Akce | Popis |
|
|
221
|
+
|------|-------|
|
|
222
|
+
| `get-account-identifier` | Detail identifikatoru |
|
|
223
|
+
| `list-account-identifiers` | Identifikatory pro ucet |
|
|
224
|
+
| `find-account-by-identifier` | Hledani uctu podle IBAN/cisla uctu/crypto adresy |
|
|
225
|
+
|
|
226
|
+
## Event system
|
|
227
|
+
|
|
228
|
+
Sluzba emituje `LedgerTransactionEvent` do `QUEUE_BUS_QUEUE`:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
type LedgerTransactionEvent = BaseEvent & {
|
|
232
|
+
eventType: 'LEDGER_TRANSACTION'
|
|
233
|
+
eventSignal: 'created' | 'updated' | 'matched' | 'failed' | 'refunding'
|
|
234
|
+
ledgerTransaction: TransactionSelectType
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
| Signal | Kdy se emituje |
|
|
239
|
+
|--------|---------------|
|
|
240
|
+
| `created` | Nova transakce vytvorena |
|
|
241
|
+
| `updated` | Status transakce zmenen |
|
|
242
|
+
| `matched` | Transakce sparovana s platbou |
|
|
243
|
+
| `failed` | Transakce selhala |
|
|
244
|
+
| `refunding` | Original TX oznacen jako RETURNING (refund zahajen) |
|
|
245
|
+
|
|
246
|
+
## Databazove schema
|
|
247
|
+
|
|
248
|
+
### transaction
|
|
249
|
+
|
|
250
|
+
Hlavni tabulka ucetnich transakci.
|
|
251
|
+
|
|
252
|
+
Klicove sloupce: `correlationId`, `referenceType`, `referenceId`, `type`, `status`, `statusReason`, `description`, `value` (real), `currency`, `paymentId`, `metadata` (JSON - TransactionMetadata), `completedAt`, `confirmationSentAt`.
|
|
253
|
+
|
|
254
|
+
### Transaction metadata
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
{
|
|
258
|
+
payment?: {
|
|
259
|
+
vs?, ss?, ks? // platebni symboly
|
|
260
|
+
message? // zprava pro prijemce
|
|
261
|
+
type: PaymentType // DOMESTIC | SEPA | SWIFT | UNKNOWN
|
|
262
|
+
paymentChargeType? // SHA | OUR | BEN
|
|
263
|
+
expressPayment? // boolean
|
|
264
|
+
reference? // dalsi reference
|
|
265
|
+
creditor? // BankAccountMetadata (prijemce)
|
|
266
|
+
debtor? // BankAccountMetadata (platce)
|
|
267
|
+
executionDate? // ISO 8601
|
|
268
|
+
currency? // CurrencyCode
|
|
269
|
+
amount? // castka
|
|
270
|
+
purpose? // ucel platby
|
|
271
|
+
sendAsSinglePayment? // odeslat jako samostatnou platbu (ne v batchi)
|
|
272
|
+
}
|
|
273
|
+
tags?: string[] // kategorizace
|
|
274
|
+
note?: string // poznamka
|
|
275
|
+
refund?: { // jen pro typ REFUND
|
|
276
|
+
isPartialRefund: boolean
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### account
|
|
282
|
+
|
|
283
|
+
Ucty s hierarchickou strukturou.
|
|
284
|
+
|
|
285
|
+
Klicove sloupce: `name`, `ownerId`, `accountType`, `assetType`, `currency`, `balanceStrategy` (SNAPSHOT | COMPUTED), `parentAccountId`, `closedAt`.
|
|
286
|
+
|
|
287
|
+
### accountIdentifier
|
|
288
|
+
|
|
289
|
+
Identifikatory uctu (IBAN, cislo uctu, crypto adresa).
|
|
290
|
+
|
|
291
|
+
Klicove sloupce: `kind`, `iban`, `accountNumber`, `bankCode`, `prefix`, `swift`, `cryptoAddress`, `holderName`, `network`, `countryCode`, `label`.
|
|
292
|
+
|
|
293
|
+
### accountIdentifierMapping
|
|
294
|
+
|
|
295
|
+
Vazebni tabulka M:N mezi `account` a `accountIdentifier`.
|
|
296
|
+
|
|
297
|
+
Sloupce: `accountId` (FK), `identifierId` (FK).
|
|
298
|
+
|
|
299
|
+
### entry (planovano)
|
|
300
|
+
|
|
301
|
+
Tabulka pro budouci entry-based ucetnictvi (double-entry bookkeeping). Schema existuje, ale neni zatim pouzivano.
|
|
302
|
+
|
|
303
|
+
Sloupce: `accountId`, `currency`, `creditAmount`, `debitAmount`, `correlationId`, `transactionId`, `status` (PENDING | REALIZED | FAILED | CANCELED), `isBalanced`, `metadata` (JSON), `timestamp`.
|
|
304
|
+
|
|
305
|
+
## Error Codes
|
|
306
|
+
|
|
307
|
+
Format: `{CATEGORY}-L-{NUMBER}`
|
|
308
|
+
|
|
309
|
+
| Code | Status | Description |
|
|
310
|
+
|------|--------|-------------|
|
|
311
|
+
| `DB-L-01` | 500 | Failed to create transaction |
|
|
312
|
+
| `DB-L-02` | 500 | Failed to process refund transaction (batch write) |
|
|
313
|
+
| `DB-L-03` | 404 | Transaction not found (refund) |
|
|
314
|
+
| `VALID-L-01` | 400 | Transaction status does not allow refund |
|
|
315
|
+
| `VALID-L-02` | 400 | Invalid refund amount (zero or negative) |
|
|
316
|
+
| `VALID-L-03` | 400 | Refund amount exceeds original transaction value |
|
|
317
|
+
| `VALID-L-04` | 400 | Transaction missing payment metadata (debtor/creditor) |
|
|
318
|
+
| `VALID-L-05` | 400 | Transaction missing currency information |
|
package/dist/database/schema.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const database_schema = require('../shared/ledger.
|
|
3
|
+
const database_schema = require('../shared/ledger.V5SF3fcq.cjs');
|
|
4
4
|
require('@develit-io/backend-sdk');
|
|
5
5
|
require('drizzle-orm');
|
|
6
6
|
require('drizzle-orm/sqlite-core');
|
|
7
|
-
require('../shared/ledger.
|
|
7
|
+
require('../shared/ledger.Bmi7Cafn.cjs');
|
|
8
8
|
require('zod');
|
|
9
9
|
require('@develit-io/general-codes');
|
|
10
10
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { G as account, H as accountIdentifier, J as accountIdentifierMapping, K as accountIdentifierMappingRelations, L as accountIdentifierRelations, M as accountRelations, N as entry, O as transaction } from '../shared/ledger.CZjiiQQk.cjs';
|
|
2
2
|
import 'drizzle-orm';
|
|
3
3
|
import 'drizzle-orm/sqlite-core';
|
|
4
4
|
import '@develit-io/backend-sdk';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { G as account, H as accountIdentifier, J as accountIdentifierMapping, K as accountIdentifierMappingRelations, L as accountIdentifierRelations, M as accountRelations, N as entry, O as transaction } from '../shared/ledger.CZjiiQQk.mjs';
|
|
2
2
|
import 'drizzle-orm';
|
|
3
3
|
import 'drizzle-orm/sqlite-core';
|
|
4
4
|
import '@develit-io/backend-sdk';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { G as account, H as accountIdentifier, J as accountIdentifierMapping, K as accountIdentifierMappingRelations, L as accountIdentifierRelations, M as accountRelations, N as entry, O as transaction } from '../shared/ledger.CZjiiQQk.js';
|
|
2
2
|
import 'drizzle-orm';
|
|
3
3
|
import 'drizzle-orm/sqlite-core';
|
|
4
4
|
import '@develit-io/backend-sdk';
|
package/dist/database/schema.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { a as account, b as accountIdentifier, c as accountIdentifierMapping, d as accountIdentifierMappingRelations, e as accountIdentifierRelations, f as accountRelations, g as entry, t as transaction } from '../shared/ledger.
|
|
1
|
+
export { a as account, b as accountIdentifier, c as accountIdentifierMapping, d as accountIdentifierMappingRelations, e as accountIdentifierRelations, f as accountRelations, g as entry, t as transaction } from '../shared/ledger.DKVdStuQ.mjs';
|
|
2
2
|
import '@develit-io/backend-sdk';
|
|
3
3
|
import 'drizzle-orm';
|
|
4
4
|
import 'drizzle-orm/sqlite-core';
|
|
5
|
-
import '../shared/ledger.
|
|
5
|
+
import '../shared/ledger.Bb6l1o9P.mjs';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import '@develit-io/general-codes';
|
package/dist/export/worker.cjs
CHANGED
|
@@ -5,9 +5,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
const backendSdk = require('@develit-io/backend-sdk');
|
|
6
6
|
const cloudflare_workers = require('cloudflare:workers');
|
|
7
7
|
const d1 = require('drizzle-orm/d1');
|
|
8
|
-
const database_schema = require('../shared/ledger.
|
|
8
|
+
const database_schema = require('../shared/ledger.V5SF3fcq.cjs');
|
|
9
9
|
const drizzleOrm = require('drizzle-orm');
|
|
10
|
-
const updateTransactionStatus = require('../shared/ledger.
|
|
10
|
+
const updateTransactionStatus = require('../shared/ledger.Bmi7Cafn.cjs');
|
|
11
11
|
require('@develit-io/general-codes');
|
|
12
12
|
require('drizzle-orm/sqlite-core');
|
|
13
13
|
require('zod');
|
|
@@ -538,6 +538,142 @@ let LedgerServiceBase = class extends backendSdk.develitWorker(
|
|
|
538
538
|
}
|
|
539
539
|
);
|
|
540
540
|
}
|
|
541
|
+
async refundTransaction(input) {
|
|
542
|
+
return this.handleAction(
|
|
543
|
+
{ data: input, schema: updateTransactionStatus.refundTransactionInputSchema },
|
|
544
|
+
{ successMessage: "Transaction successfully refunded." },
|
|
545
|
+
async (params) => {
|
|
546
|
+
const { transactionId, amount, reason } = params;
|
|
547
|
+
const originalTx = await getTransactionByIdQuery(this.db, transactionId);
|
|
548
|
+
if (!originalTx) {
|
|
549
|
+
throw backendSdk.createInternalError(null, {
|
|
550
|
+
message: "Transaction not found",
|
|
551
|
+
status: 404,
|
|
552
|
+
code: "DB-L-03"
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
if (!updateTransactionStatus.REFUNDABLE_TRANSACTION_STATUSES.some(
|
|
556
|
+
(status) => status === originalTx.status
|
|
557
|
+
)) {
|
|
558
|
+
throw backendSdk.createInternalError(null, {
|
|
559
|
+
message: `Transaction with status ${originalTx.status} cannot be refunded`,
|
|
560
|
+
status: 400,
|
|
561
|
+
code: "VALID-L-01"
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
const refundAmount = amount || originalTx.value || 0;
|
|
565
|
+
if (refundAmount <= 0) {
|
|
566
|
+
throw backendSdk.createInternalError(null, {
|
|
567
|
+
message: "Invalid refund amount",
|
|
568
|
+
status: 400,
|
|
569
|
+
code: "VALID-L-02"
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
if (originalTx.value && refundAmount > originalTx.value) {
|
|
573
|
+
throw backendSdk.createInternalError(null, {
|
|
574
|
+
message: "Refund amount exceeds transaction value",
|
|
575
|
+
status: 400,
|
|
576
|
+
code: "VALID-L-03"
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
const originalPayment = originalTx.metadata?.payment;
|
|
580
|
+
if (!originalPayment?.debtor || !originalPayment?.creditor) {
|
|
581
|
+
throw backendSdk.createInternalError(null, {
|
|
582
|
+
message: "Transaction missing payment information for refund",
|
|
583
|
+
status: 400,
|
|
584
|
+
code: "VALID-L-04"
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
if (!originalTx.currency) {
|
|
588
|
+
throw backendSdk.createInternalError(null, {
|
|
589
|
+
message: "Transaction missing currency information",
|
|
590
|
+
status: 400,
|
|
591
|
+
code: "VALID-L-05"
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
const refundTxId = backendSdk.uuidv4();
|
|
595
|
+
const correlationId = backendSdk.uuidv4();
|
|
596
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
597
|
+
const isPartialRefund = amount !== void 0 && originalTx.value != null && amount < originalTx.value;
|
|
598
|
+
const refundTransaction = {
|
|
599
|
+
id: refundTxId,
|
|
600
|
+
correlationId,
|
|
601
|
+
referenceType: "TRANSACTION",
|
|
602
|
+
referenceId: transactionId,
|
|
603
|
+
type: "REFUND",
|
|
604
|
+
description: `Refund: ${reason}`,
|
|
605
|
+
status: "WAITING_FOR_PAYMENT",
|
|
606
|
+
value: refundAmount,
|
|
607
|
+
currency: originalTx.currency,
|
|
608
|
+
createdAt: timestamp,
|
|
609
|
+
updatedAt: timestamp,
|
|
610
|
+
completedAt: null,
|
|
611
|
+
metadata: {
|
|
612
|
+
tags: ["refund", `refund-${originalTx.type.toLowerCase()}`],
|
|
613
|
+
note: reason,
|
|
614
|
+
payment: {
|
|
615
|
+
amount: refundAmount,
|
|
616
|
+
currency: originalPayment.currency,
|
|
617
|
+
type: originalPayment.type || "DOMESTIC",
|
|
618
|
+
vs: originalPayment.vs,
|
|
619
|
+
ss: originalPayment.ss,
|
|
620
|
+
ks: originalPayment.ks,
|
|
621
|
+
debtor: originalPayment.creditor,
|
|
622
|
+
creditor: originalPayment.debtor
|
|
623
|
+
},
|
|
624
|
+
refund: {
|
|
625
|
+
isPartialRefund
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
const insertRefundCommand = this.db.insert(tables.transaction).values(refundTransaction).returning();
|
|
630
|
+
const { command: updateOriginalCommand } = updateTransactionStatusCommand(this.db, {
|
|
631
|
+
transactionId,
|
|
632
|
+
status: "RETURNING",
|
|
633
|
+
statusReason: `Refund in progress via transaction ${refundTxId}`
|
|
634
|
+
});
|
|
635
|
+
const [refundResult, originalResult] = await this.db.batch([
|
|
636
|
+
insertRefundCommand,
|
|
637
|
+
updateOriginalCommand
|
|
638
|
+
]);
|
|
639
|
+
const createdRefundTx = backendSdk.first(refundResult);
|
|
640
|
+
const updatedOriginalTx = backendSdk.first(originalResult);
|
|
641
|
+
if (!createdRefundTx || !updatedOriginalTx) {
|
|
642
|
+
throw backendSdk.createInternalError(null, {
|
|
643
|
+
message: "Failed to process refund transaction",
|
|
644
|
+
status: 500,
|
|
645
|
+
code: "DB-L-02"
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
await Promise.all([
|
|
649
|
+
this.pushToQueue(this.env.QUEUE_BUS_QUEUE, {
|
|
650
|
+
eventType: "LEDGER_TRANSACTION",
|
|
651
|
+
eventSignal: "created",
|
|
652
|
+
ledgerTransaction: createdRefundTx,
|
|
653
|
+
metadata: {
|
|
654
|
+
correlationId: backendSdk.uuidv4(),
|
|
655
|
+
entityId: createdRefundTx.id,
|
|
656
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
657
|
+
}
|
|
658
|
+
}),
|
|
659
|
+
this.pushToQueue(this.env.QUEUE_BUS_QUEUE, {
|
|
660
|
+
eventType: "LEDGER_TRANSACTION",
|
|
661
|
+
eventSignal: "refunding",
|
|
662
|
+
ledgerTransaction: updatedOriginalTx,
|
|
663
|
+
metadata: {
|
|
664
|
+
correlationId: backendSdk.uuidv4(),
|
|
665
|
+
entityId: updatedOriginalTx.id,
|
|
666
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
667
|
+
}
|
|
668
|
+
})
|
|
669
|
+
]);
|
|
670
|
+
return {
|
|
671
|
+
refundTransaction: createdRefundTx,
|
|
672
|
+
originalTransaction: updatedOriginalTx
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
);
|
|
676
|
+
}
|
|
541
677
|
async getTransactionById(input) {
|
|
542
678
|
return this.handleAction(
|
|
543
679
|
{ data: input, schema: updateTransactionStatus.getTransactionByIdInputSchema },
|
|
@@ -864,6 +1000,9 @@ __decorateClass([
|
|
|
864
1000
|
__decorateClass([
|
|
865
1001
|
backendSdk.action("cancel-transaction")
|
|
866
1002
|
], LedgerServiceBase.prototype, "cancelTransaction", 1);
|
|
1003
|
+
__decorateClass([
|
|
1004
|
+
backendSdk.action("refund-transaction")
|
|
1005
|
+
], LedgerServiceBase.prototype, "refundTransaction", 1);
|
|
867
1006
|
__decorateClass([
|
|
868
1007
|
backendSdk.action("get-transaction-by-id")
|
|
869
1008
|
], LedgerServiceBase.prototype, "getTransactionById", 1);
|
package/dist/export/worker.d.cts
CHANGED
|
@@ -2,9 +2,9 @@ import * as _develit_io_backend_sdk from '@develit-io/backend-sdk';
|
|
|
2
2
|
import { IRPCResponse } from '@develit-io/backend-sdk';
|
|
3
3
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
4
4
|
import { DrizzleD1Database } from 'drizzle-orm/d1';
|
|
5
|
-
import { t as tables, C as CreateTransactionInput, a as CreateTransactionOutput, M as MatchTransactionInput, b as MatchTransactionOutput, F as FailTransactionInput, c as FailTransactionOutput, d as CancelTransactionInput, e as CancelTransactionOutput, G as GetTransactionByIdInput,
|
|
5
|
+
import { t as tables, C as CreateTransactionInput, a as CreateTransactionOutput, M as MatchTransactionInput, b as MatchTransactionOutput, F as FailTransactionInput, c as FailTransactionOutput, d as CancelTransactionInput, e as CancelTransactionOutput, R as RefundTransactionInput, f as RefundTransactionOutput, G as GetTransactionByIdInput, g as GetTransactionByIdOutput, h as GetTransactionsByIdReferenceInput, i as GetTransactionsByReferenceIdOutput, j as GetTransactionsInput, k as GetTransactionsOutput, l as CreateAccountInput, m as CreateAccountOutput, U as UpdateAccountInput, n as UpdateAccountOutput, D as DeleteAccountInput, o as DeleteAccountOutput, p as GetAccountInput, q as GetAccountOutput, r as GetAccountsByOwnerInput, s as GetAccountsByOwnerOutput, L as ListAccountsInput, u as ListAccountsOutput, v as GetAccountIdentifierInput, w as GetAccountIdentifierOutput, x as ListAccountIdentifiersInput, y as ListAccountIdentifiersOutput, z as FindAccountByIdentifierInput, A as FindAccountByIdentifierOutput, B as GetAccountBalanceInput, E as GetAccountBalanceOutput, H as UpdateTransactionConfirmationSentAtInput, I as UpdateTransactionConfirmationSentAtOutput, J as UpdateTransactionStatusInput, K as UpdateTransactionStatusOutput } from '../shared/ledger.BUVGgzID.cjs';
|
|
6
6
|
import 'zod';
|
|
7
|
-
import '../shared/ledger.
|
|
7
|
+
import '../shared/ledger.CZjiiQQk.cjs';
|
|
8
8
|
import 'drizzle-orm';
|
|
9
9
|
import 'drizzle-orm/sqlite-core';
|
|
10
10
|
import '@develit-io/general-codes';
|
|
@@ -17,6 +17,7 @@ declare class LedgerServiceBase extends LedgerServiceBase_base {
|
|
|
17
17
|
matchTransaction(input: MatchTransactionInput): Promise<IRPCResponse<MatchTransactionOutput>>;
|
|
18
18
|
failTransaction(input: FailTransactionInput): Promise<IRPCResponse<FailTransactionOutput>>;
|
|
19
19
|
cancelTransaction(input: CancelTransactionInput): Promise<IRPCResponse<CancelTransactionOutput>>;
|
|
20
|
+
refundTransaction(input: RefundTransactionInput): Promise<IRPCResponse<RefundTransactionOutput>>;
|
|
20
21
|
getTransactionById(input: GetTransactionByIdInput): Promise<IRPCResponse<GetTransactionByIdOutput | undefined>>;
|
|
21
22
|
getTransactionsByReferenceId(input: GetTransactionsByIdReferenceInput): Promise<IRPCResponse<GetTransactionsByReferenceIdOutput | undefined>>;
|
|
22
23
|
getTransactions(input: GetTransactionsInput): Promise<IRPCResponse<GetTransactionsOutput>>;
|
package/dist/export/worker.d.mts
CHANGED
|
@@ -2,9 +2,9 @@ import * as _develit_io_backend_sdk from '@develit-io/backend-sdk';
|
|
|
2
2
|
import { IRPCResponse } from '@develit-io/backend-sdk';
|
|
3
3
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
4
4
|
import { DrizzleD1Database } from 'drizzle-orm/d1';
|
|
5
|
-
import { t as tables, C as CreateTransactionInput, a as CreateTransactionOutput, M as MatchTransactionInput, b as MatchTransactionOutput, F as FailTransactionInput, c as FailTransactionOutput, d as CancelTransactionInput, e as CancelTransactionOutput, G as GetTransactionByIdInput,
|
|
5
|
+
import { t as tables, C as CreateTransactionInput, a as CreateTransactionOutput, M as MatchTransactionInput, b as MatchTransactionOutput, F as FailTransactionInput, c as FailTransactionOutput, d as CancelTransactionInput, e as CancelTransactionOutput, R as RefundTransactionInput, f as RefundTransactionOutput, G as GetTransactionByIdInput, g as GetTransactionByIdOutput, h as GetTransactionsByIdReferenceInput, i as GetTransactionsByReferenceIdOutput, j as GetTransactionsInput, k as GetTransactionsOutput, l as CreateAccountInput, m as CreateAccountOutput, U as UpdateAccountInput, n as UpdateAccountOutput, D as DeleteAccountInput, o as DeleteAccountOutput, p as GetAccountInput, q as GetAccountOutput, r as GetAccountsByOwnerInput, s as GetAccountsByOwnerOutput, L as ListAccountsInput, u as ListAccountsOutput, v as GetAccountIdentifierInput, w as GetAccountIdentifierOutput, x as ListAccountIdentifiersInput, y as ListAccountIdentifiersOutput, z as FindAccountByIdentifierInput, A as FindAccountByIdentifierOutput, B as GetAccountBalanceInput, E as GetAccountBalanceOutput, H as UpdateTransactionConfirmationSentAtInput, I as UpdateTransactionConfirmationSentAtOutput, J as UpdateTransactionStatusInput, K as UpdateTransactionStatusOutput } from '../shared/ledger.B08p9mSv.mjs';
|
|
6
6
|
import 'zod';
|
|
7
|
-
import '../shared/ledger.
|
|
7
|
+
import '../shared/ledger.CZjiiQQk.mjs';
|
|
8
8
|
import 'drizzle-orm';
|
|
9
9
|
import 'drizzle-orm/sqlite-core';
|
|
10
10
|
import '@develit-io/general-codes';
|
|
@@ -17,6 +17,7 @@ declare class LedgerServiceBase extends LedgerServiceBase_base {
|
|
|
17
17
|
matchTransaction(input: MatchTransactionInput): Promise<IRPCResponse<MatchTransactionOutput>>;
|
|
18
18
|
failTransaction(input: FailTransactionInput): Promise<IRPCResponse<FailTransactionOutput>>;
|
|
19
19
|
cancelTransaction(input: CancelTransactionInput): Promise<IRPCResponse<CancelTransactionOutput>>;
|
|
20
|
+
refundTransaction(input: RefundTransactionInput): Promise<IRPCResponse<RefundTransactionOutput>>;
|
|
20
21
|
getTransactionById(input: GetTransactionByIdInput): Promise<IRPCResponse<GetTransactionByIdOutput | undefined>>;
|
|
21
22
|
getTransactionsByReferenceId(input: GetTransactionsByIdReferenceInput): Promise<IRPCResponse<GetTransactionsByReferenceIdOutput | undefined>>;
|
|
22
23
|
getTransactions(input: GetTransactionsInput): Promise<IRPCResponse<GetTransactionsOutput>>;
|
package/dist/export/worker.d.ts
CHANGED
|
@@ -2,9 +2,9 @@ import * as _develit_io_backend_sdk from '@develit-io/backend-sdk';
|
|
|
2
2
|
import { IRPCResponse } from '@develit-io/backend-sdk';
|
|
3
3
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
4
4
|
import { DrizzleD1Database } from 'drizzle-orm/d1';
|
|
5
|
-
import { t as tables, C as CreateTransactionInput, a as CreateTransactionOutput, M as MatchTransactionInput, b as MatchTransactionOutput, F as FailTransactionInput, c as FailTransactionOutput, d as CancelTransactionInput, e as CancelTransactionOutput, G as GetTransactionByIdInput,
|
|
5
|
+
import { t as tables, C as CreateTransactionInput, a as CreateTransactionOutput, M as MatchTransactionInput, b as MatchTransactionOutput, F as FailTransactionInput, c as FailTransactionOutput, d as CancelTransactionInput, e as CancelTransactionOutput, R as RefundTransactionInput, f as RefundTransactionOutput, G as GetTransactionByIdInput, g as GetTransactionByIdOutput, h as GetTransactionsByIdReferenceInput, i as GetTransactionsByReferenceIdOutput, j as GetTransactionsInput, k as GetTransactionsOutput, l as CreateAccountInput, m as CreateAccountOutput, U as UpdateAccountInput, n as UpdateAccountOutput, D as DeleteAccountInput, o as DeleteAccountOutput, p as GetAccountInput, q as GetAccountOutput, r as GetAccountsByOwnerInput, s as GetAccountsByOwnerOutput, L as ListAccountsInput, u as ListAccountsOutput, v as GetAccountIdentifierInput, w as GetAccountIdentifierOutput, x as ListAccountIdentifiersInput, y as ListAccountIdentifiersOutput, z as FindAccountByIdentifierInput, A as FindAccountByIdentifierOutput, B as GetAccountBalanceInput, E as GetAccountBalanceOutput, H as UpdateTransactionConfirmationSentAtInput, I as UpdateTransactionConfirmationSentAtOutput, J as UpdateTransactionStatusInput, K as UpdateTransactionStatusOutput } from '../shared/ledger.5cAlw89w.js';
|
|
6
6
|
import 'zod';
|
|
7
|
-
import '../shared/ledger.
|
|
7
|
+
import '../shared/ledger.CZjiiQQk.js';
|
|
8
8
|
import 'drizzle-orm';
|
|
9
9
|
import 'drizzle-orm/sqlite-core';
|
|
10
10
|
import '@develit-io/general-codes';
|
|
@@ -17,6 +17,7 @@ declare class LedgerServiceBase extends LedgerServiceBase_base {
|
|
|
17
17
|
matchTransaction(input: MatchTransactionInput): Promise<IRPCResponse<MatchTransactionOutput>>;
|
|
18
18
|
failTransaction(input: FailTransactionInput): Promise<IRPCResponse<FailTransactionOutput>>;
|
|
19
19
|
cancelTransaction(input: CancelTransactionInput): Promise<IRPCResponse<CancelTransactionOutput>>;
|
|
20
|
+
refundTransaction(input: RefundTransactionInput): Promise<IRPCResponse<RefundTransactionOutput>>;
|
|
20
21
|
getTransactionById(input: GetTransactionByIdInput): Promise<IRPCResponse<GetTransactionByIdOutput | undefined>>;
|
|
21
22
|
getTransactionsByReferenceId(input: GetTransactionsByIdReferenceInput): Promise<IRPCResponse<GetTransactionsByReferenceIdOutput | undefined>>;
|
|
22
23
|
getTransactions(input: GetTransactionsInput): Promise<IRPCResponse<GetTransactionsOutput>>;
|