@develit-services/ledger 0.0.1

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.
@@ -0,0 +1,108 @@
1
+ import { base } from '@develit-io/backend-sdk';
2
+ import { relations } from 'drizzle-orm';
3
+ import { sqliteTable, integer, text, real } from 'drizzle-orm/sqlite-core';
4
+ import { T as TRANSACTION_STATUSES, b as TRANSACTION_TYPES, R as REFERENCE_TYPES } from './ledger.ByUO4e44.mjs';
5
+ import '@develit-io/general-codes';
6
+
7
+ const account = sqliteTable("account", {
8
+ ...base,
9
+ name: text("name").notNull(),
10
+ ownerId: text("owner_id").notNull(),
11
+ accountType: text("account_type").$type().notNull(),
12
+ assetType: text("asset_type").$type().notNull(),
13
+ currency: text("currency").$type().notNull(),
14
+ balanceStrategy: text("balance_strategy").$type().notNull(),
15
+ parentAccountId: text("parent_account_id"),
16
+ closedAt: integer("closed_at", { mode: "timestamp_ms" })
17
+ });
18
+ const accountIdentifier = sqliteTable("account_identifier", {
19
+ ...base,
20
+ kind: text("kind").$type().notNull(),
21
+ iban: text("iban"),
22
+ accountNumber: text("account_number"),
23
+ bankCode: text("bank_code").$type(),
24
+ prefix: text("prefix"),
25
+ swift: text("swift"),
26
+ cryptoAddress: text("crypto_address"),
27
+ label: text("label"),
28
+ holderName: text("holder_name").notNull(),
29
+ network: text("network").$type(),
30
+ countryCode: text("country_code").$type()
31
+ });
32
+ const accountIdentifierMapping = sqliteTable(
33
+ "account_identifier_mapping",
34
+ {
35
+ accountId: text("account_id").notNull().references(() => account.id),
36
+ identifierId: text("identifier_id").notNull().references(() => accountIdentifier.id)
37
+ }
38
+ );
39
+ const accountRelations = relations(account, ({ many }) => ({
40
+ identifiers: many(accountIdentifierMapping)
41
+ }));
42
+ const accountIdentifierRelations = relations(
43
+ accountIdentifier,
44
+ ({ many }) => ({
45
+ accountMappings: many(accountIdentifierMapping)
46
+ })
47
+ );
48
+ const accountIdentifierMappingRelations = relations(
49
+ accountIdentifierMapping,
50
+ ({ one }) => ({
51
+ account: one(account, {
52
+ fields: [accountIdentifierMapping.accountId],
53
+ references: [account.id]
54
+ }),
55
+ identifier: one(accountIdentifier, {
56
+ fields: [accountIdentifierMapping.identifierId],
57
+ references: [accountIdentifier.id]
58
+ })
59
+ })
60
+ );
61
+
62
+ const entry = sqliteTable("entry", {
63
+ ...base,
64
+ accountId: text("account_id").notNull(),
65
+ currency: text("currency").notNull(),
66
+ creditAmount: real("amount").notNull(),
67
+ debitAmount: real("debit_amount").notNull(),
68
+ correlationId: text("correlation_id").notNull(),
69
+ transactionId: text("transaction_id").notNull(),
70
+ status: text("status").$type().notNull(),
71
+ isBalanced: integer("is_balanced", { mode: "boolean" }).notNull(),
72
+ metadata: text("metadata", { mode: "json" }).$type().notNull(),
73
+ timestamp: integer("timestamp", { mode: "timestamp_ms" }).notNull()
74
+ });
75
+
76
+ const transaction = sqliteTable("transaction", {
77
+ ...base,
78
+ correlationId: text("correlation_id").notNull(),
79
+ // Unique ID for the transaction, used for correlation
80
+ // Business context
81
+ referenceType: text("reference_type", { enum: REFERENCE_TYPES }).$type().notNull(),
82
+ referenceId: text("reference_id"),
83
+ // business transaction ID
84
+ type: text("type", { enum: TRANSACTION_TYPES }).$type().notNull(),
85
+ description: text("description"),
86
+ completedAt: integer("completed_at", { mode: "timestamp_ms" }),
87
+ confirmationSentAt: integer("confirmation_sent_at", { mode: "timestamp_ms" }),
88
+ status: text("status", { enum: TRANSACTION_STATUSES }).$type().notNull(),
89
+ statusReason: text("status_reason"),
90
+ paymentId: text("payment_id"),
91
+ metadata: text("metadata", { mode: "json" }).$type().notNull(),
92
+ value: real("value"),
93
+ currency: text("currency").$type()
94
+ });
95
+
96
+ const schema = {
97
+ __proto__: null,
98
+ account: account,
99
+ accountIdentifier: accountIdentifier,
100
+ accountIdentifierMapping: accountIdentifierMapping,
101
+ accountIdentifierMappingRelations: accountIdentifierMappingRelations,
102
+ accountIdentifierRelations: accountIdentifierRelations,
103
+ accountRelations: accountRelations,
104
+ entry: entry,
105
+ transaction: transaction
106
+ };
107
+
108
+ export { account as a, accountIdentifier as b, accountIdentifierMapping as c, accountRelations as d, accountIdentifierRelations as e, accountIdentifierMappingRelations as f, entry as g, schema as s, transaction as t };
@@ -0,0 +1,285 @@
1
+ import { COUNTRY_CODES_2, BANK_CODES, CURRENCY_CODES } from '@develit-io/general-codes';
2
+ import { z } from 'zod';
3
+ import { bankAccountMetadataSchema } from '@develit-io/backend-sdk';
4
+
5
+ const ACCOUNT_TYPES = [
6
+ "INTERNAL",
7
+ // classic internal account managed in the system
8
+ "EXTERNAL",
9
+ // tracked external client account (e.g. at Spořka)
10
+ "NOSTRO",
11
+ // mirror bank account with third party (e.g. at Creditas)
12
+ "TECHNICAL",
13
+ // any internal account for system logic (AML, fees, ...)
14
+ "SETTLEMENT",
15
+ // account used for trade settlement
16
+ "FX",
17
+ // account serving currency conversion
18
+ "FEE",
19
+ // account for fee collection
20
+ "REVENUE",
21
+ // company profit account (e.g. from fees, FX)
22
+ "LOSS",
23
+ // loss account (e.g. FX spread, refunds)
24
+ "TRANSPORT",
25
+ // temporary parking of funds "in transit"
26
+ "HOLD",
27
+ // blocked funds (e.g. AML hold, pending settlement)
28
+ "SYSTEM",
29
+ // internal system account (e.g. provisioning, demo accounts)
30
+ "TEST"
31
+ // sandbox / test accounts
32
+ ];
33
+ const ASSET_TYPES = [
34
+ "FIAT",
35
+ // CZK, EUR, USD…
36
+ "CRYPTO",
37
+ // BTC, ETH, USDT…
38
+ "TOKEN",
39
+ // tokenized assets – e.g. stablecoins
40
+ "STOCK",
41
+ // securities, shares
42
+ "COMMODITY",
43
+ // physical assets like gold, silver
44
+ "OTHER"
45
+ // for specific cases
46
+ ];
47
+ const BALANCE_STRATEGIES = ["SNAPSHOT", "COMPUTED"];
48
+ const IDENTIFIER_KINDS = [
49
+ "IBAN",
50
+ "LOCAL_CZ",
51
+ "SWIFT",
52
+ "CRYPTO_ADDRESS"
53
+ ];
54
+ const ENTRY_STATUSES = [
55
+ "PENDING",
56
+ "REALIZED",
57
+ "FAILED",
58
+ "CANCELED"
59
+ ];
60
+ const TRANSACTION_STATUSES = [
61
+ "WAITING_FOR_PAYMENT",
62
+ "PAUSED",
63
+ "WAITING_FOR_MANUAL_PROCESSING",
64
+ "MATCHED",
65
+ "RETURNING",
66
+ "RETURNED",
67
+ "FAILED",
68
+ "CANCELLED",
69
+ "COMPLETED"
70
+ ];
71
+ const TRANSACTION_TYPES = [
72
+ "CLIENT_FUND_IN",
73
+ "CLIENT_FUND_OUT",
74
+ "PROVIDER_FUND_IN",
75
+ "PROVIDER_FUND_OUT",
76
+ "EXCHANGE",
77
+ // maybe in future
78
+ "UNMATCHED",
79
+ "ADJUSTMENT",
80
+ // manual correction
81
+ "TRANSFER"
82
+ // internal transfer between accounts
83
+ ];
84
+ const REFERENCE_TYPES = ["PAYMENT", "EXCHANGE", "ORDER"];
85
+ const PAYMENT_CHARGE_TYPES = ["SHA", "OUR", "BEN"];
86
+
87
+ const ALLOWED_TRANSACTION_FILTERS = {
88
+ CORRELATION_ID: "filterTransactionCorrelationId",
89
+ REFERENCE_TYPE: "filterTransactionReferenceType",
90
+ REFERENCE_ID: "filterTransactionReferenceId",
91
+ TYPE: "filterTransactionType",
92
+ FROM: "filterTransactionDateFrom",
93
+ TO: "filterTransactionDateTo",
94
+ DESCRIPTION: "filterTransactionDescription",
95
+ COMPLETED_AT: "filterTransactionCompletedAt",
96
+ STATUS: "filterTransactionStatus"
97
+ };
98
+
99
+ const PAYMENT_TYPES = ["SEPA", "SWIFT", "IFSC", "DOMESTIC"];
100
+ const PAYMENT_STATUSES = [
101
+ "PREPARED",
102
+ "INITIALIZED",
103
+ "FAILED",
104
+ "PENDING",
105
+ "COMPLETED",
106
+ "CREATED"
107
+ ];
108
+ const PAYMENT_DIRECTIONS = ["INCOMING", "OUTGOING"];
109
+ const BATCH_STATUSES = [
110
+ "OPEN",
111
+ "WAITING_FOR_PROCESSING",
112
+ "PROCESSING",
113
+ "READY_TO_SIGN",
114
+ "PREPARED",
115
+ "COMPLETED",
116
+ "FAILED"
117
+ ];
118
+ const COUNTRY_CODES = COUNTRY_CODES_2;
119
+
120
+ const createAccountInputSchema = z.object({
121
+ name: z.string().min(1),
122
+ ownerId: z.string().min(1),
123
+ accountType: z.enum(ACCOUNT_TYPES),
124
+ assetType: z.enum(ASSET_TYPES),
125
+ currency: z.enum(CURRENCY_CODES),
126
+ balanceStrategy: z.enum(BALANCE_STRATEGIES),
127
+ parentAccountId: z.string().optional(),
128
+ countryCode: z.enum(COUNTRY_CODES).optional(),
129
+ identifier: z.object({
130
+ kind: z.enum(IDENTIFIER_KINDS),
131
+ iban: z.string().optional(),
132
+ accountNumber: z.string().optional(),
133
+ bankCode: z.enum(BANK_CODES).optional(),
134
+ prefix: z.string().optional(),
135
+ swift: z.string().optional(),
136
+ cryptoAddress: z.string().optional(),
137
+ label: z.string().optional(),
138
+ holderName: z.string().min(1)
139
+ }).optional()
140
+ });
141
+
142
+ const transactionMetadataSchema = z.object({
143
+ rejectImbalanced: z.boolean().optional(),
144
+ allowPartialFailure: z.boolean().optional(),
145
+ tags: z.array(z.string()).optional(),
146
+ note: z.string().optional(),
147
+ payment: z.object({
148
+ vs: z.string().optional(),
149
+ // variabilní symbol
150
+ ss: z.string().optional(),
151
+ // specifický symbol
152
+ ks: z.string().optional(),
153
+ // konstantní symbol
154
+ message: z.string().optional(),
155
+ // zpráva pro příjemce
156
+ reference: z.string().optional(),
157
+ // další reference
158
+ creditor: bankAccountMetadataSchema.optional(),
159
+ // příjemce
160
+ debtor: bankAccountMetadataSchema.optional(),
161
+ // plátce
162
+ executionDate: z.string().optional(),
163
+ // ISO 8601
164
+ currency: z.enum(CURRENCY_CODES).optional(),
165
+ amount: z.number().optional(),
166
+ paymentChargeType: z.string().optional()
167
+ // typ poplatku za platbu
168
+ }).optional()
169
+ }).catchall(z.unknown());
170
+ const createTransactionInputSchema = z.object({
171
+ correlationId: z.string().min(1),
172
+ referenceType: z.enum(REFERENCE_TYPES),
173
+ referenceId: z.string().optional(),
174
+ type: z.enum(TRANSACTION_TYPES),
175
+ description: z.string().optional(),
176
+ paymentId: z.string().optional(),
177
+ metadata: transactionMetadataSchema.optional().default({}),
178
+ status: z.enum(TRANSACTION_STATUSES)
179
+ // entries: z.array(entryInputSchema).min(1),
180
+ });
181
+
182
+ const deleteAccountInputSchema = z.object({
183
+ accountId: z.uuid()
184
+ });
185
+
186
+ const findAccountByIdentifierInputSchema = z.object({
187
+ iban: z.string().optional(),
188
+ accountNumber: z.string().optional(),
189
+ bankCode: z.enum(BANK_CODES).optional(),
190
+ swift: z.string().optional(),
191
+ cryptoAddress: z.string().optional()
192
+ }).refine(
193
+ (data) => {
194
+ const hasIban = !!data.iban;
195
+ const hasAccountNumber = !!(data.accountNumber && data.bankCode);
196
+ const hasSwift = !!data.swift;
197
+ const hasCryptoAddress = !!data.cryptoAddress;
198
+ return hasIban || hasAccountNumber || hasSwift || hasCryptoAddress;
199
+ },
200
+ {
201
+ message: "At least one identifier (iban, accountNumber+bankCode, swift, or cryptoAddress) must be provided"
202
+ }
203
+ );
204
+
205
+ const getAccountInputSchema = z.object({
206
+ accountId: z.uuid()
207
+ });
208
+
209
+ const getAccountBalanceInputSchema = z.object({
210
+ accountId: z.uuid()
211
+ });
212
+
213
+ const getAccountIdentifierInputSchema = z.object({
214
+ identifierId: z.uuid()
215
+ });
216
+
217
+ const getAccountsByOwnerInputSchema = z.object({
218
+ ownerId: z.string().min(1)
219
+ });
220
+
221
+ const listAccountIdentifiersInputSchema = z.object({
222
+ accountId: z.uuid()
223
+ });
224
+
225
+ const listAccountsInputSchema = z.object({
226
+ ownerId: z.string().optional(),
227
+ accountType: z.enum(ACCOUNT_TYPES).optional(),
228
+ assetType: z.enum(ASSET_TYPES).optional(),
229
+ currency: z.enum(CURRENCY_CODES).optional(),
230
+ parentAccountId: z.string().optional(),
231
+ limit: z.number().int().min(1).max(1e3).default(100),
232
+ offset: z.number().int().min(0).default(0)
233
+ });
234
+
235
+ const updateAccountInputSchema = z.object({
236
+ accountId: z.uuid(),
237
+ name: z.string().min(1).optional(),
238
+ accountType: z.enum(ACCOUNT_TYPES).optional(),
239
+ assetType: z.enum(ASSET_TYPES).optional(),
240
+ currency: z.enum(CURRENCY_CODES).optional(),
241
+ balanceStrategy: z.enum(BALANCE_STRATEGIES).optional(),
242
+ parentAccountId: z.string().optional()
243
+ // todo: removed because its no longer in the account schema and the method using it does not update the account identifier which has it
244
+ // countryCode: z.enum(COUNTRY_CODES).optional(),
245
+ });
246
+
247
+ const updateTransactionInputSchema = z.object({
248
+ transactionId: z.uuid(),
249
+ status: z.enum(TRANSACTION_STATUSES),
250
+ completedAt: z.date().optional()
251
+ });
252
+
253
+ const getTransactionByIdInputSchema = z.object({
254
+ id: z.uuid()
255
+ });
256
+
257
+ const getTransactionsByReferenceIdInputSchema = z.object({
258
+ referenceType: z.enum(REFERENCE_TYPES),
259
+ referenceId: z.uuid()
260
+ });
261
+
262
+ const getTransactionsInputSchema = z.object({
263
+ page: z.number().positive(),
264
+ limit: z.number().positive(),
265
+ sort: z.object({
266
+ column: z.string(),
267
+ direction: z.enum(["asc", "desc"])
268
+ }),
269
+ [ALLOWED_TRANSACTION_FILTERS.CORRELATION_ID]: z.uuid().optional(),
270
+ [ALLOWED_TRANSACTION_FILTERS.REFERENCE_TYPE]: z.enum(REFERENCE_TYPES).optional(),
271
+ [ALLOWED_TRANSACTION_FILTERS.REFERENCE_ID]: z.uuid().optional(),
272
+ [ALLOWED_TRANSACTION_FILTERS.TYPE]: z.enum(TRANSACTION_TYPES).optional(),
273
+ [ALLOWED_TRANSACTION_FILTERS.DESCRIPTION]: z.string().optional(),
274
+ [ALLOWED_TRANSACTION_FILTERS.FROM]: z.date().optional(),
275
+ [ALLOWED_TRANSACTION_FILTERS.TO]: z.date().optional(),
276
+ [ALLOWED_TRANSACTION_FILTERS.COMPLETED_AT]: z.date().optional(),
277
+ [ALLOWED_TRANSACTION_FILTERS.STATUS]: z.enum(TRANSACTION_STATUSES).optional(),
278
+ search: z.string().optional()
279
+ });
280
+
281
+ const updateTransactionConfirmationSentAtInputSchema = z.object({
282
+ transactionId: z.uuid()
283
+ });
284
+
285
+ export { ACCOUNT_TYPES as A, BALANCE_STRATEGIES as B, COUNTRY_CODES as C, ENTRY_STATUSES as E, IDENTIFIER_KINDS as I, PAYMENT_CHARGE_TYPES as P, REFERENCE_TYPES as R, TRANSACTION_STATUSES as T, ASSET_TYPES as a, TRANSACTION_TYPES as b, ALLOWED_TRANSACTION_FILTERS as c, createAccountInputSchema as d, createTransactionInputSchema as e, deleteAccountInputSchema as f, findAccountByIdentifierInputSchema as g, getAccountInputSchema as h, getAccountBalanceInputSchema as i, getAccountIdentifierInputSchema as j, getAccountsByOwnerInputSchema as k, listAccountIdentifiersInputSchema as l, listAccountsInputSchema as m, updateTransactionInputSchema as n, getTransactionByIdInputSchema as o, getTransactionsByReferenceIdInputSchema as p, getTransactionsInputSchema as q, updateTransactionConfirmationSentAtInputSchema as r, PAYMENT_TYPES as s, PAYMENT_STATUSES as t, updateAccountInputSchema as u, PAYMENT_DIRECTIONS as v, BATCH_STATUSES as w };