@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.
- package/dist/@types.cjs +42 -0
- package/dist/@types.d.cts +44 -0
- package/dist/@types.d.mts +44 -0
- package/dist/@types.d.ts +44 -0
- package/dist/@types.mjs +4 -0
- package/dist/database/schema.cjs +20 -0
- package/dist/database/schema.d.cts +5 -0
- package/dist/database/schema.d.mts +5 -0
- package/dist/database/schema.d.ts +5 -0
- package/dist/database/schema.mjs +7 -0
- package/dist/export/worker.cjs +764 -0
- package/dist/export/worker.d.cts +39 -0
- package/dist/export/worker.d.mts +37 -0
- package/dist/export/worker.d.ts +39 -0
- package/dist/export/worker.mjs +759 -0
- package/dist/export/wrangler.cjs +90 -0
- package/dist/export/wrangler.d.cts +40 -0
- package/dist/export/wrangler.d.mts +40 -0
- package/dist/export/wrangler.d.ts +40 -0
- package/dist/export/wrangler.mjs +88 -0
- package/dist/shared/ledger.BGDeCrA0.d.mts +1019 -0
- package/dist/shared/ledger.Bl4HgQDw.mjs +108 -0
- package/dist/shared/ledger.ByUO4e44.mjs +285 -0
- package/dist/shared/ledger.CSKqugjV.d.ts +1019 -0
- package/dist/shared/ledger.CSi5bWgX.d.cts +1019 -0
- package/dist/shared/ledger.Ce2yPDUS.d.cts +18 -0
- package/dist/shared/ledger.Ce2yPDUS.d.mts +18 -0
- package/dist/shared/ledger.Ce2yPDUS.d.ts +18 -0
- package/dist/shared/ledger.D1MIlhpb.cjs +317 -0
- package/dist/shared/ledger.DGu3Pj-Y.cjs +118 -0
- package/dist/shared/ledger._YlR4Uxg.d.cts +1320 -0
- package/dist/shared/ledger._YlR4Uxg.d.mts +1320 -0
- package/dist/shared/ledger._YlR4Uxg.d.ts +1320 -0
- package/package.json +59 -0
|
@@ -0,0 +1,759 @@
|
|
|
1
|
+
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
2
|
+
import { first, develitWorker, uuidv4, useResult, createInternalError, cloudflareQueue, action, service } from '@develit-io/backend-sdk';
|
|
3
|
+
import { e as createTransactionInputSchema, n as updateTransactionInputSchema, o as getTransactionByIdInputSchema, p as getTransactionsByReferenceIdInputSchema, q as getTransactionsInputSchema, d as createAccountInputSchema, u as updateAccountInputSchema, f as deleteAccountInputSchema, h as getAccountInputSchema, k as getAccountsByOwnerInputSchema, m as listAccountsInputSchema, j as getAccountIdentifierInputSchema, l as listAccountIdentifiersInputSchema, g as findAccountByIdentifierInputSchema, i as getAccountBalanceInputSchema, r as updateTransactionConfirmationSentAtInputSchema } from '../shared/ledger.ByUO4e44.mjs';
|
|
4
|
+
import '@develit-io/general-codes';
|
|
5
|
+
import { s as schema } from '../shared/ledger.Bl4HgQDw.mjs';
|
|
6
|
+
import { eq, and, inArray, or, count, sql, gte, lte, asc, desc } from 'drizzle-orm';
|
|
7
|
+
import { drizzle } from 'drizzle-orm/d1';
|
|
8
|
+
import 'zod';
|
|
9
|
+
import 'drizzle-orm/sqlite-core';
|
|
10
|
+
|
|
11
|
+
const tables = schema;
|
|
12
|
+
|
|
13
|
+
const createAccountCommand = async (db, input) => {
|
|
14
|
+
const command = db.insert(tables.account).values(input).returning();
|
|
15
|
+
return { command };
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const createAccountIdentifierCommand = async (db, input) => {
|
|
19
|
+
const command = db.insert(tables.accountIdentifier).values(input).returning();
|
|
20
|
+
return { command };
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const deleteAccountCommand = async (db, id) => {
|
|
24
|
+
const accountIdentifierMappingCommand = db.delete(tables.accountIdentifierMapping).where(eq(tables.accountIdentifierMapping.accountId, id));
|
|
25
|
+
const accountCommand = db.delete(tables.account).where(eq(tables.account.id, id));
|
|
26
|
+
return { accountIdentifierMappingCommand, accountCommand };
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const linkAccountIdentifierCommand = async (db, accountId, identifierId) => {
|
|
30
|
+
const command = db.insert(tables.accountIdentifierMapping).values({ accountId, identifierId }).returning();
|
|
31
|
+
return { command };
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const updateAccountCommand = async (db, id, input) => {
|
|
35
|
+
const command = db.update(tables.account).set(input).where(eq(tables.account.id, id)).returning();
|
|
36
|
+
return { command };
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const updateTransactionStatusCommand = async (db, transactionId, status, completedAt) => {
|
|
40
|
+
const updateData = {
|
|
41
|
+
status,
|
|
42
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
43
|
+
...completedAt && { completedAt }
|
|
44
|
+
};
|
|
45
|
+
const command = db.update(tables.transaction).set(updateData).where(eq(tables.transaction.id, transactionId)).returning();
|
|
46
|
+
return { command };
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const updateTransactionConfirmationSentAtCommand = ({
|
|
50
|
+
db,
|
|
51
|
+
transactionId,
|
|
52
|
+
confirmationSentAt
|
|
53
|
+
}) => {
|
|
54
|
+
const command = db.update(tables.transaction).set({ confirmationSentAt, updatedAt: /* @__PURE__ */ new Date() }).where(eq(tables.transaction.id, transactionId));
|
|
55
|
+
return {
|
|
56
|
+
command
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const findAccountByIdentifierQuery = async (db, searchParams) => {
|
|
61
|
+
const conditions = [];
|
|
62
|
+
if (searchParams.iban) {
|
|
63
|
+
conditions.push(eq(tables.accountIdentifier.iban, searchParams.iban));
|
|
64
|
+
}
|
|
65
|
+
if (searchParams.accountNumber && searchParams.bankCode) {
|
|
66
|
+
conditions.push(
|
|
67
|
+
and(
|
|
68
|
+
eq(tables.accountIdentifier.accountNumber, searchParams.accountNumber),
|
|
69
|
+
eq(tables.accountIdentifier.bankCode, searchParams.bankCode)
|
|
70
|
+
)
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
if (searchParams.swift) {
|
|
74
|
+
conditions.push(eq(tables.accountIdentifier.swift, searchParams.swift));
|
|
75
|
+
}
|
|
76
|
+
if (searchParams.cryptoAddress) {
|
|
77
|
+
conditions.push(
|
|
78
|
+
eq(tables.accountIdentifier.cryptoAddress, searchParams.cryptoAddress)
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
if (conditions.length === 0) return void 0;
|
|
82
|
+
const result = await db.select({
|
|
83
|
+
account: tables.account,
|
|
84
|
+
identifier: tables.accountIdentifier
|
|
85
|
+
}).from(tables.accountIdentifier).innerJoin(
|
|
86
|
+
tables.accountIdentifierMapping,
|
|
87
|
+
eq(
|
|
88
|
+
tables.accountIdentifier.id,
|
|
89
|
+
tables.accountIdentifierMapping.identifierId
|
|
90
|
+
)
|
|
91
|
+
).innerJoin(
|
|
92
|
+
tables.account,
|
|
93
|
+
eq(tables.accountIdentifierMapping.accountId, tables.account.id)
|
|
94
|
+
).where(
|
|
95
|
+
inArray(
|
|
96
|
+
tables.account.id,
|
|
97
|
+
db.select({ accountId: tables.account.id }).from(tables.accountIdentifier).innerJoin(
|
|
98
|
+
tables.accountIdentifierMapping,
|
|
99
|
+
eq(
|
|
100
|
+
tables.accountIdentifier.id,
|
|
101
|
+
tables.accountIdentifierMapping.identifierId
|
|
102
|
+
)
|
|
103
|
+
).innerJoin(
|
|
104
|
+
tables.account,
|
|
105
|
+
eq(tables.accountIdentifierMapping.accountId, tables.account.id)
|
|
106
|
+
).where(or(...conditions))
|
|
107
|
+
)
|
|
108
|
+
);
|
|
109
|
+
if (result.length === 0) return void 0;
|
|
110
|
+
const account = result[0].account;
|
|
111
|
+
const identifiers = result.map((row) => ({
|
|
112
|
+
identifierId: row.identifier.id,
|
|
113
|
+
accountId: account.id
|
|
114
|
+
}));
|
|
115
|
+
return {
|
|
116
|
+
...account,
|
|
117
|
+
identifiers
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const getAccountBalanceByIdQuery = async (db, accountId) => {
|
|
122
|
+
const entries = await db.select().from(tables.entry).where(eq(tables.entry.accountId, accountId));
|
|
123
|
+
return entries.map((entry) => {
|
|
124
|
+
return entry.creditAmount - entry.debitAmount;
|
|
125
|
+
}).reduce((acc, curr) => acc + curr, 0);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const getAccountByIdQuery = async (db, id) => {
|
|
129
|
+
return await db.select().from(tables.account).where(eq(tables.account.id, id)).then(first);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const getAccountIdentifierByIdQuery = async (db, id) => {
|
|
133
|
+
return await db.select().from(tables.accountIdentifier).where(eq(tables.accountIdentifier.id, id)).then(first);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const getAccountWithIdentifiersQuery = async (db, accountId) => {
|
|
137
|
+
const result = await db.select({
|
|
138
|
+
account: tables.account,
|
|
139
|
+
identifier: tables.accountIdentifier
|
|
140
|
+
}).from(tables.account).innerJoin(
|
|
141
|
+
tables.accountIdentifierMapping,
|
|
142
|
+
eq(tables.account.id, tables.accountIdentifierMapping.accountId)
|
|
143
|
+
).innerJoin(
|
|
144
|
+
tables.accountIdentifier,
|
|
145
|
+
eq(
|
|
146
|
+
tables.accountIdentifierMapping.identifierId,
|
|
147
|
+
tables.accountIdentifier.id
|
|
148
|
+
)
|
|
149
|
+
).where(eq(tables.account.id, accountId));
|
|
150
|
+
if (result.length === 0) return void 0;
|
|
151
|
+
const account = result[0].account;
|
|
152
|
+
const identifiers = result.map((row) => row.identifier);
|
|
153
|
+
return {
|
|
154
|
+
...account,
|
|
155
|
+
identifiers: identifiers.map((identifier) => ({
|
|
156
|
+
identifierId: identifier.id,
|
|
157
|
+
accountId
|
|
158
|
+
}))
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const getAccountsByOwnerQuery = async (db, ownerId) => {
|
|
163
|
+
return await db.select().from(tables.account).where(eq(tables.account.ownerId, ownerId));
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const getTransactionByIdQuery = async (db, id) => {
|
|
167
|
+
return await db.select().from(tables.transaction).where(eq(tables.transaction.id, id)).then(first);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const getTransactionsByCorrelationIdQuery = async (db, correlationId) => {
|
|
171
|
+
return await db.select().from(tables.transaction).where(eq(tables.transaction.correlationId, correlationId)).execute();
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const getTransactionsByReferenceIdQuery = async (db, referenceType, referenceId) => {
|
|
175
|
+
return await db.select().from(tables.transaction).where(
|
|
176
|
+
and(
|
|
177
|
+
eq(tables.transaction.referenceType, referenceType),
|
|
178
|
+
eq(tables.transaction.referenceId, referenceId)
|
|
179
|
+
)
|
|
180
|
+
).execute();
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const listAccountIdentifiersQuery = async (db, accountId) => {
|
|
184
|
+
const result = await db.select({
|
|
185
|
+
identifier: tables.accountIdentifier
|
|
186
|
+
}).from(tables.accountIdentifierMapping).innerJoin(
|
|
187
|
+
tables.accountIdentifier,
|
|
188
|
+
eq(
|
|
189
|
+
tables.accountIdentifierMapping.identifierId,
|
|
190
|
+
tables.accountIdentifier.id
|
|
191
|
+
)
|
|
192
|
+
).where(eq(tables.accountIdentifierMapping.accountId, accountId));
|
|
193
|
+
return result.map((row) => row.identifier);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const listAccountsQuery = async (db, filters = {}, pagination = { limit: 100, offset: 0 }) => {
|
|
197
|
+
const conditions = [];
|
|
198
|
+
if (filters.ownerId) {
|
|
199
|
+
conditions.push(eq(tables.account.ownerId, filters.ownerId));
|
|
200
|
+
}
|
|
201
|
+
if (filters.accountType) {
|
|
202
|
+
conditions.push(eq(tables.account.accountType, filters.accountType));
|
|
203
|
+
}
|
|
204
|
+
if (filters.assetType) {
|
|
205
|
+
conditions.push(eq(tables.account.assetType, filters.assetType));
|
|
206
|
+
}
|
|
207
|
+
if (filters.currency) {
|
|
208
|
+
conditions.push(eq(tables.account.currency, filters.currency));
|
|
209
|
+
}
|
|
210
|
+
if (filters.parentAccountId) {
|
|
211
|
+
conditions.push(eq(tables.account.parentAccountId, filters.parentAccountId));
|
|
212
|
+
}
|
|
213
|
+
const whereClause = conditions.length > 0 ? and(...conditions) : void 0;
|
|
214
|
+
const [{ total }] = await db.select({ total: count() }).from(tables.account).where(whereClause);
|
|
215
|
+
const accounts = await db.select().from(tables.account).where(whereClause).limit(pagination.limit).offset(pagination.offset);
|
|
216
|
+
return { accounts, total };
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const buildSearchConditions = (search, columns, opts = {}) => {
|
|
220
|
+
const { wrap = "both" } = opts;
|
|
221
|
+
if (!search || search.trim() === "" || columns.length === 0) return void 0;
|
|
222
|
+
const searchTerm = search.toLowerCase();
|
|
223
|
+
const pattern = wrap === "both" ? `%${searchTerm}%` : wrap === "prefix" ? `%${searchTerm}` : wrap === "suffix" ? `${searchTerm}%` : searchTerm;
|
|
224
|
+
const parts = columns.map((col) => sql`LOWER(${col} || '') LIKE ${pattern}`);
|
|
225
|
+
return parts.length === 1 ? parts[0] : or(...parts);
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const resolveColumn = (table, column, fallback = "updatedAt") => {
|
|
229
|
+
const key = column && column in table ? column : fallback;
|
|
230
|
+
return table[key];
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const getTransactionsWithPaginationQuery = async ({
|
|
234
|
+
db,
|
|
235
|
+
pagination: {
|
|
236
|
+
limit,
|
|
237
|
+
page,
|
|
238
|
+
sort,
|
|
239
|
+
filterTransactionCorrelationId,
|
|
240
|
+
filterTransactionReferenceType,
|
|
241
|
+
filterTransactionReferenceId,
|
|
242
|
+
filterTransactionType,
|
|
243
|
+
filterTransactionDescription,
|
|
244
|
+
filterTransactionDateFrom,
|
|
245
|
+
filterTransactionDateTo,
|
|
246
|
+
filterTransactionCompletedAt,
|
|
247
|
+
filterTransactionStatus,
|
|
248
|
+
search
|
|
249
|
+
}
|
|
250
|
+
}) => {
|
|
251
|
+
const searchConditions = buildSearchConditions(search, [
|
|
252
|
+
tables.transaction.status,
|
|
253
|
+
tables.transaction.description,
|
|
254
|
+
tables.transaction.type,
|
|
255
|
+
tables.transaction.referenceId,
|
|
256
|
+
tables.transaction.correlationId
|
|
257
|
+
]);
|
|
258
|
+
const whereConditions = and(
|
|
259
|
+
searchConditions ? searchConditions : void 0,
|
|
260
|
+
filterTransactionCorrelationId ? eq(tables.transaction.correlationId, filterTransactionCorrelationId) : void 0,
|
|
261
|
+
filterTransactionReferenceType ? eq(tables.transaction.referenceType, filterTransactionReferenceType) : void 0,
|
|
262
|
+
filterTransactionReferenceId ? eq(tables.transaction.referenceId, filterTransactionReferenceId) : void 0,
|
|
263
|
+
filterTransactionType ? eq(tables.transaction.type, filterTransactionType) : void 0,
|
|
264
|
+
filterTransactionDescription ? eq(tables.transaction.description, filterTransactionDescription) : void 0,
|
|
265
|
+
filterTransactionDateFrom ? gte(tables.transaction.createdAt, filterTransactionDateFrom) : void 0,
|
|
266
|
+
filterTransactionDateTo ? lte(tables.transaction.createdAt, filterTransactionDateTo) : void 0,
|
|
267
|
+
filterTransactionCompletedAt ? eq(tables.transaction.completedAt, filterTransactionCompletedAt) : void 0,
|
|
268
|
+
filterTransactionStatus ? eq(tables.transaction.status, filterTransactionStatus) : void 0
|
|
269
|
+
);
|
|
270
|
+
const sortColumn = resolveColumn(tables.transaction, sort.column);
|
|
271
|
+
const [{ totalCount }] = await db.select({ totalCount: sql`count(*)` }).from(tables.transaction).where(whereConditions);
|
|
272
|
+
const transactionIds = await db.select({ id: tables.transaction.id }).from(tables.transaction).where(whereConditions).limit(limit).offset((page - 1) * limit).orderBy(sort.direction === "asc" ? asc(sortColumn) : desc(sortColumn));
|
|
273
|
+
if (transactionIds.length === 0) {
|
|
274
|
+
return {
|
|
275
|
+
transactions: [],
|
|
276
|
+
totalCount
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const transactions = await db.select().from(tables.transaction).where(
|
|
280
|
+
inArray(
|
|
281
|
+
tables.transaction.id,
|
|
282
|
+
transactionIds.map((o) => o.id)
|
|
283
|
+
)
|
|
284
|
+
).orderBy(sort.direction === "asc" ? asc(sortColumn) : desc(sortColumn));
|
|
285
|
+
return {
|
|
286
|
+
transactions,
|
|
287
|
+
totalCount
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
var __defProp = Object.defineProperty;
|
|
292
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
293
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
294
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
295
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
296
|
+
if (decorator = decorators[i])
|
|
297
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
298
|
+
if (kind && result) __defProp(target, key, result);
|
|
299
|
+
return result;
|
|
300
|
+
};
|
|
301
|
+
let LedgerServiceBase = class extends develitWorker(WorkerEntrypoint) {
|
|
302
|
+
constructor(ctx, env) {
|
|
303
|
+
super(ctx, env);
|
|
304
|
+
this.db = drizzle(this.env.LEDGER_D1, { schema: tables });
|
|
305
|
+
}
|
|
306
|
+
async queue(_batch) {
|
|
307
|
+
}
|
|
308
|
+
async createTransaction(input) {
|
|
309
|
+
return this.handleAction(
|
|
310
|
+
{
|
|
311
|
+
data: input,
|
|
312
|
+
schema: createTransactionInputSchema
|
|
313
|
+
},
|
|
314
|
+
{ successMessage: "Transaction successfully created." },
|
|
315
|
+
async (params) => {
|
|
316
|
+
const {
|
|
317
|
+
correlationId,
|
|
318
|
+
referenceType,
|
|
319
|
+
referenceId,
|
|
320
|
+
type,
|
|
321
|
+
description,
|
|
322
|
+
paymentId,
|
|
323
|
+
metadata
|
|
324
|
+
// TODO: entries will be implemented later
|
|
325
|
+
// entries: inputEntries,
|
|
326
|
+
} = params;
|
|
327
|
+
await getTransactionsByCorrelationIdQuery(
|
|
328
|
+
this.db,
|
|
329
|
+
correlationId
|
|
330
|
+
);
|
|
331
|
+
const transactionId = uuidv4();
|
|
332
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
333
|
+
const transaction = {
|
|
334
|
+
id: transactionId,
|
|
335
|
+
correlationId,
|
|
336
|
+
referenceType,
|
|
337
|
+
referenceId,
|
|
338
|
+
type,
|
|
339
|
+
description,
|
|
340
|
+
createdAt: timestamp,
|
|
341
|
+
completedAt: null,
|
|
342
|
+
status: "WAITING_FOR_PAYMENT",
|
|
343
|
+
//todo: get from input?
|
|
344
|
+
paymentId,
|
|
345
|
+
metadata,
|
|
346
|
+
updatedAt: timestamp
|
|
347
|
+
};
|
|
348
|
+
const [data, error] = await useResult(
|
|
349
|
+
this.db.insert(tables.transaction).values(transaction).returning().then(first)
|
|
350
|
+
);
|
|
351
|
+
if (error) {
|
|
352
|
+
throw createInternalError(null, {
|
|
353
|
+
message: "Failed to create transaction",
|
|
354
|
+
status: 500,
|
|
355
|
+
code: "INTERNAL_ERROR"
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
const result = {
|
|
359
|
+
transaction: data
|
|
360
|
+
// TODO: entries will be implemented later
|
|
361
|
+
// entries: createdEntries,
|
|
362
|
+
};
|
|
363
|
+
await this.pushToQueue(
|
|
364
|
+
this.env.QUEUE_BUS_QUEUE,
|
|
365
|
+
{
|
|
366
|
+
eventType: "LEDGER_TRANSACTION",
|
|
367
|
+
ledgerTransaction: result.transaction,
|
|
368
|
+
metadata: {
|
|
369
|
+
correlationId: uuidv4(),
|
|
370
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
);
|
|
374
|
+
return {
|
|
375
|
+
transaction: result.transaction
|
|
376
|
+
// TODO: entries will be implemented later
|
|
377
|
+
// entries: result.entries,
|
|
378
|
+
// isBalanced: false,
|
|
379
|
+
// imbalancedCurrencies:
|
|
380
|
+
// imbalancedCurrencies.length > 0 ? imbalancedCurrencies : undefined,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
async updateTransaction(input) {
|
|
386
|
+
return this.handleAction(
|
|
387
|
+
{ data: input, schema: updateTransactionInputSchema },
|
|
388
|
+
{ successMessage: "Transaction successfully updated." },
|
|
389
|
+
async (params) => {
|
|
390
|
+
const { transactionId, status, completedAt } = params;
|
|
391
|
+
const existingTransaction = await getTransactionByIdQuery(
|
|
392
|
+
this.db,
|
|
393
|
+
transactionId
|
|
394
|
+
);
|
|
395
|
+
if (!existingTransaction) {
|
|
396
|
+
throw createInternalError(null, {
|
|
397
|
+
message: "Transaction not found",
|
|
398
|
+
status: 404,
|
|
399
|
+
code: "NOT_FOUND"
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
const { command } = await updateTransactionStatusCommand(
|
|
403
|
+
this.db,
|
|
404
|
+
transactionId,
|
|
405
|
+
status,
|
|
406
|
+
completedAt
|
|
407
|
+
);
|
|
408
|
+
const [updatedTransaction] = await this.db.batch([command]);
|
|
409
|
+
if (!updatedTransaction) {
|
|
410
|
+
throw createInternalError(null, {
|
|
411
|
+
message: "Failed to update transaction",
|
|
412
|
+
status: 500,
|
|
413
|
+
code: "INTERNAL_ERROR"
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
const transaction = first(updatedTransaction);
|
|
417
|
+
await this.pushToQueue(
|
|
418
|
+
this.env.QUEUE_BUS_QUEUE,
|
|
419
|
+
{
|
|
420
|
+
eventType: "LEDGER_TRANSACTION",
|
|
421
|
+
ledgerTransaction: transaction,
|
|
422
|
+
metadata: {
|
|
423
|
+
correlationId: uuidv4(),
|
|
424
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
);
|
|
428
|
+
return transaction;
|
|
429
|
+
}
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
async getTransactionById(input) {
|
|
433
|
+
return this.handleAction(
|
|
434
|
+
{ data: input, schema: getTransactionByIdInputSchema },
|
|
435
|
+
{ successMessage: "Transaction successfully obtained." },
|
|
436
|
+
async (params) => {
|
|
437
|
+
const { id } = params;
|
|
438
|
+
const transaction = await getTransactionByIdQuery(this.db, id);
|
|
439
|
+
return transaction;
|
|
440
|
+
}
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
async getTransactionsByReferenceId(input) {
|
|
444
|
+
return this.handleAction(
|
|
445
|
+
{ data: input, schema: getTransactionsByReferenceIdInputSchema },
|
|
446
|
+
{ successMessage: "Transaction successfully obtained." },
|
|
447
|
+
async (params) => {
|
|
448
|
+
const { referenceType, referenceId } = params;
|
|
449
|
+
const transactions = await getTransactionsByReferenceIdQuery(
|
|
450
|
+
this.db,
|
|
451
|
+
referenceType,
|
|
452
|
+
referenceId
|
|
453
|
+
);
|
|
454
|
+
return transactions;
|
|
455
|
+
}
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
async getTransactions(input) {
|
|
459
|
+
return this.handleAction(
|
|
460
|
+
{ data: input, schema: getTransactionsInputSchema },
|
|
461
|
+
{ successMessage: "Transactions fetched successfully" },
|
|
462
|
+
async (pagination) => {
|
|
463
|
+
const { transactions, totalCount } = await getTransactionsWithPaginationQuery({
|
|
464
|
+
db: this.db,
|
|
465
|
+
pagination
|
|
466
|
+
});
|
|
467
|
+
return { transactions, totalCount };
|
|
468
|
+
}
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
async createAccount(input) {
|
|
472
|
+
return this.handleAction(
|
|
473
|
+
{ data: input, schema: createAccountInputSchema },
|
|
474
|
+
{ successMessage: "Account successfully created." },
|
|
475
|
+
async (params) => {
|
|
476
|
+
const { identifier, ...accountData } = params;
|
|
477
|
+
const { command } = await createAccountCommand(this.db, {
|
|
478
|
+
id: uuidv4(),
|
|
479
|
+
...accountData,
|
|
480
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
481
|
+
});
|
|
482
|
+
const [[account]] = await this.db.batch([command]);
|
|
483
|
+
if (!account) {
|
|
484
|
+
throw createInternalError(null, {
|
|
485
|
+
message: "Failed to create account",
|
|
486
|
+
status: 500,
|
|
487
|
+
code: "INTERNAL_SERVER_ERROR"
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
if (identifier) {
|
|
491
|
+
const { command: command2 } = await createAccountIdentifierCommand(this.db, {
|
|
492
|
+
id: uuidv4(),
|
|
493
|
+
...identifier,
|
|
494
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
495
|
+
});
|
|
496
|
+
const [[accountIdentifier]] = await this.db.batch([command2]);
|
|
497
|
+
if (accountIdentifier) {
|
|
498
|
+
const { command: command3 } = await linkAccountIdentifierCommand(
|
|
499
|
+
this.db,
|
|
500
|
+
account.id,
|
|
501
|
+
accountIdentifier.id
|
|
502
|
+
);
|
|
503
|
+
await this.db.batch([command3]);
|
|
504
|
+
}
|
|
505
|
+
return { account, identifier: accountIdentifier };
|
|
506
|
+
}
|
|
507
|
+
return { account, identifier: void 0 };
|
|
508
|
+
}
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
async updateAccount(input) {
|
|
512
|
+
return this.handleAction(
|
|
513
|
+
{ data: input, schema: updateAccountInputSchema },
|
|
514
|
+
{ successMessage: "Account successfully updated." },
|
|
515
|
+
async (params) => {
|
|
516
|
+
const { accountId, ...updateData } = params;
|
|
517
|
+
if (Object.keys(input).length === 0) {
|
|
518
|
+
const account2 = await getAccountByIdQuery(this.db, accountId);
|
|
519
|
+
if (!account2) {
|
|
520
|
+
throw createInternalError(null, {
|
|
521
|
+
message: "Account not found or update failed",
|
|
522
|
+
status: 404,
|
|
523
|
+
code: "NOT_FOUND"
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
return account2;
|
|
527
|
+
}
|
|
528
|
+
const { command } = await updateAccountCommand(
|
|
529
|
+
this.db,
|
|
530
|
+
accountId,
|
|
531
|
+
updateData
|
|
532
|
+
);
|
|
533
|
+
const [account] = await this.db.batch([command]);
|
|
534
|
+
if (!account) {
|
|
535
|
+
throw createInternalError(null, {
|
|
536
|
+
message: "Account not found or update failed",
|
|
537
|
+
status: 404,
|
|
538
|
+
code: "NOT_FOUND"
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
return first(account);
|
|
542
|
+
}
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
async deleteAccount(input) {
|
|
546
|
+
return this.handleAction(
|
|
547
|
+
{ data: input, schema: deleteAccountInputSchema },
|
|
548
|
+
{ successMessage: "Account successfully deleted." },
|
|
549
|
+
async (params) => {
|
|
550
|
+
const { accountId } = params;
|
|
551
|
+
const { accountIdentifierMappingCommand, accountCommand } = await deleteAccountCommand(this.db, accountId);
|
|
552
|
+
const [result] = await this.db.batch([
|
|
553
|
+
accountIdentifierMappingCommand,
|
|
554
|
+
accountCommand
|
|
555
|
+
]);
|
|
556
|
+
return result.success;
|
|
557
|
+
}
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
async getAccount(input) {
|
|
561
|
+
return this.handleAction(
|
|
562
|
+
{ data: input, schema: getAccountInputSchema },
|
|
563
|
+
{ successMessage: "Account successfully retrieved." },
|
|
564
|
+
async (params) => {
|
|
565
|
+
const { accountId } = params;
|
|
566
|
+
const account = await getAccountWithIdentifiersQuery(this.db, accountId);
|
|
567
|
+
if (!account) {
|
|
568
|
+
throw createInternalError(null, {
|
|
569
|
+
message: "Account not found",
|
|
570
|
+
status: 404,
|
|
571
|
+
code: "NOT_FOUND"
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
return account;
|
|
575
|
+
}
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
async getAccountsByOwner(input) {
|
|
579
|
+
return this.handleAction(
|
|
580
|
+
{ data: input, schema: getAccountsByOwnerInputSchema },
|
|
581
|
+
{ successMessage: "Accounts successfully retrieved." },
|
|
582
|
+
async (params) => {
|
|
583
|
+
const { ownerId } = params;
|
|
584
|
+
const accounts = await getAccountsByOwnerQuery(this.db, ownerId);
|
|
585
|
+
return accounts;
|
|
586
|
+
}
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
async listAccounts(input) {
|
|
590
|
+
return this.handleAction(
|
|
591
|
+
{ data: input, schema: listAccountsInputSchema },
|
|
592
|
+
{ successMessage: "Accounts successfully listed." },
|
|
593
|
+
async (params) => {
|
|
594
|
+
const {
|
|
595
|
+
ownerId,
|
|
596
|
+
accountType,
|
|
597
|
+
assetType,
|
|
598
|
+
currency,
|
|
599
|
+
parentAccountId,
|
|
600
|
+
limit,
|
|
601
|
+
offset
|
|
602
|
+
} = params;
|
|
603
|
+
const result = await listAccountsQuery(
|
|
604
|
+
this.db,
|
|
605
|
+
{ ownerId, accountType, assetType, currency, parentAccountId },
|
|
606
|
+
{ limit, offset }
|
|
607
|
+
);
|
|
608
|
+
return {
|
|
609
|
+
accounts: result.accounts,
|
|
610
|
+
total: result.total,
|
|
611
|
+
limit,
|
|
612
|
+
offset
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
async getAccountIdentifierById(input) {
|
|
618
|
+
return this.handleAction(
|
|
619
|
+
{ data: input, schema: getAccountIdentifierInputSchema },
|
|
620
|
+
{ successMessage: "Account identifier successfully retrieved." },
|
|
621
|
+
async (params) => {
|
|
622
|
+
const { identifierId } = params;
|
|
623
|
+
const identifier = await getAccountIdentifierByIdQuery(
|
|
624
|
+
this.db,
|
|
625
|
+
identifierId
|
|
626
|
+
);
|
|
627
|
+
if (!identifier) {
|
|
628
|
+
throw createInternalError(null, {
|
|
629
|
+
message: "Account identifier not found",
|
|
630
|
+
status: 404,
|
|
631
|
+
code: "NOT_FOUND"
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
return identifier;
|
|
635
|
+
}
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
async listAccountIdentifiers(input) {
|
|
639
|
+
return this.handleAction(
|
|
640
|
+
{ data: input, schema: listAccountIdentifiersInputSchema },
|
|
641
|
+
{ successMessage: "Account identifiers successfully listed." },
|
|
642
|
+
async (params) => {
|
|
643
|
+
const { accountId } = params;
|
|
644
|
+
const identifiers = await listAccountIdentifiersQuery(
|
|
645
|
+
this.db,
|
|
646
|
+
accountId
|
|
647
|
+
);
|
|
648
|
+
return identifiers;
|
|
649
|
+
}
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
async findAccountByIdentifier(input) {
|
|
653
|
+
return this.handleAction(
|
|
654
|
+
{ data: input, schema: findAccountByIdentifierInputSchema },
|
|
655
|
+
{ successMessage: "Account search completed." },
|
|
656
|
+
async (params) => {
|
|
657
|
+
const searchParams = params;
|
|
658
|
+
const account = await findAccountByIdentifierQuery(
|
|
659
|
+
this.db,
|
|
660
|
+
searchParams
|
|
661
|
+
);
|
|
662
|
+
return account;
|
|
663
|
+
}
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
async getAccountBalance(input) {
|
|
667
|
+
return this.handleAction(
|
|
668
|
+
{ data: input, schema: getAccountBalanceInputSchema },
|
|
669
|
+
{ successMessage: "Balance successfully obtained." },
|
|
670
|
+
async (params) => {
|
|
671
|
+
const { accountId } = params;
|
|
672
|
+
const account = await getAccountByIdQuery(this.db, accountId);
|
|
673
|
+
if (!account) {
|
|
674
|
+
throw new Error(`Account ${accountId} not found`);
|
|
675
|
+
}
|
|
676
|
+
const balance = await getAccountBalanceByIdQuery(this.db, accountId);
|
|
677
|
+
return { balance };
|
|
678
|
+
}
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
async updateTransactionConfirmationSentAt(input) {
|
|
682
|
+
return this.handleAction(
|
|
683
|
+
{ data: input, schema: updateTransactionConfirmationSentAtInputSchema },
|
|
684
|
+
{ successMessage: "Confirmation email sent successfully" },
|
|
685
|
+
async ({ transactionId }) => {
|
|
686
|
+
const { command: transactionCommand } = updateTransactionConfirmationSentAtCommand({
|
|
687
|
+
db: this.db,
|
|
688
|
+
transactionId,
|
|
689
|
+
confirmationSentAt: /* @__PURE__ */ new Date()
|
|
690
|
+
});
|
|
691
|
+
await this.db.batch([transactionCommand]);
|
|
692
|
+
}
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
__decorateClass([
|
|
697
|
+
cloudflareQueue({ baseDelay: 60 })
|
|
698
|
+
], LedgerServiceBase.prototype, "queue", 1);
|
|
699
|
+
__decorateClass([
|
|
700
|
+
action("create-transaction")
|
|
701
|
+
], LedgerServiceBase.prototype, "createTransaction", 1);
|
|
702
|
+
__decorateClass([
|
|
703
|
+
action("update-transaction")
|
|
704
|
+
], LedgerServiceBase.prototype, "updateTransaction", 1);
|
|
705
|
+
__decorateClass([
|
|
706
|
+
action("get-transaction-by-id")
|
|
707
|
+
], LedgerServiceBase.prototype, "getTransactionById", 1);
|
|
708
|
+
__decorateClass([
|
|
709
|
+
action("get-transactions-by-reference-id")
|
|
710
|
+
], LedgerServiceBase.prototype, "getTransactionsByReferenceId", 1);
|
|
711
|
+
__decorateClass([
|
|
712
|
+
action("get-transactions")
|
|
713
|
+
], LedgerServiceBase.prototype, "getTransactions", 1);
|
|
714
|
+
__decorateClass([
|
|
715
|
+
action("create-account")
|
|
716
|
+
], LedgerServiceBase.prototype, "createAccount", 1);
|
|
717
|
+
__decorateClass([
|
|
718
|
+
action("update-account")
|
|
719
|
+
], LedgerServiceBase.prototype, "updateAccount", 1);
|
|
720
|
+
__decorateClass([
|
|
721
|
+
action("delete-account")
|
|
722
|
+
], LedgerServiceBase.prototype, "deleteAccount", 1);
|
|
723
|
+
__decorateClass([
|
|
724
|
+
action("get-account")
|
|
725
|
+
], LedgerServiceBase.prototype, "getAccount", 1);
|
|
726
|
+
__decorateClass([
|
|
727
|
+
action("get-accounts-by-owner")
|
|
728
|
+
], LedgerServiceBase.prototype, "getAccountsByOwner", 1);
|
|
729
|
+
__decorateClass([
|
|
730
|
+
action("list-accounts")
|
|
731
|
+
], LedgerServiceBase.prototype, "listAccounts", 1);
|
|
732
|
+
__decorateClass([
|
|
733
|
+
action("get-account-identifier")
|
|
734
|
+
], LedgerServiceBase.prototype, "getAccountIdentifierById", 1);
|
|
735
|
+
__decorateClass([
|
|
736
|
+
action("list-account-identifiers")
|
|
737
|
+
], LedgerServiceBase.prototype, "listAccountIdentifiers", 1);
|
|
738
|
+
__decorateClass([
|
|
739
|
+
action("find-account-by-identifier")
|
|
740
|
+
], LedgerServiceBase.prototype, "findAccountByIdentifier", 1);
|
|
741
|
+
__decorateClass([
|
|
742
|
+
action("get-account-balance")
|
|
743
|
+
], LedgerServiceBase.prototype, "getAccountBalance", 1);
|
|
744
|
+
__decorateClass([
|
|
745
|
+
action("update-transaction-confirmation-sent-at")
|
|
746
|
+
], LedgerServiceBase.prototype, "updateTransactionConfirmationSentAt", 1);
|
|
747
|
+
LedgerServiceBase = __decorateClass([
|
|
748
|
+
service("ledger")
|
|
749
|
+
], LedgerServiceBase);
|
|
750
|
+
function defineLedgerService() {
|
|
751
|
+
return class LedgerService extends LedgerServiceBase {
|
|
752
|
+
constructor(ctx, env) {
|
|
753
|
+
super(ctx, env);
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
const LedgerService = defineLedgerService();
|
|
758
|
+
|
|
759
|
+
export { LedgerService as default, defineLedgerService };
|