@firela/api-types 0.0.0-canary.209966
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/index.d.mts +6570 -0
- package/dist/index.d.ts +6570 -0
- package/dist/index.js +1235 -0
- package/dist/index.mjs +1202 -0
- package/package.json +47 -0
- package/src/generated/core/ApiError.ts +25 -0
- package/src/generated/core/ApiRequestOptions.ts +20 -0
- package/src/generated/core/ApiResult.ts +7 -0
- package/src/generated/core/CancelablePromise.ts +126 -0
- package/src/generated/core/OpenAPI.ts +56 -0
- package/src/generated/core/request.ts +391 -0
- package/src/generated/index.ts +7 -0
- package/src/generated/schemas.gen.ts +4833 -0
- package/src/generated/services.gen.ts +3330 -0
- package/src/generated/types.gen.ts +6832 -0
- package/src/index.ts +12 -0
|
@@ -0,0 +1,4833 @@
|
|
|
1
|
+
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
|
+
|
|
3
|
+
export const $CreateAccountDto = {
|
|
4
|
+
type: 'object',
|
|
5
|
+
properties: {
|
|
6
|
+
path: {
|
|
7
|
+
type: 'string',
|
|
8
|
+
description: 'Account path (hierarchical, colon-separated)',
|
|
9
|
+
example: 'Assets:CN:Bank:ICBC:Checking'
|
|
10
|
+
},
|
|
11
|
+
openDate: {
|
|
12
|
+
format: 'date-time',
|
|
13
|
+
type: 'string',
|
|
14
|
+
description: 'Account open date',
|
|
15
|
+
example: '2024-01-01'
|
|
16
|
+
},
|
|
17
|
+
currencies: {
|
|
18
|
+
description: 'Allowed currencies (null = no restriction)',
|
|
19
|
+
example: ['CNY', 'USD'],
|
|
20
|
+
type: 'array',
|
|
21
|
+
items: {
|
|
22
|
+
type: 'string'
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
bookingMethod: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
description: 'Booking method for cost basis',
|
|
28
|
+
enum: [
|
|
29
|
+
'FIFO',
|
|
30
|
+
'LIFO',
|
|
31
|
+
'HIFO',
|
|
32
|
+
'AVERAGE',
|
|
33
|
+
'STRICT',
|
|
34
|
+
'STRICT_WITH_SIZE',
|
|
35
|
+
'NONE'
|
|
36
|
+
],
|
|
37
|
+
default: 'FIFO'
|
|
38
|
+
},
|
|
39
|
+
templatePath: {
|
|
40
|
+
type: 'string',
|
|
41
|
+
description: 'Reference to account-standards template path',
|
|
42
|
+
example: 'Assets:CN:Bank:ICBC:Checking'
|
|
43
|
+
},
|
|
44
|
+
isCustom: {
|
|
45
|
+
type: 'boolean',
|
|
46
|
+
description: 'Whether this is a custom (user-created) account',
|
|
47
|
+
default: false
|
|
48
|
+
},
|
|
49
|
+
i18nKey: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
description: 'i18n key for display name (overrides template)',
|
|
52
|
+
example: 'account.custom.mybank'
|
|
53
|
+
},
|
|
54
|
+
icon: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: 'Icon identifier (overrides template)',
|
|
57
|
+
example: 'bank-custom'
|
|
58
|
+
},
|
|
59
|
+
openMeta: {
|
|
60
|
+
type: 'object',
|
|
61
|
+
description: 'Additional metadata',
|
|
62
|
+
example: {
|
|
63
|
+
branch: 'Downtown',
|
|
64
|
+
accountNumber: '1234'
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
platformId: {
|
|
68
|
+
type: 'string',
|
|
69
|
+
description: 'Platform ID (references Platform.id)',
|
|
70
|
+
example: 'c98e5d4a-2f71-4a5a-bb3c-92c9f231d5e2'
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
required: ['path', 'openDate']
|
|
74
|
+
} as const;
|
|
75
|
+
|
|
76
|
+
export const $AccountResponseDto = {
|
|
77
|
+
type: 'object',
|
|
78
|
+
properties: {
|
|
79
|
+
id: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
description: 'Account UUID',
|
|
82
|
+
example: '550e8400-e29b-41d4-a716-446655440000'
|
|
83
|
+
},
|
|
84
|
+
path: {
|
|
85
|
+
type: 'string',
|
|
86
|
+
description: 'Account path (hierarchical, colon-separated)',
|
|
87
|
+
example: 'Assets:CN:Bank:ICBC:Checking'
|
|
88
|
+
},
|
|
89
|
+
type: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'Account type (root segment)',
|
|
92
|
+
enum: ['Assets', 'Liabilities', 'Income', 'Expenses', 'Equity'],
|
|
93
|
+
example: 'Assets'
|
|
94
|
+
},
|
|
95
|
+
status: {
|
|
96
|
+
type: 'string',
|
|
97
|
+
description: 'Account status',
|
|
98
|
+
enum: ['OPEN', 'CLOSED', 'SUSPENDED'],
|
|
99
|
+
example: 'OPEN'
|
|
100
|
+
},
|
|
101
|
+
openDate: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
description: 'Account open date',
|
|
104
|
+
example: '2024-01-01'
|
|
105
|
+
},
|
|
106
|
+
closeDate: {
|
|
107
|
+
type: 'string',
|
|
108
|
+
description: 'Account close date (if closed)',
|
|
109
|
+
example: '2024-12-31'
|
|
110
|
+
},
|
|
111
|
+
currencies: {
|
|
112
|
+
description: 'Allowed currencies (null = no restriction)',
|
|
113
|
+
example: ['CNY', 'USD'],
|
|
114
|
+
type: 'array',
|
|
115
|
+
items: {
|
|
116
|
+
type: 'string'
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
bookingMethod: {
|
|
120
|
+
type: 'string',
|
|
121
|
+
description: 'Booking method',
|
|
122
|
+
enum: [
|
|
123
|
+
'FIFO',
|
|
124
|
+
'LIFO',
|
|
125
|
+
'HIFO',
|
|
126
|
+
'AVERAGE',
|
|
127
|
+
'STRICT',
|
|
128
|
+
'STRICT_WITH_SIZE',
|
|
129
|
+
'NONE'
|
|
130
|
+
],
|
|
131
|
+
example: 'FIFO'
|
|
132
|
+
},
|
|
133
|
+
templatePath: {
|
|
134
|
+
type: 'string',
|
|
135
|
+
description: 'Template path reference',
|
|
136
|
+
example: 'Assets:CN:Bank:ICBC:Checking'
|
|
137
|
+
},
|
|
138
|
+
isCustom: {
|
|
139
|
+
type: 'boolean',
|
|
140
|
+
description: 'Whether this is a custom (user-created) account',
|
|
141
|
+
example: false
|
|
142
|
+
},
|
|
143
|
+
i18nKey: {
|
|
144
|
+
type: 'string',
|
|
145
|
+
description: 'i18n key for display name',
|
|
146
|
+
example: 'account.assets.cn.bank.icbc.checking'
|
|
147
|
+
},
|
|
148
|
+
icon: {
|
|
149
|
+
type: 'string',
|
|
150
|
+
description: 'Icon identifier',
|
|
151
|
+
example: 'bank-icbc'
|
|
152
|
+
},
|
|
153
|
+
openMeta: {
|
|
154
|
+
type: 'object',
|
|
155
|
+
description: 'Account metadata',
|
|
156
|
+
example: {
|
|
157
|
+
branch: 'Downtown'
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
platformId: {
|
|
161
|
+
type: 'object',
|
|
162
|
+
description: 'Platform ID (null if unbound)',
|
|
163
|
+
example: 'c98e5d4a-2f71-4a5a-bb3c-92c9f231d5e2'
|
|
164
|
+
},
|
|
165
|
+
platform: {
|
|
166
|
+
type: 'object',
|
|
167
|
+
description: 'Platform details (populated if platformId is set)'
|
|
168
|
+
},
|
|
169
|
+
createdAt: {
|
|
170
|
+
type: 'string',
|
|
171
|
+
description: 'Created timestamp',
|
|
172
|
+
example: '2024-01-01T00:00:00.000Z'
|
|
173
|
+
},
|
|
174
|
+
updatedAt: {
|
|
175
|
+
type: 'string',
|
|
176
|
+
description: 'Updated timestamp',
|
|
177
|
+
example: '2024-01-01T00:00:00.000Z'
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
required: [
|
|
181
|
+
'id',
|
|
182
|
+
'path',
|
|
183
|
+
'type',
|
|
184
|
+
'status',
|
|
185
|
+
'openDate',
|
|
186
|
+
'bookingMethod',
|
|
187
|
+
'isCustom',
|
|
188
|
+
'createdAt',
|
|
189
|
+
'updatedAt'
|
|
190
|
+
]
|
|
191
|
+
} as const;
|
|
192
|
+
|
|
193
|
+
export const $AccountListResponseDto = {
|
|
194
|
+
type: 'object',
|
|
195
|
+
properties: {
|
|
196
|
+
items: {
|
|
197
|
+
description: 'Array of accounts',
|
|
198
|
+
type: 'array',
|
|
199
|
+
items: {
|
|
200
|
+
$ref: '#/components/schemas/AccountResponseDto'
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
total: {
|
|
204
|
+
type: 'number',
|
|
205
|
+
description: 'Total number of accounts matching the query',
|
|
206
|
+
example: 50
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
required: ['items', 'total']
|
|
210
|
+
} as const;
|
|
211
|
+
|
|
212
|
+
export const $UpdateAccountDto = {
|
|
213
|
+
type: 'object',
|
|
214
|
+
properties: {
|
|
215
|
+
currencies: {
|
|
216
|
+
description: 'Allowed currencies (null = no restriction)',
|
|
217
|
+
example: ['CNY', 'USD'],
|
|
218
|
+
type: 'array',
|
|
219
|
+
items: {
|
|
220
|
+
type: 'string'
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
bookingMethod: {
|
|
224
|
+
type: 'string',
|
|
225
|
+
description: 'Booking method for cost basis',
|
|
226
|
+
enum: [
|
|
227
|
+
'FIFO',
|
|
228
|
+
'LIFO',
|
|
229
|
+
'HIFO',
|
|
230
|
+
'AVERAGE',
|
|
231
|
+
'STRICT',
|
|
232
|
+
'STRICT_WITH_SIZE',
|
|
233
|
+
'NONE'
|
|
234
|
+
]
|
|
235
|
+
},
|
|
236
|
+
i18nKey: {
|
|
237
|
+
type: 'string',
|
|
238
|
+
description: 'i18n key for display name',
|
|
239
|
+
example: 'account.custom.mybank'
|
|
240
|
+
},
|
|
241
|
+
icon: {
|
|
242
|
+
type: 'string',
|
|
243
|
+
description: 'Icon identifier',
|
|
244
|
+
example: 'bank-custom'
|
|
245
|
+
},
|
|
246
|
+
openMeta: {
|
|
247
|
+
type: 'object',
|
|
248
|
+
description: 'Additional metadata (merged with existing)',
|
|
249
|
+
example: {
|
|
250
|
+
branch: 'Uptown'
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
platformId: {
|
|
254
|
+
type: 'object',
|
|
255
|
+
description:
|
|
256
|
+
'Platform ID (references Platform.id), null to clear association',
|
|
257
|
+
example: 'c98e5d4a-2f71-4a5a-bb3c-92c9f231d5e2',
|
|
258
|
+
nullable: true
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
} as const;
|
|
262
|
+
|
|
263
|
+
export const $CloseAccountDto = {
|
|
264
|
+
type: 'object',
|
|
265
|
+
properties: {
|
|
266
|
+
closeDate: {
|
|
267
|
+
format: 'date-time',
|
|
268
|
+
type: 'string',
|
|
269
|
+
description: 'Account close date',
|
|
270
|
+
example: '2024-12-31'
|
|
271
|
+
},
|
|
272
|
+
closeMeta: {
|
|
273
|
+
type: 'object',
|
|
274
|
+
description: 'Close directive metadata',
|
|
275
|
+
example: {
|
|
276
|
+
reason: 'Account migrated to new bank'
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
required: ['closeDate']
|
|
281
|
+
} as const;
|
|
282
|
+
|
|
283
|
+
export const $ReopenAccountDto = {
|
|
284
|
+
type: 'object',
|
|
285
|
+
properties: {
|
|
286
|
+
reopenDate: {
|
|
287
|
+
format: 'date-time',
|
|
288
|
+
type: 'string',
|
|
289
|
+
description: 'New open date (optional)',
|
|
290
|
+
example: '2025-01-01'
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
} as const;
|
|
294
|
+
|
|
295
|
+
export const $CreatePostingDto = {
|
|
296
|
+
type: 'object',
|
|
297
|
+
properties: {
|
|
298
|
+
account: {
|
|
299
|
+
type: 'string',
|
|
300
|
+
description:
|
|
301
|
+
'Account name in Beancount format (must start with uppercase, colon-separated)',
|
|
302
|
+
example: 'Assets:Bank:Checking'
|
|
303
|
+
},
|
|
304
|
+
units: {
|
|
305
|
+
type: 'string',
|
|
306
|
+
description:
|
|
307
|
+
'Amount as decimal string (max 15 integer + 15 decimal digits). Can be omitted for interpolation, but currency must also be omitted.',
|
|
308
|
+
example: '100.50',
|
|
309
|
+
pattern: '^-?\\d{1,15}(\\.\\d{1,15})?$'
|
|
310
|
+
},
|
|
311
|
+
currency: {
|
|
312
|
+
type: 'string',
|
|
313
|
+
description:
|
|
314
|
+
'Currency/commodity code. Required if units is provided, must be omitted if units is omitted.',
|
|
315
|
+
example: 'USD',
|
|
316
|
+
maxLength: 20
|
|
317
|
+
},
|
|
318
|
+
meta: {
|
|
319
|
+
type: 'object',
|
|
320
|
+
description: 'Posting-level metadata',
|
|
321
|
+
example: {
|
|
322
|
+
'tax-lot': 'Q1-2024'
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
required: ['account']
|
|
327
|
+
} as const;
|
|
328
|
+
|
|
329
|
+
export const $CreateTransactionDto = {
|
|
330
|
+
type: 'object',
|
|
331
|
+
properties: {
|
|
332
|
+
date: {
|
|
333
|
+
type: 'string',
|
|
334
|
+
description: 'Transaction date (ISO 8601 format)',
|
|
335
|
+
example: '2024-11-28'
|
|
336
|
+
},
|
|
337
|
+
flag: {
|
|
338
|
+
type: 'string',
|
|
339
|
+
description: 'Transaction flag: * (cleared), ! (pending)',
|
|
340
|
+
enum: ['*', '!'],
|
|
341
|
+
example: '*'
|
|
342
|
+
},
|
|
343
|
+
payee: {
|
|
344
|
+
type: 'string',
|
|
345
|
+
description: 'Payee name',
|
|
346
|
+
example: 'Whole Foods Market'
|
|
347
|
+
},
|
|
348
|
+
narration: {
|
|
349
|
+
type: 'string',
|
|
350
|
+
description: 'Transaction narration/description',
|
|
351
|
+
example: 'Grocery shopping'
|
|
352
|
+
},
|
|
353
|
+
tags: {
|
|
354
|
+
description: 'Transaction tags (without # prefix)',
|
|
355
|
+
example: ['vacation', 'personal'],
|
|
356
|
+
type: 'array',
|
|
357
|
+
items: {
|
|
358
|
+
type: 'string'
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
links: {
|
|
362
|
+
description: 'Transaction links (without ^ prefix)',
|
|
363
|
+
example: ['invoice-123'],
|
|
364
|
+
type: 'array',
|
|
365
|
+
items: {
|
|
366
|
+
type: 'string'
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
postings: {
|
|
370
|
+
description:
|
|
371
|
+
'Transaction postings (minimum 1, typically 2 for double-entry)',
|
|
372
|
+
type: 'array',
|
|
373
|
+
items: {
|
|
374
|
+
$ref: '#/components/schemas/CreatePostingDto'
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
meta: {
|
|
378
|
+
type: 'object',
|
|
379
|
+
description: 'Transaction-level metadata',
|
|
380
|
+
example: {
|
|
381
|
+
invoice: '12345'
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
idempotencyKey: {
|
|
385
|
+
type: 'string',
|
|
386
|
+
description:
|
|
387
|
+
'Unique key for idempotent transaction creation. If provided, duplicate requests with the same key will return the existing transaction.',
|
|
388
|
+
example: 'import-2024-01-15-batch-001',
|
|
389
|
+
maxLength: 128
|
|
390
|
+
},
|
|
391
|
+
autoCreateAccounts: {
|
|
392
|
+
type: 'boolean',
|
|
393
|
+
description:
|
|
394
|
+
'Auto-create accounts if not found. When true, missing accounts will be automatically created. When false (default for API), missing accounts will cause a validation error. Set to true for quick entry scenarios where you want to create accounts on-the-fly.',
|
|
395
|
+
default: true,
|
|
396
|
+
example: true
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
required: ['date', 'narration', 'postings']
|
|
400
|
+
} as const;
|
|
401
|
+
|
|
402
|
+
export const $PostingResponseDto = {
|
|
403
|
+
type: 'object',
|
|
404
|
+
properties: {
|
|
405
|
+
account: {
|
|
406
|
+
type: 'string',
|
|
407
|
+
description: 'Account name',
|
|
408
|
+
example: 'Assets:Bank:Checking'
|
|
409
|
+
},
|
|
410
|
+
units: {
|
|
411
|
+
type: 'string',
|
|
412
|
+
description: 'Amount (may be null if interpolated)',
|
|
413
|
+
example: '100.50'
|
|
414
|
+
},
|
|
415
|
+
currency: {
|
|
416
|
+
type: 'string',
|
|
417
|
+
description: 'Currency',
|
|
418
|
+
example: 'USD'
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
required: ['account']
|
|
422
|
+
} as const;
|
|
423
|
+
|
|
424
|
+
export const $RecurringSuggestionDto = {
|
|
425
|
+
type: 'object',
|
|
426
|
+
properties: {
|
|
427
|
+
shouldSuggest: {
|
|
428
|
+
type: 'boolean',
|
|
429
|
+
description: 'Whether to suggest creating a recurring rule',
|
|
430
|
+
example: true
|
|
431
|
+
},
|
|
432
|
+
suggestedFrequency: {
|
|
433
|
+
type: 'string',
|
|
434
|
+
description: 'Suggested frequency based on pattern analysis',
|
|
435
|
+
enum: [
|
|
436
|
+
'WEEKLY',
|
|
437
|
+
'BIWEEKLY',
|
|
438
|
+
'MONTHLY',
|
|
439
|
+
'BIMONTHLY',
|
|
440
|
+
'QUARTERLY',
|
|
441
|
+
'YEARLY',
|
|
442
|
+
'CUSTOM'
|
|
443
|
+
],
|
|
444
|
+
example: 'MONTHLY'
|
|
445
|
+
},
|
|
446
|
+
confidence: {
|
|
447
|
+
type: 'number',
|
|
448
|
+
description: 'Confidence score (0-1)',
|
|
449
|
+
minimum: 0,
|
|
450
|
+
maximum: 1,
|
|
451
|
+
example: 0.75
|
|
452
|
+
},
|
|
453
|
+
similarCount: {
|
|
454
|
+
type: 'number',
|
|
455
|
+
description: 'Number of similar historical transactions found',
|
|
456
|
+
minimum: 1,
|
|
457
|
+
example: 3
|
|
458
|
+
},
|
|
459
|
+
averageAmount: {
|
|
460
|
+
type: 'number',
|
|
461
|
+
description: 'Average amount across similar transactions',
|
|
462
|
+
example: 299
|
|
463
|
+
},
|
|
464
|
+
suggestedExpectedDay: {
|
|
465
|
+
type: 'number',
|
|
466
|
+
description:
|
|
467
|
+
'Suggested expected day of month (1-28). Only provided when dates are consistent.',
|
|
468
|
+
minimum: 1,
|
|
469
|
+
maximum: 28,
|
|
470
|
+
example: 15
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
required: [
|
|
474
|
+
'shouldSuggest',
|
|
475
|
+
'suggestedFrequency',
|
|
476
|
+
'confidence',
|
|
477
|
+
'similarCount',
|
|
478
|
+
'averageAmount'
|
|
479
|
+
]
|
|
480
|
+
} as const;
|
|
481
|
+
|
|
482
|
+
export const $TransactionResponseDto = {
|
|
483
|
+
type: 'object',
|
|
484
|
+
properties: {
|
|
485
|
+
transactionId: {
|
|
486
|
+
type: 'string',
|
|
487
|
+
description: 'Database transaction ID',
|
|
488
|
+
example: 'clh1234567890abcdef'
|
|
489
|
+
},
|
|
490
|
+
idempotencyKey: {
|
|
491
|
+
type: 'string',
|
|
492
|
+
description: 'Idempotency key if provided during creation'
|
|
493
|
+
},
|
|
494
|
+
date: {
|
|
495
|
+
type: 'string',
|
|
496
|
+
description: 'Transaction date',
|
|
497
|
+
example: '2024-11-28'
|
|
498
|
+
},
|
|
499
|
+
flag: {
|
|
500
|
+
type: 'string',
|
|
501
|
+
description: 'Transaction flag',
|
|
502
|
+
example: '*'
|
|
503
|
+
},
|
|
504
|
+
payee: {
|
|
505
|
+
type: 'string',
|
|
506
|
+
description: 'Payee name',
|
|
507
|
+
example: 'Whole Foods Market'
|
|
508
|
+
},
|
|
509
|
+
narration: {
|
|
510
|
+
type: 'string',
|
|
511
|
+
description: 'Transaction narration',
|
|
512
|
+
example: 'Grocery shopping'
|
|
513
|
+
},
|
|
514
|
+
postings: {
|
|
515
|
+
description: 'Transaction postings',
|
|
516
|
+
type: 'array',
|
|
517
|
+
items: {
|
|
518
|
+
$ref: '#/components/schemas/PostingResponseDto'
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
interpolated: {
|
|
522
|
+
type: 'boolean',
|
|
523
|
+
description:
|
|
524
|
+
'Whether interpolation was applied to balance the transaction',
|
|
525
|
+
example: false
|
|
526
|
+
},
|
|
527
|
+
booked: {
|
|
528
|
+
type: 'boolean',
|
|
529
|
+
description: 'Whether booking (cost resolution) was applied',
|
|
530
|
+
example: false
|
|
531
|
+
},
|
|
532
|
+
warnings: {
|
|
533
|
+
description: 'Non-blocking warnings from pipeline processing',
|
|
534
|
+
example: ['Posting amount precision truncated'],
|
|
535
|
+
type: 'array',
|
|
536
|
+
items: {
|
|
537
|
+
type: 'string'
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
createdAccountIds: {
|
|
541
|
+
description:
|
|
542
|
+
'Account IDs auto-created for this transaction (empty for API source)',
|
|
543
|
+
example: [],
|
|
544
|
+
type: 'array',
|
|
545
|
+
items: {
|
|
546
|
+
type: 'string'
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
recurringSuggestion: {
|
|
550
|
+
description:
|
|
551
|
+
'Recurring rule creation suggestion. Only present when no existing rule matched and similar historical transactions were detected.',
|
|
552
|
+
allOf: [
|
|
553
|
+
{
|
|
554
|
+
$ref: '#/components/schemas/RecurringSuggestionDto'
|
|
555
|
+
}
|
|
556
|
+
]
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
required: [
|
|
560
|
+
'transactionId',
|
|
561
|
+
'date',
|
|
562
|
+
'narration',
|
|
563
|
+
'postings',
|
|
564
|
+
'interpolated',
|
|
565
|
+
'booked',
|
|
566
|
+
'createdAccountIds'
|
|
567
|
+
]
|
|
568
|
+
} as const;
|
|
569
|
+
|
|
570
|
+
export const $ApiProblemResponseDto = {
|
|
571
|
+
type: 'object',
|
|
572
|
+
properties: {
|
|
573
|
+
type: {
|
|
574
|
+
type: 'string',
|
|
575
|
+
description: 'A URI reference that identifies the problem type',
|
|
576
|
+
example: '/errors/resource-not-found'
|
|
577
|
+
},
|
|
578
|
+
title: {
|
|
579
|
+
type: 'string',
|
|
580
|
+
description: 'A short, human-readable summary of the problem',
|
|
581
|
+
example: 'Resource not found'
|
|
582
|
+
},
|
|
583
|
+
status: {
|
|
584
|
+
type: 'number',
|
|
585
|
+
description: 'The HTTP status code',
|
|
586
|
+
example: 404
|
|
587
|
+
},
|
|
588
|
+
detail: {
|
|
589
|
+
type: 'string',
|
|
590
|
+
description: 'A human-readable explanation of the problem',
|
|
591
|
+
example: 'The requested resource with ID uuid-123 does not exist'
|
|
592
|
+
},
|
|
593
|
+
instance: {
|
|
594
|
+
type: 'string',
|
|
595
|
+
description: 'A URI reference that identifies the specific occurrence',
|
|
596
|
+
example: '/api/v1/resources/uuid-123'
|
|
597
|
+
},
|
|
598
|
+
extensions: {
|
|
599
|
+
type: 'object',
|
|
600
|
+
description: 'Additional extension data',
|
|
601
|
+
example: {
|
|
602
|
+
resourceId: 'uuid-123',
|
|
603
|
+
operation: 'findById'
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
required: ['type', 'title', 'status', 'detail']
|
|
608
|
+
} as const;
|
|
609
|
+
|
|
610
|
+
export const $PostingDetailDto = {
|
|
611
|
+
type: 'object',
|
|
612
|
+
properties: {
|
|
613
|
+
id: {
|
|
614
|
+
type: 'string',
|
|
615
|
+
description: 'Posting ID',
|
|
616
|
+
example: 'clh1234567890abcdef'
|
|
617
|
+
},
|
|
618
|
+
accountId: {
|
|
619
|
+
type: 'string',
|
|
620
|
+
description: 'Account ID',
|
|
621
|
+
example: 'clh1234567890abcdef'
|
|
622
|
+
},
|
|
623
|
+
accountName: {
|
|
624
|
+
type: 'string',
|
|
625
|
+
description: 'Account name',
|
|
626
|
+
example: 'Assets:Bank:Checking'
|
|
627
|
+
},
|
|
628
|
+
units: {
|
|
629
|
+
type: 'string',
|
|
630
|
+
description: 'Amount (may be null if interpolated)',
|
|
631
|
+
example: '100.50'
|
|
632
|
+
},
|
|
633
|
+
currency: {
|
|
634
|
+
type: 'string',
|
|
635
|
+
description: 'Currency',
|
|
636
|
+
example: 'USD'
|
|
637
|
+
},
|
|
638
|
+
costAmount: {
|
|
639
|
+
type: 'string',
|
|
640
|
+
description: 'Cost amount',
|
|
641
|
+
example: '98.00'
|
|
642
|
+
},
|
|
643
|
+
costCurrency: {
|
|
644
|
+
type: 'string',
|
|
645
|
+
description: 'Cost currency',
|
|
646
|
+
example: 'USD'
|
|
647
|
+
},
|
|
648
|
+
costDate: {
|
|
649
|
+
type: 'string',
|
|
650
|
+
description: 'Cost date',
|
|
651
|
+
example: '2024-01-15'
|
|
652
|
+
},
|
|
653
|
+
priceAmount: {
|
|
654
|
+
type: 'string',
|
|
655
|
+
description: 'Price amount',
|
|
656
|
+
example: '1.02'
|
|
657
|
+
},
|
|
658
|
+
priceCurrency: {
|
|
659
|
+
type: 'string',
|
|
660
|
+
description: 'Price currency',
|
|
661
|
+
example: 'EUR'
|
|
662
|
+
},
|
|
663
|
+
flag: {
|
|
664
|
+
type: 'string',
|
|
665
|
+
description: 'Posting flag',
|
|
666
|
+
example: '*'
|
|
667
|
+
},
|
|
668
|
+
meta: {
|
|
669
|
+
type: 'object',
|
|
670
|
+
description: 'Posting metadata'
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
required: ['id', 'accountId', 'accountName']
|
|
674
|
+
} as const;
|
|
675
|
+
|
|
676
|
+
export const $TransactionDetailDto = {
|
|
677
|
+
type: 'object',
|
|
678
|
+
properties: {
|
|
679
|
+
id: {
|
|
680
|
+
type: 'string',
|
|
681
|
+
description: 'Transaction ID',
|
|
682
|
+
example: 'clh1234567890abcdef'
|
|
683
|
+
},
|
|
684
|
+
date: {
|
|
685
|
+
type: 'string',
|
|
686
|
+
description: 'Transaction date',
|
|
687
|
+
example: '2024-11-28'
|
|
688
|
+
},
|
|
689
|
+
flag: {
|
|
690
|
+
type: 'string',
|
|
691
|
+
description: 'Transaction flag',
|
|
692
|
+
enum: [
|
|
693
|
+
'CLEARED',
|
|
694
|
+
'PENDING',
|
|
695
|
+
'PADDING',
|
|
696
|
+
'SUMMARIZE',
|
|
697
|
+
'TRANSFER',
|
|
698
|
+
'CONVERSIONS'
|
|
699
|
+
],
|
|
700
|
+
example: 'CLEARED'
|
|
701
|
+
},
|
|
702
|
+
customFlag: {
|
|
703
|
+
type: 'string',
|
|
704
|
+
description: 'Custom flag (if not using standard flags)',
|
|
705
|
+
example: 'R'
|
|
706
|
+
},
|
|
707
|
+
payee: {
|
|
708
|
+
type: 'string',
|
|
709
|
+
description: 'Payee name',
|
|
710
|
+
example: 'Whole Foods Market'
|
|
711
|
+
},
|
|
712
|
+
narration: {
|
|
713
|
+
type: 'string',
|
|
714
|
+
description: 'Transaction narration',
|
|
715
|
+
example: 'Grocery shopping'
|
|
716
|
+
},
|
|
717
|
+
tags: {
|
|
718
|
+
description: 'Transaction tags',
|
|
719
|
+
example: ['groceries'],
|
|
720
|
+
type: 'array',
|
|
721
|
+
items: {
|
|
722
|
+
type: 'string'
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
links: {
|
|
726
|
+
description: 'Transaction links',
|
|
727
|
+
example: ['invoice-2024-001'],
|
|
728
|
+
type: 'array',
|
|
729
|
+
items: {
|
|
730
|
+
type: 'string'
|
|
731
|
+
}
|
|
732
|
+
},
|
|
733
|
+
meta: {
|
|
734
|
+
type: 'object',
|
|
735
|
+
description: 'Transaction metadata'
|
|
736
|
+
},
|
|
737
|
+
status: {
|
|
738
|
+
type: 'string',
|
|
739
|
+
description: 'Transaction status',
|
|
740
|
+
enum: ['ACTIVE', 'VOIDED', 'SUPERSEDED'],
|
|
741
|
+
example: 'ACTIVE'
|
|
742
|
+
},
|
|
743
|
+
sourceType: {
|
|
744
|
+
type: 'string',
|
|
745
|
+
description: 'Source type (how the transaction was created)',
|
|
746
|
+
enum: ['NLP', 'CSV', 'OCR', 'API']
|
|
747
|
+
},
|
|
748
|
+
sourcePlatform: {
|
|
749
|
+
type: 'string',
|
|
750
|
+
description: 'Source platform (e.g., alipay, wechat)',
|
|
751
|
+
example: 'alipay'
|
|
752
|
+
},
|
|
753
|
+
postings: {
|
|
754
|
+
description: 'Transaction postings',
|
|
755
|
+
type: 'array',
|
|
756
|
+
items: {
|
|
757
|
+
$ref: '#/components/schemas/PostingDetailDto'
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
createdAt: {
|
|
761
|
+
type: 'string',
|
|
762
|
+
description: 'Created at timestamp',
|
|
763
|
+
example: '2024-11-28T10:30:00.000Z'
|
|
764
|
+
},
|
|
765
|
+
voidedAt: {
|
|
766
|
+
type: 'string',
|
|
767
|
+
description: 'Voided at timestamp (if voided)',
|
|
768
|
+
example: '2024-11-29T15:00:00.000Z'
|
|
769
|
+
},
|
|
770
|
+
voidedBy: {
|
|
771
|
+
type: 'string',
|
|
772
|
+
description: 'User ID who voided this transaction',
|
|
773
|
+
example: 'clh1234567890abcdef'
|
|
774
|
+
},
|
|
775
|
+
correctionReason: {
|
|
776
|
+
type: 'string',
|
|
777
|
+
description: 'Correction reason (if voided or superseded)',
|
|
778
|
+
example: 'Duplicate entry'
|
|
779
|
+
}
|
|
780
|
+
},
|
|
781
|
+
required: [
|
|
782
|
+
'id',
|
|
783
|
+
'date',
|
|
784
|
+
'narration',
|
|
785
|
+
'tags',
|
|
786
|
+
'links',
|
|
787
|
+
'status',
|
|
788
|
+
'postings',
|
|
789
|
+
'createdAt'
|
|
790
|
+
]
|
|
791
|
+
} as const;
|
|
792
|
+
|
|
793
|
+
export const $TransactionListResponseDto = {
|
|
794
|
+
type: 'object',
|
|
795
|
+
properties: {
|
|
796
|
+
data: {
|
|
797
|
+
description: 'List of transactions',
|
|
798
|
+
type: 'array',
|
|
799
|
+
items: {
|
|
800
|
+
$ref: '#/components/schemas/TransactionDetailDto'
|
|
801
|
+
}
|
|
802
|
+
},
|
|
803
|
+
total: {
|
|
804
|
+
type: 'number',
|
|
805
|
+
description: 'Total count of matching transactions',
|
|
806
|
+
example: 100
|
|
807
|
+
},
|
|
808
|
+
limit: {
|
|
809
|
+
type: 'number',
|
|
810
|
+
description: 'Number of items per page',
|
|
811
|
+
example: 20
|
|
812
|
+
},
|
|
813
|
+
offset: {
|
|
814
|
+
type: 'number',
|
|
815
|
+
description: 'Number of items skipped',
|
|
816
|
+
example: 0
|
|
817
|
+
}
|
|
818
|
+
},
|
|
819
|
+
required: ['data', 'total', 'limit', 'offset']
|
|
820
|
+
} as const;
|
|
821
|
+
|
|
822
|
+
export const $UpdateTransactionDto = {
|
|
823
|
+
type: 'object',
|
|
824
|
+
properties: {
|
|
825
|
+
flag: {
|
|
826
|
+
type: 'string',
|
|
827
|
+
description: 'Transaction flag (CLEARED, PENDING, etc.)',
|
|
828
|
+
enum: [
|
|
829
|
+
'CLEARED',
|
|
830
|
+
'PENDING',
|
|
831
|
+
'PADDING',
|
|
832
|
+
'SUMMARIZE',
|
|
833
|
+
'TRANSFER',
|
|
834
|
+
'CONVERSIONS'
|
|
835
|
+
],
|
|
836
|
+
example: 'CLEARED'
|
|
837
|
+
},
|
|
838
|
+
payee: {
|
|
839
|
+
type: 'string',
|
|
840
|
+
description: 'Payee name',
|
|
841
|
+
maxLength: 500,
|
|
842
|
+
example: 'Whole Foods Market'
|
|
843
|
+
},
|
|
844
|
+
narration: {
|
|
845
|
+
type: 'string',
|
|
846
|
+
description: 'Transaction narration/description',
|
|
847
|
+
maxLength: 1000,
|
|
848
|
+
example: 'Weekly grocery shopping'
|
|
849
|
+
},
|
|
850
|
+
tags: {
|
|
851
|
+
description: 'Transaction tags',
|
|
852
|
+
maxItems: 50,
|
|
853
|
+
example: ['groceries', 'weekly'],
|
|
854
|
+
type: 'array',
|
|
855
|
+
items: {
|
|
856
|
+
type: 'string'
|
|
857
|
+
}
|
|
858
|
+
},
|
|
859
|
+
links: {
|
|
860
|
+
description: 'Transaction links',
|
|
861
|
+
maxItems: 50,
|
|
862
|
+
example: ['invoice-2024-001'],
|
|
863
|
+
type: 'array',
|
|
864
|
+
items: {
|
|
865
|
+
type: 'string'
|
|
866
|
+
}
|
|
867
|
+
},
|
|
868
|
+
meta: {
|
|
869
|
+
type: 'object',
|
|
870
|
+
description: 'Transaction metadata (JSON object)',
|
|
871
|
+
example: {
|
|
872
|
+
category: 'Food:Groceries',
|
|
873
|
+
reviewed: true
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
} as const;
|
|
878
|
+
|
|
879
|
+
export const $AccountStandardResponseDto = {
|
|
880
|
+
type: 'object',
|
|
881
|
+
properties: {
|
|
882
|
+
path: {
|
|
883
|
+
type: 'string',
|
|
884
|
+
description: 'Account path (hierarchical, colon-separated)',
|
|
885
|
+
example: 'Assets:CN:Bank:ICBC:Checking'
|
|
886
|
+
},
|
|
887
|
+
type: {
|
|
888
|
+
type: 'string',
|
|
889
|
+
description: 'Account type in Beancount hierarchy',
|
|
890
|
+
enum: ['Assets', 'Liabilities', 'Income', 'Expenses', 'Equity'],
|
|
891
|
+
example: 'Assets'
|
|
892
|
+
},
|
|
893
|
+
i18nKey: {
|
|
894
|
+
type: 'string',
|
|
895
|
+
description: 'i18n key for localized display name',
|
|
896
|
+
example: 'account.assets.cn.bank.icbc.checking'
|
|
897
|
+
},
|
|
898
|
+
description: {
|
|
899
|
+
type: 'string',
|
|
900
|
+
description: 'Account description',
|
|
901
|
+
example: 'ICBC checking account for daily transactions'
|
|
902
|
+
},
|
|
903
|
+
tags: {
|
|
904
|
+
description: 'Account tags for categorization',
|
|
905
|
+
example: ['bank', 'checking', 'primary'],
|
|
906
|
+
type: 'array',
|
|
907
|
+
items: {
|
|
908
|
+
type: 'string'
|
|
909
|
+
}
|
|
910
|
+
},
|
|
911
|
+
icon: {
|
|
912
|
+
type: 'string',
|
|
913
|
+
description: 'Icon identifier for UI display',
|
|
914
|
+
example: 'bank-icbc'
|
|
915
|
+
}
|
|
916
|
+
},
|
|
917
|
+
required: ['path', 'type']
|
|
918
|
+
} as const;
|
|
919
|
+
|
|
920
|
+
export const $AccountStandardListResponseDto = {
|
|
921
|
+
type: 'object',
|
|
922
|
+
properties: {
|
|
923
|
+
items: {
|
|
924
|
+
description: 'Array of account templates',
|
|
925
|
+
type: 'array',
|
|
926
|
+
items: {
|
|
927
|
+
$ref: '#/components/schemas/AccountStandardResponseDto'
|
|
928
|
+
}
|
|
929
|
+
},
|
|
930
|
+
total: {
|
|
931
|
+
type: 'number',
|
|
932
|
+
description: 'Total number of account templates',
|
|
933
|
+
example: 150
|
|
934
|
+
},
|
|
935
|
+
region: {
|
|
936
|
+
type: 'string',
|
|
937
|
+
description: 'Region code',
|
|
938
|
+
example: 'CN'
|
|
939
|
+
}
|
|
940
|
+
},
|
|
941
|
+
required: ['items', 'total', 'region']
|
|
942
|
+
} as const;
|
|
943
|
+
|
|
944
|
+
export const $BalanceResponseDto = {
|
|
945
|
+
type: 'object',
|
|
946
|
+
properties: {
|
|
947
|
+
account: {
|
|
948
|
+
type: 'string',
|
|
949
|
+
description: 'Account name',
|
|
950
|
+
example: 'Assets:Bank:Checking'
|
|
951
|
+
},
|
|
952
|
+
balance: {
|
|
953
|
+
type: 'string',
|
|
954
|
+
description: 'Balance amount (decimal string for precision)',
|
|
955
|
+
example: '12345.67'
|
|
956
|
+
},
|
|
957
|
+
currency: {
|
|
958
|
+
type: 'string',
|
|
959
|
+
description: 'Currency code',
|
|
960
|
+
example: 'USD'
|
|
961
|
+
},
|
|
962
|
+
date: {
|
|
963
|
+
type: 'string',
|
|
964
|
+
description: 'Date of the balance calculation (ISO 8601)',
|
|
965
|
+
example: '2024-12-31T00:00:00.000Z'
|
|
966
|
+
}
|
|
967
|
+
},
|
|
968
|
+
required: ['account', 'balance', 'currency', 'date']
|
|
969
|
+
} as const;
|
|
970
|
+
|
|
971
|
+
export const $MultiCurrencyBalanceResponseDto = {
|
|
972
|
+
type: 'object',
|
|
973
|
+
properties: {
|
|
974
|
+
account: {
|
|
975
|
+
type: 'string',
|
|
976
|
+
description: 'Account name',
|
|
977
|
+
example: 'Assets:Bank:Checking'
|
|
978
|
+
},
|
|
979
|
+
balances: {
|
|
980
|
+
type: 'object',
|
|
981
|
+
description: 'Balances by currency',
|
|
982
|
+
example: {
|
|
983
|
+
USD: '12345.67',
|
|
984
|
+
CNY: '100000.00'
|
|
985
|
+
}
|
|
986
|
+
},
|
|
987
|
+
date: {
|
|
988
|
+
type: 'string',
|
|
989
|
+
description: 'Date of the balance calculation (ISO 8601)',
|
|
990
|
+
example: '2024-12-31T00:00:00.000Z'
|
|
991
|
+
}
|
|
992
|
+
},
|
|
993
|
+
required: ['account', 'balances', 'date']
|
|
994
|
+
} as const;
|
|
995
|
+
|
|
996
|
+
export const $TransactionSummaryDto = {
|
|
997
|
+
type: 'object',
|
|
998
|
+
properties: {
|
|
999
|
+
id: {
|
|
1000
|
+
type: 'string',
|
|
1001
|
+
description: 'Transaction ID (null if transaction deleted)',
|
|
1002
|
+
example: 'clh1234567890abcdef',
|
|
1003
|
+
nullable: true
|
|
1004
|
+
},
|
|
1005
|
+
date: {
|
|
1006
|
+
type: 'string',
|
|
1007
|
+
description: 'Transaction date (YYYY-MM-DD)',
|
|
1008
|
+
example: '2024-03-15'
|
|
1009
|
+
},
|
|
1010
|
+
amount: {
|
|
1011
|
+
type: 'string',
|
|
1012
|
+
description: 'Transaction amount (absolute value)',
|
|
1013
|
+
example: '128.50'
|
|
1014
|
+
},
|
|
1015
|
+
currency: {
|
|
1016
|
+
type: 'string',
|
|
1017
|
+
description: 'Currency code',
|
|
1018
|
+
example: 'CNY'
|
|
1019
|
+
},
|
|
1020
|
+
payee: {
|
|
1021
|
+
type: 'string',
|
|
1022
|
+
description: 'Payee/Merchant name',
|
|
1023
|
+
example: 'Starbucks'
|
|
1024
|
+
},
|
|
1025
|
+
narration: {
|
|
1026
|
+
type: 'string',
|
|
1027
|
+
description: 'Transaction narration',
|
|
1028
|
+
example: 'Coffee purchase'
|
|
1029
|
+
},
|
|
1030
|
+
accountName: {
|
|
1031
|
+
type: 'string',
|
|
1032
|
+
description: 'Source account name (first posting)',
|
|
1033
|
+
example: 'Assets:Bank:Checking'
|
|
1034
|
+
},
|
|
1035
|
+
sourceType: {
|
|
1036
|
+
type: 'string',
|
|
1037
|
+
description: 'Source type (NLP, CSV, OCR, API)',
|
|
1038
|
+
enum: ['NLP', 'CSV', 'OCR', 'API']
|
|
1039
|
+
},
|
|
1040
|
+
sourcePlatform: {
|
|
1041
|
+
type: 'string',
|
|
1042
|
+
description: 'Source platform (e.g., alipay, wechat)',
|
|
1043
|
+
example: 'alipay'
|
|
1044
|
+
}
|
|
1045
|
+
},
|
|
1046
|
+
required: ['date', 'amount', 'currency', 'narration']
|
|
1047
|
+
} as const;
|
|
1048
|
+
|
|
1049
|
+
export const $ReviewSummaryDto = {
|
|
1050
|
+
type: 'object',
|
|
1051
|
+
properties: {
|
|
1052
|
+
id: {
|
|
1053
|
+
type: 'string',
|
|
1054
|
+
description: 'Review item ID'
|
|
1055
|
+
},
|
|
1056
|
+
type: {
|
|
1057
|
+
type: 'string',
|
|
1058
|
+
description: 'Review type',
|
|
1059
|
+
enum: [
|
|
1060
|
+
'DUPLICATE',
|
|
1061
|
+
'RULE_MATCH',
|
|
1062
|
+
'PAYEE_MATCH',
|
|
1063
|
+
'ACCOUNT_VALIDATION',
|
|
1064
|
+
'PIPELINE_ERROR'
|
|
1065
|
+
]
|
|
1066
|
+
},
|
|
1067
|
+
status: {
|
|
1068
|
+
type: 'string',
|
|
1069
|
+
description: 'Review status',
|
|
1070
|
+
enum: ['PENDING', 'RESOLVED', 'EXPIRED', 'CANCELLED']
|
|
1071
|
+
},
|
|
1072
|
+
confidence: {
|
|
1073
|
+
type: 'number',
|
|
1074
|
+
description: 'Confidence score (0-1)'
|
|
1075
|
+
},
|
|
1076
|
+
confidenceLevel: {
|
|
1077
|
+
type: 'string',
|
|
1078
|
+
description: 'Confidence level derived from score',
|
|
1079
|
+
enum: ['HIGH', 'MEDIUM', 'LOW']
|
|
1080
|
+
},
|
|
1081
|
+
summary: {
|
|
1082
|
+
type: 'string',
|
|
1083
|
+
description: 'Human-readable summary of the review item'
|
|
1084
|
+
},
|
|
1085
|
+
matchReasons: {
|
|
1086
|
+
description: 'Human-readable reasons for branching',
|
|
1087
|
+
type: 'array',
|
|
1088
|
+
items: {
|
|
1089
|
+
type: 'string'
|
|
1090
|
+
}
|
|
1091
|
+
},
|
|
1092
|
+
sourceType: {
|
|
1093
|
+
type: 'string',
|
|
1094
|
+
description: 'Source type (NLP, CSV, OCR, API)'
|
|
1095
|
+
},
|
|
1096
|
+
sourcePlatform: {
|
|
1097
|
+
type: 'string',
|
|
1098
|
+
description: 'Source platform (e.g., alipay, wechat)'
|
|
1099
|
+
},
|
|
1100
|
+
createdAt: {
|
|
1101
|
+
format: 'date-time',
|
|
1102
|
+
type: 'string',
|
|
1103
|
+
description: 'Creation timestamp'
|
|
1104
|
+
},
|
|
1105
|
+
transaction: {
|
|
1106
|
+
description:
|
|
1107
|
+
'Transaction summary for display (null if transaction deleted)',
|
|
1108
|
+
nullable: true,
|
|
1109
|
+
allOf: [
|
|
1110
|
+
{
|
|
1111
|
+
$ref: '#/components/schemas/TransactionSummaryDto'
|
|
1112
|
+
}
|
|
1113
|
+
]
|
|
1114
|
+
},
|
|
1115
|
+
amount: {
|
|
1116
|
+
type: 'string',
|
|
1117
|
+
description: 'Transaction amount (convenience field for mobile display)'
|
|
1118
|
+
},
|
|
1119
|
+
currency: {
|
|
1120
|
+
type: 'string',
|
|
1121
|
+
description: 'Currency code (convenience field for mobile display)'
|
|
1122
|
+
},
|
|
1123
|
+
merchantName: {
|
|
1124
|
+
type: 'string',
|
|
1125
|
+
description: 'Payee/Merchant name (convenience field for mobile display)'
|
|
1126
|
+
},
|
|
1127
|
+
accountName: {
|
|
1128
|
+
type: 'string',
|
|
1129
|
+
description: 'Account name (convenience field for mobile display)'
|
|
1130
|
+
},
|
|
1131
|
+
transactionTime: {
|
|
1132
|
+
type: 'string',
|
|
1133
|
+
description:
|
|
1134
|
+
'Transaction date/time (convenience field for mobile display)'
|
|
1135
|
+
}
|
|
1136
|
+
},
|
|
1137
|
+
required: [
|
|
1138
|
+
'id',
|
|
1139
|
+
'type',
|
|
1140
|
+
'status',
|
|
1141
|
+
'confidence',
|
|
1142
|
+
'confidenceLevel',
|
|
1143
|
+
'summary',
|
|
1144
|
+
'matchReasons',
|
|
1145
|
+
'sourceType',
|
|
1146
|
+
'createdAt'
|
|
1147
|
+
]
|
|
1148
|
+
} as const;
|
|
1149
|
+
|
|
1150
|
+
export const $ReviewListResponseDto = {
|
|
1151
|
+
type: 'object',
|
|
1152
|
+
properties: {
|
|
1153
|
+
items: {
|
|
1154
|
+
type: 'array',
|
|
1155
|
+
items: {
|
|
1156
|
+
$ref: '#/components/schemas/ReviewSummaryDto'
|
|
1157
|
+
}
|
|
1158
|
+
},
|
|
1159
|
+
total: {
|
|
1160
|
+
type: 'number',
|
|
1161
|
+
description: 'Total number of items'
|
|
1162
|
+
},
|
|
1163
|
+
page: {
|
|
1164
|
+
type: 'number',
|
|
1165
|
+
description: 'Current page number'
|
|
1166
|
+
},
|
|
1167
|
+
limit: {
|
|
1168
|
+
type: 'number',
|
|
1169
|
+
description: 'Items per page'
|
|
1170
|
+
},
|
|
1171
|
+
hasMore: {
|
|
1172
|
+
type: 'boolean',
|
|
1173
|
+
description: 'Whether there are more pages'
|
|
1174
|
+
}
|
|
1175
|
+
},
|
|
1176
|
+
required: ['items', 'total', 'page', 'limit', 'hasMore']
|
|
1177
|
+
} as const;
|
|
1178
|
+
|
|
1179
|
+
export const $ReviewStatsDto = {
|
|
1180
|
+
type: 'object',
|
|
1181
|
+
properties: {
|
|
1182
|
+
total: {
|
|
1183
|
+
type: 'number',
|
|
1184
|
+
description: 'Total pending reviews'
|
|
1185
|
+
},
|
|
1186
|
+
byType: {
|
|
1187
|
+
type: 'object',
|
|
1188
|
+
description: 'Count by type'
|
|
1189
|
+
},
|
|
1190
|
+
oldestPending: {
|
|
1191
|
+
format: 'date-time',
|
|
1192
|
+
type: 'string',
|
|
1193
|
+
description: 'Oldest pending review date'
|
|
1194
|
+
}
|
|
1195
|
+
},
|
|
1196
|
+
required: ['total', 'byType']
|
|
1197
|
+
} as const;
|
|
1198
|
+
|
|
1199
|
+
export const $DecisionOptionDto = {
|
|
1200
|
+
type: 'object',
|
|
1201
|
+
properties: {
|
|
1202
|
+
value: {
|
|
1203
|
+
type: 'string',
|
|
1204
|
+
description: 'The action value to submit (e.g., UPGRADE_REPLACE, ACCEPT)'
|
|
1205
|
+
},
|
|
1206
|
+
labelKey: {
|
|
1207
|
+
type: 'string',
|
|
1208
|
+
description:
|
|
1209
|
+
'i18n message key for display label (e.g., review.payee.accept.label)'
|
|
1210
|
+
},
|
|
1211
|
+
descriptionKey: {
|
|
1212
|
+
type: 'string',
|
|
1213
|
+
description: 'i18n message key for description'
|
|
1214
|
+
},
|
|
1215
|
+
recommended: {
|
|
1216
|
+
type: 'boolean',
|
|
1217
|
+
description: 'Whether this is the recommended option'
|
|
1218
|
+
}
|
|
1219
|
+
},
|
|
1220
|
+
required: ['value', 'labelKey']
|
|
1221
|
+
} as const;
|
|
1222
|
+
|
|
1223
|
+
export const $ReviewDetailDto = {
|
|
1224
|
+
type: 'object',
|
|
1225
|
+
properties: {
|
|
1226
|
+
id: {
|
|
1227
|
+
type: 'string',
|
|
1228
|
+
description: 'Review item ID'
|
|
1229
|
+
},
|
|
1230
|
+
type: {
|
|
1231
|
+
type: 'string',
|
|
1232
|
+
description: 'Review type',
|
|
1233
|
+
enum: [
|
|
1234
|
+
'DUPLICATE',
|
|
1235
|
+
'RULE_MATCH',
|
|
1236
|
+
'PAYEE_MATCH',
|
|
1237
|
+
'ACCOUNT_VALIDATION',
|
|
1238
|
+
'PIPELINE_ERROR'
|
|
1239
|
+
]
|
|
1240
|
+
},
|
|
1241
|
+
status: {
|
|
1242
|
+
type: 'string',
|
|
1243
|
+
description: 'Review status',
|
|
1244
|
+
enum: ['PENDING', 'RESOLVED', 'EXPIRED', 'CANCELLED']
|
|
1245
|
+
},
|
|
1246
|
+
confidence: {
|
|
1247
|
+
type: 'number',
|
|
1248
|
+
description: 'Confidence score (0-1)'
|
|
1249
|
+
},
|
|
1250
|
+
confidenceLevel: {
|
|
1251
|
+
type: 'string',
|
|
1252
|
+
description: 'Confidence level derived from score',
|
|
1253
|
+
enum: ['HIGH', 'MEDIUM', 'LOW']
|
|
1254
|
+
},
|
|
1255
|
+
summary: {
|
|
1256
|
+
type: 'string',
|
|
1257
|
+
description: 'Human-readable summary of the review item'
|
|
1258
|
+
},
|
|
1259
|
+
matchReasons: {
|
|
1260
|
+
description: 'Human-readable reasons for branching',
|
|
1261
|
+
type: 'array',
|
|
1262
|
+
items: {
|
|
1263
|
+
type: 'string'
|
|
1264
|
+
}
|
|
1265
|
+
},
|
|
1266
|
+
sourceType: {
|
|
1267
|
+
type: 'string',
|
|
1268
|
+
description: 'Source type (NLP, CSV, OCR, API)'
|
|
1269
|
+
},
|
|
1270
|
+
sourcePlatform: {
|
|
1271
|
+
type: 'string',
|
|
1272
|
+
description: 'Source platform (e.g., alipay, wechat)'
|
|
1273
|
+
},
|
|
1274
|
+
createdAt: {
|
|
1275
|
+
format: 'date-time',
|
|
1276
|
+
type: 'string',
|
|
1277
|
+
description: 'Creation timestamp'
|
|
1278
|
+
},
|
|
1279
|
+
transaction: {
|
|
1280
|
+
description:
|
|
1281
|
+
'Transaction summary for display (null if transaction deleted)',
|
|
1282
|
+
nullable: true,
|
|
1283
|
+
allOf: [
|
|
1284
|
+
{
|
|
1285
|
+
$ref: '#/components/schemas/TransactionSummaryDto'
|
|
1286
|
+
}
|
|
1287
|
+
]
|
|
1288
|
+
},
|
|
1289
|
+
amount: {
|
|
1290
|
+
type: 'string',
|
|
1291
|
+
description: 'Transaction amount (convenience field for mobile display)'
|
|
1292
|
+
},
|
|
1293
|
+
currency: {
|
|
1294
|
+
type: 'string',
|
|
1295
|
+
description: 'Currency code (convenience field for mobile display)'
|
|
1296
|
+
},
|
|
1297
|
+
merchantName: {
|
|
1298
|
+
type: 'string',
|
|
1299
|
+
description: 'Payee/Merchant name (convenience field for mobile display)'
|
|
1300
|
+
},
|
|
1301
|
+
accountName: {
|
|
1302
|
+
type: 'string',
|
|
1303
|
+
description: 'Account name (convenience field for mobile display)'
|
|
1304
|
+
},
|
|
1305
|
+
transactionTime: {
|
|
1306
|
+
type: 'string',
|
|
1307
|
+
description:
|
|
1308
|
+
'Transaction date/time (convenience field for mobile display)'
|
|
1309
|
+
},
|
|
1310
|
+
reviewData: {
|
|
1311
|
+
type: 'object',
|
|
1312
|
+
description:
|
|
1313
|
+
'Review-type-specific data (JSONB). Structure varies by type: DUPLICATE: {newTransaction, existingTransaction, matchScore}, RULE_MATCH: {transaction, matchedRule, suggestedAccount}, PAYEE_MATCH: {originalPayee, suggestedPayee}, ACCOUNT_VALIDATION: {invalidAccount, suggestedCorrection, similarAccounts}, PIPELINE_ERROR: {errorType, errorMessage}'
|
|
1314
|
+
},
|
|
1315
|
+
decisionOptions: {
|
|
1316
|
+
description: 'Available decision options',
|
|
1317
|
+
type: 'array',
|
|
1318
|
+
items: {
|
|
1319
|
+
$ref: '#/components/schemas/DecisionOptionDto'
|
|
1320
|
+
}
|
|
1321
|
+
},
|
|
1322
|
+
transactionId: {
|
|
1323
|
+
type: 'string',
|
|
1324
|
+
description: 'Related transaction ID if applicable'
|
|
1325
|
+
}
|
|
1326
|
+
},
|
|
1327
|
+
required: [
|
|
1328
|
+
'id',
|
|
1329
|
+
'type',
|
|
1330
|
+
'status',
|
|
1331
|
+
'confidence',
|
|
1332
|
+
'confidenceLevel',
|
|
1333
|
+
'summary',
|
|
1334
|
+
'matchReasons',
|
|
1335
|
+
'sourceType',
|
|
1336
|
+
'createdAt',
|
|
1337
|
+
'reviewData',
|
|
1338
|
+
'decisionOptions'
|
|
1339
|
+
]
|
|
1340
|
+
} as const;
|
|
1341
|
+
|
|
1342
|
+
export const $PayeeResponseDto = {
|
|
1343
|
+
type: 'object',
|
|
1344
|
+
properties: {
|
|
1345
|
+
id: {
|
|
1346
|
+
type: 'string',
|
|
1347
|
+
description: 'Unique identifier (UUID)',
|
|
1348
|
+
example: 'uuid-123-456'
|
|
1349
|
+
},
|
|
1350
|
+
userId: {
|
|
1351
|
+
type: 'string',
|
|
1352
|
+
description: 'User ID (owner of this payee mapping)',
|
|
1353
|
+
example: 'user-123'
|
|
1354
|
+
},
|
|
1355
|
+
payee: {
|
|
1356
|
+
type: 'string',
|
|
1357
|
+
description: "User's original payee name (e.g., 'Starbucks', 'McDonald')",
|
|
1358
|
+
example: 'Starbucks'
|
|
1359
|
+
},
|
|
1360
|
+
payeeProfileId: {
|
|
1361
|
+
type: 'object',
|
|
1362
|
+
description:
|
|
1363
|
+
'Reference to global PayeeProfile (merchant info, i18n keys, categories)',
|
|
1364
|
+
example: 'uuid-789',
|
|
1365
|
+
nullable: true
|
|
1366
|
+
},
|
|
1367
|
+
customCategory: {
|
|
1368
|
+
type: 'object',
|
|
1369
|
+
description:
|
|
1370
|
+
"User's custom category (overrides PayeeProfile category if set)",
|
|
1371
|
+
example: 'Dining:Coffee',
|
|
1372
|
+
nullable: true
|
|
1373
|
+
},
|
|
1374
|
+
customTags: {
|
|
1375
|
+
description: "User's custom tags (e.g., ['favorite', 'work_meal'])",
|
|
1376
|
+
example: ['favorite', 'work_meal'],
|
|
1377
|
+
type: 'array',
|
|
1378
|
+
items: {
|
|
1379
|
+
type: 'string'
|
|
1380
|
+
}
|
|
1381
|
+
},
|
|
1382
|
+
useCount: {
|
|
1383
|
+
type: 'number',
|
|
1384
|
+
description:
|
|
1385
|
+
'Usage count (number of times this payee was used in transactions)',
|
|
1386
|
+
example: 42
|
|
1387
|
+
},
|
|
1388
|
+
lastUsedAt: {
|
|
1389
|
+
format: 'date-time',
|
|
1390
|
+
type: 'string',
|
|
1391
|
+
description: 'Last used timestamp',
|
|
1392
|
+
example: '2024-11-20T10:00:00Z'
|
|
1393
|
+
},
|
|
1394
|
+
meta: {
|
|
1395
|
+
type: 'object',
|
|
1396
|
+
description: 'Extended metadata (location, notes, contact info, etc.)',
|
|
1397
|
+
example: {
|
|
1398
|
+
location: 'Zhongguancun',
|
|
1399
|
+
note: 'Near subway station',
|
|
1400
|
+
favorite: true
|
|
1401
|
+
}
|
|
1402
|
+
},
|
|
1403
|
+
isActive: {
|
|
1404
|
+
type: 'boolean',
|
|
1405
|
+
description: 'Active status (inactive payees hidden from autocomplete)',
|
|
1406
|
+
example: true
|
|
1407
|
+
},
|
|
1408
|
+
createdAt: {
|
|
1409
|
+
format: 'date-time',
|
|
1410
|
+
type: 'string',
|
|
1411
|
+
description: 'Creation timestamp (first time this payee was used)',
|
|
1412
|
+
example: '2024-01-01T10:00:00Z'
|
|
1413
|
+
},
|
|
1414
|
+
updatedAt: {
|
|
1415
|
+
format: 'date-time',
|
|
1416
|
+
type: 'string',
|
|
1417
|
+
description: 'Last update timestamp',
|
|
1418
|
+
example: '2024-11-20T10:00:00Z'
|
|
1419
|
+
}
|
|
1420
|
+
},
|
|
1421
|
+
required: [
|
|
1422
|
+
'id',
|
|
1423
|
+
'userId',
|
|
1424
|
+
'payee',
|
|
1425
|
+
'customTags',
|
|
1426
|
+
'useCount',
|
|
1427
|
+
'lastUsedAt',
|
|
1428
|
+
'meta',
|
|
1429
|
+
'isActive',
|
|
1430
|
+
'createdAt',
|
|
1431
|
+
'updatedAt'
|
|
1432
|
+
]
|
|
1433
|
+
} as const;
|
|
1434
|
+
|
|
1435
|
+
export const $PayeeListResponseDto = {
|
|
1436
|
+
type: 'object',
|
|
1437
|
+
properties: {
|
|
1438
|
+
items: {
|
|
1439
|
+
description: 'List of payees',
|
|
1440
|
+
type: 'array',
|
|
1441
|
+
items: {
|
|
1442
|
+
$ref: '#/components/schemas/PayeeResponseDto'
|
|
1443
|
+
}
|
|
1444
|
+
},
|
|
1445
|
+
total: {
|
|
1446
|
+
type: 'number',
|
|
1447
|
+
description: 'Total number of payees',
|
|
1448
|
+
example: 42
|
|
1449
|
+
}
|
|
1450
|
+
},
|
|
1451
|
+
required: ['items', 'total']
|
|
1452
|
+
} as const;
|
|
1453
|
+
|
|
1454
|
+
export const $PayeeAutocompleteResponseDto = {
|
|
1455
|
+
type: 'object',
|
|
1456
|
+
properties: {
|
|
1457
|
+
suggestions: {
|
|
1458
|
+
description: 'List of matching payee names',
|
|
1459
|
+
example: ['Starbucks', 'Starbucks Coffee', 'Starbucks Reserve'],
|
|
1460
|
+
type: 'array',
|
|
1461
|
+
items: {
|
|
1462
|
+
type: 'string'
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
},
|
|
1466
|
+
required: ['suggestions']
|
|
1467
|
+
} as const;
|
|
1468
|
+
|
|
1469
|
+
export const $PayeeStatsResponseDto = {
|
|
1470
|
+
type: 'object',
|
|
1471
|
+
properties: {
|
|
1472
|
+
payee: {
|
|
1473
|
+
type: 'string',
|
|
1474
|
+
description: 'Payee name',
|
|
1475
|
+
example: 'Starbucks'
|
|
1476
|
+
},
|
|
1477
|
+
transactionCount: {
|
|
1478
|
+
type: 'number',
|
|
1479
|
+
description: 'Total transaction count',
|
|
1480
|
+
example: 42
|
|
1481
|
+
},
|
|
1482
|
+
lastUsedAt: {
|
|
1483
|
+
format: 'date-time',
|
|
1484
|
+
type: 'string',
|
|
1485
|
+
description: 'Last used timestamp',
|
|
1486
|
+
example: '2024-11-20T10:00:00Z'
|
|
1487
|
+
}
|
|
1488
|
+
},
|
|
1489
|
+
required: ['payee', 'transactionCount', 'lastUsedAt']
|
|
1490
|
+
} as const;
|
|
1491
|
+
|
|
1492
|
+
export const $PayeeProfileResponseDto = {
|
|
1493
|
+
type: 'object',
|
|
1494
|
+
properties: {
|
|
1495
|
+
id: {
|
|
1496
|
+
type: 'string',
|
|
1497
|
+
description: 'Unique identifier (UUID)',
|
|
1498
|
+
example: '550e8400-e29b-41d4-a716-446655440000'
|
|
1499
|
+
},
|
|
1500
|
+
canonical: {
|
|
1501
|
+
type: 'string',
|
|
1502
|
+
description: 'Canonical payee name (unique, case-insensitive)',
|
|
1503
|
+
example: 'Starbucks'
|
|
1504
|
+
},
|
|
1505
|
+
aliases: {
|
|
1506
|
+
description: 'Multi-language aliases',
|
|
1507
|
+
example: ['Starbucks Coffee', 'SBUX'],
|
|
1508
|
+
type: 'array',
|
|
1509
|
+
items: {
|
|
1510
|
+
type: 'string'
|
|
1511
|
+
}
|
|
1512
|
+
},
|
|
1513
|
+
i18nKey: {
|
|
1514
|
+
type: 'object',
|
|
1515
|
+
description: 'Translation key for i18n',
|
|
1516
|
+
example: 'payee.starbucks',
|
|
1517
|
+
nullable: true
|
|
1518
|
+
},
|
|
1519
|
+
category: {
|
|
1520
|
+
type: 'string',
|
|
1521
|
+
description: 'Payee category',
|
|
1522
|
+
enum: [
|
|
1523
|
+
'RESTAURANT',
|
|
1524
|
+
'CAFE',
|
|
1525
|
+
'FAST_FOOD',
|
|
1526
|
+
'BAR',
|
|
1527
|
+
'SUPERMARKET',
|
|
1528
|
+
'CONVENIENCE_STORE',
|
|
1529
|
+
'SHOPPING_MALL',
|
|
1530
|
+
'ONLINE_SHOPPING',
|
|
1531
|
+
'TAXI',
|
|
1532
|
+
'RIDE_SHARING',
|
|
1533
|
+
'PUBLIC_TRANSPORT',
|
|
1534
|
+
'PARKING',
|
|
1535
|
+
'GAS_STATION',
|
|
1536
|
+
'UTILITIES',
|
|
1537
|
+
'TELECOM',
|
|
1538
|
+
'STREAMING',
|
|
1539
|
+
'HEALTHCARE',
|
|
1540
|
+
'EDUCATION',
|
|
1541
|
+
'ENTERTAINMENT',
|
|
1542
|
+
'SPORTS',
|
|
1543
|
+
'TRAVEL',
|
|
1544
|
+
'HOTEL',
|
|
1545
|
+
'OTHER'
|
|
1546
|
+
],
|
|
1547
|
+
example: 'CAFE'
|
|
1548
|
+
},
|
|
1549
|
+
subCategory: {
|
|
1550
|
+
type: 'object',
|
|
1551
|
+
description: 'Sub-category',
|
|
1552
|
+
example: 'coffee_chain',
|
|
1553
|
+
nullable: true
|
|
1554
|
+
},
|
|
1555
|
+
countries: {
|
|
1556
|
+
description: 'Country codes where payee operates',
|
|
1557
|
+
example: ['CN', 'US', 'JP'],
|
|
1558
|
+
type: 'array',
|
|
1559
|
+
items: {
|
|
1560
|
+
type: 'string'
|
|
1561
|
+
}
|
|
1562
|
+
},
|
|
1563
|
+
primaryCountry: {
|
|
1564
|
+
type: 'object',
|
|
1565
|
+
description: 'Primary operating country',
|
|
1566
|
+
example: 'US',
|
|
1567
|
+
nullable: true
|
|
1568
|
+
},
|
|
1569
|
+
keywords: {
|
|
1570
|
+
description: 'Search keywords',
|
|
1571
|
+
example: ['coffee', 'cafe'],
|
|
1572
|
+
type: 'array',
|
|
1573
|
+
items: {
|
|
1574
|
+
type: 'string'
|
|
1575
|
+
}
|
|
1576
|
+
},
|
|
1577
|
+
logoUrl: {
|
|
1578
|
+
type: 'object',
|
|
1579
|
+
description: 'Logo URL',
|
|
1580
|
+
example: 'https://example.com/logo.png',
|
|
1581
|
+
nullable: true
|
|
1582
|
+
},
|
|
1583
|
+
website: {
|
|
1584
|
+
type: 'object',
|
|
1585
|
+
description: 'Official website',
|
|
1586
|
+
example: 'https://www.starbucks.com',
|
|
1587
|
+
nullable: true
|
|
1588
|
+
},
|
|
1589
|
+
description: {
|
|
1590
|
+
type: 'object',
|
|
1591
|
+
description: 'Description',
|
|
1592
|
+
example: 'Global coffeehouse chain',
|
|
1593
|
+
nullable: true
|
|
1594
|
+
},
|
|
1595
|
+
meta: {
|
|
1596
|
+
type: 'object',
|
|
1597
|
+
description: 'Extended metadata'
|
|
1598
|
+
},
|
|
1599
|
+
dataSource: {
|
|
1600
|
+
type: 'string',
|
|
1601
|
+
description: 'Data source',
|
|
1602
|
+
enum: ['MANUAL', 'IMPORT', 'API', 'CROWDSOURCED'],
|
|
1603
|
+
example: 'MANUAL'
|
|
1604
|
+
},
|
|
1605
|
+
verifiedAt: {
|
|
1606
|
+
type: 'object',
|
|
1607
|
+
description: 'Verification timestamp (null if not verified)',
|
|
1608
|
+
example: '2025-01-01T00:00:00.000Z',
|
|
1609
|
+
nullable: true
|
|
1610
|
+
},
|
|
1611
|
+
isActive: {
|
|
1612
|
+
type: 'boolean',
|
|
1613
|
+
description: 'Whether the profile is active',
|
|
1614
|
+
example: true
|
|
1615
|
+
},
|
|
1616
|
+
createdAt: {
|
|
1617
|
+
format: 'date-time',
|
|
1618
|
+
type: 'string',
|
|
1619
|
+
description: 'Creation timestamp',
|
|
1620
|
+
example: '2025-01-01T00:00:00.000Z'
|
|
1621
|
+
},
|
|
1622
|
+
updatedAt: {
|
|
1623
|
+
format: 'date-time',
|
|
1624
|
+
type: 'string',
|
|
1625
|
+
description: 'Last update timestamp',
|
|
1626
|
+
example: '2025-01-01T00:00:00.000Z'
|
|
1627
|
+
}
|
|
1628
|
+
},
|
|
1629
|
+
required: [
|
|
1630
|
+
'id',
|
|
1631
|
+
'canonical',
|
|
1632
|
+
'aliases',
|
|
1633
|
+
'category',
|
|
1634
|
+
'countries',
|
|
1635
|
+
'keywords',
|
|
1636
|
+
'meta',
|
|
1637
|
+
'dataSource',
|
|
1638
|
+
'isActive',
|
|
1639
|
+
'createdAt',
|
|
1640
|
+
'updatedAt'
|
|
1641
|
+
]
|
|
1642
|
+
} as const;
|
|
1643
|
+
|
|
1644
|
+
export const $PayeeProfileListResponseDto = {
|
|
1645
|
+
type: 'object',
|
|
1646
|
+
properties: {
|
|
1647
|
+
items: {
|
|
1648
|
+
description: 'List of payee profiles',
|
|
1649
|
+
type: 'array',
|
|
1650
|
+
items: {
|
|
1651
|
+
$ref: '#/components/schemas/PayeeProfileResponseDto'
|
|
1652
|
+
}
|
|
1653
|
+
},
|
|
1654
|
+
total: {
|
|
1655
|
+
type: 'number',
|
|
1656
|
+
description: 'Total count of matching records',
|
|
1657
|
+
example: 100
|
|
1658
|
+
}
|
|
1659
|
+
},
|
|
1660
|
+
required: ['items', 'total']
|
|
1661
|
+
} as const;
|
|
1662
|
+
|
|
1663
|
+
export const $CommodityResponseDto = {
|
|
1664
|
+
type: 'object',
|
|
1665
|
+
properties: {
|
|
1666
|
+
id: {
|
|
1667
|
+
type: 'string',
|
|
1668
|
+
description: 'Unique identifier',
|
|
1669
|
+
example: 'uuid-123-456'
|
|
1670
|
+
},
|
|
1671
|
+
userId: {
|
|
1672
|
+
type: 'object',
|
|
1673
|
+
description: 'User ID (owner of the commodity)',
|
|
1674
|
+
example: 'user-123',
|
|
1675
|
+
nullable: true
|
|
1676
|
+
},
|
|
1677
|
+
symbol: {
|
|
1678
|
+
type: 'string',
|
|
1679
|
+
description: 'Commodity symbol (corresponds to Beancount currency field)',
|
|
1680
|
+
example: 'AAPL'
|
|
1681
|
+
},
|
|
1682
|
+
date: {
|
|
1683
|
+
type: 'string',
|
|
1684
|
+
description:
|
|
1685
|
+
'Commodity definition date (required per Beancount spec). Represents when this commodity was first defined in the accounting system.',
|
|
1686
|
+
example: '2024-01-01',
|
|
1687
|
+
format: 'date'
|
|
1688
|
+
},
|
|
1689
|
+
metadata: {
|
|
1690
|
+
type: 'object',
|
|
1691
|
+
description:
|
|
1692
|
+
'Metadata (corresponds to Beancount meta field). Contains name, assetClass, precision, note, tags, etc.',
|
|
1693
|
+
example: {
|
|
1694
|
+
name: 'Apple Inc.',
|
|
1695
|
+
assetClass: 'stock',
|
|
1696
|
+
precision: 2,
|
|
1697
|
+
note: 'Tech stock',
|
|
1698
|
+
source: 'AUTO_CREATED'
|
|
1699
|
+
}
|
|
1700
|
+
},
|
|
1701
|
+
symbolProfileId: {
|
|
1702
|
+
type: 'object',
|
|
1703
|
+
description:
|
|
1704
|
+
'Reference to SymbolProfile (market data integration, SaaS feature)',
|
|
1705
|
+
example: 'uuid-789',
|
|
1706
|
+
nullable: true
|
|
1707
|
+
},
|
|
1708
|
+
createdAt: {
|
|
1709
|
+
format: 'date-time',
|
|
1710
|
+
type: 'string',
|
|
1711
|
+
description: 'Creation timestamp',
|
|
1712
|
+
example: '2024-11-03T10:00:00Z'
|
|
1713
|
+
},
|
|
1714
|
+
updatedAt: {
|
|
1715
|
+
format: 'date-time',
|
|
1716
|
+
type: 'string',
|
|
1717
|
+
description: 'Last update timestamp',
|
|
1718
|
+
example: '2024-11-03T10:00:00Z'
|
|
1719
|
+
}
|
|
1720
|
+
},
|
|
1721
|
+
required: ['id', 'symbol', 'date', 'metadata', 'createdAt', 'updatedAt']
|
|
1722
|
+
} as const;
|
|
1723
|
+
|
|
1724
|
+
export const $CommodityListResponseDto = {
|
|
1725
|
+
type: 'object',
|
|
1726
|
+
properties: {
|
|
1727
|
+
items: {
|
|
1728
|
+
description: 'List of commodities',
|
|
1729
|
+
type: 'array',
|
|
1730
|
+
items: {
|
|
1731
|
+
$ref: '#/components/schemas/CommodityResponseDto'
|
|
1732
|
+
}
|
|
1733
|
+
},
|
|
1734
|
+
total: {
|
|
1735
|
+
type: 'number',
|
|
1736
|
+
description: 'Total number of commodities',
|
|
1737
|
+
example: 42
|
|
1738
|
+
}
|
|
1739
|
+
},
|
|
1740
|
+
required: ['items', 'total']
|
|
1741
|
+
} as const;
|
|
1742
|
+
|
|
1743
|
+
export const $RecurringRuleResponseDto = {
|
|
1744
|
+
type: 'object',
|
|
1745
|
+
properties: {
|
|
1746
|
+
id: {
|
|
1747
|
+
type: 'string',
|
|
1748
|
+
description: 'Rule ID'
|
|
1749
|
+
},
|
|
1750
|
+
userId: {
|
|
1751
|
+
type: 'string',
|
|
1752
|
+
description: 'User ID'
|
|
1753
|
+
},
|
|
1754
|
+
name: {
|
|
1755
|
+
type: 'string',
|
|
1756
|
+
description: 'Rule name'
|
|
1757
|
+
},
|
|
1758
|
+
icon: {
|
|
1759
|
+
type: 'object',
|
|
1760
|
+
description: 'Icon emoji'
|
|
1761
|
+
},
|
|
1762
|
+
frequency: {
|
|
1763
|
+
type: 'string',
|
|
1764
|
+
description: 'Recurring frequency'
|
|
1765
|
+
},
|
|
1766
|
+
expectedAmount: {
|
|
1767
|
+
type: 'number',
|
|
1768
|
+
description: 'Expected amount'
|
|
1769
|
+
},
|
|
1770
|
+
expectedDay: {
|
|
1771
|
+
type: 'object',
|
|
1772
|
+
description: 'Expected day of month'
|
|
1773
|
+
},
|
|
1774
|
+
customIntervalDays: {
|
|
1775
|
+
type: 'object',
|
|
1776
|
+
description: 'Custom interval in days'
|
|
1777
|
+
},
|
|
1778
|
+
currency: {
|
|
1779
|
+
type: 'string',
|
|
1780
|
+
description: 'Currency code'
|
|
1781
|
+
},
|
|
1782
|
+
matchPayeePattern: {
|
|
1783
|
+
type: 'object',
|
|
1784
|
+
description: 'Payee matching pattern'
|
|
1785
|
+
},
|
|
1786
|
+
matchAmountTolerance: {
|
|
1787
|
+
type: 'number',
|
|
1788
|
+
description: 'Amount tolerance percentage'
|
|
1789
|
+
},
|
|
1790
|
+
defaultExpenseAccount: {
|
|
1791
|
+
type: 'object',
|
|
1792
|
+
description: 'Default expense account'
|
|
1793
|
+
},
|
|
1794
|
+
defaultPaymentAccount: {
|
|
1795
|
+
type: 'object',
|
|
1796
|
+
description: 'Default payment account'
|
|
1797
|
+
},
|
|
1798
|
+
defaultPayee: {
|
|
1799
|
+
type: 'object',
|
|
1800
|
+
description: 'Default payee'
|
|
1801
|
+
},
|
|
1802
|
+
isActive: {
|
|
1803
|
+
type: 'boolean',
|
|
1804
|
+
description: 'Whether rule is active'
|
|
1805
|
+
},
|
|
1806
|
+
startDate: {
|
|
1807
|
+
type: 'string',
|
|
1808
|
+
description: 'Rule start date (YYYY-MM-DD)'
|
|
1809
|
+
},
|
|
1810
|
+
endDate: {
|
|
1811
|
+
type: 'object',
|
|
1812
|
+
description: 'Rule end date (YYYY-MM-DD)'
|
|
1813
|
+
},
|
|
1814
|
+
autoCreate: {
|
|
1815
|
+
type: 'boolean',
|
|
1816
|
+
description: 'Auto-create transaction on expected date'
|
|
1817
|
+
},
|
|
1818
|
+
lastOccurrence: {
|
|
1819
|
+
type: 'object',
|
|
1820
|
+
description: 'Last matched occurrence date (YYYY-MM-DD)'
|
|
1821
|
+
},
|
|
1822
|
+
totalCount: {
|
|
1823
|
+
type: 'number',
|
|
1824
|
+
description: 'Total matched transactions count'
|
|
1825
|
+
},
|
|
1826
|
+
createdAt: {
|
|
1827
|
+
format: 'date-time',
|
|
1828
|
+
type: 'string',
|
|
1829
|
+
description: 'Created at timestamp'
|
|
1830
|
+
},
|
|
1831
|
+
updatedAt: {
|
|
1832
|
+
format: 'date-time',
|
|
1833
|
+
type: 'string',
|
|
1834
|
+
description: 'Updated at timestamp'
|
|
1835
|
+
}
|
|
1836
|
+
},
|
|
1837
|
+
required: [
|
|
1838
|
+
'id',
|
|
1839
|
+
'userId',
|
|
1840
|
+
'name',
|
|
1841
|
+
'frequency',
|
|
1842
|
+
'expectedAmount',
|
|
1843
|
+
'currency',
|
|
1844
|
+
'matchAmountTolerance',
|
|
1845
|
+
'isActive',
|
|
1846
|
+
'startDate',
|
|
1847
|
+
'autoCreate',
|
|
1848
|
+
'totalCount',
|
|
1849
|
+
'createdAt',
|
|
1850
|
+
'updatedAt'
|
|
1851
|
+
]
|
|
1852
|
+
} as const;
|
|
1853
|
+
|
|
1854
|
+
export const $RecurringRuleWithStatsResponseDto = {
|
|
1855
|
+
type: 'object',
|
|
1856
|
+
properties: {
|
|
1857
|
+
id: {
|
|
1858
|
+
type: 'string',
|
|
1859
|
+
description: 'Rule ID'
|
|
1860
|
+
},
|
|
1861
|
+
userId: {
|
|
1862
|
+
type: 'string',
|
|
1863
|
+
description: 'User ID'
|
|
1864
|
+
},
|
|
1865
|
+
name: {
|
|
1866
|
+
type: 'string',
|
|
1867
|
+
description: 'Rule name'
|
|
1868
|
+
},
|
|
1869
|
+
icon: {
|
|
1870
|
+
type: 'object',
|
|
1871
|
+
description: 'Icon emoji'
|
|
1872
|
+
},
|
|
1873
|
+
frequency: {
|
|
1874
|
+
type: 'string',
|
|
1875
|
+
description: 'Recurring frequency'
|
|
1876
|
+
},
|
|
1877
|
+
expectedAmount: {
|
|
1878
|
+
type: 'number',
|
|
1879
|
+
description: 'Expected amount'
|
|
1880
|
+
},
|
|
1881
|
+
expectedDay: {
|
|
1882
|
+
type: 'object',
|
|
1883
|
+
description: 'Expected day of month'
|
|
1884
|
+
},
|
|
1885
|
+
customIntervalDays: {
|
|
1886
|
+
type: 'object',
|
|
1887
|
+
description: 'Custom interval in days'
|
|
1888
|
+
},
|
|
1889
|
+
currency: {
|
|
1890
|
+
type: 'string',
|
|
1891
|
+
description: 'Currency code'
|
|
1892
|
+
},
|
|
1893
|
+
matchPayeePattern: {
|
|
1894
|
+
type: 'object',
|
|
1895
|
+
description: 'Payee matching pattern'
|
|
1896
|
+
},
|
|
1897
|
+
matchAmountTolerance: {
|
|
1898
|
+
type: 'number',
|
|
1899
|
+
description: 'Amount tolerance percentage'
|
|
1900
|
+
},
|
|
1901
|
+
defaultExpenseAccount: {
|
|
1902
|
+
type: 'object',
|
|
1903
|
+
description: 'Default expense account'
|
|
1904
|
+
},
|
|
1905
|
+
defaultPaymentAccount: {
|
|
1906
|
+
type: 'object',
|
|
1907
|
+
description: 'Default payment account'
|
|
1908
|
+
},
|
|
1909
|
+
defaultPayee: {
|
|
1910
|
+
type: 'object',
|
|
1911
|
+
description: 'Default payee'
|
|
1912
|
+
},
|
|
1913
|
+
isActive: {
|
|
1914
|
+
type: 'boolean',
|
|
1915
|
+
description: 'Whether rule is active'
|
|
1916
|
+
},
|
|
1917
|
+
startDate: {
|
|
1918
|
+
type: 'string',
|
|
1919
|
+
description: 'Rule start date (YYYY-MM-DD)'
|
|
1920
|
+
},
|
|
1921
|
+
endDate: {
|
|
1922
|
+
type: 'object',
|
|
1923
|
+
description: 'Rule end date (YYYY-MM-DD)'
|
|
1924
|
+
},
|
|
1925
|
+
autoCreate: {
|
|
1926
|
+
type: 'boolean',
|
|
1927
|
+
description: 'Auto-create transaction on expected date'
|
|
1928
|
+
},
|
|
1929
|
+
lastOccurrence: {
|
|
1930
|
+
type: 'object',
|
|
1931
|
+
description: 'Last matched occurrence date (YYYY-MM-DD)'
|
|
1932
|
+
},
|
|
1933
|
+
totalCount: {
|
|
1934
|
+
type: 'number',
|
|
1935
|
+
description: 'Total matched transactions count'
|
|
1936
|
+
},
|
|
1937
|
+
createdAt: {
|
|
1938
|
+
format: 'date-time',
|
|
1939
|
+
type: 'string',
|
|
1940
|
+
description: 'Created at timestamp'
|
|
1941
|
+
},
|
|
1942
|
+
updatedAt: {
|
|
1943
|
+
format: 'date-time',
|
|
1944
|
+
type: 'string',
|
|
1945
|
+
description: 'Updated at timestamp'
|
|
1946
|
+
},
|
|
1947
|
+
pendingCount: {
|
|
1948
|
+
type: 'number',
|
|
1949
|
+
description: 'Number of pending expected transactions'
|
|
1950
|
+
},
|
|
1951
|
+
overdueCount: {
|
|
1952
|
+
type: 'number',
|
|
1953
|
+
description: 'Number of overdue expected transactions'
|
|
1954
|
+
},
|
|
1955
|
+
nextExpectedDate: {
|
|
1956
|
+
type: 'object',
|
|
1957
|
+
description: 'Next expected date (YYYY-MM-DD)'
|
|
1958
|
+
},
|
|
1959
|
+
totalAmount: {
|
|
1960
|
+
type: 'number',
|
|
1961
|
+
description: 'Total amount of all matched transactions'
|
|
1962
|
+
},
|
|
1963
|
+
averageAmount: {
|
|
1964
|
+
type: 'number',
|
|
1965
|
+
description: 'Average amount per transaction'
|
|
1966
|
+
},
|
|
1967
|
+
transactionCount: {
|
|
1968
|
+
type: 'number',
|
|
1969
|
+
description: 'Number of matched transactions'
|
|
1970
|
+
},
|
|
1971
|
+
firstDate: {
|
|
1972
|
+
type: 'object',
|
|
1973
|
+
description: 'First matched transaction date (YYYY-MM-DD)'
|
|
1974
|
+
},
|
|
1975
|
+
lastDate: {
|
|
1976
|
+
type: 'object',
|
|
1977
|
+
description: 'Last matched transaction date (YYYY-MM-DD)'
|
|
1978
|
+
},
|
|
1979
|
+
variance: {
|
|
1980
|
+
type: 'number',
|
|
1981
|
+
description: 'Amount variance (standard deviation squared)'
|
|
1982
|
+
},
|
|
1983
|
+
upcomingCount: {
|
|
1984
|
+
type: 'number',
|
|
1985
|
+
description: 'Number of upcoming expected transactions'
|
|
1986
|
+
}
|
|
1987
|
+
},
|
|
1988
|
+
required: [
|
|
1989
|
+
'id',
|
|
1990
|
+
'userId',
|
|
1991
|
+
'name',
|
|
1992
|
+
'frequency',
|
|
1993
|
+
'expectedAmount',
|
|
1994
|
+
'currency',
|
|
1995
|
+
'matchAmountTolerance',
|
|
1996
|
+
'isActive',
|
|
1997
|
+
'startDate',
|
|
1998
|
+
'autoCreate',
|
|
1999
|
+
'totalCount',
|
|
2000
|
+
'createdAt',
|
|
2001
|
+
'updatedAt',
|
|
2002
|
+
'pendingCount',
|
|
2003
|
+
'overdueCount',
|
|
2004
|
+
'totalAmount',
|
|
2005
|
+
'averageAmount',
|
|
2006
|
+
'transactionCount',
|
|
2007
|
+
'variance',
|
|
2008
|
+
'upcomingCount'
|
|
2009
|
+
]
|
|
2010
|
+
} as const;
|
|
2011
|
+
|
|
2012
|
+
export const $ExpectedTransactionRuleDto = {
|
|
2013
|
+
type: 'object',
|
|
2014
|
+
properties: {
|
|
2015
|
+
name: {
|
|
2016
|
+
type: 'string',
|
|
2017
|
+
description: 'Rule name'
|
|
2018
|
+
},
|
|
2019
|
+
icon: {
|
|
2020
|
+
type: 'object',
|
|
2021
|
+
description: 'Rule icon'
|
|
2022
|
+
},
|
|
2023
|
+
frequency: {
|
|
2024
|
+
type: 'string',
|
|
2025
|
+
description: 'Rule frequency'
|
|
2026
|
+
},
|
|
2027
|
+
currency: {
|
|
2028
|
+
type: 'string',
|
|
2029
|
+
description: 'Currency code'
|
|
2030
|
+
}
|
|
2031
|
+
},
|
|
2032
|
+
required: ['name', 'frequency', 'currency']
|
|
2033
|
+
} as const;
|
|
2034
|
+
|
|
2035
|
+
export const $ExpectedTransactionResponseDto = {
|
|
2036
|
+
type: 'object',
|
|
2037
|
+
properties: {
|
|
2038
|
+
id: {
|
|
2039
|
+
type: 'string',
|
|
2040
|
+
description: 'Expected transaction ID'
|
|
2041
|
+
},
|
|
2042
|
+
userId: {
|
|
2043
|
+
type: 'string',
|
|
2044
|
+
description: 'User ID'
|
|
2045
|
+
},
|
|
2046
|
+
ruleId: {
|
|
2047
|
+
type: 'string',
|
|
2048
|
+
description: 'Associated rule ID'
|
|
2049
|
+
},
|
|
2050
|
+
expectedDate: {
|
|
2051
|
+
type: 'string',
|
|
2052
|
+
description: 'Expected date (YYYY-MM-DD)'
|
|
2053
|
+
},
|
|
2054
|
+
expectedAmount: {
|
|
2055
|
+
type: 'number',
|
|
2056
|
+
description: 'Expected amount'
|
|
2057
|
+
},
|
|
2058
|
+
status: {
|
|
2059
|
+
type: 'string',
|
|
2060
|
+
description: 'Status (PENDING, COMPLETED, SKIPPED)'
|
|
2061
|
+
},
|
|
2062
|
+
matchedTransactionId: {
|
|
2063
|
+
type: 'object',
|
|
2064
|
+
description: 'Matched transaction ID'
|
|
2065
|
+
},
|
|
2066
|
+
matchedAt: {
|
|
2067
|
+
type: 'object',
|
|
2068
|
+
description: 'Match timestamp (ISO 8601)'
|
|
2069
|
+
},
|
|
2070
|
+
matchConfidence: {
|
|
2071
|
+
type: 'object',
|
|
2072
|
+
description: 'Match confidence score (0-1)'
|
|
2073
|
+
},
|
|
2074
|
+
isOverdue: {
|
|
2075
|
+
type: 'boolean',
|
|
2076
|
+
description: 'Whether this expected transaction is overdue'
|
|
2077
|
+
},
|
|
2078
|
+
rule: {
|
|
2079
|
+
description: 'Rule information',
|
|
2080
|
+
allOf: [
|
|
2081
|
+
{
|
|
2082
|
+
$ref: '#/components/schemas/ExpectedTransactionRuleDto'
|
|
2083
|
+
}
|
|
2084
|
+
]
|
|
2085
|
+
},
|
|
2086
|
+
createdAt: {
|
|
2087
|
+
format: 'date-time',
|
|
2088
|
+
type: 'string',
|
|
2089
|
+
description: 'Created at timestamp'
|
|
2090
|
+
},
|
|
2091
|
+
updatedAt: {
|
|
2092
|
+
format: 'date-time',
|
|
2093
|
+
type: 'string',
|
|
2094
|
+
description: 'Updated at timestamp'
|
|
2095
|
+
}
|
|
2096
|
+
},
|
|
2097
|
+
required: [
|
|
2098
|
+
'id',
|
|
2099
|
+
'userId',
|
|
2100
|
+
'ruleId',
|
|
2101
|
+
'expectedDate',
|
|
2102
|
+
'expectedAmount',
|
|
2103
|
+
'status',
|
|
2104
|
+
'isOverdue',
|
|
2105
|
+
'rule',
|
|
2106
|
+
'createdAt',
|
|
2107
|
+
'updatedAt'
|
|
2108
|
+
]
|
|
2109
|
+
} as const;
|
|
2110
|
+
|
|
2111
|
+
export const $ExpectedTransactionListResponseDto = {
|
|
2112
|
+
type: 'object',
|
|
2113
|
+
properties: {
|
|
2114
|
+
items: {
|
|
2115
|
+
type: 'array',
|
|
2116
|
+
items: {
|
|
2117
|
+
$ref: '#/components/schemas/ExpectedTransactionResponseDto'
|
|
2118
|
+
}
|
|
2119
|
+
},
|
|
2120
|
+
total: {
|
|
2121
|
+
type: 'number',
|
|
2122
|
+
description: 'Total count'
|
|
2123
|
+
}
|
|
2124
|
+
},
|
|
2125
|
+
required: ['items', 'total']
|
|
2126
|
+
} as const;
|
|
2127
|
+
|
|
2128
|
+
export const $ForecastItemDto = {
|
|
2129
|
+
type: 'object',
|
|
2130
|
+
properties: {
|
|
2131
|
+
rule: {
|
|
2132
|
+
type: 'string',
|
|
2133
|
+
description: 'Rule name',
|
|
2134
|
+
example: 'Rent'
|
|
2135
|
+
},
|
|
2136
|
+
ruleId: {
|
|
2137
|
+
type: 'string',
|
|
2138
|
+
description: 'Rule ID',
|
|
2139
|
+
example: 'clx123...'
|
|
2140
|
+
},
|
|
2141
|
+
amount: {
|
|
2142
|
+
type: 'number',
|
|
2143
|
+
description: 'Expected amount',
|
|
2144
|
+
example: 3000
|
|
2145
|
+
},
|
|
2146
|
+
date: {
|
|
2147
|
+
type: 'string',
|
|
2148
|
+
description: 'Expected date (YYYY-MM-DD)',
|
|
2149
|
+
example: '2024-04-01'
|
|
2150
|
+
},
|
|
2151
|
+
icon: {
|
|
2152
|
+
type: 'object',
|
|
2153
|
+
description: 'Rule icon emoji',
|
|
2154
|
+
example: '🏠',
|
|
2155
|
+
nullable: true
|
|
2156
|
+
},
|
|
2157
|
+
currency: {
|
|
2158
|
+
type: 'string',
|
|
2159
|
+
description: 'Currency code',
|
|
2160
|
+
example: 'CNY'
|
|
2161
|
+
}
|
|
2162
|
+
},
|
|
2163
|
+
required: ['rule', 'ruleId', 'amount', 'date', 'icon', 'currency']
|
|
2164
|
+
} as const;
|
|
2165
|
+
|
|
2166
|
+
export const $MonthlyForecastDto = {
|
|
2167
|
+
type: 'object',
|
|
2168
|
+
properties: {
|
|
2169
|
+
month: {
|
|
2170
|
+
type: 'string',
|
|
2171
|
+
description: 'Month (YYYY-MM)',
|
|
2172
|
+
example: '2024-04'
|
|
2173
|
+
},
|
|
2174
|
+
expectedOutflow: {
|
|
2175
|
+
type: 'number',
|
|
2176
|
+
description: 'Total expected outflow for the month',
|
|
2177
|
+
example: 8500
|
|
2178
|
+
},
|
|
2179
|
+
itemCount: {
|
|
2180
|
+
type: 'number',
|
|
2181
|
+
description: 'Number of expected transactions',
|
|
2182
|
+
example: 3
|
|
2183
|
+
},
|
|
2184
|
+
byCurrency: {
|
|
2185
|
+
type: 'object',
|
|
2186
|
+
description: 'Breakdown by currency',
|
|
2187
|
+
example: {
|
|
2188
|
+
CNY: 8500,
|
|
2189
|
+
USD: 100
|
|
2190
|
+
}
|
|
2191
|
+
},
|
|
2192
|
+
items: {
|
|
2193
|
+
description: 'Individual forecast items',
|
|
2194
|
+
type: 'array',
|
|
2195
|
+
items: {
|
|
2196
|
+
$ref: '#/components/schemas/ForecastItemDto'
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
},
|
|
2200
|
+
required: ['month', 'expectedOutflow', 'itemCount', 'byCurrency', 'items']
|
|
2201
|
+
} as const;
|
|
2202
|
+
|
|
2203
|
+
export const $ForecastResponseDto = {
|
|
2204
|
+
type: 'object',
|
|
2205
|
+
properties: {
|
|
2206
|
+
forecast: {
|
|
2207
|
+
description: 'Monthly forecast data',
|
|
2208
|
+
type: 'array',
|
|
2209
|
+
items: {
|
|
2210
|
+
$ref: '#/components/schemas/MonthlyForecastDto'
|
|
2211
|
+
}
|
|
2212
|
+
},
|
|
2213
|
+
totalOutflow: {
|
|
2214
|
+
type: 'number',
|
|
2215
|
+
description: 'Total expected outflow across all months',
|
|
2216
|
+
example: 25500
|
|
2217
|
+
},
|
|
2218
|
+
totalByCurrency: {
|
|
2219
|
+
type: 'object',
|
|
2220
|
+
description: 'Total by currency across all months',
|
|
2221
|
+
example: {
|
|
2222
|
+
CNY: 25500,
|
|
2223
|
+
USD: 300
|
|
2224
|
+
}
|
|
2225
|
+
},
|
|
2226
|
+
rulesCount: {
|
|
2227
|
+
type: 'number',
|
|
2228
|
+
description: 'Number of active recurring rules included',
|
|
2229
|
+
example: 5
|
|
2230
|
+
},
|
|
2231
|
+
periodStart: {
|
|
2232
|
+
type: 'string',
|
|
2233
|
+
description: 'Forecast period start date',
|
|
2234
|
+
example: '2024-04-01'
|
|
2235
|
+
},
|
|
2236
|
+
periodEnd: {
|
|
2237
|
+
type: 'string',
|
|
2238
|
+
description: 'Forecast period end date',
|
|
2239
|
+
example: '2024-06-30'
|
|
2240
|
+
}
|
|
2241
|
+
},
|
|
2242
|
+
required: [
|
|
2243
|
+
'forecast',
|
|
2244
|
+
'totalOutflow',
|
|
2245
|
+
'totalByCurrency',
|
|
2246
|
+
'rulesCount',
|
|
2247
|
+
'periodStart',
|
|
2248
|
+
'periodEnd'
|
|
2249
|
+
]
|
|
2250
|
+
} as const;
|
|
2251
|
+
|
|
2252
|
+
export const $TransactionRuleResponseDto = {
|
|
2253
|
+
type: 'object',
|
|
2254
|
+
properties: {
|
|
2255
|
+
id: {
|
|
2256
|
+
type: 'string',
|
|
2257
|
+
description: 'Rule ID'
|
|
2258
|
+
},
|
|
2259
|
+
name: {
|
|
2260
|
+
type: 'string',
|
|
2261
|
+
description: 'Rule name'
|
|
2262
|
+
},
|
|
2263
|
+
description: {
|
|
2264
|
+
type: 'string',
|
|
2265
|
+
description: 'Rule description'
|
|
2266
|
+
},
|
|
2267
|
+
narrationKeywords: {
|
|
2268
|
+
description: 'Keywords to match in transaction narration',
|
|
2269
|
+
type: 'array',
|
|
2270
|
+
items: {
|
|
2271
|
+
type: 'string'
|
|
2272
|
+
}
|
|
2273
|
+
},
|
|
2274
|
+
payeeKeywords: {
|
|
2275
|
+
description: 'Keywords to match in payee name',
|
|
2276
|
+
type: 'array',
|
|
2277
|
+
items: {
|
|
2278
|
+
type: 'string'
|
|
2279
|
+
}
|
|
2280
|
+
},
|
|
2281
|
+
categoryKeywords: {
|
|
2282
|
+
description: 'Keywords to match in category',
|
|
2283
|
+
type: 'array',
|
|
2284
|
+
items: {
|
|
2285
|
+
type: 'string'
|
|
2286
|
+
}
|
|
2287
|
+
},
|
|
2288
|
+
methodKeywords: {
|
|
2289
|
+
description: 'Keywords to match in payment method',
|
|
2290
|
+
type: 'array',
|
|
2291
|
+
items: {
|
|
2292
|
+
type: 'string'
|
|
2293
|
+
}
|
|
2294
|
+
},
|
|
2295
|
+
categoryAccount: {
|
|
2296
|
+
type: 'string',
|
|
2297
|
+
description: 'Destination account for categorization'
|
|
2298
|
+
},
|
|
2299
|
+
matchLogic: {
|
|
2300
|
+
type: 'string',
|
|
2301
|
+
description: 'Keyword matching logic',
|
|
2302
|
+
enum: ['OR', 'AND'],
|
|
2303
|
+
example: 'OR'
|
|
2304
|
+
},
|
|
2305
|
+
amountRange: {
|
|
2306
|
+
type: 'object',
|
|
2307
|
+
description: 'Amount range for matching',
|
|
2308
|
+
example: {
|
|
2309
|
+
min: 0,
|
|
2310
|
+
max: 100
|
|
2311
|
+
}
|
|
2312
|
+
},
|
|
2313
|
+
priority: {
|
|
2314
|
+
type: 'number',
|
|
2315
|
+
description: 'Rule priority (0-1000, higher = first match)',
|
|
2316
|
+
example: 50
|
|
2317
|
+
},
|
|
2318
|
+
enabled: {
|
|
2319
|
+
type: 'boolean',
|
|
2320
|
+
description: 'Whether the rule is enabled'
|
|
2321
|
+
},
|
|
2322
|
+
learningSource: {
|
|
2323
|
+
type: 'string',
|
|
2324
|
+
description: 'Learning source: NLP, REVIEW_CENTER, or null for manual',
|
|
2325
|
+
enum: ['NLP', 'REVIEW_CENTER'],
|
|
2326
|
+
example: 'REVIEW_CENTER'
|
|
2327
|
+
},
|
|
2328
|
+
autoApplyEnabled: {
|
|
2329
|
+
type: 'boolean',
|
|
2330
|
+
description: 'Whether auto-apply is enabled for this rule'
|
|
2331
|
+
},
|
|
2332
|
+
confirmationCount: {
|
|
2333
|
+
type: 'number',
|
|
2334
|
+
description: 'Number of confirmations for NLP-learned rules',
|
|
2335
|
+
example: 3
|
|
2336
|
+
},
|
|
2337
|
+
additionalTags: {
|
|
2338
|
+
description: 'Additional tags',
|
|
2339
|
+
type: 'array',
|
|
2340
|
+
items: {
|
|
2341
|
+
type: 'string'
|
|
2342
|
+
}
|
|
2343
|
+
},
|
|
2344
|
+
additionalMetadata: {
|
|
2345
|
+
type: 'object',
|
|
2346
|
+
description: 'Additional metadata',
|
|
2347
|
+
example: {}
|
|
2348
|
+
},
|
|
2349
|
+
createdAt: {
|
|
2350
|
+
format: 'date-time',
|
|
2351
|
+
type: 'string',
|
|
2352
|
+
description: 'Created timestamp'
|
|
2353
|
+
},
|
|
2354
|
+
updatedAt: {
|
|
2355
|
+
format: 'date-time',
|
|
2356
|
+
type: 'string',
|
|
2357
|
+
description: 'Updated timestamp'
|
|
2358
|
+
}
|
|
2359
|
+
},
|
|
2360
|
+
required: [
|
|
2361
|
+
'id',
|
|
2362
|
+
'name',
|
|
2363
|
+
'narrationKeywords',
|
|
2364
|
+
'payeeKeywords',
|
|
2365
|
+
'categoryKeywords',
|
|
2366
|
+
'methodKeywords',
|
|
2367
|
+
'matchLogic',
|
|
2368
|
+
'priority',
|
|
2369
|
+
'enabled',
|
|
2370
|
+
'autoApplyEnabled',
|
|
2371
|
+
'confirmationCount',
|
|
2372
|
+
'additionalTags',
|
|
2373
|
+
'createdAt',
|
|
2374
|
+
'updatedAt'
|
|
2375
|
+
]
|
|
2376
|
+
} as const;
|
|
2377
|
+
|
|
2378
|
+
export const $TransactionRuleListResponseDto = {
|
|
2379
|
+
type: 'object',
|
|
2380
|
+
properties: {
|
|
2381
|
+
data: {
|
|
2382
|
+
type: 'array',
|
|
2383
|
+
items: {
|
|
2384
|
+
$ref: '#/components/schemas/TransactionRuleResponseDto'
|
|
2385
|
+
}
|
|
2386
|
+
},
|
|
2387
|
+
total: {
|
|
2388
|
+
type: 'number',
|
|
2389
|
+
description: 'Total count of rules'
|
|
2390
|
+
},
|
|
2391
|
+
limit: {
|
|
2392
|
+
type: 'number',
|
|
2393
|
+
description: 'Results per page'
|
|
2394
|
+
},
|
|
2395
|
+
offset: {
|
|
2396
|
+
type: 'number',
|
|
2397
|
+
description: 'Pagination offset'
|
|
2398
|
+
}
|
|
2399
|
+
},
|
|
2400
|
+
required: ['data', 'total', 'limit', 'offset']
|
|
2401
|
+
} as const;
|
|
2402
|
+
|
|
2403
|
+
export const $ValidateRuleDto = {
|
|
2404
|
+
type: 'object',
|
|
2405
|
+
properties: {
|
|
2406
|
+
name: {
|
|
2407
|
+
type: 'string',
|
|
2408
|
+
minLength: 1,
|
|
2409
|
+
maxLength: 100
|
|
2410
|
+
},
|
|
2411
|
+
description: {
|
|
2412
|
+
type: 'string',
|
|
2413
|
+
maxLength: 500
|
|
2414
|
+
},
|
|
2415
|
+
narrationKeywords: {
|
|
2416
|
+
items: {
|
|
2417
|
+
type: 'array'
|
|
2418
|
+
},
|
|
2419
|
+
maxItems: 50,
|
|
2420
|
+
type: 'array'
|
|
2421
|
+
},
|
|
2422
|
+
payeeKeywords: {
|
|
2423
|
+
items: {
|
|
2424
|
+
type: 'array'
|
|
2425
|
+
},
|
|
2426
|
+
maxItems: 50,
|
|
2427
|
+
type: 'array'
|
|
2428
|
+
},
|
|
2429
|
+
categoryKeywords: {
|
|
2430
|
+
items: {
|
|
2431
|
+
type: 'array'
|
|
2432
|
+
},
|
|
2433
|
+
maxItems: 50,
|
|
2434
|
+
type: 'array'
|
|
2435
|
+
},
|
|
2436
|
+
methodKeywords: {
|
|
2437
|
+
items: {
|
|
2438
|
+
type: 'array'
|
|
2439
|
+
},
|
|
2440
|
+
maxItems: 50,
|
|
2441
|
+
description: 'Payment method keywords (e.g., HuaBei, YuEBao)',
|
|
2442
|
+
type: 'array'
|
|
2443
|
+
},
|
|
2444
|
+
categoryAccount: {
|
|
2445
|
+
type: 'string',
|
|
2446
|
+
maxLength: 200,
|
|
2447
|
+
description:
|
|
2448
|
+
'Destination account for expenses/income (e.g., Expenses:Food:Coffee)'
|
|
2449
|
+
},
|
|
2450
|
+
matchLogic: {
|
|
2451
|
+
type: 'string',
|
|
2452
|
+
enum: ['OR', 'AND'],
|
|
2453
|
+
default: 'OR'
|
|
2454
|
+
},
|
|
2455
|
+
amountMin: {
|
|
2456
|
+
type: 'number',
|
|
2457
|
+
minimum: 0,
|
|
2458
|
+
description: 'Minimum transaction amount (inclusive)'
|
|
2459
|
+
},
|
|
2460
|
+
amountMax: {
|
|
2461
|
+
type: 'number',
|
|
2462
|
+
minimum: 0,
|
|
2463
|
+
description: 'Maximum transaction amount (inclusive)'
|
|
2464
|
+
},
|
|
2465
|
+
priority: {
|
|
2466
|
+
type: 'number',
|
|
2467
|
+
default: 50,
|
|
2468
|
+
minimum: 0,
|
|
2469
|
+
maximum: 1000
|
|
2470
|
+
},
|
|
2471
|
+
additionalTags: {
|
|
2472
|
+
items: {
|
|
2473
|
+
type: 'array'
|
|
2474
|
+
},
|
|
2475
|
+
maxItems: 20,
|
|
2476
|
+
type: 'array'
|
|
2477
|
+
},
|
|
2478
|
+
additionalMetadata: {
|
|
2479
|
+
type: 'object'
|
|
2480
|
+
},
|
|
2481
|
+
upsertByPayee: {
|
|
2482
|
+
type: 'boolean',
|
|
2483
|
+
description:
|
|
2484
|
+
'If true, update existing rule with matching payeeKeywords[0] instead of creating new rule'
|
|
2485
|
+
}
|
|
2486
|
+
},
|
|
2487
|
+
required: ['name', 'matchLogic', 'priority']
|
|
2488
|
+
} as const;
|
|
2489
|
+
|
|
2490
|
+
export const $ValidateRuleResponseDto = {
|
|
2491
|
+
type: 'object',
|
|
2492
|
+
properties: {
|
|
2493
|
+
valid: {
|
|
2494
|
+
type: 'boolean',
|
|
2495
|
+
description: 'Whether the rule configuration is valid',
|
|
2496
|
+
example: true
|
|
2497
|
+
},
|
|
2498
|
+
errors: {
|
|
2499
|
+
description: 'List of validation errors (empty if valid)',
|
|
2500
|
+
example: [],
|
|
2501
|
+
items: {
|
|
2502
|
+
type: 'array'
|
|
2503
|
+
},
|
|
2504
|
+
type: 'array'
|
|
2505
|
+
},
|
|
2506
|
+
warnings: {
|
|
2507
|
+
description: 'List of validation warnings (non-blocking issues)',
|
|
2508
|
+
example: [
|
|
2509
|
+
'No account constraints specified - rule will match any account'
|
|
2510
|
+
],
|
|
2511
|
+
items: {
|
|
2512
|
+
type: 'array'
|
|
2513
|
+
},
|
|
2514
|
+
type: 'array'
|
|
2515
|
+
}
|
|
2516
|
+
},
|
|
2517
|
+
required: ['valid', 'errors', 'warnings']
|
|
2518
|
+
} as const;
|
|
2519
|
+
|
|
2520
|
+
export const $ExportRulesResponseDto = {
|
|
2521
|
+
type: 'object',
|
|
2522
|
+
properties: {
|
|
2523
|
+
exportedAt: {
|
|
2524
|
+
type: 'string',
|
|
2525
|
+
description: 'Export timestamp'
|
|
2526
|
+
},
|
|
2527
|
+
userId: {
|
|
2528
|
+
type: 'string',
|
|
2529
|
+
description: 'User ID'
|
|
2530
|
+
},
|
|
2531
|
+
ruleCount: {
|
|
2532
|
+
type: 'number',
|
|
2533
|
+
description: 'Number of exported rules'
|
|
2534
|
+
},
|
|
2535
|
+
rules: {
|
|
2536
|
+
type: 'array',
|
|
2537
|
+
description: 'Exported rules'
|
|
2538
|
+
}
|
|
2539
|
+
},
|
|
2540
|
+
required: ['exportedAt', 'userId', 'ruleCount', 'rules']
|
|
2541
|
+
} as const;
|
|
2542
|
+
|
|
2543
|
+
export const $RuleStatisticsResponseDto = {
|
|
2544
|
+
type: 'object',
|
|
2545
|
+
properties: {
|
|
2546
|
+
period: {
|
|
2547
|
+
type: 'string',
|
|
2548
|
+
description: 'Statistics time period',
|
|
2549
|
+
enum: ['7d', '30d', '90d']
|
|
2550
|
+
},
|
|
2551
|
+
totalRules: {
|
|
2552
|
+
type: 'number',
|
|
2553
|
+
description: 'Total number of rules'
|
|
2554
|
+
},
|
|
2555
|
+
rulesWithMatches: {
|
|
2556
|
+
type: 'number',
|
|
2557
|
+
description: 'Number of rules with at least one match'
|
|
2558
|
+
},
|
|
2559
|
+
totalMatches: {
|
|
2560
|
+
type: 'number',
|
|
2561
|
+
description: 'Total number of matches across all rules'
|
|
2562
|
+
},
|
|
2563
|
+
averageConfidence: {
|
|
2564
|
+
type: 'number',
|
|
2565
|
+
description: 'Average confidence score across all matches',
|
|
2566
|
+
example: 0.82
|
|
2567
|
+
},
|
|
2568
|
+
ruleStats: {
|
|
2569
|
+
type: 'array',
|
|
2570
|
+
description: 'Per-rule statistics',
|
|
2571
|
+
items: {
|
|
2572
|
+
type: 'object',
|
|
2573
|
+
properties: {
|
|
2574
|
+
ruleId: {
|
|
2575
|
+
type: 'string'
|
|
2576
|
+
},
|
|
2577
|
+
ruleName: {
|
|
2578
|
+
type: 'string'
|
|
2579
|
+
},
|
|
2580
|
+
matchCount: {
|
|
2581
|
+
type: 'number'
|
|
2582
|
+
},
|
|
2583
|
+
averageConfidence: {
|
|
2584
|
+
type: 'number'
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
},
|
|
2590
|
+
required: [
|
|
2591
|
+
'period',
|
|
2592
|
+
'totalRules',
|
|
2593
|
+
'rulesWithMatches',
|
|
2594
|
+
'totalMatches',
|
|
2595
|
+
'averageConfidence',
|
|
2596
|
+
'ruleStats'
|
|
2597
|
+
]
|
|
2598
|
+
} as const;
|
|
2599
|
+
|
|
2600
|
+
export const $TestRuleDto = {
|
|
2601
|
+
type: 'object',
|
|
2602
|
+
properties: {
|
|
2603
|
+
narration: {
|
|
2604
|
+
type: 'string',
|
|
2605
|
+
minLength: 1,
|
|
2606
|
+
maxLength: 500
|
|
2607
|
+
},
|
|
2608
|
+
payee: {
|
|
2609
|
+
type: 'string',
|
|
2610
|
+
maxLength: 200
|
|
2611
|
+
},
|
|
2612
|
+
categoryAccount: {
|
|
2613
|
+
type: 'string',
|
|
2614
|
+
maxLength: 200
|
|
2615
|
+
},
|
|
2616
|
+
amount: {
|
|
2617
|
+
type: 'number'
|
|
2618
|
+
},
|
|
2619
|
+
currency: {
|
|
2620
|
+
type: 'string',
|
|
2621
|
+
maxLength: 10
|
|
2622
|
+
}
|
|
2623
|
+
},
|
|
2624
|
+
required: ['narration']
|
|
2625
|
+
} as const;
|
|
2626
|
+
|
|
2627
|
+
export const $TestRuleResponseDto = {
|
|
2628
|
+
type: 'object',
|
|
2629
|
+
properties: {
|
|
2630
|
+
ruleId: {
|
|
2631
|
+
type: 'string',
|
|
2632
|
+
description: 'Rule ID that was tested'
|
|
2633
|
+
},
|
|
2634
|
+
matches: {
|
|
2635
|
+
type: 'boolean',
|
|
2636
|
+
description: 'Whether the rule matched the test data'
|
|
2637
|
+
},
|
|
2638
|
+
confidence: {
|
|
2639
|
+
type: 'number',
|
|
2640
|
+
description: 'Match confidence score (0-1)',
|
|
2641
|
+
example: 0.85
|
|
2642
|
+
},
|
|
2643
|
+
matchDetails: {
|
|
2644
|
+
type: 'object',
|
|
2645
|
+
description: 'Details of which fields matched',
|
|
2646
|
+
example: {
|
|
2647
|
+
narration: true,
|
|
2648
|
+
payee: false,
|
|
2649
|
+
categoryAccount: false
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
},
|
|
2653
|
+
required: ['ruleId', 'matches', 'confidence', 'matchDetails']
|
|
2654
|
+
} as const;
|
|
2655
|
+
|
|
2656
|
+
export const $DeleteOwnUserDto = {
|
|
2657
|
+
type: 'object',
|
|
2658
|
+
properties: {
|
|
2659
|
+
accessToken: {
|
|
2660
|
+
type: 'string',
|
|
2661
|
+
description: 'Access token for user verification',
|
|
2662
|
+
example: 'abc123xyz'
|
|
2663
|
+
}
|
|
2664
|
+
},
|
|
2665
|
+
required: ['accessToken']
|
|
2666
|
+
} as const;
|
|
2667
|
+
|
|
2668
|
+
export const $SignupDto = {
|
|
2669
|
+
type: 'object',
|
|
2670
|
+
properties: {
|
|
2671
|
+
turnstileToken: {
|
|
2672
|
+
type: 'string',
|
|
2673
|
+
description:
|
|
2674
|
+
'Cloudflare Turnstile verification token (optional when Turnstile disabled)',
|
|
2675
|
+
example: '0.abc123def456...'
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
} as const;
|
|
2679
|
+
|
|
2680
|
+
export const $UpdateUserSettingDto = {
|
|
2681
|
+
type: 'object',
|
|
2682
|
+
properties: {
|
|
2683
|
+
secId: {
|
|
2684
|
+
type: 'number',
|
|
2685
|
+
description: 'Security ID'
|
|
2686
|
+
},
|
|
2687
|
+
annualInterestRate: {
|
|
2688
|
+
type: 'number',
|
|
2689
|
+
description: 'Annual interest rate',
|
|
2690
|
+
example: 0.05
|
|
2691
|
+
},
|
|
2692
|
+
currency: {
|
|
2693
|
+
type: 'string',
|
|
2694
|
+
description: 'Currency code',
|
|
2695
|
+
example: 'USD'
|
|
2696
|
+
},
|
|
2697
|
+
baseCurrency: {
|
|
2698
|
+
type: 'string',
|
|
2699
|
+
description: 'Base currency code',
|
|
2700
|
+
example: 'USD'
|
|
2701
|
+
},
|
|
2702
|
+
benchmark: {
|
|
2703
|
+
type: 'string',
|
|
2704
|
+
description: 'Benchmark symbol',
|
|
2705
|
+
example: 'SPY'
|
|
2706
|
+
},
|
|
2707
|
+
colorScheme: {
|
|
2708
|
+
type: 'string',
|
|
2709
|
+
description: 'Color scheme',
|
|
2710
|
+
enum: ['DARK', 'LIGHT']
|
|
2711
|
+
},
|
|
2712
|
+
dateRange: {
|
|
2713
|
+
type: 'string',
|
|
2714
|
+
description: 'Date range filter',
|
|
2715
|
+
example: '1y'
|
|
2716
|
+
},
|
|
2717
|
+
emergencyFund: {
|
|
2718
|
+
type: 'number',
|
|
2719
|
+
description: 'Emergency fund amount',
|
|
2720
|
+
example: 10000
|
|
2721
|
+
},
|
|
2722
|
+
'filters.accounts': {
|
|
2723
|
+
description: 'Account filter IDs',
|
|
2724
|
+
type: 'array',
|
|
2725
|
+
items: {
|
|
2726
|
+
type: 'string'
|
|
2727
|
+
}
|
|
2728
|
+
},
|
|
2729
|
+
'filters.assetClasses': {
|
|
2730
|
+
description: 'Asset class filters',
|
|
2731
|
+
type: 'array',
|
|
2732
|
+
items: {
|
|
2733
|
+
type: 'string'
|
|
2734
|
+
}
|
|
2735
|
+
},
|
|
2736
|
+
'filters.dataSource': {
|
|
2737
|
+
type: 'string',
|
|
2738
|
+
description: 'Data source filter'
|
|
2739
|
+
},
|
|
2740
|
+
'filters.symbol': {
|
|
2741
|
+
type: 'string',
|
|
2742
|
+
description: 'Symbol filter'
|
|
2743
|
+
},
|
|
2744
|
+
'filters.tags': {
|
|
2745
|
+
description: 'Tag filters',
|
|
2746
|
+
type: 'array',
|
|
2747
|
+
items: {
|
|
2748
|
+
type: 'string'
|
|
2749
|
+
}
|
|
2750
|
+
},
|
|
2751
|
+
isExperimentalFeatures: {
|
|
2752
|
+
type: 'boolean',
|
|
2753
|
+
description: 'Enable experimental features'
|
|
2754
|
+
},
|
|
2755
|
+
isRestrictedView: {
|
|
2756
|
+
type: 'boolean',
|
|
2757
|
+
description: 'Enable restricted view mode'
|
|
2758
|
+
},
|
|
2759
|
+
language: {
|
|
2760
|
+
type: 'string',
|
|
2761
|
+
description: 'Language code',
|
|
2762
|
+
example: 'en'
|
|
2763
|
+
},
|
|
2764
|
+
locale: {
|
|
2765
|
+
type: 'string',
|
|
2766
|
+
description: 'Locale code',
|
|
2767
|
+
example: 'en-US'
|
|
2768
|
+
},
|
|
2769
|
+
projectedTotalAmount: {
|
|
2770
|
+
type: 'number',
|
|
2771
|
+
description: 'Projected total amount',
|
|
2772
|
+
example: 1000000
|
|
2773
|
+
},
|
|
2774
|
+
retirementDate: {
|
|
2775
|
+
type: 'string',
|
|
2776
|
+
description: 'Retirement date in ISO 8601 format',
|
|
2777
|
+
example: '2050-01-01'
|
|
2778
|
+
},
|
|
2779
|
+
savingsRate: {
|
|
2780
|
+
type: 'number',
|
|
2781
|
+
description: 'Savings rate percentage',
|
|
2782
|
+
example: 0.2
|
|
2783
|
+
},
|
|
2784
|
+
viewMode: {
|
|
2785
|
+
type: 'string',
|
|
2786
|
+
description: 'View mode',
|
|
2787
|
+
enum: ['DEFAULT', 'ZEN']
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
} as const;
|
|
2791
|
+
|
|
2792
|
+
export const $FileImportDto = {
|
|
2793
|
+
type: 'object',
|
|
2794
|
+
properties: {
|
|
2795
|
+
file: {
|
|
2796
|
+
type: 'string',
|
|
2797
|
+
format: 'binary',
|
|
2798
|
+
description: 'Bill file to import (CSV, PDF, OFX, etc.)',
|
|
2799
|
+
example: 'alipay.csv'
|
|
2800
|
+
}
|
|
2801
|
+
},
|
|
2802
|
+
required: ['file']
|
|
2803
|
+
} as const;
|
|
2804
|
+
|
|
2805
|
+
export const $ImportErrorDto = {
|
|
2806
|
+
type: 'object',
|
|
2807
|
+
properties: {
|
|
2808
|
+
index: {
|
|
2809
|
+
type: 'number',
|
|
2810
|
+
description: 'Index of failed transaction in the file',
|
|
2811
|
+
example: 5
|
|
2812
|
+
},
|
|
2813
|
+
error: {
|
|
2814
|
+
type: 'string',
|
|
2815
|
+
description: 'Error message',
|
|
2816
|
+
example: 'Transaction does not balance: -100 USD != 0'
|
|
2817
|
+
}
|
|
2818
|
+
},
|
|
2819
|
+
required: ['index', 'error']
|
|
2820
|
+
} as const;
|
|
2821
|
+
|
|
2822
|
+
export const $ReviewItemPreviewDto = {
|
|
2823
|
+
type: 'object',
|
|
2824
|
+
properties: {
|
|
2825
|
+
index: {
|
|
2826
|
+
type: 'number',
|
|
2827
|
+
description: 'Index in the import batch (for tracking)',
|
|
2828
|
+
example: 0
|
|
2829
|
+
},
|
|
2830
|
+
date: {
|
|
2831
|
+
type: 'string',
|
|
2832
|
+
description: 'Transaction date (ISO format)',
|
|
2833
|
+
example: '2026-03-05'
|
|
2834
|
+
},
|
|
2835
|
+
amount: {
|
|
2836
|
+
type: 'number',
|
|
2837
|
+
description: 'Transaction amount (absolute value)',
|
|
2838
|
+
example: 99
|
|
2839
|
+
},
|
|
2840
|
+
currency: {
|
|
2841
|
+
type: 'string',
|
|
2842
|
+
description: 'Currency code',
|
|
2843
|
+
example: 'CNY'
|
|
2844
|
+
},
|
|
2845
|
+
narration: {
|
|
2846
|
+
type: 'string',
|
|
2847
|
+
description: 'Transaction narration/description',
|
|
2848
|
+
example: 'Restaurant expense'
|
|
2849
|
+
},
|
|
2850
|
+
payee: {
|
|
2851
|
+
type: 'string',
|
|
2852
|
+
description: 'Payee name',
|
|
2853
|
+
example: 'Restaurant ABC'
|
|
2854
|
+
},
|
|
2855
|
+
category: {
|
|
2856
|
+
type: 'string',
|
|
2857
|
+
description: 'Inferred category from rule matching',
|
|
2858
|
+
example: 'food'
|
|
2859
|
+
},
|
|
2860
|
+
confidence: {
|
|
2861
|
+
type: 'number',
|
|
2862
|
+
description: 'Confidence score for the match (0-1)',
|
|
2863
|
+
example: 0.85
|
|
2864
|
+
},
|
|
2865
|
+
branchType: {
|
|
2866
|
+
type: 'string',
|
|
2867
|
+
description: 'Type of branch requiring review',
|
|
2868
|
+
enum: [
|
|
2869
|
+
'DUPLICATE',
|
|
2870
|
+
'PAYEE_MATCH',
|
|
2871
|
+
'RULE_MATCH',
|
|
2872
|
+
'ACCOUNT_VALIDATION',
|
|
2873
|
+
'PIPELINE_ERROR'
|
|
2874
|
+
],
|
|
2875
|
+
example: 'RULE_MATCH'
|
|
2876
|
+
},
|
|
2877
|
+
reasons: {
|
|
2878
|
+
description: 'Human-readable reasons for requiring review',
|
|
2879
|
+
example: ['Moderate confidence rule match', 'Multiple rules matched'],
|
|
2880
|
+
type: 'array',
|
|
2881
|
+
items: {
|
|
2882
|
+
type: 'string'
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
},
|
|
2886
|
+
required: ['index', 'date', 'narration']
|
|
2887
|
+
} as const;
|
|
2888
|
+
|
|
2889
|
+
export const $ImportResultDto = {
|
|
2890
|
+
type: 'object',
|
|
2891
|
+
properties: {
|
|
2892
|
+
imported: {
|
|
2893
|
+
type: 'number',
|
|
2894
|
+
description: 'Number of successfully imported transactions',
|
|
2895
|
+
example: 45
|
|
2896
|
+
},
|
|
2897
|
+
failed: {
|
|
2898
|
+
type: 'number',
|
|
2899
|
+
description: 'Number of failed transactions',
|
|
2900
|
+
example: 2
|
|
2901
|
+
},
|
|
2902
|
+
skipped: {
|
|
2903
|
+
type: 'number',
|
|
2904
|
+
description:
|
|
2905
|
+
'Number of skipped transactions (high confidence duplicates, auto-skipped)',
|
|
2906
|
+
example: 3
|
|
2907
|
+
},
|
|
2908
|
+
pendingReview: {
|
|
2909
|
+
type: 'number',
|
|
2910
|
+
description:
|
|
2911
|
+
'Number of transactions pending review (medium confidence duplicates)',
|
|
2912
|
+
example: 2
|
|
2913
|
+
},
|
|
2914
|
+
errors: {
|
|
2915
|
+
description: 'Array of error details for failed transactions',
|
|
2916
|
+
type: 'array',
|
|
2917
|
+
items: {
|
|
2918
|
+
$ref: '#/components/schemas/ImportErrorDto'
|
|
2919
|
+
}
|
|
2920
|
+
},
|
|
2921
|
+
reviewItems: {
|
|
2922
|
+
description:
|
|
2923
|
+
'Array of transactions pending review with preview data. Contains essential information for displaying in the import preview UI.',
|
|
2924
|
+
type: 'array',
|
|
2925
|
+
items: {
|
|
2926
|
+
$ref: '#/components/schemas/ReviewItemPreviewDto'
|
|
2927
|
+
}
|
|
2928
|
+
},
|
|
2929
|
+
transactions: {
|
|
2930
|
+
type: 'object',
|
|
2931
|
+
description: 'Array of imported transactions (optional, for debugging)'
|
|
2932
|
+
}
|
|
2933
|
+
},
|
|
2934
|
+
required: ['imported', 'failed', 'skipped', 'pendingReview', 'errors']
|
|
2935
|
+
} as const;
|
|
2936
|
+
|
|
2937
|
+
export const $IdentifyResultDto = {
|
|
2938
|
+
type: 'object',
|
|
2939
|
+
properties: {
|
|
2940
|
+
identified: {
|
|
2941
|
+
type: 'boolean',
|
|
2942
|
+
description: 'Whether the file was successfully identified',
|
|
2943
|
+
example: true
|
|
2944
|
+
},
|
|
2945
|
+
importerName: {
|
|
2946
|
+
type: 'string',
|
|
2947
|
+
description: 'Name of the importer that can handle this file',
|
|
2948
|
+
example: 'AlipayImporter'
|
|
2949
|
+
},
|
|
2950
|
+
importerId: {
|
|
2951
|
+
type: 'string',
|
|
2952
|
+
description: 'Unique identifier of the importer',
|
|
2953
|
+
example: 'alipay'
|
|
2954
|
+
},
|
|
2955
|
+
account: {
|
|
2956
|
+
type: 'string',
|
|
2957
|
+
description: 'Default account used by this importer',
|
|
2958
|
+
example: 'Assets:Alipay:Balance'
|
|
2959
|
+
},
|
|
2960
|
+
message: {
|
|
2961
|
+
type: 'string',
|
|
2962
|
+
description: 'Message when file cannot be identified',
|
|
2963
|
+
example: 'No matching importer found'
|
|
2964
|
+
}
|
|
2965
|
+
},
|
|
2966
|
+
required: ['identified']
|
|
2967
|
+
} as const;
|
|
2968
|
+
|
|
2969
|
+
export const $MapperDefaultsDto = {
|
|
2970
|
+
type: 'object',
|
|
2971
|
+
properties: {
|
|
2972
|
+
sourceAccount: {
|
|
2973
|
+
type: 'string',
|
|
2974
|
+
description: 'Source account for transactions (Beancount format)',
|
|
2975
|
+
example: 'Assets:Alipay:Balance'
|
|
2976
|
+
},
|
|
2977
|
+
currency: {
|
|
2978
|
+
type: 'string',
|
|
2979
|
+
description: 'Default currency (ISO 4217 code)',
|
|
2980
|
+
example: 'CNY'
|
|
2981
|
+
},
|
|
2982
|
+
expenseAccount: {
|
|
2983
|
+
type: 'string',
|
|
2984
|
+
description: 'Default expense account',
|
|
2985
|
+
example: 'Expenses:Unknown'
|
|
2986
|
+
},
|
|
2987
|
+
incomeAccount: {
|
|
2988
|
+
type: 'string',
|
|
2989
|
+
description: 'Default income account',
|
|
2990
|
+
example: 'Income:Unknown'
|
|
2991
|
+
},
|
|
2992
|
+
accountMapping: {
|
|
2993
|
+
type: 'object',
|
|
2994
|
+
description:
|
|
2995
|
+
'Filename prefix to account mapping (for HK importers). Maps filename prefix to Beancount account path.',
|
|
2996
|
+
example: {
|
|
2997
|
+
One: 'Assets:HSBC:One',
|
|
2998
|
+
PULSE: 'Liabilities:CreditCards:HSBC:Pulse'
|
|
2999
|
+
}
|
|
3000
|
+
},
|
|
3001
|
+
useCnh: {
|
|
3002
|
+
type: 'boolean',
|
|
3003
|
+
description:
|
|
3004
|
+
'Convert CNY to CNH (offshore RMB) (for HK importers). Default: false.',
|
|
3005
|
+
example: false
|
|
3006
|
+
},
|
|
3007
|
+
methodAccountMapping: {
|
|
3008
|
+
type: 'object',
|
|
3009
|
+
description:
|
|
3010
|
+
'Payment method to source account mapping. Maps payment method keywords to Beancount account paths. Used by Alipay/WeChat importers to determine sourceAccount based on payment method (e.g., HuaBei, CreditCard).',
|
|
3011
|
+
example: {
|
|
3012
|
+
HuaBei: 'Liabilities:Alipay:Huabei',
|
|
3013
|
+
CreditCard: 'Liabilities:CreditCard'
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
},
|
|
3017
|
+
required: ['sourceAccount', 'currency']
|
|
3018
|
+
} as const;
|
|
3019
|
+
|
|
3020
|
+
export const $ImporterConfigDataDto = {
|
|
3021
|
+
type: 'object',
|
|
3022
|
+
properties: {
|
|
3023
|
+
defaults: {
|
|
3024
|
+
description: 'Mapper defaults configuration',
|
|
3025
|
+
allOf: [
|
|
3026
|
+
{
|
|
3027
|
+
$ref: '#/components/schemas/MapperDefaultsDto'
|
|
3028
|
+
}
|
|
3029
|
+
]
|
|
3030
|
+
}
|
|
3031
|
+
},
|
|
3032
|
+
required: ['defaults']
|
|
3033
|
+
} as const;
|
|
3034
|
+
|
|
3035
|
+
export const $VersionedConfigDto = {
|
|
3036
|
+
type: 'object',
|
|
3037
|
+
properties: {
|
|
3038
|
+
version: {
|
|
3039
|
+
type: 'string',
|
|
3040
|
+
description: 'Configuration version (semver)',
|
|
3041
|
+
example: '1.0.0'
|
|
3042
|
+
},
|
|
3043
|
+
schema: {
|
|
3044
|
+
type: 'string',
|
|
3045
|
+
description: 'Configuration schema identifier',
|
|
3046
|
+
example: 'importer-config-v1'
|
|
3047
|
+
},
|
|
3048
|
+
data: {
|
|
3049
|
+
description: 'Configuration data',
|
|
3050
|
+
allOf: [
|
|
3051
|
+
{
|
|
3052
|
+
$ref: '#/components/schemas/ImporterConfigDataDto'
|
|
3053
|
+
}
|
|
3054
|
+
]
|
|
3055
|
+
}
|
|
3056
|
+
},
|
|
3057
|
+
required: ['version', 'schema', 'data']
|
|
3058
|
+
} as const;
|
|
3059
|
+
|
|
3060
|
+
export const $ImporterConfigDto = {
|
|
3061
|
+
type: 'object',
|
|
3062
|
+
properties: {
|
|
3063
|
+
id: {
|
|
3064
|
+
type: 'string',
|
|
3065
|
+
description: 'Configuration ID',
|
|
3066
|
+
example: 'clx1234567890'
|
|
3067
|
+
},
|
|
3068
|
+
userId: {
|
|
3069
|
+
type: 'string',
|
|
3070
|
+
description: 'User ID',
|
|
3071
|
+
example: 'user-abc-123'
|
|
3072
|
+
},
|
|
3073
|
+
importerId: {
|
|
3074
|
+
type: 'string',
|
|
3075
|
+
description: 'Importer identifier',
|
|
3076
|
+
example: 'alipay',
|
|
3077
|
+
enum: [
|
|
3078
|
+
'alipay',
|
|
3079
|
+
'alipay-web',
|
|
3080
|
+
'alipay-yuebao',
|
|
3081
|
+
'wechat',
|
|
3082
|
+
'wechat-xlsx',
|
|
3083
|
+
'boc',
|
|
3084
|
+
'boc-credit',
|
|
3085
|
+
'ccb',
|
|
3086
|
+
'cmb',
|
|
3087
|
+
'cmbc',
|
|
3088
|
+
'cmbc-credit',
|
|
3089
|
+
'icbc',
|
|
3090
|
+
'icbc-credit',
|
|
3091
|
+
'hsbc-hk'
|
|
3092
|
+
]
|
|
3093
|
+
},
|
|
3094
|
+
version: {
|
|
3095
|
+
type: 'string',
|
|
3096
|
+
description: 'Configuration version (semver)',
|
|
3097
|
+
example: '1.0.0'
|
|
3098
|
+
},
|
|
3099
|
+
schema: {
|
|
3100
|
+
type: 'string',
|
|
3101
|
+
description: 'Configuration schema identifier',
|
|
3102
|
+
example: 'importer-config-v1'
|
|
3103
|
+
},
|
|
3104
|
+
config: {
|
|
3105
|
+
description: 'Configuration data (validated against Zod schema)',
|
|
3106
|
+
allOf: [
|
|
3107
|
+
{
|
|
3108
|
+
$ref: '#/components/schemas/VersionedConfigDto'
|
|
3109
|
+
}
|
|
3110
|
+
]
|
|
3111
|
+
},
|
|
3112
|
+
createdAt: {
|
|
3113
|
+
format: 'date-time',
|
|
3114
|
+
type: 'string',
|
|
3115
|
+
description: 'Creation timestamp',
|
|
3116
|
+
example: '2025-01-27T10:00:00Z'
|
|
3117
|
+
},
|
|
3118
|
+
updatedAt: {
|
|
3119
|
+
format: 'date-time',
|
|
3120
|
+
type: 'string',
|
|
3121
|
+
description: 'Last update timestamp',
|
|
3122
|
+
example: '2025-01-27T10:00:00Z'
|
|
3123
|
+
}
|
|
3124
|
+
},
|
|
3125
|
+
required: [
|
|
3126
|
+
'id',
|
|
3127
|
+
'userId',
|
|
3128
|
+
'importerId',
|
|
3129
|
+
'version',
|
|
3130
|
+
'schema',
|
|
3131
|
+
'config',
|
|
3132
|
+
'createdAt',
|
|
3133
|
+
'updatedAt'
|
|
3134
|
+
]
|
|
3135
|
+
} as const;
|
|
3136
|
+
|
|
3137
|
+
export const $ProviderSyncConfigDto = {
|
|
3138
|
+
type: 'object',
|
|
3139
|
+
properties: {
|
|
3140
|
+
sourceAccount: {
|
|
3141
|
+
type: 'string',
|
|
3142
|
+
description: 'Source account for the first posting',
|
|
3143
|
+
example: 'Assets:Bank:Chase'
|
|
3144
|
+
},
|
|
3145
|
+
defaultCurrency: {
|
|
3146
|
+
type: 'string',
|
|
3147
|
+
description: 'Default currency for transactions',
|
|
3148
|
+
example: 'USD'
|
|
3149
|
+
},
|
|
3150
|
+
defaultExpenseAccount: {
|
|
3151
|
+
type: 'string',
|
|
3152
|
+
description: 'Default expense account for the second posting',
|
|
3153
|
+
example: 'Expenses:Unknown'
|
|
3154
|
+
},
|
|
3155
|
+
defaultIncomeAccount: {
|
|
3156
|
+
type: 'string',
|
|
3157
|
+
description: 'Default income account for the second posting',
|
|
3158
|
+
example: 'Income:Unknown'
|
|
3159
|
+
},
|
|
3160
|
+
filterPending: {
|
|
3161
|
+
type: 'boolean',
|
|
3162
|
+
description: 'Filter pending transactions',
|
|
3163
|
+
default: true
|
|
3164
|
+
}
|
|
3165
|
+
},
|
|
3166
|
+
required: [
|
|
3167
|
+
'sourceAccount',
|
|
3168
|
+
'defaultCurrency',
|
|
3169
|
+
'defaultExpenseAccount',
|
|
3170
|
+
'defaultIncomeAccount'
|
|
3171
|
+
]
|
|
3172
|
+
} as const;
|
|
3173
|
+
|
|
3174
|
+
export const $ProviderSyncDto = {
|
|
3175
|
+
type: 'object',
|
|
3176
|
+
properties: {
|
|
3177
|
+
provider: {
|
|
3178
|
+
type: 'string',
|
|
3179
|
+
description:
|
|
3180
|
+
'Provider name (already in URL path, optional here for reference)',
|
|
3181
|
+
example: 'plaid'
|
|
3182
|
+
},
|
|
3183
|
+
syncId: {
|
|
3184
|
+
type: 'string',
|
|
3185
|
+
description: 'Unique sync identifier for idempotency',
|
|
3186
|
+
example: 'sync-12345'
|
|
3187
|
+
},
|
|
3188
|
+
config: {
|
|
3189
|
+
description: 'Provider sync configuration',
|
|
3190
|
+
allOf: [
|
|
3191
|
+
{
|
|
3192
|
+
$ref: '#/components/schemas/ProviderSyncConfigDto'
|
|
3193
|
+
}
|
|
3194
|
+
]
|
|
3195
|
+
},
|
|
3196
|
+
transactions: {
|
|
3197
|
+
type: 'array',
|
|
3198
|
+
description: 'Raw transactions from provider',
|
|
3199
|
+
example: [
|
|
3200
|
+
{
|
|
3201
|
+
transaction_id: 'txn-001',
|
|
3202
|
+
amount: 50,
|
|
3203
|
+
iso_currency_code: 'USD',
|
|
3204
|
+
date: '2024-01-15',
|
|
3205
|
+
merchant_name: 'Starbucks',
|
|
3206
|
+
name: 'STARBUCKS STORE 12345',
|
|
3207
|
+
pending: false,
|
|
3208
|
+
account_id: 'acc-001'
|
|
3209
|
+
}
|
|
3210
|
+
]
|
|
3211
|
+
}
|
|
3212
|
+
},
|
|
3213
|
+
required: ['config', 'transactions']
|
|
3214
|
+
} as const;
|
|
3215
|
+
|
|
3216
|
+
export const $ProviderSyncResponseDto = {
|
|
3217
|
+
type: 'object',
|
|
3218
|
+
properties: {
|
|
3219
|
+
imported: {
|
|
3220
|
+
type: 'number',
|
|
3221
|
+
description: 'Number of transactions successfully imported',
|
|
3222
|
+
example: 10
|
|
3223
|
+
},
|
|
3224
|
+
skipped: {
|
|
3225
|
+
type: 'number',
|
|
3226
|
+
description: 'Number of transactions skipped (duplicates)',
|
|
3227
|
+
example: 2
|
|
3228
|
+
},
|
|
3229
|
+
pendingReview: {
|
|
3230
|
+
type: 'number',
|
|
3231
|
+
description: 'Number of transactions pending review',
|
|
3232
|
+
example: 3
|
|
3233
|
+
},
|
|
3234
|
+
failed: {
|
|
3235
|
+
type: 'number',
|
|
3236
|
+
description: 'Number of transactions that failed to import',
|
|
3237
|
+
example: 0
|
|
3238
|
+
},
|
|
3239
|
+
importedTransactionIds: {
|
|
3240
|
+
description: 'IDs of successfully imported transactions',
|
|
3241
|
+
example: ['txn-001', 'txn-002'],
|
|
3242
|
+
type: 'array',
|
|
3243
|
+
items: {
|
|
3244
|
+
type: 'string'
|
|
3245
|
+
}
|
|
3246
|
+
},
|
|
3247
|
+
reviewItemIds: {
|
|
3248
|
+
description: 'IDs of review items created for branched transactions',
|
|
3249
|
+
example: ['review-001', 'review-002'],
|
|
3250
|
+
type: 'array',
|
|
3251
|
+
items: {
|
|
3252
|
+
type: 'string'
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
},
|
|
3256
|
+
required: ['imported', 'skipped', 'pendingReview', 'failed']
|
|
3257
|
+
} as const;
|
|
3258
|
+
|
|
3259
|
+
export const $SupportedProvidersResponseDto = {
|
|
3260
|
+
type: 'object',
|
|
3261
|
+
properties: {
|
|
3262
|
+
providers: {
|
|
3263
|
+
description: 'List of supported provider names',
|
|
3264
|
+
example: [
|
|
3265
|
+
'plaid',
|
|
3266
|
+
'teller',
|
|
3267
|
+
'truelayer',
|
|
3268
|
+
'gocardless',
|
|
3269
|
+
'simplefin',
|
|
3270
|
+
'yodlee',
|
|
3271
|
+
'beancount-direct'
|
|
3272
|
+
],
|
|
3273
|
+
type: 'array',
|
|
3274
|
+
items: {
|
|
3275
|
+
type: 'string'
|
|
3276
|
+
}
|
|
3277
|
+
}
|
|
3278
|
+
},
|
|
3279
|
+
required: ['providers']
|
|
3280
|
+
} as const;
|
|
3281
|
+
|
|
3282
|
+
export const $ProcessNlpDto = {
|
|
3283
|
+
type: 'object',
|
|
3284
|
+
properties: {
|
|
3285
|
+
message: {
|
|
3286
|
+
type: 'string',
|
|
3287
|
+
description: 'Natural language text describing a transaction (Chinese)',
|
|
3288
|
+
example: 'yesterday Starbucks spent 35 yuan',
|
|
3289
|
+
maxLength: 500
|
|
3290
|
+
},
|
|
3291
|
+
sessionId: {
|
|
3292
|
+
type: 'string',
|
|
3293
|
+
description:
|
|
3294
|
+
'Session ID for multi-turn conversation (auto-generated if not provided)',
|
|
3295
|
+
example: 'session_abc123'
|
|
3296
|
+
}
|
|
3297
|
+
},
|
|
3298
|
+
required: ['message']
|
|
3299
|
+
} as const;
|
|
3300
|
+
|
|
3301
|
+
export const $NlpTransactionInfoDto = {
|
|
3302
|
+
type: 'object',
|
|
3303
|
+
properties: {
|
|
3304
|
+
id: {
|
|
3305
|
+
type: 'string',
|
|
3306
|
+
description: 'Transaction ID'
|
|
3307
|
+
},
|
|
3308
|
+
date: {
|
|
3309
|
+
type: 'string',
|
|
3310
|
+
description: 'Transaction date (ISO format)'
|
|
3311
|
+
},
|
|
3312
|
+
amount: {
|
|
3313
|
+
type: 'number',
|
|
3314
|
+
description: 'Transaction amount'
|
|
3315
|
+
},
|
|
3316
|
+
currency: {
|
|
3317
|
+
type: 'string',
|
|
3318
|
+
description: 'Currency code'
|
|
3319
|
+
},
|
|
3320
|
+
payee: {
|
|
3321
|
+
type: 'string',
|
|
3322
|
+
description: 'Payee name'
|
|
3323
|
+
},
|
|
3324
|
+
narration: {
|
|
3325
|
+
type: 'string',
|
|
3326
|
+
description: 'Transaction narration'
|
|
3327
|
+
},
|
|
3328
|
+
warning: {
|
|
3329
|
+
type: 'string',
|
|
3330
|
+
description:
|
|
3331
|
+
'Warning message for special transaction scenarios (e.g., cross-currency settlement)',
|
|
3332
|
+
example: '此交易使用USD账户结算。如需记录CNY支出,请创建货币转换交易。'
|
|
3333
|
+
}
|
|
3334
|
+
},
|
|
3335
|
+
required: ['id', 'date', 'amount', 'currency']
|
|
3336
|
+
} as const;
|
|
3337
|
+
|
|
3338
|
+
export const $NlpParsedDataDto = {
|
|
3339
|
+
type: 'object',
|
|
3340
|
+
properties: {
|
|
3341
|
+
amount: {
|
|
3342
|
+
type: 'number',
|
|
3343
|
+
description: 'Extracted amount'
|
|
3344
|
+
},
|
|
3345
|
+
currency: {
|
|
3346
|
+
type: 'string',
|
|
3347
|
+
description: 'Currency code',
|
|
3348
|
+
default: 'CNY'
|
|
3349
|
+
},
|
|
3350
|
+
date: {
|
|
3351
|
+
type: 'string',
|
|
3352
|
+
description: 'Transaction date (ISO format)'
|
|
3353
|
+
},
|
|
3354
|
+
payee: {
|
|
3355
|
+
type: 'string',
|
|
3356
|
+
description: 'Payee name'
|
|
3357
|
+
},
|
|
3358
|
+
narration: {
|
|
3359
|
+
type: 'string',
|
|
3360
|
+
description: 'Transaction narration'
|
|
3361
|
+
},
|
|
3362
|
+
category: {
|
|
3363
|
+
type: 'string',
|
|
3364
|
+
description: 'Category'
|
|
3365
|
+
},
|
|
3366
|
+
incomeType: {
|
|
3367
|
+
type: 'string',
|
|
3368
|
+
description: 'Income type (e.g., Salary, Bonus, Dividend, Interest)',
|
|
3369
|
+
example: 'Salary'
|
|
3370
|
+
},
|
|
3371
|
+
incomeSource: {
|
|
3372
|
+
type: 'string',
|
|
3373
|
+
description: 'Income source (e.g., company name)',
|
|
3374
|
+
example: 'Anthropic Inc.'
|
|
3375
|
+
},
|
|
3376
|
+
symbol: {
|
|
3377
|
+
type: 'string',
|
|
3378
|
+
description: 'Security symbol code (e.g., 600519, AAPL)',
|
|
3379
|
+
example: '600519'
|
|
3380
|
+
},
|
|
3381
|
+
quantity: {
|
|
3382
|
+
type: 'number',
|
|
3383
|
+
description: 'Quantity of shares/units',
|
|
3384
|
+
example: 100
|
|
3385
|
+
},
|
|
3386
|
+
price: {
|
|
3387
|
+
type: 'number',
|
|
3388
|
+
description: 'Unit price per share/unit',
|
|
3389
|
+
example: 1900
|
|
3390
|
+
},
|
|
3391
|
+
investmentAction: {
|
|
3392
|
+
type: 'string',
|
|
3393
|
+
description: 'Investment action',
|
|
3394
|
+
enum: ['buy', 'sell'],
|
|
3395
|
+
example: 'buy'
|
|
3396
|
+
},
|
|
3397
|
+
paymentSource: {
|
|
3398
|
+
type: 'string',
|
|
3399
|
+
description: 'Payment source: asset (default) or liability (credit card)',
|
|
3400
|
+
enum: ['asset', 'liability'],
|
|
3401
|
+
example: 'asset'
|
|
3402
|
+
},
|
|
3403
|
+
liabilityHint: {
|
|
3404
|
+
type: 'string',
|
|
3405
|
+
description: 'Liability account hint (CreditCard/Huabei/Baitiao)',
|
|
3406
|
+
example: 'CreditCard'
|
|
3407
|
+
},
|
|
3408
|
+
warning: {
|
|
3409
|
+
type: 'string',
|
|
3410
|
+
description:
|
|
3411
|
+
'Warning message for special scenarios (e.g., cross-currency settlement)',
|
|
3412
|
+
example: '此交易使用USD账户结算。如需记录CNY支出,请创建货币转换交易。'
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
} as const;
|
|
3416
|
+
|
|
3417
|
+
export const $NlpSourceTransactionDto = {
|
|
3418
|
+
type: 'object',
|
|
3419
|
+
properties: {
|
|
3420
|
+
date: {
|
|
3421
|
+
type: 'string',
|
|
3422
|
+
description: 'Transaction date (ISO format)'
|
|
3423
|
+
},
|
|
3424
|
+
amount: {
|
|
3425
|
+
type: 'string',
|
|
3426
|
+
description: 'Amount as string'
|
|
3427
|
+
},
|
|
3428
|
+
currency: {
|
|
3429
|
+
type: 'string',
|
|
3430
|
+
description: 'Currency code'
|
|
3431
|
+
},
|
|
3432
|
+
payee: {
|
|
3433
|
+
type: 'string',
|
|
3434
|
+
description: 'Payee name'
|
|
3435
|
+
},
|
|
3436
|
+
narration: {
|
|
3437
|
+
type: 'string',
|
|
3438
|
+
description: 'Transaction narration'
|
|
3439
|
+
}
|
|
3440
|
+
},
|
|
3441
|
+
required: ['date', 'amount', 'currency', 'narration']
|
|
3442
|
+
} as const;
|
|
3443
|
+
|
|
3444
|
+
export const $NlpTargetTransactionDto = {
|
|
3445
|
+
type: 'object',
|
|
3446
|
+
properties: {
|
|
3447
|
+
id: {
|
|
3448
|
+
type: 'string',
|
|
3449
|
+
description: 'Existing transaction ID'
|
|
3450
|
+
},
|
|
3451
|
+
date: {
|
|
3452
|
+
type: 'string',
|
|
3453
|
+
description: 'Transaction date (ISO format)'
|
|
3454
|
+
},
|
|
3455
|
+
amount: {
|
|
3456
|
+
type: 'string',
|
|
3457
|
+
description: 'Amount as string'
|
|
3458
|
+
},
|
|
3459
|
+
currency: {
|
|
3460
|
+
type: 'string',
|
|
3461
|
+
description: 'Currency code'
|
|
3462
|
+
},
|
|
3463
|
+
payee: {
|
|
3464
|
+
type: 'string',
|
|
3465
|
+
description: 'Payee name'
|
|
3466
|
+
},
|
|
3467
|
+
narration: {
|
|
3468
|
+
type: 'string',
|
|
3469
|
+
description: 'Transaction narration'
|
|
3470
|
+
}
|
|
3471
|
+
},
|
|
3472
|
+
required: ['id', 'date', 'amount', 'currency', 'narration']
|
|
3473
|
+
} as const;
|
|
3474
|
+
|
|
3475
|
+
export const $NlpSimilarityDto = {
|
|
3476
|
+
type: 'object',
|
|
3477
|
+
properties: {
|
|
3478
|
+
dateMatch: {
|
|
3479
|
+
type: 'boolean',
|
|
3480
|
+
description: 'Whether dates match'
|
|
3481
|
+
},
|
|
3482
|
+
dateDiff: {
|
|
3483
|
+
type: 'number',
|
|
3484
|
+
description: 'Date difference in days'
|
|
3485
|
+
},
|
|
3486
|
+
amountMatch: {
|
|
3487
|
+
type: 'boolean',
|
|
3488
|
+
description: 'Whether amounts match'
|
|
3489
|
+
},
|
|
3490
|
+
amountDiff: {
|
|
3491
|
+
type: 'string',
|
|
3492
|
+
description: 'Amount difference as decimal string'
|
|
3493
|
+
},
|
|
3494
|
+
payeeMatch: {
|
|
3495
|
+
type: 'boolean',
|
|
3496
|
+
description: 'Whether payees match'
|
|
3497
|
+
},
|
|
3498
|
+
payeeSimilarity: {
|
|
3499
|
+
type: 'number',
|
|
3500
|
+
description: 'Payee similarity score (0-1)'
|
|
3501
|
+
},
|
|
3502
|
+
accountOverlap: {
|
|
3503
|
+
type: 'number',
|
|
3504
|
+
description: 'Account overlap score (0-1)'
|
|
3505
|
+
}
|
|
3506
|
+
},
|
|
3507
|
+
required: [
|
|
3508
|
+
'dateMatch',
|
|
3509
|
+
'dateDiff',
|
|
3510
|
+
'amountMatch',
|
|
3511
|
+
'amountDiff',
|
|
3512
|
+
'payeeMatch',
|
|
3513
|
+
'payeeSimilarity',
|
|
3514
|
+
'accountOverlap'
|
|
3515
|
+
]
|
|
3516
|
+
} as const;
|
|
3517
|
+
|
|
3518
|
+
export const $NlpDuplicateConfirmationDataDto = {
|
|
3519
|
+
type: 'object',
|
|
3520
|
+
properties: {
|
|
3521
|
+
confidence: {
|
|
3522
|
+
type: 'number',
|
|
3523
|
+
description: 'Duplicate detection confidence score (0.5-0.89)',
|
|
3524
|
+
example: 0.85
|
|
3525
|
+
},
|
|
3526
|
+
sourceTransaction: {
|
|
3527
|
+
description:
|
|
3528
|
+
'Source transaction summary (the new transaction being entered)',
|
|
3529
|
+
allOf: [
|
|
3530
|
+
{
|
|
3531
|
+
$ref: '#/components/schemas/NlpSourceTransactionDto'
|
|
3532
|
+
}
|
|
3533
|
+
]
|
|
3534
|
+
},
|
|
3535
|
+
targetTransaction: {
|
|
3536
|
+
description: 'Target transaction summary (existing potential duplicate)',
|
|
3537
|
+
allOf: [
|
|
3538
|
+
{
|
|
3539
|
+
$ref: '#/components/schemas/NlpTargetTransactionDto'
|
|
3540
|
+
}
|
|
3541
|
+
]
|
|
3542
|
+
},
|
|
3543
|
+
similarity: {
|
|
3544
|
+
description: 'Detailed similarity information',
|
|
3545
|
+
allOf: [
|
|
3546
|
+
{
|
|
3547
|
+
$ref: '#/components/schemas/NlpSimilarityDto'
|
|
3548
|
+
}
|
|
3549
|
+
]
|
|
3550
|
+
},
|
|
3551
|
+
reasons: {
|
|
3552
|
+
description: 'Human-readable reasons for duplicate detection',
|
|
3553
|
+
example: ['日期匹配', '金额匹配', '商户相似'],
|
|
3554
|
+
type: 'array',
|
|
3555
|
+
items: {
|
|
3556
|
+
type: 'string'
|
|
3557
|
+
}
|
|
3558
|
+
}
|
|
3559
|
+
},
|
|
3560
|
+
required: [
|
|
3561
|
+
'confidence',
|
|
3562
|
+
'sourceTransaction',
|
|
3563
|
+
'targetTransaction',
|
|
3564
|
+
'similarity',
|
|
3565
|
+
'reasons'
|
|
3566
|
+
]
|
|
3567
|
+
} as const;
|
|
3568
|
+
|
|
3569
|
+
export const $NlpRuleConfirmationDataDto = {
|
|
3570
|
+
type: 'object',
|
|
3571
|
+
properties: {
|
|
3572
|
+
confidence: {
|
|
3573
|
+
type: 'number',
|
|
3574
|
+
description: 'Rule match confidence score (0.5-0.74)',
|
|
3575
|
+
example: 0.65
|
|
3576
|
+
},
|
|
3577
|
+
matchedRule: {
|
|
3578
|
+
type: 'object',
|
|
3579
|
+
description: 'Matched rule information'
|
|
3580
|
+
},
|
|
3581
|
+
suggestedAccounts: {
|
|
3582
|
+
type: 'object',
|
|
3583
|
+
description: 'Suggested accounts from the rule'
|
|
3584
|
+
},
|
|
3585
|
+
alternatives: {
|
|
3586
|
+
type: 'array',
|
|
3587
|
+
description: 'Alternative rules that also match'
|
|
3588
|
+
},
|
|
3589
|
+
reasons: {
|
|
3590
|
+
description: 'Human-readable reasons for the match',
|
|
3591
|
+
example: [
|
|
3592
|
+
'Moderate confidence (65%)',
|
|
3593
|
+
'Some keywords matched (OR logic)'
|
|
3594
|
+
],
|
|
3595
|
+
type: 'array',
|
|
3596
|
+
items: {
|
|
3597
|
+
type: 'string'
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
},
|
|
3601
|
+
required: [
|
|
3602
|
+
'confidence',
|
|
3603
|
+
'matchedRule',
|
|
3604
|
+
'suggestedAccounts',
|
|
3605
|
+
'alternatives',
|
|
3606
|
+
'reasons'
|
|
3607
|
+
]
|
|
3608
|
+
} as const;
|
|
3609
|
+
|
|
3610
|
+
export const $NlpAccountConfirmationDataDto = {
|
|
3611
|
+
type: 'object',
|
|
3612
|
+
properties: {
|
|
3613
|
+
invalidAccount: {
|
|
3614
|
+
type: 'string',
|
|
3615
|
+
description: 'The invalid account name',
|
|
3616
|
+
example: 'Expenses:Food:Coffee'
|
|
3617
|
+
},
|
|
3618
|
+
suggestedAccount: {
|
|
3619
|
+
type: 'string',
|
|
3620
|
+
description: 'Suggested replacement account',
|
|
3621
|
+
example: 'Expenses:Food:Drinks'
|
|
3622
|
+
},
|
|
3623
|
+
similarAccounts: {
|
|
3624
|
+
description: 'Similar accounts for user selection',
|
|
3625
|
+
type: 'array',
|
|
3626
|
+
items: {
|
|
3627
|
+
type: 'string'
|
|
3628
|
+
}
|
|
3629
|
+
},
|
|
3630
|
+
errorMessage: {
|
|
3631
|
+
type: 'string',
|
|
3632
|
+
description: 'Error message explaining the issue',
|
|
3633
|
+
example: 'No similar account found'
|
|
3634
|
+
},
|
|
3635
|
+
transactionContext: {
|
|
3636
|
+
type: 'object',
|
|
3637
|
+
description: 'Transaction context for reference'
|
|
3638
|
+
}
|
|
3639
|
+
},
|
|
3640
|
+
required: [
|
|
3641
|
+
'invalidAccount',
|
|
3642
|
+
'suggestedAccount',
|
|
3643
|
+
'similarAccounts',
|
|
3644
|
+
'errorMessage',
|
|
3645
|
+
'transactionContext'
|
|
3646
|
+
]
|
|
3647
|
+
} as const;
|
|
3648
|
+
|
|
3649
|
+
export const $NlpSuggestedPayeeDto = {
|
|
3650
|
+
type: 'object',
|
|
3651
|
+
properties: {
|
|
3652
|
+
id: {
|
|
3653
|
+
type: 'string',
|
|
3654
|
+
description: 'Payee ID',
|
|
3655
|
+
example: 'payee-123'
|
|
3656
|
+
},
|
|
3657
|
+
name: {
|
|
3658
|
+
type: 'string',
|
|
3659
|
+
description: 'Payee name',
|
|
3660
|
+
example: 'Starbucks'
|
|
3661
|
+
},
|
|
3662
|
+
category: {
|
|
3663
|
+
type: 'string',
|
|
3664
|
+
description: 'Payee category',
|
|
3665
|
+
example: 'food'
|
|
3666
|
+
},
|
|
3667
|
+
source: {
|
|
3668
|
+
type: 'string',
|
|
3669
|
+
description: 'Source of the payee',
|
|
3670
|
+
enum: ['user', 'global']
|
|
3671
|
+
},
|
|
3672
|
+
payeeProfileId: {
|
|
3673
|
+
type: 'string',
|
|
3674
|
+
description: 'PayeeProfile ID (if matched from global)',
|
|
3675
|
+
example: 'profile-456'
|
|
3676
|
+
}
|
|
3677
|
+
},
|
|
3678
|
+
required: ['id', 'name']
|
|
3679
|
+
} as const;
|
|
3680
|
+
|
|
3681
|
+
export const $NlpAlternativePayeeDto = {
|
|
3682
|
+
type: 'object',
|
|
3683
|
+
properties: {
|
|
3684
|
+
id: {
|
|
3685
|
+
type: 'string',
|
|
3686
|
+
description: 'Payee ID',
|
|
3687
|
+
example: 'payee-alt-1'
|
|
3688
|
+
},
|
|
3689
|
+
name: {
|
|
3690
|
+
type: 'string',
|
|
3691
|
+
description: 'Payee name',
|
|
3692
|
+
example: 'Starbucks Coffee'
|
|
3693
|
+
},
|
|
3694
|
+
similarity: {
|
|
3695
|
+
type: 'number',
|
|
3696
|
+
description: 'Similarity score (0-1)',
|
|
3697
|
+
example: 0.75
|
|
3698
|
+
}
|
|
3699
|
+
},
|
|
3700
|
+
required: ['id', 'name', 'similarity']
|
|
3701
|
+
} as const;
|
|
3702
|
+
|
|
3703
|
+
export const $NlpPayeeConfirmationDataDto = {
|
|
3704
|
+
type: 'object',
|
|
3705
|
+
properties: {
|
|
3706
|
+
confidence: {
|
|
3707
|
+
type: 'number',
|
|
3708
|
+
description: 'Confidence score for the payee match (0-1)',
|
|
3709
|
+
example: 0.65
|
|
3710
|
+
},
|
|
3711
|
+
originalPayee: {
|
|
3712
|
+
type: 'string',
|
|
3713
|
+
description: 'Original payee string from user input',
|
|
3714
|
+
example: '星巴'
|
|
3715
|
+
},
|
|
3716
|
+
suggestedPayee: {
|
|
3717
|
+
description: 'Suggested payee to use (null when no similar payees found)',
|
|
3718
|
+
nullable: true,
|
|
3719
|
+
allOf: [
|
|
3720
|
+
{
|
|
3721
|
+
$ref: '#/components/schemas/NlpSuggestedPayeeDto'
|
|
3722
|
+
}
|
|
3723
|
+
]
|
|
3724
|
+
},
|
|
3725
|
+
similarity: {
|
|
3726
|
+
type: 'number',
|
|
3727
|
+
description: 'Similarity score between original and suggested (0-1)',
|
|
3728
|
+
example: 0.85
|
|
3729
|
+
},
|
|
3730
|
+
alternatives: {
|
|
3731
|
+
description: 'Alternative payee options',
|
|
3732
|
+
type: 'array',
|
|
3733
|
+
items: {
|
|
3734
|
+
$ref: '#/components/schemas/NlpAlternativePayeeDto'
|
|
3735
|
+
}
|
|
3736
|
+
},
|
|
3737
|
+
reasons: {
|
|
3738
|
+
description: 'Human-readable reasons for the match',
|
|
3739
|
+
example: ['Moderate similarity (65%)', 'Fuzzy match on name'],
|
|
3740
|
+
type: 'array',
|
|
3741
|
+
items: {
|
|
3742
|
+
type: 'string'
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
},
|
|
3746
|
+
required: [
|
|
3747
|
+
'confidence',
|
|
3748
|
+
'originalPayee',
|
|
3749
|
+
'similarity',
|
|
3750
|
+
'alternatives',
|
|
3751
|
+
'reasons'
|
|
3752
|
+
]
|
|
3753
|
+
} as const;
|
|
3754
|
+
|
|
3755
|
+
export const $RecurringMatchInfoDto = {
|
|
3756
|
+
type: 'object',
|
|
3757
|
+
properties: {
|
|
3758
|
+
expectedId: {
|
|
3759
|
+
type: 'string',
|
|
3760
|
+
description: 'Expected transaction ID'
|
|
3761
|
+
},
|
|
3762
|
+
ruleId: {
|
|
3763
|
+
type: 'string',
|
|
3764
|
+
description: 'Recurring rule ID'
|
|
3765
|
+
},
|
|
3766
|
+
ruleName: {
|
|
3767
|
+
type: 'string',
|
|
3768
|
+
description: 'Rule name for display'
|
|
3769
|
+
},
|
|
3770
|
+
ruleIcon: {
|
|
3771
|
+
type: 'string',
|
|
3772
|
+
description: 'Rule icon'
|
|
3773
|
+
},
|
|
3774
|
+
expectedDate: {
|
|
3775
|
+
type: 'string',
|
|
3776
|
+
description: 'Expected date (YYYY-MM-DD)',
|
|
3777
|
+
example: '2026-01-05'
|
|
3778
|
+
},
|
|
3779
|
+
expectedAmount: {
|
|
3780
|
+
type: 'number',
|
|
3781
|
+
description: 'Expected amount',
|
|
3782
|
+
example: 3000
|
|
3783
|
+
},
|
|
3784
|
+
confidence: {
|
|
3785
|
+
type: 'number',
|
|
3786
|
+
description: 'Match confidence score (0-1)',
|
|
3787
|
+
example: 0.88
|
|
3788
|
+
},
|
|
3789
|
+
isAutoMatched: {
|
|
3790
|
+
type: 'boolean',
|
|
3791
|
+
description: 'Whether auto-matched (confidence >= 0.82)'
|
|
3792
|
+
}
|
|
3793
|
+
},
|
|
3794
|
+
required: [
|
|
3795
|
+
'expectedId',
|
|
3796
|
+
'ruleId',
|
|
3797
|
+
'ruleName',
|
|
3798
|
+
'expectedDate',
|
|
3799
|
+
'expectedAmount',
|
|
3800
|
+
'confidence',
|
|
3801
|
+
'isAutoMatched'
|
|
3802
|
+
]
|
|
3803
|
+
} as const;
|
|
3804
|
+
|
|
3805
|
+
export const $NlpSuggestedAccountDto = {
|
|
3806
|
+
type: 'object',
|
|
3807
|
+
properties: {
|
|
3808
|
+
account: {
|
|
3809
|
+
type: 'string',
|
|
3810
|
+
description: 'Suggested account path',
|
|
3811
|
+
example: 'Assets:Bank:Checking'
|
|
3812
|
+
},
|
|
3813
|
+
confidence: {
|
|
3814
|
+
type: 'number',
|
|
3815
|
+
description: 'Confidence score for this suggestion (0-1)',
|
|
3816
|
+
example: 0.9
|
|
3817
|
+
}
|
|
3818
|
+
},
|
|
3819
|
+
required: ['account']
|
|
3820
|
+
} as const;
|
|
3821
|
+
|
|
3822
|
+
export const $NlpSuggestedAccountsDto = {
|
|
3823
|
+
type: 'object',
|
|
3824
|
+
properties: {
|
|
3825
|
+
source: {
|
|
3826
|
+
description:
|
|
3827
|
+
'Source account suggestion (where money comes from). For expense: asset/liability account. For income: income account.',
|
|
3828
|
+
allOf: [
|
|
3829
|
+
{
|
|
3830
|
+
$ref: '#/components/schemas/NlpSuggestedAccountDto'
|
|
3831
|
+
}
|
|
3832
|
+
]
|
|
3833
|
+
},
|
|
3834
|
+
destination: {
|
|
3835
|
+
description:
|
|
3836
|
+
'Destination account suggestion (where money goes to). For expense: expense account. For income: asset/liability account.',
|
|
3837
|
+
allOf: [
|
|
3838
|
+
{
|
|
3839
|
+
$ref: '#/components/schemas/NlpSuggestedAccountDto'
|
|
3840
|
+
}
|
|
3841
|
+
]
|
|
3842
|
+
}
|
|
3843
|
+
}
|
|
3844
|
+
} as const;
|
|
3845
|
+
|
|
3846
|
+
export const $NlpDefaultAccountsDto = {
|
|
3847
|
+
type: 'object',
|
|
3848
|
+
properties: {
|
|
3849
|
+
asset: {
|
|
3850
|
+
type: 'string',
|
|
3851
|
+
description: 'Default asset account',
|
|
3852
|
+
example: 'Assets:Bank:Checking'
|
|
3853
|
+
},
|
|
3854
|
+
expense: {
|
|
3855
|
+
type: 'string',
|
|
3856
|
+
description: 'Default expense account',
|
|
3857
|
+
example: 'Expenses:Uncategorized'
|
|
3858
|
+
},
|
|
3859
|
+
income: {
|
|
3860
|
+
type: 'string',
|
|
3861
|
+
description: 'Default income account',
|
|
3862
|
+
example: 'Income:Uncategorized'
|
|
3863
|
+
},
|
|
3864
|
+
liability: {
|
|
3865
|
+
type: 'string',
|
|
3866
|
+
description: 'Default liability account',
|
|
3867
|
+
example: 'Liabilities:CreditCard'
|
|
3868
|
+
}
|
|
3869
|
+
},
|
|
3870
|
+
required: ['asset', 'expense', 'income', 'liability']
|
|
3871
|
+
} as const;
|
|
3872
|
+
|
|
3873
|
+
export const $NlpResponseDto = {
|
|
3874
|
+
type: 'object',
|
|
3875
|
+
properties: {
|
|
3876
|
+
status: {
|
|
3877
|
+
type: 'string',
|
|
3878
|
+
description: 'Response status',
|
|
3879
|
+
enum: ['success', 'pending', 'error']
|
|
3880
|
+
},
|
|
3881
|
+
action: {
|
|
3882
|
+
type: 'string',
|
|
3883
|
+
description: 'Action taken or requested',
|
|
3884
|
+
enum: [
|
|
3885
|
+
'created',
|
|
3886
|
+
'ask',
|
|
3887
|
+
'confirm',
|
|
3888
|
+
'confirm_duplicate',
|
|
3889
|
+
'confirm_rule',
|
|
3890
|
+
'confirm_account',
|
|
3891
|
+
'confirm_payee',
|
|
3892
|
+
'cancel'
|
|
3893
|
+
]
|
|
3894
|
+
},
|
|
3895
|
+
intent: {
|
|
3896
|
+
type: 'string',
|
|
3897
|
+
description:
|
|
3898
|
+
'Transaction intent detected by EntityRouter (v6.0: 5 core intents). Frontend uses this to render scenario-specific form fields.',
|
|
3899
|
+
enum: ['expense', 'asset', 'income', 'liability', 'equity'],
|
|
3900
|
+
example: 'expense'
|
|
3901
|
+
},
|
|
3902
|
+
assetSubType: {
|
|
3903
|
+
type: 'string',
|
|
3904
|
+
description:
|
|
3905
|
+
'Asset sub-type (only present when intent is "asset"). Determines which asset-related form to render.',
|
|
3906
|
+
enum: ['transfer', 'banking', 'investment'],
|
|
3907
|
+
example: 'investment'
|
|
3908
|
+
},
|
|
3909
|
+
liabilitySubType: {
|
|
3910
|
+
type: 'string',
|
|
3911
|
+
description:
|
|
3912
|
+
'Liability sub-type (only present when intent is "liability"). borrow: borrowing money (Liabilities → Assets), repay: repaying debt (Assets → Liabilities).',
|
|
3913
|
+
enum: ['borrow', 'repay'],
|
|
3914
|
+
example: 'borrow'
|
|
3915
|
+
},
|
|
3916
|
+
equitySubType: {
|
|
3917
|
+
type: 'string',
|
|
3918
|
+
description:
|
|
3919
|
+
'Equity sub-type (only present when intent is "equity"). opening: account opening balance (Equity → Assets), adjustment: balance correction.',
|
|
3920
|
+
enum: ['opening', 'adjustment'],
|
|
3921
|
+
example: 'opening'
|
|
3922
|
+
},
|
|
3923
|
+
paymentSource: {
|
|
3924
|
+
type: 'string',
|
|
3925
|
+
description:
|
|
3926
|
+
'Payment source for expense transactions (v6.1). Indicates whether payment comes from asset or liability account. Only present when intent is "expense".',
|
|
3927
|
+
enum: ['asset', 'liability'],
|
|
3928
|
+
example: 'liability'
|
|
3929
|
+
},
|
|
3930
|
+
liabilityHint: {
|
|
3931
|
+
type: 'string',
|
|
3932
|
+
description:
|
|
3933
|
+
'Liability account type hint for credit card/BNPL spending (v6.1). Only present when paymentSource is "liability". Values: CreditCard, Huabei, Baitiao',
|
|
3934
|
+
example: 'CreditCard'
|
|
3935
|
+
},
|
|
3936
|
+
message: {
|
|
3937
|
+
type: 'string',
|
|
3938
|
+
description:
|
|
3939
|
+
'Human-readable message (for ask or error actions). Deprecated: Use messageKey for i18n support.',
|
|
3940
|
+
example: 'How much did you spend?',
|
|
3941
|
+
deprecated: true
|
|
3942
|
+
},
|
|
3943
|
+
messageKey: {
|
|
3944
|
+
type: 'string',
|
|
3945
|
+
description:
|
|
3946
|
+
'i18n message key for frontend translation. Use this instead of message for internationalization support.',
|
|
3947
|
+
example: 'nlp.slot.prompt'
|
|
3948
|
+
},
|
|
3949
|
+
messageParams: {
|
|
3950
|
+
type: 'object',
|
|
3951
|
+
description:
|
|
3952
|
+
'Parameters for message interpolation. Used with messageKey for dynamic values in translated messages.',
|
|
3953
|
+
example: {
|
|
3954
|
+
slot: 'amount',
|
|
3955
|
+
name: 'Starbucks',
|
|
3956
|
+
similarity: 85
|
|
3957
|
+
}
|
|
3958
|
+
},
|
|
3959
|
+
sessionId: {
|
|
3960
|
+
type: 'string',
|
|
3961
|
+
description:
|
|
3962
|
+
'Session ID for multi-turn dialogue. Must be included in subsequent requests to continue the conversation.',
|
|
3963
|
+
example: 'session_abc123'
|
|
3964
|
+
},
|
|
3965
|
+
waitingFor: {
|
|
3966
|
+
type: 'string',
|
|
3967
|
+
description: 'Which slot is waiting for user input',
|
|
3968
|
+
example: 'amount'
|
|
3969
|
+
},
|
|
3970
|
+
transaction: {
|
|
3971
|
+
description: 'Created transaction info (for created action)',
|
|
3972
|
+
allOf: [
|
|
3973
|
+
{
|
|
3974
|
+
$ref: '#/components/schemas/NlpTransactionInfoDto'
|
|
3975
|
+
}
|
|
3976
|
+
]
|
|
3977
|
+
},
|
|
3978
|
+
parsedData: {
|
|
3979
|
+
description:
|
|
3980
|
+
'Parsed data for confirmation (when action is "confirm"). Contains extracted fields that user should verify before transaction creation.',
|
|
3981
|
+
allOf: [
|
|
3982
|
+
{
|
|
3983
|
+
$ref: '#/components/schemas/NlpParsedDataDto'
|
|
3984
|
+
}
|
|
3985
|
+
]
|
|
3986
|
+
},
|
|
3987
|
+
duplicateData: {
|
|
3988
|
+
description:
|
|
3989
|
+
'Duplicate detection data (when action is "confirm_duplicate"). Contains information about potential duplicate transaction for user confirmation.',
|
|
3990
|
+
allOf: [
|
|
3991
|
+
{
|
|
3992
|
+
$ref: '#/components/schemas/NlpDuplicateConfirmationDataDto'
|
|
3993
|
+
}
|
|
3994
|
+
]
|
|
3995
|
+
},
|
|
3996
|
+
ruleData: {
|
|
3997
|
+
description:
|
|
3998
|
+
'Rule match data (when action is "confirm_rule"). Contains information about medium-confidence rule match for user confirmation.',
|
|
3999
|
+
allOf: [
|
|
4000
|
+
{
|
|
4001
|
+
$ref: '#/components/schemas/NlpRuleConfirmationDataDto'
|
|
4002
|
+
}
|
|
4003
|
+
]
|
|
4004
|
+
},
|
|
4005
|
+
accountData: {
|
|
4006
|
+
description:
|
|
4007
|
+
'Account validation data (when action is "confirm_account"). Contains information about invalid account for user correction.',
|
|
4008
|
+
allOf: [
|
|
4009
|
+
{
|
|
4010
|
+
$ref: '#/components/schemas/NlpAccountConfirmationDataDto'
|
|
4011
|
+
}
|
|
4012
|
+
]
|
|
4013
|
+
},
|
|
4014
|
+
payeeData: {
|
|
4015
|
+
description:
|
|
4016
|
+
'Payee confirmation data (when action is "confirm_payee"). Contains information about medium/low confidence payee match for user confirmation.',
|
|
4017
|
+
allOf: [
|
|
4018
|
+
{
|
|
4019
|
+
$ref: '#/components/schemas/NlpPayeeConfirmationDataDto'
|
|
4020
|
+
}
|
|
4021
|
+
]
|
|
4022
|
+
},
|
|
4023
|
+
confidence: {
|
|
4024
|
+
type: 'number',
|
|
4025
|
+
description: 'Overall confidence score (0-1)',
|
|
4026
|
+
example: 0.85
|
|
4027
|
+
},
|
|
4028
|
+
confidenceThreshold: {
|
|
4029
|
+
type: 'number',
|
|
4030
|
+
description:
|
|
4031
|
+
'Confidence threshold for automatic creation (default: 0.75). When confidence < threshold, action will be "confirm" requiring user verification.',
|
|
4032
|
+
example: 0.75
|
|
4033
|
+
},
|
|
4034
|
+
recurringMatch: {
|
|
4035
|
+
description:
|
|
4036
|
+
'Recurring transaction match info (when action is "created"). Contains match details when transaction matches a pending expected transaction.',
|
|
4037
|
+
allOf: [
|
|
4038
|
+
{
|
|
4039
|
+
$ref: '#/components/schemas/RecurringMatchInfoDto'
|
|
4040
|
+
}
|
|
4041
|
+
]
|
|
4042
|
+
},
|
|
4043
|
+
recurringSuggestion: {
|
|
4044
|
+
description:
|
|
4045
|
+
'Recurring rule creation suggestion (when action is "created"). Contains suggestion to create a recurring rule based on detected patterns. Only present when no existing rule matched and similar historical transactions were found.',
|
|
4046
|
+
allOf: [
|
|
4047
|
+
{
|
|
4048
|
+
$ref: '#/components/schemas/RecurringSuggestionDto'
|
|
4049
|
+
}
|
|
4050
|
+
]
|
|
4051
|
+
},
|
|
4052
|
+
suggestedAccounts: {
|
|
4053
|
+
description:
|
|
4054
|
+
'Suggested accounts for this transaction. Contains recommended source and destination accounts based on the detected intent and rules.',
|
|
4055
|
+
allOf: [
|
|
4056
|
+
{
|
|
4057
|
+
$ref: '#/components/schemas/NlpSuggestedAccountsDto'
|
|
4058
|
+
}
|
|
4059
|
+
]
|
|
4060
|
+
},
|
|
4061
|
+
defaultAccounts: {
|
|
4062
|
+
description:
|
|
4063
|
+
'Default accounts for the user/region. These are fallback accounts used when no specific suggestion is available.',
|
|
4064
|
+
allOf: [
|
|
4065
|
+
{
|
|
4066
|
+
$ref: '#/components/schemas/NlpDefaultAccountsDto'
|
|
4067
|
+
}
|
|
4068
|
+
]
|
|
4069
|
+
}
|
|
4070
|
+
},
|
|
4071
|
+
required: ['status', 'action']
|
|
4072
|
+
} as const;
|
|
4073
|
+
|
|
4074
|
+
export const $BalanceByCurrencyDto = {
|
|
4075
|
+
type: 'object',
|
|
4076
|
+
properties: {
|
|
4077
|
+
currency: {
|
|
4078
|
+
type: 'string',
|
|
4079
|
+
description: 'ISO 4217 currency code',
|
|
4080
|
+
example: 'CNY'
|
|
4081
|
+
},
|
|
4082
|
+
balance: {
|
|
4083
|
+
type: 'string',
|
|
4084
|
+
description: 'Balance amount',
|
|
4085
|
+
example: '50000.00'
|
|
4086
|
+
}
|
|
4087
|
+
},
|
|
4088
|
+
required: ['currency', 'balance']
|
|
4089
|
+
} as const;
|
|
4090
|
+
|
|
4091
|
+
export const $NetWorthByCurrencyDto = {
|
|
4092
|
+
type: 'object',
|
|
4093
|
+
properties: {
|
|
4094
|
+
netWorth: {
|
|
4095
|
+
description: 'Net worth by currency',
|
|
4096
|
+
type: 'array',
|
|
4097
|
+
items: {
|
|
4098
|
+
$ref: '#/components/schemas/BalanceByCurrencyDto'
|
|
4099
|
+
}
|
|
4100
|
+
},
|
|
4101
|
+
assets: {
|
|
4102
|
+
description: 'Assets by currency',
|
|
4103
|
+
type: 'array',
|
|
4104
|
+
items: {
|
|
4105
|
+
$ref: '#/components/schemas/BalanceByCurrencyDto'
|
|
4106
|
+
}
|
|
4107
|
+
},
|
|
4108
|
+
liabilities: {
|
|
4109
|
+
description: 'Liabilities by currency',
|
|
4110
|
+
type: 'array',
|
|
4111
|
+
items: {
|
|
4112
|
+
$ref: '#/components/schemas/BalanceByCurrencyDto'
|
|
4113
|
+
}
|
|
4114
|
+
}
|
|
4115
|
+
},
|
|
4116
|
+
required: ['netWorth', 'assets', 'liabilities']
|
|
4117
|
+
} as const;
|
|
4118
|
+
|
|
4119
|
+
export const $ConvertedNetWorthDto = {
|
|
4120
|
+
type: 'object',
|
|
4121
|
+
properties: {
|
|
4122
|
+
baseCurrency: {
|
|
4123
|
+
type: 'string',
|
|
4124
|
+
description: 'Base currency for conversion',
|
|
4125
|
+
example: 'CNY'
|
|
4126
|
+
},
|
|
4127
|
+
netWorth: {
|
|
4128
|
+
type: 'string',
|
|
4129
|
+
description: 'Converted net worth',
|
|
4130
|
+
example: '500000.00'
|
|
4131
|
+
},
|
|
4132
|
+
assets: {
|
|
4133
|
+
type: 'string',
|
|
4134
|
+
description: 'Converted assets',
|
|
4135
|
+
example: '600000.00'
|
|
4136
|
+
},
|
|
4137
|
+
liabilities: {
|
|
4138
|
+
type: 'string',
|
|
4139
|
+
description: 'Converted liabilities',
|
|
4140
|
+
example: '100000.00'
|
|
4141
|
+
},
|
|
4142
|
+
exchangeRates: {
|
|
4143
|
+
type: 'object',
|
|
4144
|
+
description: 'Exchange rates used for conversion',
|
|
4145
|
+
example: {
|
|
4146
|
+
USD: '7.200000',
|
|
4147
|
+
EUR: '7.800000'
|
|
4148
|
+
}
|
|
4149
|
+
}
|
|
4150
|
+
},
|
|
4151
|
+
required: [
|
|
4152
|
+
'baseCurrency',
|
|
4153
|
+
'netWorth',
|
|
4154
|
+
'assets',
|
|
4155
|
+
'liabilities',
|
|
4156
|
+
'exchangeRates'
|
|
4157
|
+
]
|
|
4158
|
+
} as const;
|
|
4159
|
+
|
|
4160
|
+
export const $ExchangeRateWarningDto = {
|
|
4161
|
+
type: 'object',
|
|
4162
|
+
properties: {
|
|
4163
|
+
type: {
|
|
4164
|
+
type: 'string',
|
|
4165
|
+
description: 'Warning type',
|
|
4166
|
+
example: 'MISSING_EXCHANGE_RATE'
|
|
4167
|
+
},
|
|
4168
|
+
currency: {
|
|
4169
|
+
type: 'string',
|
|
4170
|
+
description: 'Currency without exchange rate',
|
|
4171
|
+
example: 'EUR'
|
|
4172
|
+
},
|
|
4173
|
+
totalAmount: {
|
|
4174
|
+
type: 'string',
|
|
4175
|
+
description: 'Total amount affected',
|
|
4176
|
+
example: '1000.00'
|
|
4177
|
+
}
|
|
4178
|
+
},
|
|
4179
|
+
required: ['type', 'currency', 'totalAmount']
|
|
4180
|
+
} as const;
|
|
4181
|
+
|
|
4182
|
+
export const $NetWorthResponseDto = {
|
|
4183
|
+
type: 'object',
|
|
4184
|
+
properties: {
|
|
4185
|
+
netWorth: {
|
|
4186
|
+
type: 'string',
|
|
4187
|
+
description:
|
|
4188
|
+
'Total net worth (assets - liabilities, converted to base currency)',
|
|
4189
|
+
example: '500000.00'
|
|
4190
|
+
},
|
|
4191
|
+
assets: {
|
|
4192
|
+
type: 'string',
|
|
4193
|
+
description: 'Total assets value (converted)',
|
|
4194
|
+
example: '600000.00'
|
|
4195
|
+
},
|
|
4196
|
+
liabilities: {
|
|
4197
|
+
type: 'string',
|
|
4198
|
+
description: 'Total liabilities value (positive number, converted)',
|
|
4199
|
+
example: '100000.00'
|
|
4200
|
+
},
|
|
4201
|
+
monthlyReturn: {
|
|
4202
|
+
type: 'string',
|
|
4203
|
+
description: 'Monthly return (change from last month)',
|
|
4204
|
+
example: '15000.00'
|
|
4205
|
+
},
|
|
4206
|
+
monthlyReturnPercentage: {
|
|
4207
|
+
type: 'string',
|
|
4208
|
+
description: 'Monthly return percentage',
|
|
4209
|
+
example: '3.15'
|
|
4210
|
+
},
|
|
4211
|
+
currency: {
|
|
4212
|
+
type: 'string',
|
|
4213
|
+
description: 'Base currency code',
|
|
4214
|
+
example: 'CNY'
|
|
4215
|
+
},
|
|
4216
|
+
asOf: {
|
|
4217
|
+
type: 'string',
|
|
4218
|
+
description: 'Data as of date (ISO 8601)',
|
|
4219
|
+
example: '2024-06-15T00:00:00.000Z'
|
|
4220
|
+
},
|
|
4221
|
+
byCurrency: {
|
|
4222
|
+
description: 'Balances grouped by original currency',
|
|
4223
|
+
allOf: [
|
|
4224
|
+
{
|
|
4225
|
+
$ref: '#/components/schemas/NetWorthByCurrencyDto'
|
|
4226
|
+
}
|
|
4227
|
+
]
|
|
4228
|
+
},
|
|
4229
|
+
converted: {
|
|
4230
|
+
description:
|
|
4231
|
+
'Converted values in base currency (undefined if no exchange rates available)',
|
|
4232
|
+
allOf: [
|
|
4233
|
+
{
|
|
4234
|
+
$ref: '#/components/schemas/ConvertedNetWorthDto'
|
|
4235
|
+
}
|
|
4236
|
+
]
|
|
4237
|
+
},
|
|
4238
|
+
warnings: {
|
|
4239
|
+
description: 'Exchange rate warnings',
|
|
4240
|
+
type: 'array',
|
|
4241
|
+
items: {
|
|
4242
|
+
$ref: '#/components/schemas/ExchangeRateWarningDto'
|
|
4243
|
+
}
|
|
4244
|
+
}
|
|
4245
|
+
},
|
|
4246
|
+
required: [
|
|
4247
|
+
'netWorth',
|
|
4248
|
+
'assets',
|
|
4249
|
+
'liabilities',
|
|
4250
|
+
'monthlyReturn',
|
|
4251
|
+
'monthlyReturnPercentage',
|
|
4252
|
+
'currency',
|
|
4253
|
+
'asOf'
|
|
4254
|
+
]
|
|
4255
|
+
} as const;
|
|
4256
|
+
|
|
4257
|
+
export const $AccountItemDto = {
|
|
4258
|
+
type: 'object',
|
|
4259
|
+
properties: {
|
|
4260
|
+
id: {
|
|
4261
|
+
type: 'string',
|
|
4262
|
+
description: 'Account ID'
|
|
4263
|
+
},
|
|
4264
|
+
name: {
|
|
4265
|
+
type: 'string',
|
|
4266
|
+
description: 'Full account name',
|
|
4267
|
+
example: 'Assets:Bank:CMB:Savings'
|
|
4268
|
+
},
|
|
4269
|
+
displayName: {
|
|
4270
|
+
type: 'string',
|
|
4271
|
+
description: 'Display name (last part of account path)',
|
|
4272
|
+
example: 'Savings'
|
|
4273
|
+
},
|
|
4274
|
+
balance: {
|
|
4275
|
+
type: 'string',
|
|
4276
|
+
description: 'Account balance',
|
|
4277
|
+
example: '50000.00'
|
|
4278
|
+
},
|
|
4279
|
+
currency: {
|
|
4280
|
+
type: 'string',
|
|
4281
|
+
description: 'Currency code',
|
|
4282
|
+
example: 'CNY'
|
|
4283
|
+
}
|
|
4284
|
+
},
|
|
4285
|
+
required: ['id', 'name', 'displayName', 'balance', 'currency']
|
|
4286
|
+
} as const;
|
|
4287
|
+
|
|
4288
|
+
export const $PlatformGroupDto = {
|
|
4289
|
+
type: 'object',
|
|
4290
|
+
properties: {
|
|
4291
|
+
platformId: {
|
|
4292
|
+
type: 'string',
|
|
4293
|
+
description: 'Platform ID'
|
|
4294
|
+
},
|
|
4295
|
+
platformName: {
|
|
4296
|
+
type: 'string',
|
|
4297
|
+
description: 'Platform display name',
|
|
4298
|
+
example: 'CMB Bank'
|
|
4299
|
+
},
|
|
4300
|
+
accounts: {
|
|
4301
|
+
description: 'Accounts within this platform',
|
|
4302
|
+
type: 'array',
|
|
4303
|
+
items: {
|
|
4304
|
+
$ref: '#/components/schemas/AccountItemDto'
|
|
4305
|
+
}
|
|
4306
|
+
},
|
|
4307
|
+
totalBalance: {
|
|
4308
|
+
type: 'string',
|
|
4309
|
+
description: 'Total balance across all accounts in platform',
|
|
4310
|
+
example: '100000.00'
|
|
4311
|
+
}
|
|
4312
|
+
},
|
|
4313
|
+
required: ['platformId', 'platformName', 'accounts', 'totalBalance']
|
|
4314
|
+
} as const;
|
|
4315
|
+
|
|
4316
|
+
export const $AccountsSummaryDto = {
|
|
4317
|
+
type: 'object',
|
|
4318
|
+
properties: {
|
|
4319
|
+
totalAccounts: {
|
|
4320
|
+
type: 'number',
|
|
4321
|
+
description: 'Total number of accounts'
|
|
4322
|
+
},
|
|
4323
|
+
totalPlatforms: {
|
|
4324
|
+
type: 'number',
|
|
4325
|
+
description: 'Total number of platforms'
|
|
4326
|
+
}
|
|
4327
|
+
},
|
|
4328
|
+
required: ['totalAccounts', 'totalPlatforms']
|
|
4329
|
+
} as const;
|
|
4330
|
+
|
|
4331
|
+
export const $AccountsResponseDto = {
|
|
4332
|
+
type: 'object',
|
|
4333
|
+
properties: {
|
|
4334
|
+
groups: {
|
|
4335
|
+
description: 'Account groups by platform',
|
|
4336
|
+
type: 'array',
|
|
4337
|
+
items: {
|
|
4338
|
+
$ref: '#/components/schemas/PlatformGroupDto'
|
|
4339
|
+
}
|
|
4340
|
+
},
|
|
4341
|
+
summary: {
|
|
4342
|
+
description: 'Summary statistics',
|
|
4343
|
+
allOf: [
|
|
4344
|
+
{
|
|
4345
|
+
$ref: '#/components/schemas/AccountsSummaryDto'
|
|
4346
|
+
}
|
|
4347
|
+
]
|
|
4348
|
+
}
|
|
4349
|
+
},
|
|
4350
|
+
required: ['groups', 'summary']
|
|
4351
|
+
} as const;
|
|
4352
|
+
|
|
4353
|
+
export const $AccountItemWithAssetClassDto = {
|
|
4354
|
+
type: 'object',
|
|
4355
|
+
properties: {
|
|
4356
|
+
id: {
|
|
4357
|
+
type: 'string',
|
|
4358
|
+
description: 'Account ID'
|
|
4359
|
+
},
|
|
4360
|
+
name: {
|
|
4361
|
+
type: 'string',
|
|
4362
|
+
description: 'Full account name',
|
|
4363
|
+
example: 'Assets:Bank:CMB:Savings'
|
|
4364
|
+
},
|
|
4365
|
+
displayName: {
|
|
4366
|
+
type: 'string',
|
|
4367
|
+
description: 'Display name (last part of account path)',
|
|
4368
|
+
example: 'Savings'
|
|
4369
|
+
},
|
|
4370
|
+
balance: {
|
|
4371
|
+
type: 'string',
|
|
4372
|
+
description: 'Account balance',
|
|
4373
|
+
example: '50000.00'
|
|
4374
|
+
},
|
|
4375
|
+
currency: {
|
|
4376
|
+
type: 'string',
|
|
4377
|
+
description: 'Currency code',
|
|
4378
|
+
example: 'CNY'
|
|
4379
|
+
},
|
|
4380
|
+
assetClass: {
|
|
4381
|
+
type: 'string',
|
|
4382
|
+
description: 'Asset class',
|
|
4383
|
+
example: 'LIQUIDITY'
|
|
4384
|
+
},
|
|
4385
|
+
assetSubClass: {
|
|
4386
|
+
type: 'string',
|
|
4387
|
+
description: 'Asset sub-class (Prisma-compatible)',
|
|
4388
|
+
example: 'RETIREMENT_ACCOUNT'
|
|
4389
|
+
},
|
|
4390
|
+
regionalSubClass: {
|
|
4391
|
+
type: 'string',
|
|
4392
|
+
description: 'Regional sub-class (region-specific, for display)',
|
|
4393
|
+
example: 'FOUR_ZERO_ONE_K'
|
|
4394
|
+
},
|
|
4395
|
+
riskLevel: {
|
|
4396
|
+
type: 'string',
|
|
4397
|
+
description: 'Risk level',
|
|
4398
|
+
example: 'LOW'
|
|
4399
|
+
}
|
|
4400
|
+
},
|
|
4401
|
+
required: ['id', 'name', 'displayName', 'balance', 'currency', 'assetClass']
|
|
4402
|
+
} as const;
|
|
4403
|
+
|
|
4404
|
+
export const $AssetClassGroupDto = {
|
|
4405
|
+
type: 'object',
|
|
4406
|
+
properties: {
|
|
4407
|
+
assetClass: {
|
|
4408
|
+
type: 'string',
|
|
4409
|
+
description: 'Asset class name',
|
|
4410
|
+
example: 'LIQUIDITY',
|
|
4411
|
+
enum: [
|
|
4412
|
+
'LIQUIDITY',
|
|
4413
|
+
'EQUITY',
|
|
4414
|
+
'FIXED_INCOME',
|
|
4415
|
+
'PRECIOUS_METALS',
|
|
4416
|
+
'COMMODITY',
|
|
4417
|
+
'INSURANCE',
|
|
4418
|
+
'ALTERNATIVE_INVESTMENT',
|
|
4419
|
+
'PERSONAL_ASSETS',
|
|
4420
|
+
'LIABILITY',
|
|
4421
|
+
'REAL_ESTATE',
|
|
4422
|
+
'INDEX'
|
|
4423
|
+
]
|
|
4424
|
+
},
|
|
4425
|
+
assetSubClass: {
|
|
4426
|
+
type: 'string',
|
|
4427
|
+
description: 'Asset sub-class name',
|
|
4428
|
+
example: 'DEPOSIT'
|
|
4429
|
+
},
|
|
4430
|
+
accounts: {
|
|
4431
|
+
description: 'Accounts within this asset class',
|
|
4432
|
+
type: 'array',
|
|
4433
|
+
items: {
|
|
4434
|
+
$ref: '#/components/schemas/AccountItemWithAssetClassDto'
|
|
4435
|
+
}
|
|
4436
|
+
},
|
|
4437
|
+
balanceByCurrency: {
|
|
4438
|
+
description: 'Balances grouped by currency',
|
|
4439
|
+
type: 'array',
|
|
4440
|
+
items: {
|
|
4441
|
+
$ref: '#/components/schemas/BalanceByCurrencyDto'
|
|
4442
|
+
}
|
|
4443
|
+
},
|
|
4444
|
+
convertedBalance: {
|
|
4445
|
+
type: 'string',
|
|
4446
|
+
description: 'Converted balance in base currency',
|
|
4447
|
+
example: '100000.00'
|
|
4448
|
+
}
|
|
4449
|
+
},
|
|
4450
|
+
required: ['assetClass', 'accounts', 'balanceByCurrency']
|
|
4451
|
+
} as const;
|
|
4452
|
+
|
|
4453
|
+
export const $AccountExchangeRateWarningDto = {
|
|
4454
|
+
type: 'object',
|
|
4455
|
+
properties: {
|
|
4456
|
+
type: {
|
|
4457
|
+
type: 'string',
|
|
4458
|
+
description: 'Warning type',
|
|
4459
|
+
example: 'MISSING_EXCHANGE_RATE'
|
|
4460
|
+
},
|
|
4461
|
+
currency: {
|
|
4462
|
+
type: 'string',
|
|
4463
|
+
description: 'Currency without exchange rate',
|
|
4464
|
+
example: 'USD'
|
|
4465
|
+
},
|
|
4466
|
+
accounts: {
|
|
4467
|
+
description: 'Affected account paths',
|
|
4468
|
+
type: 'array',
|
|
4469
|
+
items: {
|
|
4470
|
+
type: 'string'
|
|
4471
|
+
}
|
|
4472
|
+
},
|
|
4473
|
+
totalAmount: {
|
|
4474
|
+
type: 'string',
|
|
4475
|
+
description: 'Total amount in this currency',
|
|
4476
|
+
example: '5000.00'
|
|
4477
|
+
}
|
|
4478
|
+
},
|
|
4479
|
+
required: ['type', 'currency', 'accounts', 'totalAmount']
|
|
4480
|
+
} as const;
|
|
4481
|
+
|
|
4482
|
+
export const $AssetClassSummaryDto = {
|
|
4483
|
+
type: 'object',
|
|
4484
|
+
properties: {
|
|
4485
|
+
totalAccounts: {
|
|
4486
|
+
type: 'number',
|
|
4487
|
+
description: 'Total number of accounts'
|
|
4488
|
+
},
|
|
4489
|
+
totalAssetClasses: {
|
|
4490
|
+
type: 'number',
|
|
4491
|
+
description: 'Total number of asset classes'
|
|
4492
|
+
},
|
|
4493
|
+
baseCurrency: {
|
|
4494
|
+
type: 'string',
|
|
4495
|
+
description: 'Base currency for conversion',
|
|
4496
|
+
example: 'CNY'
|
|
4497
|
+
},
|
|
4498
|
+
warnings: {
|
|
4499
|
+
description: 'Exchange rate warnings',
|
|
4500
|
+
type: 'array',
|
|
4501
|
+
items: {
|
|
4502
|
+
$ref: '#/components/schemas/AccountExchangeRateWarningDto'
|
|
4503
|
+
}
|
|
4504
|
+
}
|
|
4505
|
+
},
|
|
4506
|
+
required: ['totalAccounts', 'totalAssetClasses', 'baseCurrency']
|
|
4507
|
+
} as const;
|
|
4508
|
+
|
|
4509
|
+
export const $AssetClassAccountsResponseDto = {
|
|
4510
|
+
type: 'object',
|
|
4511
|
+
properties: {
|
|
4512
|
+
groups: {
|
|
4513
|
+
description: 'Account groups by asset class',
|
|
4514
|
+
type: 'array',
|
|
4515
|
+
items: {
|
|
4516
|
+
$ref: '#/components/schemas/AssetClassGroupDto'
|
|
4517
|
+
}
|
|
4518
|
+
},
|
|
4519
|
+
summary: {
|
|
4520
|
+
description: 'Summary statistics',
|
|
4521
|
+
allOf: [
|
|
4522
|
+
{
|
|
4523
|
+
$ref: '#/components/schemas/AssetClassSummaryDto'
|
|
4524
|
+
}
|
|
4525
|
+
]
|
|
4526
|
+
}
|
|
4527
|
+
},
|
|
4528
|
+
required: ['groups', 'summary']
|
|
4529
|
+
} as const;
|
|
4530
|
+
|
|
4531
|
+
export const $CashFlowByCurrencyDto = {
|
|
4532
|
+
type: 'object',
|
|
4533
|
+
properties: {
|
|
4534
|
+
income: {
|
|
4535
|
+
description: 'Income by currency',
|
|
4536
|
+
type: 'array',
|
|
4537
|
+
items: {
|
|
4538
|
+
$ref: '#/components/schemas/BalanceByCurrencyDto'
|
|
4539
|
+
}
|
|
4540
|
+
},
|
|
4541
|
+
expense: {
|
|
4542
|
+
description: 'Expense by currency',
|
|
4543
|
+
type: 'array',
|
|
4544
|
+
items: {
|
|
4545
|
+
$ref: '#/components/schemas/BalanceByCurrencyDto'
|
|
4546
|
+
}
|
|
4547
|
+
},
|
|
4548
|
+
netSavings: {
|
|
4549
|
+
description: 'Net savings by currency',
|
|
4550
|
+
type: 'array',
|
|
4551
|
+
items: {
|
|
4552
|
+
$ref: '#/components/schemas/BalanceByCurrencyDto'
|
|
4553
|
+
}
|
|
4554
|
+
}
|
|
4555
|
+
},
|
|
4556
|
+
required: ['income', 'expense', 'netSavings']
|
|
4557
|
+
} as const;
|
|
4558
|
+
|
|
4559
|
+
export const $ConvertedCashFlowDto = {
|
|
4560
|
+
type: 'object',
|
|
4561
|
+
properties: {
|
|
4562
|
+
baseCurrency: {
|
|
4563
|
+
type: 'string',
|
|
4564
|
+
description: 'Base currency for conversion',
|
|
4565
|
+
example: 'CNY'
|
|
4566
|
+
},
|
|
4567
|
+
income: {
|
|
4568
|
+
type: 'string',
|
|
4569
|
+
description: 'Converted income',
|
|
4570
|
+
example: '25000.00'
|
|
4571
|
+
},
|
|
4572
|
+
expense: {
|
|
4573
|
+
type: 'string',
|
|
4574
|
+
description: 'Converted expense',
|
|
4575
|
+
example: '18000.00'
|
|
4576
|
+
},
|
|
4577
|
+
netSavings: {
|
|
4578
|
+
type: 'string',
|
|
4579
|
+
description: 'Converted net savings',
|
|
4580
|
+
example: '7000.00'
|
|
4581
|
+
},
|
|
4582
|
+
exchangeRates: {
|
|
4583
|
+
type: 'object',
|
|
4584
|
+
description: 'Exchange rates used for conversion',
|
|
4585
|
+
example: {
|
|
4586
|
+
USD: '7.200000'
|
|
4587
|
+
}
|
|
4588
|
+
}
|
|
4589
|
+
},
|
|
4590
|
+
required: ['baseCurrency', 'income', 'expense', 'netSavings', 'exchangeRates']
|
|
4591
|
+
} as const;
|
|
4592
|
+
|
|
4593
|
+
export const $CashFlowResponseDto = {
|
|
4594
|
+
type: 'object',
|
|
4595
|
+
properties: {
|
|
4596
|
+
period: {
|
|
4597
|
+
type: 'string',
|
|
4598
|
+
description: 'Period identifier (YYYY-MM)',
|
|
4599
|
+
example: '2024-06'
|
|
4600
|
+
},
|
|
4601
|
+
income: {
|
|
4602
|
+
type: 'string',
|
|
4603
|
+
description: 'Total income for the period (converted)',
|
|
4604
|
+
example: '25000.00'
|
|
4605
|
+
},
|
|
4606
|
+
expense: {
|
|
4607
|
+
type: 'string',
|
|
4608
|
+
description: 'Total expenses for the period (converted)',
|
|
4609
|
+
example: '18000.00'
|
|
4610
|
+
},
|
|
4611
|
+
netSavings: {
|
|
4612
|
+
type: 'string',
|
|
4613
|
+
description: 'Net savings (income - expense, converted)',
|
|
4614
|
+
example: '7000.00'
|
|
4615
|
+
},
|
|
4616
|
+
savingsRate: {
|
|
4617
|
+
type: 'string',
|
|
4618
|
+
description: 'Savings rate percentage (netSavings / income * 100)',
|
|
4619
|
+
example: '28.00'
|
|
4620
|
+
},
|
|
4621
|
+
currency: {
|
|
4622
|
+
type: 'string',
|
|
4623
|
+
description: 'Base currency code',
|
|
4624
|
+
example: 'CNY'
|
|
4625
|
+
},
|
|
4626
|
+
byCurrency: {
|
|
4627
|
+
description: 'Cash flow grouped by original currency',
|
|
4628
|
+
allOf: [
|
|
4629
|
+
{
|
|
4630
|
+
$ref: '#/components/schemas/CashFlowByCurrencyDto'
|
|
4631
|
+
}
|
|
4632
|
+
]
|
|
4633
|
+
},
|
|
4634
|
+
converted: {
|
|
4635
|
+
description: 'Converted values in base currency',
|
|
4636
|
+
allOf: [
|
|
4637
|
+
{
|
|
4638
|
+
$ref: '#/components/schemas/ConvertedCashFlowDto'
|
|
4639
|
+
}
|
|
4640
|
+
]
|
|
4641
|
+
},
|
|
4642
|
+
warnings: {
|
|
4643
|
+
description: 'Exchange rate warnings',
|
|
4644
|
+
type: 'array',
|
|
4645
|
+
items: {
|
|
4646
|
+
$ref: '#/components/schemas/ExchangeRateWarningDto'
|
|
4647
|
+
}
|
|
4648
|
+
}
|
|
4649
|
+
},
|
|
4650
|
+
required: [
|
|
4651
|
+
'period',
|
|
4652
|
+
'income',
|
|
4653
|
+
'expense',
|
|
4654
|
+
'netSavings',
|
|
4655
|
+
'savingsRate',
|
|
4656
|
+
'currency'
|
|
4657
|
+
]
|
|
4658
|
+
} as const;
|
|
4659
|
+
|
|
4660
|
+
export const $CurrencyBalanceDto = {
|
|
4661
|
+
type: 'object',
|
|
4662
|
+
properties: {
|
|
4663
|
+
currency: {
|
|
4664
|
+
type: 'string',
|
|
4665
|
+
description: 'ISO 4217 currency code',
|
|
4666
|
+
example: 'CNY'
|
|
4667
|
+
},
|
|
4668
|
+
balance: {
|
|
4669
|
+
type: 'string',
|
|
4670
|
+
description: 'Balance amount',
|
|
4671
|
+
example: '500000.00'
|
|
4672
|
+
}
|
|
4673
|
+
},
|
|
4674
|
+
required: ['currency', 'balance']
|
|
4675
|
+
} as const;
|
|
4676
|
+
|
|
4677
|
+
export const $TimeSeriesPointDto = {
|
|
4678
|
+
type: 'object',
|
|
4679
|
+
properties: {
|
|
4680
|
+
date: {
|
|
4681
|
+
type: 'string',
|
|
4682
|
+
description: 'Date in YYYY-MM-DD format',
|
|
4683
|
+
example: '2024-06-15'
|
|
4684
|
+
},
|
|
4685
|
+
value: {
|
|
4686
|
+
type: 'string',
|
|
4687
|
+
description: 'Value at this date (in base currency)',
|
|
4688
|
+
example: '500000.00'
|
|
4689
|
+
},
|
|
4690
|
+
change: {
|
|
4691
|
+
type: 'object',
|
|
4692
|
+
description: 'Change from previous point',
|
|
4693
|
+
example: '5000.00'
|
|
4694
|
+
},
|
|
4695
|
+
byCurrency: {
|
|
4696
|
+
description: 'Multi-currency breakdown for this point',
|
|
4697
|
+
type: 'array',
|
|
4698
|
+
items: {
|
|
4699
|
+
$ref: '#/components/schemas/CurrencyBalanceDto'
|
|
4700
|
+
}
|
|
4701
|
+
}
|
|
4702
|
+
},
|
|
4703
|
+
required: ['date', 'value']
|
|
4704
|
+
} as const;
|
|
4705
|
+
|
|
4706
|
+
export const $TrendSummaryDto = {
|
|
4707
|
+
type: 'object',
|
|
4708
|
+
properties: {
|
|
4709
|
+
startValue: {
|
|
4710
|
+
type: 'string',
|
|
4711
|
+
description: 'Value at start of period',
|
|
4712
|
+
example: '450000.00'
|
|
4713
|
+
},
|
|
4714
|
+
endValue: {
|
|
4715
|
+
type: 'string',
|
|
4716
|
+
description: 'Value at end of period',
|
|
4717
|
+
example: '500000.00'
|
|
4718
|
+
},
|
|
4719
|
+
totalChange: {
|
|
4720
|
+
type: 'string',
|
|
4721
|
+
description: 'Total change over period',
|
|
4722
|
+
example: '50000.00'
|
|
4723
|
+
},
|
|
4724
|
+
totalChangePercentage: {
|
|
4725
|
+
type: 'string',
|
|
4726
|
+
description: 'Total change percentage',
|
|
4727
|
+
example: '+11.11%'
|
|
4728
|
+
}
|
|
4729
|
+
},
|
|
4730
|
+
required: ['startValue', 'endValue', 'totalChange', 'totalChangePercentage']
|
|
4731
|
+
} as const;
|
|
4732
|
+
|
|
4733
|
+
export const $MultiCurrencyPointDto = {
|
|
4734
|
+
type: 'object',
|
|
4735
|
+
properties: {
|
|
4736
|
+
date: {
|
|
4737
|
+
type: 'string',
|
|
4738
|
+
description: 'Date in YYYY-MM-DD format',
|
|
4739
|
+
example: '2024-06-15'
|
|
4740
|
+
},
|
|
4741
|
+
byCurrency: {
|
|
4742
|
+
description: 'Balances by currency',
|
|
4743
|
+
type: 'array',
|
|
4744
|
+
items: {
|
|
4745
|
+
$ref: '#/components/schemas/CurrencyBalanceDto'
|
|
4746
|
+
}
|
|
4747
|
+
}
|
|
4748
|
+
},
|
|
4749
|
+
required: ['date', 'byCurrency']
|
|
4750
|
+
} as const;
|
|
4751
|
+
|
|
4752
|
+
export const $PortfolioTrendsResponseDto = {
|
|
4753
|
+
type: 'object',
|
|
4754
|
+
properties: {
|
|
4755
|
+
series: {
|
|
4756
|
+
description: 'Time series data points',
|
|
4757
|
+
type: 'array',
|
|
4758
|
+
items: {
|
|
4759
|
+
$ref: '#/components/schemas/TimeSeriesPointDto'
|
|
4760
|
+
}
|
|
4761
|
+
},
|
|
4762
|
+
summary: {
|
|
4763
|
+
description: 'Period summary',
|
|
4764
|
+
allOf: [
|
|
4765
|
+
{
|
|
4766
|
+
$ref: '#/components/schemas/TrendSummaryDto'
|
|
4767
|
+
}
|
|
4768
|
+
]
|
|
4769
|
+
},
|
|
4770
|
+
period: {
|
|
4771
|
+
type: 'string',
|
|
4772
|
+
description: 'Period requested',
|
|
4773
|
+
example: '6m'
|
|
4774
|
+
},
|
|
4775
|
+
granularity: {
|
|
4776
|
+
type: 'string',
|
|
4777
|
+
description: 'Data granularity',
|
|
4778
|
+
example: 'month'
|
|
4779
|
+
},
|
|
4780
|
+
currency: {
|
|
4781
|
+
type: 'string',
|
|
4782
|
+
description: 'Base currency for converted values',
|
|
4783
|
+
example: 'CNY'
|
|
4784
|
+
},
|
|
4785
|
+
byCurrency: {
|
|
4786
|
+
description:
|
|
4787
|
+
'Multi-currency time series (each point has currency breakdown)',
|
|
4788
|
+
type: 'array',
|
|
4789
|
+
items: {
|
|
4790
|
+
$ref: '#/components/schemas/MultiCurrencyPointDto'
|
|
4791
|
+
}
|
|
4792
|
+
},
|
|
4793
|
+
warnings: {
|
|
4794
|
+
description: 'Exchange rate warnings',
|
|
4795
|
+
type: 'array',
|
|
4796
|
+
items: {
|
|
4797
|
+
$ref: '#/components/schemas/ExchangeRateWarningDto'
|
|
4798
|
+
}
|
|
4799
|
+
}
|
|
4800
|
+
},
|
|
4801
|
+
required: ['series', 'summary', 'period', 'granularity', 'currency']
|
|
4802
|
+
} as const;
|
|
4803
|
+
|
|
4804
|
+
export const $GenerateSnapshotBody = {
|
|
4805
|
+
type: 'object',
|
|
4806
|
+
properties: {}
|
|
4807
|
+
} as const;
|
|
4808
|
+
|
|
4809
|
+
export const $GenerateSnapshotResponse = {
|
|
4810
|
+
type: 'object',
|
|
4811
|
+
properties: {}
|
|
4812
|
+
} as const;
|
|
4813
|
+
|
|
4814
|
+
export const $BackfillSnapshotsBody = {
|
|
4815
|
+
type: 'object',
|
|
4816
|
+
properties: {}
|
|
4817
|
+
} as const;
|
|
4818
|
+
|
|
4819
|
+
export const $BackfillSnapshotsResponse = {
|
|
4820
|
+
type: 'object',
|
|
4821
|
+
properties: {}
|
|
4822
|
+
} as const;
|
|
4823
|
+
|
|
4824
|
+
export const $AnonymousLoginDto = {
|
|
4825
|
+
type: 'object',
|
|
4826
|
+
properties: {
|
|
4827
|
+
accessToken: {
|
|
4828
|
+
type: 'string',
|
|
4829
|
+
description: 'Access token for anonymous login'
|
|
4830
|
+
}
|
|
4831
|
+
},
|
|
4832
|
+
required: ['accessToken']
|
|
4833
|
+
} as const;
|