@firela/api-types 0.0.0-canary.5639ea2d → 0.0.0-canary.6feee68d

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.
@@ -8,6 +8,12 @@ export const $CreateAccountDto = {
8
8
  description: 'Account path (hierarchical, colon-separated)',
9
9
  example: 'Assets:CN:Bank:ICBC:Checking'
10
10
  },
11
+ displayName: {
12
+ type: 'string',
13
+ description:
14
+ 'Display name to distinguish accounts at the same path (default: "")',
15
+ example: '工资卡'
16
+ },
11
17
  openDate: {
12
18
  format: 'date-time',
13
19
  type: 'string',
@@ -86,6 +92,12 @@ export const $AccountResponseDto = {
86
92
  description: 'Account path (hierarchical, colon-separated)',
87
93
  example: 'Assets:CN:Bank:ICBC:Checking'
88
94
  },
95
+ displayName: {
96
+ type: 'string',
97
+ description:
98
+ 'Display name distinguishing multiple accounts at the same path',
99
+ example: '工资卡'
100
+ },
89
101
  type: {
90
102
  type: 'string',
91
103
  description: 'Account type (root segment)',
@@ -180,6 +192,7 @@ export const $AccountResponseDto = {
180
192
  required: [
181
193
  'id',
182
194
  'path',
195
+ 'displayName',
183
196
  'type',
184
197
  'status',
185
198
  'openDate',
@@ -212,6 +225,11 @@ export const $AccountListResponseDto = {
212
225
  export const $UpdateAccountDto = {
213
226
  type: 'object',
214
227
  properties: {
228
+ displayName: {
229
+ type: 'string',
230
+ description: 'Display name to distinguish accounts at the same path',
231
+ example: '招行工资卡'
232
+ },
215
233
  currencies: {
216
234
  description: 'Allowed currencies (null = no restriction)',
217
235
  example: ['CNY', 'USD'],
@@ -251,7 +269,7 @@ export const $UpdateAccountDto = {
251
269
  }
252
270
  },
253
271
  platformId: {
254
- type: 'object',
272
+ type: 'string',
255
273
  description:
256
274
  'Platform ID (references Platform.id), null to clear association',
257
275
  example: 'c98e5d4a-2f71-4a5a-bb3c-92c9f231d5e2',
@@ -292,6 +310,162 @@ export const $ReopenAccountDto = {
292
310
  }
293
311
  } as const;
294
312
 
313
+ export const $AccountStandardResponseDto = {
314
+ type: 'object',
315
+ properties: {
316
+ path: {
317
+ type: 'string',
318
+ description: 'Account path (hierarchical, colon-separated)',
319
+ example: 'Assets:CN:Bank:ICBC:Checking'
320
+ },
321
+ type: {
322
+ type: 'string',
323
+ description: 'Account type in Beancount hierarchy',
324
+ enum: ['Assets', 'Liabilities', 'Income', 'Expenses', 'Equity'],
325
+ example: 'Assets'
326
+ },
327
+ i18nKey: {
328
+ type: 'string',
329
+ description: 'i18n key for localized display name',
330
+ example: 'account.assets.cn.bank.icbc.checking'
331
+ },
332
+ name: {
333
+ type: 'string',
334
+ description: 'Short localized display name',
335
+ example: 'Housing Fund'
336
+ },
337
+ description: {
338
+ type: 'string',
339
+ description: 'Account description (stable semantics only)',
340
+ example: 'ICBC checking account for daily transactions'
341
+ },
342
+ tags: {
343
+ description: 'Account tags for categorization',
344
+ example: ['bank', 'checking', 'primary'],
345
+ type: 'array',
346
+ items: {
347
+ type: 'string'
348
+ }
349
+ },
350
+ icon: {
351
+ type: 'string',
352
+ description: 'Icon identifier for UI display',
353
+ example: 'bank-icbc'
354
+ }
355
+ },
356
+ required: ['path', 'type', 'i18nKey', 'description', 'tags', 'icon']
357
+ } as const;
358
+
359
+ export const $AccountStandardListResponseDto = {
360
+ type: 'object',
361
+ properties: {
362
+ items: {
363
+ description: 'Array of account templates',
364
+ type: 'array',
365
+ items: {
366
+ $ref: '#/components/schemas/AccountStandardResponseDto'
367
+ }
368
+ },
369
+ total: {
370
+ type: 'number',
371
+ description: 'Total number of account templates',
372
+ example: 150
373
+ },
374
+ region: {
375
+ type: 'string',
376
+ description: 'Region code',
377
+ example: 'CN'
378
+ }
379
+ },
380
+ required: ['items', 'total', 'region']
381
+ } as const;
382
+
383
+ export const $TemplateMetadataDto = {
384
+ type: 'object',
385
+ properties: {
386
+ extendable: {
387
+ type: 'boolean',
388
+ description: 'Whether this path can be extended',
389
+ example: true
390
+ },
391
+ rootType: {
392
+ type: 'string',
393
+ description: 'Root account type',
394
+ example: 'Assets'
395
+ }
396
+ },
397
+ required: ['extendable', 'rootType']
398
+ } as const;
399
+
400
+ export const $TemplateMetadataResponseDto = {
401
+ type: 'object',
402
+ properties: {
403
+ metadata: {
404
+ $ref: '#/components/schemas/TemplateMetadataDto'
405
+ }
406
+ }
407
+ } as const;
408
+
409
+ export const $RegionConfigDto = {
410
+ type: 'object',
411
+ properties: {
412
+ currency: {
413
+ type: 'string',
414
+ example: 'EUR'
415
+ },
416
+ dateFormat: {
417
+ type: 'string',
418
+ example: 'DD.MM.YYYY'
419
+ },
420
+ locale: {
421
+ type: 'string',
422
+ example: 'de-DE'
423
+ }
424
+ },
425
+ required: ['currency', 'dateFormat', 'locale']
426
+ } as const;
427
+
428
+ export const $RegionInfoDto = {
429
+ type: 'object',
430
+ properties: {
431
+ code: {
432
+ type: 'string',
433
+ example: 'de'
434
+ },
435
+ displayName: {
436
+ type: 'string',
437
+ example: 'Germany'
438
+ },
439
+ parent: {
440
+ type: 'string'
441
+ },
442
+ chain: {
443
+ example: ['de'],
444
+ type: 'array',
445
+ items: {
446
+ type: 'string'
447
+ }
448
+ },
449
+ config: {
450
+ $ref: '#/components/schemas/RegionConfigDto'
451
+ }
452
+ },
453
+ required: ['code', 'displayName', 'chain', 'config']
454
+ } as const;
455
+
456
+ export const $RegionsMetadataResponseDto = {
457
+ type: 'object',
458
+ properties: {
459
+ regions: {
460
+ type: 'array',
461
+ items: {
462
+ $ref: '#/components/schemas/RegionInfoDto'
463
+ }
464
+ }
465
+ },
466
+ required: ['regions']
467
+ } as const;
468
+
295
469
  export const $CreatePostingDto = {
296
470
  type: 'object',
297
471
  properties: {
@@ -607,6 +781,65 @@ export const $ApiProblemResponseDto = {
607
781
  required: ['type', 'title', 'status', 'detail']
608
782
  } as const;
609
783
 
784
+ export const $BatchCreateTransactionDto = {
785
+ type: 'object',
786
+ properties: {
787
+ transactions: {
788
+ description: 'Array of transactions to create',
789
+ minItems: 1,
790
+ maxItems: 100,
791
+ type: 'array',
792
+ items: {
793
+ $ref: '#/components/schemas/CreateTransactionDto'
794
+ }
795
+ }
796
+ },
797
+ required: ['transactions']
798
+ } as const;
799
+
800
+ export const $BatchTransactionErrorDto = {
801
+ type: 'object',
802
+ properties: {
803
+ index: {
804
+ type: 'number',
805
+ description: 'Index of failed transaction in the input array',
806
+ example: 0
807
+ },
808
+ error: {
809
+ type: 'string',
810
+ description: 'Error message describing the failure',
811
+ example: 'Transaction does not balance'
812
+ },
813
+ errorCode: {
814
+ type: 'string',
815
+ description: 'Structured error code for programmatic handling',
816
+ example: 'INSUFFICIENT_QUANTITY'
817
+ }
818
+ },
819
+ required: ['index', 'error']
820
+ } as const;
821
+
822
+ export const $BatchTransactionResponseDto = {
823
+ type: 'object',
824
+ properties: {
825
+ succeeded: {
826
+ description: 'Successfully created transactions',
827
+ type: 'array',
828
+ items: {
829
+ $ref: '#/components/schemas/TransactionResponseDto'
830
+ }
831
+ },
832
+ failed: {
833
+ description: 'Failed transactions with error details',
834
+ type: 'array',
835
+ items: {
836
+ $ref: '#/components/schemas/BatchTransactionErrorDto'
837
+ }
838
+ }
839
+ },
840
+ required: ['succeeded', 'failed']
841
+ } as const;
842
+
610
843
  export const $PostingDetailDto = {
611
844
  type: 'object',
612
845
  properties: {
@@ -876,185 +1109,59 @@ export const $UpdateTransactionDto = {
876
1109
  }
877
1110
  } as const;
878
1111
 
879
- export const $AccountStandardResponseDto = {
1112
+ export const $BalanceResponseDto = {
880
1113
  type: 'object',
881
1114
  properties: {
882
- path: {
1115
+ account: {
883
1116
  type: 'string',
884
- description: 'Account path (hierarchical, colon-separated)',
885
- example: 'Assets:CN:Bank:ICBC:Checking'
1117
+ description: 'Account name',
1118
+ example: 'Assets:Bank:Checking'
886
1119
  },
887
- type: {
1120
+ balance: {
888
1121
  type: 'string',
889
- description: 'Account type in Beancount hierarchy',
890
- enum: ['Assets', 'Liabilities', 'Income', 'Expenses', 'Equity'],
891
- example: 'Assets'
1122
+ description: 'Balance amount (decimal string for precision)',
1123
+ example: '12345.67'
892
1124
  },
893
- i18nKey: {
1125
+ currency: {
894
1126
  type: 'string',
895
- description: 'i18n key for localized display name',
896
- example: 'account.assets.cn.bank.icbc.checking'
1127
+ description: 'Currency code',
1128
+ example: 'USD'
897
1129
  },
898
- description: {
1130
+ date: {
899
1131
  type: 'string',
900
- description: 'Account description',
901
- example: 'ICBC checking account for daily transactions'
1132
+ description: 'Date of the balance calculation (ISO 8601)',
1133
+ example: '2024-12-31T00:00:00.000Z'
1134
+ }
1135
+ },
1136
+ required: ['account', 'balance', 'currency', 'date']
1137
+ } as const;
1138
+
1139
+ export const $MultiCurrencyBalanceResponseDto = {
1140
+ type: 'object',
1141
+ properties: {
1142
+ account: {
1143
+ type: 'string',
1144
+ description: 'Account name',
1145
+ example: 'Assets:Bank:Checking'
902
1146
  },
903
- tags: {
904
- description: 'Account tags for categorization',
905
- example: ['bank', 'checking', 'primary'],
906
- type: 'array',
907
- items: {
908
- type: 'string'
1147
+ balances: {
1148
+ type: 'object',
1149
+ description: 'Balances by currency',
1150
+ example: {
1151
+ USD: '12345.67',
1152
+ CNY: '100000.00'
909
1153
  }
910
1154
  },
911
- icon: {
1155
+ date: {
912
1156
  type: 'string',
913
- description: 'Icon identifier for UI display',
914
- example: 'bank-icbc'
1157
+ description: 'Date of the balance calculation (ISO 8601)',
1158
+ example: '2024-12-31T00:00:00.000Z'
915
1159
  }
916
1160
  },
917
- required: ['path', 'type']
1161
+ required: ['account', 'balances', 'date']
918
1162
  } as const;
919
1163
 
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 $RegionConfigDto = {
945
- type: 'object',
946
- properties: {
947
- currency: {
948
- type: 'string',
949
- example: 'EUR'
950
- },
951
- dateFormat: {
952
- type: 'string',
953
- example: 'DD.MM.YYYY'
954
- },
955
- locale: {
956
- type: 'string',
957
- example: 'de-DE'
958
- }
959
- },
960
- required: ['currency', 'dateFormat', 'locale']
961
- } as const;
962
-
963
- export const $RegionInfoDto = {
964
- type: 'object',
965
- properties: {
966
- code: {
967
- type: 'string',
968
- example: 'de'
969
- },
970
- displayName: {
971
- type: 'string',
972
- example: 'Germany'
973
- },
974
- parent: {
975
- type: 'string',
976
- example: 'eu-core'
977
- },
978
- chain: {
979
- example: ['eu-core', 'de'],
980
- type: 'array',
981
- items: {
982
- type: 'string'
983
- }
984
- },
985
- config: {
986
- $ref: '#/components/schemas/RegionConfigDto'
987
- }
988
- },
989
- required: ['code', 'displayName', 'chain', 'config']
990
- } as const;
991
-
992
- export const $RegionsMetadataResponseDto = {
993
- type: 'object',
994
- properties: {
995
- regions: {
996
- type: 'array',
997
- items: {
998
- $ref: '#/components/schemas/RegionInfoDto'
999
- }
1000
- }
1001
- },
1002
- required: ['regions']
1003
- } as const;
1004
-
1005
- export const $BalanceResponseDto = {
1006
- type: 'object',
1007
- properties: {
1008
- account: {
1009
- type: 'string',
1010
- description: 'Account name',
1011
- example: 'Assets:Bank:Checking'
1012
- },
1013
- balance: {
1014
- type: 'string',
1015
- description: 'Balance amount (decimal string for precision)',
1016
- example: '12345.67'
1017
- },
1018
- currency: {
1019
- type: 'string',
1020
- description: 'Currency code',
1021
- example: 'USD'
1022
- },
1023
- date: {
1024
- type: 'string',
1025
- description: 'Date of the balance calculation (ISO 8601)',
1026
- example: '2024-12-31T00:00:00.000Z'
1027
- }
1028
- },
1029
- required: ['account', 'balance', 'currency', 'date']
1030
- } as const;
1031
-
1032
- export const $MultiCurrencyBalanceResponseDto = {
1033
- type: 'object',
1034
- properties: {
1035
- account: {
1036
- type: 'string',
1037
- description: 'Account name',
1038
- example: 'Assets:Bank:Checking'
1039
- },
1040
- balances: {
1041
- type: 'object',
1042
- description: 'Balances by currency',
1043
- example: {
1044
- USD: '12345.67',
1045
- CNY: '100000.00'
1046
- }
1047
- },
1048
- date: {
1049
- type: 'string',
1050
- description: 'Date of the balance calculation (ISO 8601)',
1051
- example: '2024-12-31T00:00:00.000Z'
1052
- }
1053
- },
1054
- required: ['account', 'balances', 'date']
1055
- } as const;
1056
-
1057
- export const $TransactionSummaryDto = {
1164
+ export const $TransactionSummaryDto = {
1058
1165
  type: 'object',
1059
1166
  properties: {
1060
1167
  id: {
@@ -1418,154 +1525,495 @@ export const $ReviewDetailDto = {
1418
1525
  ]
1419
1526
  } as const;
1420
1527
 
1421
- export const $PayeeResponseDto = {
1528
+ export const $ResolveReviewDto = {
1422
1529
  type: 'object',
1423
1530
  properties: {
1424
- id: {
1531
+ action: {
1425
1532
  type: 'string',
1426
- description: 'Unique identifier (UUID)',
1427
- example: 'uuid-123-456'
1533
+ description:
1534
+ 'Decision action. Available actions vary by review type: DUPLICATE: UPGRADE_REPLACE, KEEP_EXISTING, KEEP_BOTH | PAYEE_MATCH: ACCEPT, REJECT, ACCEPT_AND_LEARN | ACCOUNT_VALIDATION: FIX, REJECT | RULE_MATCH: ACCEPT, REJECT, ACCEPT_AND_LEARN',
1535
+ example: 'ACCEPT'
1428
1536
  },
1429
- userId: {
1430
- type: 'string',
1431
- description: 'User ID (owner of this payee mapping)',
1432
- example: 'user-123'
1537
+ data: {
1538
+ type: 'object',
1539
+ description:
1540
+ 'Additional data for the decision (e.g., selected account ID)',
1541
+ example: {
1542
+ accountId: 'acc-123'
1543
+ }
1544
+ }
1545
+ },
1546
+ required: ['action']
1547
+ } as const;
1548
+
1549
+ export const $ResolveResultDto = {
1550
+ type: 'object',
1551
+ properties: {
1552
+ success: {
1553
+ type: 'boolean',
1554
+ description: 'Whether resolution was successful'
1433
1555
  },
1434
- payee: {
1556
+ messageKey: {
1435
1557
  type: 'string',
1436
- description: "User's original payee name (e.g., 'Starbucks', 'McDonald')",
1437
- example: 'Starbucks'
1438
- },
1439
- payeeProfileId: {
1440
- type: 'object',
1441
1558
  description:
1442
- 'Reference to global PayeeProfile (merchant info, i18n keys, categories)',
1443
- example: 'uuid-789',
1444
- nullable: true
1559
+ 'i18n message key for result message (e.g., review.payee.result.mapped)'
1445
1560
  },
1446
- customCategory: {
1561
+ messageParams: {
1447
1562
  type: 'object',
1448
1563
  description:
1449
- "User's custom category (overrides PayeeProfile category if set)",
1450
- example: 'Dining:Coffee',
1451
- nullable: true
1452
- },
1453
- customTags: {
1454
- description: "User's custom tags (e.g., ['favorite', 'work_meal'])",
1455
- example: ['favorite', 'work_meal'],
1456
- type: 'array',
1457
- items: {
1564
+ 'Parameters for message interpolation (e.g., { name: "PayeeName" })',
1565
+ additionalProperties: {
1458
1566
  type: 'string'
1459
1567
  }
1460
1568
  },
1461
- useCount: {
1462
- type: 'number',
1463
- description:
1464
- 'Usage count (number of times this payee was used in transactions)',
1465
- example: 42
1569
+ resolutionId: {
1570
+ type: 'string',
1571
+ description: 'Resolution ID for undo'
1466
1572
  },
1467
- lastUsedAt: {
1573
+ canUndo: {
1574
+ type: 'boolean',
1575
+ description: 'Whether this decision can be undone'
1576
+ },
1577
+ undoDeadline: {
1468
1578
  format: 'date-time',
1469
1579
  type: 'string',
1470
- description: 'Last used timestamp',
1471
- example: '2024-11-20T10:00:00Z'
1472
- },
1473
- meta: {
1474
- type: 'object',
1475
- description: 'Extended metadata (location, notes, contact info, etc.)',
1476
- example: {
1477
- location: 'Zhongguancun',
1478
- note: 'Near subway station',
1479
- favorite: true
1480
- }
1580
+ description: 'Deadline for undo (24h from resolution)'
1481
1581
  },
1482
- isActive: {
1582
+ learnedRuleId: {
1583
+ type: 'string',
1584
+ description:
1585
+ 'Rule ID if learning was triggered (ACCEPT_AND_LEARN actions). Use this to deep-link to the rule management page.',
1586
+ example: 'rule_01HXK5V8N2M3P4Q5R6S7T8U9V0'
1587
+ }
1588
+ },
1589
+ required: ['success', 'resolutionId', 'canUndo', 'undoDeadline']
1590
+ } as const;
1591
+
1592
+ export const $UndoResultDto = {
1593
+ type: 'object',
1594
+ properties: {
1595
+ success: {
1483
1596
  type: 'boolean',
1484
- description: 'Active status (inactive payees hidden from autocomplete)',
1485
- example: true
1597
+ description: 'Whether undo was successful'
1486
1598
  },
1487
- createdAt: {
1488
- format: 'date-time',
1599
+ message: {
1489
1600
  type: 'string',
1490
- description: 'Creation timestamp (first time this payee was used)',
1491
- example: '2024-01-01T10:00:00Z'
1601
+ description: 'Message'
1492
1602
  },
1493
- updatedAt: {
1494
- format: 'date-time',
1603
+ reviewId: {
1495
1604
  type: 'string',
1496
- description: 'Last update timestamp',
1497
- example: '2024-11-20T10:00:00Z'
1605
+ description: 'Review item ID that was restored'
1498
1606
  }
1499
1607
  },
1500
- required: [
1501
- 'id',
1502
- 'userId',
1503
- 'payee',
1504
- 'customTags',
1505
- 'useCount',
1506
- 'lastUsedAt',
1507
- 'meta',
1508
- 'isActive',
1509
- 'createdAt',
1510
- 'updatedAt'
1511
- ]
1608
+ required: ['success', 'reviewId']
1512
1609
  } as const;
1513
1610
 
1514
- export const $PayeeListResponseDto = {
1611
+ export const $BatchResolveDto = {
1515
1612
  type: 'object',
1516
1613
  properties: {
1517
- items: {
1518
- description: 'List of payees',
1614
+ reviewIds: {
1615
+ description: 'Review item IDs to resolve',
1616
+ example: ['review-1', 'review-2', 'review-3'],
1519
1617
  type: 'array',
1520
1618
  items: {
1521
- $ref: '#/components/schemas/PayeeResponseDto'
1619
+ type: 'string'
1522
1620
  }
1523
1621
  },
1524
- total: {
1525
- type: 'number',
1526
- description: 'Total number of payees',
1527
- example: 42
1622
+ action: {
1623
+ type: 'string',
1624
+ description: 'Decision action to apply to all items',
1625
+ example: 'ACCEPT'
1626
+ },
1627
+ data: {
1628
+ type: 'object',
1629
+ description: 'Additional data for the decision'
1528
1630
  }
1529
1631
  },
1530
- required: ['items', 'total']
1632
+ required: ['reviewIds', 'action']
1531
1633
  } as const;
1532
1634
 
1533
- export const $PayeeAutocompleteResponseDto = {
1635
+ export const $BatchResolveResultDto = {
1534
1636
  type: 'object',
1535
1637
  properties: {
1536
- suggestions: {
1537
- description: 'List of matching payee names',
1538
- example: ['Starbucks', 'Starbucks Coffee', 'Starbucks Reserve'],
1638
+ successCount: {
1639
+ type: 'number',
1640
+ description: 'Number of successfully resolved items'
1641
+ },
1642
+ failedCount: {
1643
+ type: 'number',
1644
+ description: 'Number of failed items'
1645
+ },
1646
+ results: {
1647
+ description: 'Details for each item',
1539
1648
  type: 'array',
1540
1649
  items: {
1541
1650
  type: 'string'
1542
1651
  }
1543
1652
  }
1544
1653
  },
1545
- required: ['suggestions']
1654
+ required: ['successCount', 'failedCount', 'results']
1546
1655
  } as const;
1547
1656
 
1548
- export const $PayeeStatsResponseDto = {
1657
+ export const $CreatePayeeDto = {
1549
1658
  type: 'object',
1550
1659
  properties: {
1551
1660
  payee: {
1552
1661
  type: 'string',
1553
- description: 'Payee name',
1554
- example: 'Starbucks'
1555
- },
1662
+ description:
1663
+ "User's original payee name (e.g., 'Starbucks', 'McDonald'). This is the raw payee string as entered by the user.",
1664
+ example: 'Starbucks',
1665
+ maxLength: 200
1666
+ },
1667
+ payeeProfileId: {
1668
+ type: 'string',
1669
+ description:
1670
+ 'Optional reference to global PayeeProfile for standardized data (merchant info, i18n keys, categories)',
1671
+ example: 'uuid-123',
1672
+ format: 'uuid'
1673
+ },
1674
+ customCategory: {
1675
+ type: 'string',
1676
+ description:
1677
+ "User's custom category for this payee (overrides PayeeProfile category)",
1678
+ example: 'Dining:Coffee',
1679
+ maxLength: 100
1680
+ },
1681
+ customTags: {
1682
+ description:
1683
+ "User's custom tags for this payee (e.g., ['favorite', 'work_meal'])",
1684
+ example: ['favorite', 'work_meal'],
1685
+ type: 'array',
1686
+ items: {
1687
+ type: 'string'
1688
+ }
1689
+ },
1690
+ meta: {
1691
+ type: 'object',
1692
+ description:
1693
+ 'Metadata for extended information (location, notes, contact info, etc.)',
1694
+ example: {
1695
+ location: 'Zhongguancun',
1696
+ note: 'Near subway station',
1697
+ favorite: true
1698
+ }
1699
+ }
1700
+ },
1701
+ required: ['payee']
1702
+ } as const;
1703
+
1704
+ export const $PayeeResponseDto = {
1705
+ type: 'object',
1706
+ properties: {
1707
+ id: {
1708
+ type: 'string',
1709
+ description: 'Unique identifier (UUID)',
1710
+ example: 'uuid-123-456'
1711
+ },
1712
+ userId: {
1713
+ type: 'string',
1714
+ description: 'User ID (owner of this payee mapping)',
1715
+ example: 'user-123'
1716
+ },
1717
+ payee: {
1718
+ type: 'string',
1719
+ description: "User's original payee name (e.g., 'Starbucks', 'McDonald')",
1720
+ example: 'Starbucks'
1721
+ },
1722
+ payeeProfileId: {
1723
+ type: 'string',
1724
+ description:
1725
+ 'Reference to global PayeeProfile (merchant info, i18n keys, categories)',
1726
+ example: 'uuid-789',
1727
+ nullable: true
1728
+ },
1729
+ customCategory: {
1730
+ type: 'string',
1731
+ description:
1732
+ "User's custom category (overrides PayeeProfile category if set)",
1733
+ example: 'Dining:Coffee',
1734
+ nullable: true
1735
+ },
1736
+ customTags: {
1737
+ description: "User's custom tags (e.g., ['favorite', 'work_meal'])",
1738
+ example: ['favorite', 'work_meal'],
1739
+ type: 'array',
1740
+ items: {
1741
+ type: 'string'
1742
+ }
1743
+ },
1744
+ useCount: {
1745
+ type: 'number',
1746
+ description:
1747
+ 'Usage count (number of times this payee was used in transactions)',
1748
+ example: 42
1749
+ },
1750
+ lastUsedAt: {
1751
+ format: 'date-time',
1752
+ type: 'string',
1753
+ description: 'Last used timestamp',
1754
+ example: '2024-11-20T10:00:00Z'
1755
+ },
1756
+ meta: {
1757
+ type: 'object',
1758
+ description: 'Extended metadata (location, notes, contact info, etc.)',
1759
+ example: {
1760
+ location: 'Zhongguancun',
1761
+ note: 'Near subway station',
1762
+ favorite: true
1763
+ }
1764
+ },
1765
+ isActive: {
1766
+ type: 'boolean',
1767
+ description: 'Active status (inactive payees hidden from autocomplete)',
1768
+ example: true
1769
+ },
1770
+ createdAt: {
1771
+ format: 'date-time',
1772
+ type: 'string',
1773
+ description: 'Creation timestamp (first time this payee was used)',
1774
+ example: '2024-01-01T10:00:00Z'
1775
+ },
1776
+ updatedAt: {
1777
+ format: 'date-time',
1778
+ type: 'string',
1779
+ description: 'Last update timestamp',
1780
+ example: '2024-11-20T10:00:00Z'
1781
+ }
1782
+ },
1783
+ required: [
1784
+ 'id',
1785
+ 'userId',
1786
+ 'payee',
1787
+ 'customTags',
1788
+ 'useCount',
1789
+ 'lastUsedAt',
1790
+ 'meta',
1791
+ 'isActive',
1792
+ 'createdAt',
1793
+ 'updatedAt'
1794
+ ]
1795
+ } as const;
1796
+
1797
+ export const $PayeeListResponseDto = {
1798
+ type: 'object',
1799
+ properties: {
1800
+ items: {
1801
+ description: 'List of payees',
1802
+ type: 'array',
1803
+ items: {
1804
+ $ref: '#/components/schemas/PayeeResponseDto'
1805
+ }
1806
+ },
1807
+ total: {
1808
+ type: 'number',
1809
+ description: 'Total number of payees',
1810
+ example: 42
1811
+ }
1812
+ },
1813
+ required: ['items', 'total']
1814
+ } as const;
1815
+
1816
+ export const $PayeeAutocompleteResponseDto = {
1817
+ type: 'object',
1818
+ properties: {
1819
+ suggestions: {
1820
+ description: 'List of matching payee names',
1821
+ example: ['Starbucks', 'Starbucks Coffee', 'Starbucks Reserve'],
1822
+ type: 'array',
1823
+ items: {
1824
+ type: 'string'
1825
+ }
1826
+ }
1827
+ },
1828
+ required: ['suggestions']
1829
+ } as const;
1830
+
1831
+ export const $PayeeStatsResponseDto = {
1832
+ type: 'object',
1833
+ properties: {
1834
+ payee: {
1835
+ type: 'string',
1836
+ description: 'Payee name',
1837
+ example: 'Starbucks'
1838
+ },
1556
1839
  transactionCount: {
1557
1840
  type: 'number',
1558
1841
  description: 'Total transaction count',
1559
1842
  example: 42
1560
1843
  },
1561
- lastUsedAt: {
1562
- format: 'date-time',
1844
+ lastUsedAt: {
1845
+ format: 'date-time',
1846
+ type: 'string',
1847
+ description: 'Last used timestamp',
1848
+ example: '2024-11-20T10:00:00Z'
1849
+ }
1850
+ },
1851
+ required: ['payee', 'transactionCount', 'lastUsedAt']
1852
+ } as const;
1853
+
1854
+ export const $UpdatePayeeDto = {
1855
+ type: 'object',
1856
+ properties: {
1857
+ payeeProfileId: {
1858
+ type: 'string',
1859
+ description:
1860
+ 'Optional reference to global PayeeProfile for standardized data (merchant info, i18n keys, categories)',
1861
+ example: 'uuid-123',
1862
+ format: 'uuid'
1863
+ },
1864
+ customCategory: {
1865
+ type: 'string',
1866
+ description:
1867
+ "User's custom category for this payee (overrides PayeeProfile category)",
1868
+ example: 'Dining:Coffee',
1869
+ maxLength: 100
1870
+ },
1871
+ customTags: {
1872
+ description:
1873
+ "User's custom tags for this payee (e.g., ['favorite', 'work_meal'])",
1874
+ example: ['favorite', 'work_meal'],
1875
+ type: 'array',
1876
+ items: {
1877
+ type: 'string'
1878
+ }
1879
+ },
1880
+ meta: {
1881
+ type: 'object',
1882
+ description:
1883
+ 'Metadata for extended information (location, notes, contact info, etc.). Will merge with existing metadata.',
1884
+ example: {
1885
+ location: 'Zhongguancun',
1886
+ note: 'Updated note',
1887
+ favorite: true
1888
+ }
1889
+ },
1890
+ isActive: {
1891
+ type: 'boolean',
1892
+ description:
1893
+ 'Enable or disable this payee. Disabled payees will not appear in autocomplete suggestions.',
1894
+ example: true
1895
+ }
1896
+ }
1897
+ } as const;
1898
+
1899
+ export const $CreatePayeeProfileDto = {
1900
+ type: 'object',
1901
+ properties: {
1902
+ canonical: {
1903
+ type: 'string',
1904
+ description:
1905
+ 'Canonical payee name (unique, case-insensitive). This is the primary identifier for the payee.',
1906
+ example: 'Starbucks',
1907
+ maxLength: 200
1908
+ },
1909
+ aliases: {
1910
+ description:
1911
+ 'Multi-language aliases for the payee. Used for matching user input in different languages.',
1912
+ example: ['Starbucks Coffee', 'SBUX'],
1913
+ type: 'array',
1914
+ items: {
1915
+ type: 'string'
1916
+ }
1917
+ },
1918
+ i18nKey: {
1919
+ type: 'string',
1920
+ description:
1921
+ 'Translation key for i18n integration (XLIFF translation system)',
1922
+ example: 'payee.starbucks',
1923
+ maxLength: 100
1924
+ },
1925
+ category: {
1926
+ type: 'string',
1927
+ description: 'Payee category classification',
1928
+ enum: [
1929
+ 'RESTAURANT',
1930
+ 'CAFE',
1931
+ 'FAST_FOOD',
1932
+ 'BAR',
1933
+ 'SUPERMARKET',
1934
+ 'CONVENIENCE_STORE',
1935
+ 'SHOPPING_MALL',
1936
+ 'ONLINE_SHOPPING',
1937
+ 'TAXI',
1938
+ 'RIDE_SHARING',
1939
+ 'PUBLIC_TRANSPORT',
1940
+ 'PARKING',
1941
+ 'GAS_STATION',
1942
+ 'UTILITIES',
1943
+ 'TELECOM',
1944
+ 'STREAMING',
1945
+ 'HEALTHCARE',
1946
+ 'EDUCATION',
1947
+ 'ENTERTAINMENT',
1948
+ 'SPORTS',
1949
+ 'TRAVEL',
1950
+ 'HOTEL',
1951
+ 'OTHER'
1952
+ ],
1953
+ example: 'CAFE'
1954
+ },
1955
+ subCategory: {
1956
+ type: 'string',
1957
+ description: 'Sub-category for more specific classification',
1958
+ example: 'coffee_chain',
1959
+ maxLength: 100
1960
+ },
1961
+ countries: {
1962
+ description:
1963
+ 'Country/region codes where the payee operates (ISO 3166-1 alpha-2)',
1964
+ example: ['CN', 'US', 'JP'],
1965
+ type: 'array',
1966
+ items: {
1967
+ type: 'string'
1968
+ }
1969
+ },
1970
+ primaryCountry: {
1971
+ type: 'string',
1972
+ description: 'Primary operating country (ISO 3166-1 alpha-2)',
1973
+ example: 'US',
1974
+ maxLength: 2
1975
+ },
1976
+ keywords: {
1977
+ description: 'Search keywords for fuzzy matching',
1978
+ example: ['coffee', 'cafe', 'drinks'],
1979
+ type: 'array',
1980
+ items: {
1981
+ type: 'string'
1982
+ }
1983
+ },
1984
+ logoUrl: {
1563
1985
  type: 'string',
1564
- description: 'Last used timestamp',
1565
- example: '2024-11-20T10:00:00Z'
1986
+ description: 'Payee logo URL',
1987
+ example: 'https://example.com/logo.png'
1988
+ },
1989
+ website: {
1990
+ type: 'string',
1991
+ description: 'Official website URL',
1992
+ example: 'https://www.starbucks.com'
1993
+ },
1994
+ description: {
1995
+ type: 'string',
1996
+ description: 'Payee description',
1997
+ example: 'Global coffeehouse chain headquartered in Seattle',
1998
+ maxLength: 1000
1999
+ },
2000
+ meta: {
2001
+ type: 'object',
2002
+ description:
2003
+ 'Extended metadata (business hours, contact info, additional details)',
2004
+ example: {
2005
+ businessHours: '07:00-22:00',
2006
+ phone: '+1-800-782-7282'
2007
+ }
2008
+ },
2009
+ dataSource: {
2010
+ type: 'string',
2011
+ description: 'Data source for this profile',
2012
+ enum: ['MANUAL', 'IMPORT', 'API', 'CROWDSOURCED'],
2013
+ default: 'MANUAL'
1566
2014
  }
1567
2015
  },
1568
- required: ['payee', 'transactionCount', 'lastUsedAt']
2016
+ required: ['canonical', 'category']
1569
2017
  } as const;
1570
2018
 
1571
2019
  export const $PayeeProfileResponseDto = {
@@ -1590,7 +2038,7 @@ export const $PayeeProfileResponseDto = {
1590
2038
  }
1591
2039
  },
1592
2040
  i18nKey: {
1593
- type: 'object',
2041
+ type: 'string',
1594
2042
  description: 'Translation key for i18n',
1595
2043
  example: 'payee.starbucks',
1596
2044
  nullable: true
@@ -1626,7 +2074,7 @@ export const $PayeeProfileResponseDto = {
1626
2074
  example: 'CAFE'
1627
2075
  },
1628
2076
  subCategory: {
1629
- type: 'object',
2077
+ type: 'string',
1630
2078
  description: 'Sub-category',
1631
2079
  example: 'coffee_chain',
1632
2080
  nullable: true
@@ -1640,7 +2088,7 @@ export const $PayeeProfileResponseDto = {
1640
2088
  }
1641
2089
  },
1642
2090
  primaryCountry: {
1643
- type: 'object',
2091
+ type: 'string',
1644
2092
  description: 'Primary operating country',
1645
2093
  example: 'US',
1646
2094
  nullable: true
@@ -1654,19 +2102,19 @@ export const $PayeeProfileResponseDto = {
1654
2102
  }
1655
2103
  },
1656
2104
  logoUrl: {
1657
- type: 'object',
2105
+ type: 'string',
1658
2106
  description: 'Logo URL',
1659
2107
  example: 'https://example.com/logo.png',
1660
2108
  nullable: true
1661
2109
  },
1662
2110
  website: {
1663
- type: 'object',
2111
+ type: 'string',
1664
2112
  description: 'Official website',
1665
2113
  example: 'https://www.starbucks.com',
1666
2114
  nullable: true
1667
2115
  },
1668
2116
  description: {
1669
- type: 'object',
2117
+ type: 'string',
1670
2118
  description: 'Description',
1671
2119
  example: 'Global coffeehouse chain',
1672
2120
  nullable: true
@@ -1682,9 +2130,10 @@ export const $PayeeProfileResponseDto = {
1682
2130
  example: 'MANUAL'
1683
2131
  },
1684
2132
  verifiedAt: {
1685
- type: 'object',
2133
+ type: 'string',
1686
2134
  description: 'Verification timestamp (null if not verified)',
1687
2135
  example: '2025-01-01T00:00:00.000Z',
2136
+ format: 'date-time',
1688
2137
  nullable: true
1689
2138
  },
1690
2139
  isActive: {
@@ -1739,6 +2188,164 @@ export const $PayeeProfileListResponseDto = {
1739
2188
  required: ['items', 'total']
1740
2189
  } as const;
1741
2190
 
2191
+ export const $UpdatePayeeProfileDto = {
2192
+ type: 'object',
2193
+ properties: {
2194
+ aliases: {
2195
+ description:
2196
+ 'Multi-language aliases for the payee. Used for matching user input in different languages.',
2197
+ example: ['Starbucks Coffee', 'SBUX'],
2198
+ type: 'array',
2199
+ items: {
2200
+ type: 'string'
2201
+ }
2202
+ },
2203
+ i18nKey: {
2204
+ type: 'string',
2205
+ description:
2206
+ 'Translation key for i18n integration (XLIFF translation system)',
2207
+ example: 'payee.starbucks',
2208
+ maxLength: 100
2209
+ },
2210
+ category: {
2211
+ type: 'string',
2212
+ description: 'Payee category classification',
2213
+ enum: [
2214
+ 'RESTAURANT',
2215
+ 'CAFE',
2216
+ 'FAST_FOOD',
2217
+ 'BAR',
2218
+ 'SUPERMARKET',
2219
+ 'CONVENIENCE_STORE',
2220
+ 'SHOPPING_MALL',
2221
+ 'ONLINE_SHOPPING',
2222
+ 'TAXI',
2223
+ 'RIDE_SHARING',
2224
+ 'PUBLIC_TRANSPORT',
2225
+ 'PARKING',
2226
+ 'GAS_STATION',
2227
+ 'UTILITIES',
2228
+ 'TELECOM',
2229
+ 'STREAMING',
2230
+ 'HEALTHCARE',
2231
+ 'EDUCATION',
2232
+ 'ENTERTAINMENT',
2233
+ 'SPORTS',
2234
+ 'TRAVEL',
2235
+ 'HOTEL',
2236
+ 'OTHER'
2237
+ ],
2238
+ example: 'CAFE'
2239
+ },
2240
+ subCategory: {
2241
+ type: 'string',
2242
+ description: 'Sub-category for more specific classification',
2243
+ example: 'coffee_chain',
2244
+ maxLength: 100
2245
+ },
2246
+ countries: {
2247
+ description:
2248
+ 'Country/region codes where the payee operates (ISO 3166-1 alpha-2)',
2249
+ example: ['CN', 'US', 'JP'],
2250
+ type: 'array',
2251
+ items: {
2252
+ type: 'string'
2253
+ }
2254
+ },
2255
+ primaryCountry: {
2256
+ type: 'string',
2257
+ description: 'Primary operating country (ISO 3166-1 alpha-2)',
2258
+ example: 'US',
2259
+ maxLength: 2
2260
+ },
2261
+ keywords: {
2262
+ description: 'Search keywords for fuzzy matching',
2263
+ example: ['coffee', 'cafe', 'drinks'],
2264
+ type: 'array',
2265
+ items: {
2266
+ type: 'string'
2267
+ }
2268
+ },
2269
+ logoUrl: {
2270
+ type: 'string',
2271
+ description: 'Payee logo URL',
2272
+ example: 'https://example.com/logo.png'
2273
+ },
2274
+ website: {
2275
+ type: 'string',
2276
+ description: 'Official website URL',
2277
+ example: 'https://www.starbucks.com'
2278
+ },
2279
+ description: {
2280
+ type: 'string',
2281
+ description: 'Payee description',
2282
+ example: 'Global coffeehouse chain headquartered in Seattle',
2283
+ maxLength: 1000
2284
+ },
2285
+ meta: {
2286
+ type: 'object',
2287
+ description:
2288
+ 'Extended metadata (business hours, contact info, additional details)',
2289
+ example: {
2290
+ businessHours: '07:00-22:00',
2291
+ phone: '+1-800-782-7282'
2292
+ }
2293
+ },
2294
+ dataSource: {
2295
+ type: 'string',
2296
+ description: 'Data source for this profile',
2297
+ enum: ['MANUAL', 'IMPORT', 'API', 'CROWDSOURCED'],
2298
+ default: 'MANUAL'
2299
+ },
2300
+ isActive: {
2301
+ type: 'boolean',
2302
+ description: 'Whether the payee profile is active (soft delete)',
2303
+ example: true
2304
+ },
2305
+ verifiedAt: {
2306
+ type: 'string',
2307
+ description:
2308
+ 'Verification timestamp. Set to current time to verify, or null to unverify.',
2309
+ example: '2025-01-01T00:00:00.000Z',
2310
+ format: 'date-time',
2311
+ nullable: true
2312
+ }
2313
+ }
2314
+ } as const;
2315
+
2316
+ export const $CreateCommodityDto = {
2317
+ type: 'object',
2318
+ properties: {
2319
+ symbol: {
2320
+ type: 'string',
2321
+ description:
2322
+ 'Commodity symbol (e.g., AAPL, USD, BTC) - corresponds to Beancount currency field',
2323
+ example: 'AAPL',
2324
+ maxLength: 50
2325
+ },
2326
+ date: {
2327
+ type: 'string',
2328
+ description:
2329
+ 'Commodity definition date (ISO 8601, required per Beancount spec). Represents when this commodity was first defined in the accounting system.',
2330
+ example: '2024-01-01',
2331
+ format: 'date'
2332
+ },
2333
+ metadata: {
2334
+ type: 'object',
2335
+ description:
2336
+ 'Metadata (corresponds to Beancount meta field). Can contain name, assetClass, precision, note, tags, etc.',
2337
+ example: {
2338
+ name: 'Apple Inc.',
2339
+ assetClass: 'stock',
2340
+ precision: 2,
2341
+ note: 'Long-term investment',
2342
+ tags: ['tech', 'dividend']
2343
+ }
2344
+ }
2345
+ },
2346
+ required: ['symbol', 'date']
2347
+ } as const;
2348
+
1742
2349
  export const $CommodityResponseDto = {
1743
2350
  type: 'object',
1744
2351
  properties: {
@@ -1748,7 +2355,7 @@ export const $CommodityResponseDto = {
1748
2355
  example: 'uuid-123-456'
1749
2356
  },
1750
2357
  userId: {
1751
- type: 'object',
2358
+ type: 'string',
1752
2359
  description: 'User ID (owner of the commodity)',
1753
2360
  example: 'user-123',
1754
2361
  nullable: true
@@ -1777,13 +2384,6 @@ export const $CommodityResponseDto = {
1777
2384
  source: 'AUTO_CREATED'
1778
2385
  }
1779
2386
  },
1780
- symbolProfileId: {
1781
- type: 'object',
1782
- description:
1783
- 'Reference to SymbolProfile (market data integration, SaaS feature)',
1784
- example: 'uuid-789',
1785
- nullable: true
1786
- },
1787
2387
  createdAt: {
1788
2388
  format: 'date-time',
1789
2389
  type: 'string',
@@ -1810,13 +2410,137 @@ export const $CommodityListResponseDto = {
1810
2410
  $ref: '#/components/schemas/CommodityResponseDto'
1811
2411
  }
1812
2412
  },
1813
- total: {
1814
- type: 'number',
1815
- description: 'Total number of commodities',
1816
- example: 42
2413
+ total: {
2414
+ type: 'number',
2415
+ description: 'Total number of commodities',
2416
+ example: 42
2417
+ }
2418
+ },
2419
+ required: ['items', 'total']
2420
+ } as const;
2421
+
2422
+ export const $UpdateCommodityDto = {
2423
+ type: 'object',
2424
+ properties: {
2425
+ date: {
2426
+ type: 'string',
2427
+ description:
2428
+ 'Commodity definition date (ISO 8601). Represents when this commodity was first defined in the accounting system.',
2429
+ example: '2024-01-01',
2430
+ format: 'date'
2431
+ },
2432
+ metadata: {
2433
+ type: 'object',
2434
+ description:
2435
+ 'Metadata (corresponds to Beancount meta field). Will merge with existing metadata. Can contain name, assetClass, precision, note, tags, etc.',
2436
+ example: {
2437
+ name: 'Updated Apple Inc.',
2438
+ assetClass: 'equity',
2439
+ precision: 4,
2440
+ note: 'Updated investment strategy',
2441
+ lastReviewed: '2024-11-03'
2442
+ }
2443
+ }
2444
+ }
2445
+ } as const;
2446
+
2447
+ export const $CreateRecurringRuleDto = {
2448
+ type: 'object',
2449
+ properties: {
2450
+ name: {
2451
+ type: 'string',
2452
+ description: 'Rule name (unique per user)',
2453
+ maxLength: 100
2454
+ },
2455
+ icon: {
2456
+ type: 'string',
2457
+ description: 'Icon emoji',
2458
+ maxLength: 10
2459
+ },
2460
+ frequency: {
2461
+ type: 'string',
2462
+ description: 'Recurring frequency',
2463
+ enum: [
2464
+ 'WEEKLY',
2465
+ 'BIWEEKLY',
2466
+ 'MONTHLY',
2467
+ 'BIMONTHLY',
2468
+ 'QUARTERLY',
2469
+ 'YEARLY',
2470
+ 'CUSTOM'
2471
+ ]
2472
+ },
2473
+ expectedAmount: {
2474
+ type: 'number',
2475
+ description: 'Expected amount (positive number)',
2476
+ minimum: 0
2477
+ },
2478
+ expectedDay: {
2479
+ type: 'number',
2480
+ description: 'Expected day of month (1-31)',
2481
+ minimum: 1,
2482
+ maximum: 31
2483
+ },
2484
+ customIntervalDays: {
2485
+ type: 'number',
2486
+ description: 'Custom interval in days (required for CUSTOM frequency)',
2487
+ minimum: 1
2488
+ },
2489
+ currency: {
2490
+ type: 'string',
2491
+ description: 'Currency code',
2492
+ default: 'CNY',
2493
+ maxLength: 10
2494
+ },
2495
+ matchPayeePattern: {
2496
+ type: 'string',
2497
+ description: 'Payee matching pattern (supports wildcards)',
2498
+ maxLength: 200
2499
+ },
2500
+ matchAmountTolerance: {
2501
+ type: 'number',
2502
+ description: 'Amount tolerance percentage (0-1)',
2503
+ default: 0.075,
2504
+ minimum: 0,
2505
+ maximum: 1
2506
+ },
2507
+ defaultExpenseAccount: {
2508
+ type: 'string',
2509
+ description: 'Default expense account for auto-create',
2510
+ maxLength: 200
2511
+ },
2512
+ defaultPaymentAccount: {
2513
+ type: 'string',
2514
+ description: 'Default payment account for auto-create',
2515
+ maxLength: 200
2516
+ },
2517
+ defaultPayee: {
2518
+ type: 'string',
2519
+ description: 'Default payee for auto-create',
2520
+ maxLength: 200
2521
+ },
2522
+ autoCreate: {
2523
+ type: 'boolean',
2524
+ description: 'Auto-create transaction when expected date arrives',
2525
+ default: false
2526
+ },
2527
+ startDate: {
2528
+ type: 'string',
2529
+ description: 'Rule start date (ISO format)'
2530
+ },
2531
+ endDate: {
2532
+ type: 'string',
2533
+ description: 'Rule end date (ISO format)'
1817
2534
  }
1818
2535
  },
1819
- required: ['items', 'total']
2536
+ required: [
2537
+ 'name',
2538
+ 'frequency',
2539
+ 'expectedAmount',
2540
+ 'currency',
2541
+ 'matchAmountTolerance',
2542
+ 'autoCreate'
2543
+ ]
1820
2544
  } as const;
1821
2545
 
1822
2546
  export const $RecurringRuleResponseDto = {
@@ -1930,6 +2654,37 @@ export const $RecurringRuleResponseDto = {
1930
2654
  ]
1931
2655
  } as const;
1932
2656
 
2657
+ export const $CreateRuleFromTransactionDto = {
2658
+ type: 'object',
2659
+ properties: {
2660
+ frequency: {
2661
+ type: 'string',
2662
+ description: 'Recurring frequency',
2663
+ enum: [
2664
+ 'WEEKLY',
2665
+ 'BIWEEKLY',
2666
+ 'MONTHLY',
2667
+ 'BIMONTHLY',
2668
+ 'QUARTERLY',
2669
+ 'YEARLY',
2670
+ 'CUSTOM'
2671
+ ],
2672
+ example: 'MONTHLY'
2673
+ },
2674
+ name: {
2675
+ type: 'string',
2676
+ description: 'Optional name override (default: transaction payee)',
2677
+ maxLength: 100
2678
+ },
2679
+ icon: {
2680
+ type: 'string',
2681
+ description: 'Optional icon emoji',
2682
+ maxLength: 10
2683
+ }
2684
+ },
2685
+ required: ['frequency']
2686
+ } as const;
2687
+
1933
2688
  export const $RecurringRuleWithStatsResponseDto = {
1934
2689
  type: 'object',
1935
2690
  properties: {
@@ -2088,6 +2843,94 @@ export const $RecurringRuleWithStatsResponseDto = {
2088
2843
  ]
2089
2844
  } as const;
2090
2845
 
2846
+ export const $UpdateRecurringRuleDto = {
2847
+ type: 'object',
2848
+ properties: {
2849
+ name: {
2850
+ type: 'string',
2851
+ description: 'Rule name',
2852
+ maxLength: 100
2853
+ },
2854
+ icon: {
2855
+ type: 'string',
2856
+ description: 'Icon emoji',
2857
+ maxLength: 10
2858
+ },
2859
+ frequency: {
2860
+ type: 'string',
2861
+ description: 'Recurring frequency',
2862
+ enum: [
2863
+ 'WEEKLY',
2864
+ 'BIWEEKLY',
2865
+ 'MONTHLY',
2866
+ 'BIMONTHLY',
2867
+ 'QUARTERLY',
2868
+ 'YEARLY',
2869
+ 'CUSTOM'
2870
+ ]
2871
+ },
2872
+ expectedAmount: {
2873
+ type: 'number',
2874
+ description: 'Expected amount',
2875
+ minimum: 0
2876
+ },
2877
+ expectedDay: {
2878
+ type: 'number',
2879
+ description: 'Expected day of month (1-31)',
2880
+ minimum: 1,
2881
+ maximum: 31
2882
+ },
2883
+ customIntervalDays: {
2884
+ type: 'number',
2885
+ description: 'Custom interval in days',
2886
+ minimum: 1
2887
+ },
2888
+ currency: {
2889
+ type: 'string',
2890
+ description: 'Currency code',
2891
+ maxLength: 10
2892
+ },
2893
+ matchPayeePattern: {
2894
+ type: 'string',
2895
+ description: 'Payee matching pattern',
2896
+ maxLength: 200
2897
+ },
2898
+ matchAmountTolerance: {
2899
+ type: 'number',
2900
+ description: 'Amount tolerance percentage (0-1)',
2901
+ minimum: 0,
2902
+ maximum: 1
2903
+ },
2904
+ defaultExpenseAccount: {
2905
+ type: 'string',
2906
+ description: 'Default expense account',
2907
+ maxLength: 200
2908
+ },
2909
+ defaultPaymentAccount: {
2910
+ type: 'string',
2911
+ description: 'Default payment account',
2912
+ maxLength: 200
2913
+ },
2914
+ defaultPayee: {
2915
+ type: 'string',
2916
+ description: 'Default payee',
2917
+ maxLength: 200
2918
+ },
2919
+ autoCreate: {
2920
+ type: 'boolean',
2921
+ description: 'Auto-create transaction'
2922
+ },
2923
+ isActive: {
2924
+ type: 'boolean',
2925
+ description: 'Rule active status'
2926
+ },
2927
+ endDate: {
2928
+ type: 'string',
2929
+ description: 'Rule end date (ISO format)'
2930
+ }
2931
+ }
2932
+ } as const;
2933
+
2091
2934
  export const $ExpectedTransactionRuleDto = {
2092
2935
  type: 'object',
2093
2936
  properties: {
@@ -2204,6 +3047,50 @@ export const $ExpectedTransactionListResponseDto = {
2204
3047
  required: ['items', 'total']
2205
3048
  } as const;
2206
3049
 
3050
+ export const $ConfirmMatchDto = {
3051
+ type: 'object',
3052
+ properties: {
3053
+ transactionId: {
3054
+ type: 'string',
3055
+ description: 'Transaction ID to match with'
3056
+ }
3057
+ },
3058
+ required: ['transactionId']
3059
+ } as const;
3060
+
3061
+ export const $EnterNowDto = {
3062
+ type: 'object',
3063
+ properties: {
3064
+ expenseAccount: {
3065
+ type: 'string',
3066
+ description:
3067
+ 'Override expense account (uses rule default if not provided)',
3068
+ maxLength: 200
3069
+ },
3070
+ paymentAccount: {
3071
+ type: 'string',
3072
+ description:
3073
+ 'Override payment account (uses rule default if not provided)',
3074
+ maxLength: 200
3075
+ },
3076
+ amount: {
3077
+ type: 'number',
3078
+ description: 'Override amount (uses expected amount if not provided)',
3079
+ minimum: 0
3080
+ },
3081
+ payee: {
3082
+ type: 'string',
3083
+ description: 'Override payee (uses rule default if not provided)',
3084
+ maxLength: 200
3085
+ },
3086
+ narration: {
3087
+ type: 'string',
3088
+ description: 'Optional narration',
3089
+ maxLength: 500
3090
+ }
3091
+ }
3092
+ } as const;
3093
+
2207
3094
  export const $ForecastItemDto = {
2208
3095
  type: 'object',
2209
3096
  properties: {
@@ -2228,7 +3115,7 @@ export const $ForecastItemDto = {
2228
3115
  example: '2024-04-01'
2229
3116
  },
2230
3117
  icon: {
2231
- type: 'object',
3118
+ type: 'string',
2232
3119
  description: 'Rule icon emoji',
2233
3120
  example: '🏠',
2234
3121
  nullable: true
@@ -2328,6 +3215,107 @@ export const $ForecastResponseDto = {
2328
3215
  ]
2329
3216
  } as const;
2330
3217
 
3218
+ export const $CreateTransactionRuleDto = {
3219
+ type: 'object',
3220
+ properties: {
3221
+ name: {
3222
+ type: 'string',
3223
+ minLength: 1,
3224
+ maxLength: 100
3225
+ },
3226
+ description: {
3227
+ type: 'string',
3228
+ maxLength: 500
3229
+ },
3230
+ narrationKeywords: {
3231
+ items: {
3232
+ type: 'array'
3233
+ },
3234
+ maxItems: 50,
3235
+ type: 'array'
3236
+ },
3237
+ payeeKeywords: {
3238
+ items: {
3239
+ type: 'array'
3240
+ },
3241
+ maxItems: 50,
3242
+ type: 'array'
3243
+ },
3244
+ categoryKeywords: {
3245
+ items: {
3246
+ type: 'array'
3247
+ },
3248
+ maxItems: 50,
3249
+ type: 'array'
3250
+ },
3251
+ methodKeywords: {
3252
+ items: {
3253
+ type: 'array'
3254
+ },
3255
+ maxItems: 50,
3256
+ description: 'Payment method keywords (e.g., HuaBei, YuEBao)',
3257
+ type: 'array'
3258
+ },
3259
+ categoryAccount: {
3260
+ type: 'string',
3261
+ maxLength: 200,
3262
+ description:
3263
+ 'Destination account for expenses/income (e.g., Expenses:Food:Coffee)'
3264
+ },
3265
+ matchLogic: {
3266
+ type: 'string',
3267
+ enum: ['OR', 'AND'],
3268
+ default: 'OR'
3269
+ },
3270
+ amountMin: {
3271
+ type: 'number',
3272
+ minimum: 0,
3273
+ description: 'Minimum transaction amount (inclusive)'
3274
+ },
3275
+ amountMax: {
3276
+ type: 'number',
3277
+ minimum: 0,
3278
+ description: 'Maximum transaction amount (inclusive)'
3279
+ },
3280
+ priority: {
3281
+ type: 'number',
3282
+ default: 50,
3283
+ minimum: 0,
3284
+ maximum: 1000
3285
+ },
3286
+ additionalTags: {
3287
+ items: {
3288
+ type: 'array'
3289
+ },
3290
+ maxItems: 20,
3291
+ type: 'array'
3292
+ },
3293
+ additionalMetadata: {
3294
+ type: 'object'
3295
+ },
3296
+ upsertByPayee: {
3297
+ type: 'boolean',
3298
+ description:
3299
+ 'If true, update existing rule with matching payeeKeywords[0] instead of creating new rule'
3300
+ }
3301
+ },
3302
+ required: ['name', 'matchLogic', 'priority']
3303
+ } as const;
3304
+
3305
+ export const $AmountRangeDto = {
3306
+ type: 'object',
3307
+ properties: {
3308
+ min: {
3309
+ type: 'number',
3310
+ description: 'Minimum amount'
3311
+ },
3312
+ max: {
3313
+ type: 'number',
3314
+ description: 'Maximum amount'
3315
+ }
3316
+ }
3317
+ } as const;
3318
+
2331
3319
  export const $TransactionRuleResponseDto = {
2332
3320
  type: 'object',
2333
3321
  properties: {
@@ -2382,12 +3370,12 @@ export const $TransactionRuleResponseDto = {
2382
3370
  example: 'OR'
2383
3371
  },
2384
3372
  amountRange: {
2385
- type: 'object',
2386
3373
  description: 'Amount range for matching',
2387
- example: {
2388
- min: 0,
2389
- max: 100
2390
- }
3374
+ allOf: [
3375
+ {
3376
+ $ref: '#/components/schemas/AmountRangeDto'
3377
+ }
3378
+ ]
2391
3379
  },
2392
3380
  priority: {
2393
3381
  type: 'number',
@@ -2402,6 +3390,7 @@ export const $TransactionRuleResponseDto = {
2402
3390
  type: 'string',
2403
3391
  description: 'Learning source: NLP, REVIEW_CENTER, or null for manual',
2404
3392
  enum: ['NLP', 'REVIEW_CENTER'],
3393
+ nullable: true,
2405
3394
  example: 'REVIEW_CENTER'
2406
3395
  },
2407
3396
  autoApplyEnabled: {
@@ -2423,7 +3412,9 @@ export const $TransactionRuleResponseDto = {
2423
3412
  additionalMetadata: {
2424
3413
  type: 'object',
2425
3414
  description: 'Additional metadata',
2426
- example: {}
3415
+ additionalProperties: {
3416
+ type: 'string'
3417
+ }
2427
3418
  },
2428
3419
  createdAt: {
2429
3420
  format: 'date-time',
@@ -2596,6 +3587,64 @@ export const $ValidateRuleResponseDto = {
2596
3587
  required: ['valid', 'errors', 'warnings']
2597
3588
  } as const;
2598
3589
 
3590
+ export const $BulkCreateRulesDto = {
3591
+ type: 'object',
3592
+ properties: {
3593
+ rules: {
3594
+ items: {
3595
+ type: 'array'
3596
+ },
3597
+ description: 'Array of rules to import',
3598
+ type: 'array'
3599
+ },
3600
+ conflictStrategy: {
3601
+ type: 'string',
3602
+ enum: ['replace', 'skip'],
3603
+ default: 'skip',
3604
+ description:
3605
+ 'Conflict handling strategy: skip (default) ignores duplicates, replace soft-deletes existing rule'
3606
+ }
3607
+ },
3608
+ required: ['rules', 'conflictStrategy']
3609
+ } as const;
3610
+
3611
+ export const $BulkCreateRulesResponseDto = {
3612
+ type: 'object',
3613
+ properties: {
3614
+ successCount: {
3615
+ type: 'number',
3616
+ description: 'Number of successfully created rules'
3617
+ },
3618
+ failureCount: {
3619
+ type: 'number',
3620
+ description: 'Number of failed rules'
3621
+ },
3622
+ errors: {
3623
+ type: 'array',
3624
+ description: 'Error details for failed rules',
3625
+ items: {
3626
+ type: 'object',
3627
+ properties: {
3628
+ index: {
3629
+ type: 'number'
3630
+ },
3631
+ message: {
3632
+ type: 'string'
3633
+ }
3634
+ }
3635
+ }
3636
+ },
3637
+ createdRuleIds: {
3638
+ description: 'IDs of successfully created rules',
3639
+ type: 'array',
3640
+ items: {
3641
+ type: 'string'
3642
+ }
3643
+ }
3644
+ },
3645
+ required: ['successCount', 'failureCount', 'errors', 'createdRuleIds']
3646
+ } as const;
3647
+
2599
3648
  export const $ExportRulesResponseDto = {
2600
3649
  type: 'object',
2601
3650
  properties: {
@@ -2676,6 +3725,89 @@ export const $RuleStatisticsResponseDto = {
2676
3725
  ]
2677
3726
  } as const;
2678
3727
 
3728
+ export const $UpdateTransactionRuleDto = {
3729
+ type: 'object',
3730
+ properties: {
3731
+ name: {
3732
+ type: 'string',
3733
+ minLength: 1,
3734
+ maxLength: 100
3735
+ },
3736
+ description: {
3737
+ type: 'string',
3738
+ maxLength: 500
3739
+ },
3740
+ narrationKeywords: {
3741
+ items: {
3742
+ type: 'array'
3743
+ },
3744
+ maxItems: 50,
3745
+ type: 'array'
3746
+ },
3747
+ payeeKeywords: {
3748
+ items: {
3749
+ type: 'array'
3750
+ },
3751
+ maxItems: 50,
3752
+ type: 'array'
3753
+ },
3754
+ categoryKeywords: {
3755
+ items: {
3756
+ type: 'array'
3757
+ },
3758
+ maxItems: 50,
3759
+ type: 'array'
3760
+ },
3761
+ methodKeywords: {
3762
+ items: {
3763
+ type: 'array'
3764
+ },
3765
+ maxItems: 50,
3766
+ description: 'Payment method keywords (e.g., HuaBei, YuEBao)',
3767
+ type: 'array'
3768
+ },
3769
+ categoryAccount: {
3770
+ type: 'string',
3771
+ maxLength: 200,
3772
+ description:
3773
+ 'Destination account for expenses/income (e.g., Expenses:Food:Coffee)'
3774
+ },
3775
+ matchLogic: {
3776
+ type: 'string',
3777
+ enum: ['OR', 'AND']
3778
+ },
3779
+ amountMin: {
3780
+ type: 'number',
3781
+ minimum: 0,
3782
+ description: 'Minimum transaction amount (inclusive)'
3783
+ },
3784
+ amountMax: {
3785
+ type: 'number',
3786
+ minimum: 0,
3787
+ description: 'Maximum transaction amount (inclusive)'
3788
+ },
3789
+ priority: {
3790
+ type: 'number',
3791
+ minimum: 0,
3792
+ maximum: 1000
3793
+ },
3794
+ enabled: {
3795
+ type: 'boolean',
3796
+ description: 'Enable or disable the rule'
3797
+ },
3798
+ additionalTags: {
3799
+ items: {
3800
+ type: 'array'
3801
+ },
3802
+ maxItems: 20,
3803
+ type: 'array'
3804
+ },
3805
+ additionalMetadata: {
3806
+ type: 'object'
3807
+ }
3808
+ }
3809
+ } as const;
3810
+
2679
3811
  export const $TestRuleDto = {
2680
3812
  type: 'object',
2681
3813
  properties: {
@@ -2868,6 +4000,17 @@ export const $UpdateUserSettingDto = {
2868
4000
  }
2869
4001
  } as const;
2870
4002
 
4003
+ export const $UpdatePropertyDto = {
4004
+ type: 'object',
4005
+ properties: {
4006
+ value: {
4007
+ type: 'string',
4008
+ description: 'Property value'
4009
+ }
4010
+ },
4011
+ required: ['value']
4012
+ } as const;
4013
+
2871
4014
  export const $FileImportDto = {
2872
4015
  type: 'object',
2873
4016
  properties: {
@@ -3214,6 +4357,181 @@ export const $ImporterConfigDto = {
3214
4357
  ]
3215
4358
  } as const;
3216
4359
 
4360
+ export const $UpdateMapperDefaultsDto = {
4361
+ type: 'object',
4362
+ properties: {
4363
+ sourceAccount: {
4364
+ type: 'string',
4365
+ description: 'Source account for transactions (Beancount format)',
4366
+ example: 'Assets:Alipay:Balance',
4367
+ pattern: '^[A-Z][a-zA-Z0-9-]*:[a-zA-Z0-9-:]+$'
4368
+ },
4369
+ currency: {
4370
+ type: 'string',
4371
+ description: 'Default currency (ISO 4217 code)',
4372
+ example: 'CNY',
4373
+ minLength: 3,
4374
+ maxLength: 3,
4375
+ pattern: '^[A-Z]{3}$'
4376
+ },
4377
+ expenseAccount: {
4378
+ type: 'string',
4379
+ description: 'Default expense account (optional)',
4380
+ example: 'Expenses:Unknown',
4381
+ pattern: '^[A-Z][a-zA-Z0-9-]*:[a-zA-Z0-9-:]+$'
4382
+ },
4383
+ incomeAccount: {
4384
+ type: 'string',
4385
+ description: 'Default income account (optional)',
4386
+ example: 'Income:Unknown',
4387
+ pattern: '^[A-Z][a-zA-Z0-9-]*:[a-zA-Z0-9-:]+$'
4388
+ },
4389
+ methodAccountMapping: {
4390
+ type: 'object',
4391
+ description:
4392
+ '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).',
4393
+ example: {
4394
+ HuaBei: 'Liabilities:Alipay:Huabei',
4395
+ CreditCard: 'Liabilities:CreditCard'
4396
+ }
4397
+ }
4398
+ }
4399
+ } as const;
4400
+
4401
+ export const $UpdateConfigDataDto = {
4402
+ type: 'object',
4403
+ properties: {
4404
+ defaults: {
4405
+ description: 'Mapper defaults configuration',
4406
+ allOf: [
4407
+ {
4408
+ $ref: '#/components/schemas/UpdateMapperDefaultsDto'
4409
+ }
4410
+ ]
4411
+ }
4412
+ }
4413
+ } as const;
4414
+
4415
+ export const $UpdateImporterConfigDto = {
4416
+ type: 'object',
4417
+ properties: {
4418
+ data: {
4419
+ description: 'Configuration data (v1 schema)',
4420
+ allOf: [
4421
+ {
4422
+ $ref: '#/components/schemas/UpdateConfigDataDto'
4423
+ }
4424
+ ]
4425
+ }
4426
+ }
4427
+ } as const;
4428
+
4429
+ export const $CreatePlatformDto = {
4430
+ type: 'object',
4431
+ properties: {
4432
+ name: {
4433
+ type: 'string',
4434
+ description: 'Platform name',
4435
+ example: 'Binance'
4436
+ },
4437
+ canonical: {
4438
+ type: 'string',
4439
+ description: 'Platform canonical identifier (lowercase, kebab-case)',
4440
+ example: 'binance'
4441
+ },
4442
+ aliases: {
4443
+ description: 'Platform aliases (multi-language names for lookup)',
4444
+ example: ['Binance', 'Binance Exchange', 'BNB'],
4445
+ type: 'array',
4446
+ items: {
4447
+ type: 'string'
4448
+ }
4449
+ },
4450
+ url: {
4451
+ type: 'string',
4452
+ description: 'Platform URL',
4453
+ example: 'https://www.binance.com'
4454
+ },
4455
+ type: {
4456
+ type: 'string',
4457
+ description: 'Platform type',
4458
+ enum: [
4459
+ 'BANK',
4460
+ 'BROKERAGE',
4461
+ 'CRYPTO_EXCHANGE',
4462
+ 'PAYMENT',
4463
+ 'INVESTMENT',
4464
+ 'INSURANCE',
4465
+ 'OTHER'
4466
+ ],
4467
+ example: 'CRYPTO_EXCHANGE'
4468
+ },
4469
+ logoUrl: {
4470
+ type: 'string',
4471
+ description: 'Platform logo URL',
4472
+ example: 'https://example.com/logos/binance.png'
4473
+ },
4474
+ isActive: {
4475
+ type: 'boolean',
4476
+ description: 'Whether the platform is active',
4477
+ default: true
4478
+ }
4479
+ },
4480
+ required: ['name', 'canonical', 'aliases', 'url', 'type']
4481
+ } as const;
4482
+
4483
+ export const $UpdatePlatformDto = {
4484
+ type: 'object',
4485
+ properties: {
4486
+ name: {
4487
+ type: 'string',
4488
+ description: 'Platform name',
4489
+ example: 'Binance'
4490
+ },
4491
+ canonical: {
4492
+ type: 'string',
4493
+ description: 'Platform canonical identifier (lowercase, kebab-case)',
4494
+ example: 'binance'
4495
+ },
4496
+ aliases: {
4497
+ description: 'Platform aliases (multi-language names for lookup)',
4498
+ example: ['Binance', 'Binance Exchange', 'BNB'],
4499
+ type: 'array',
4500
+ items: {
4501
+ type: 'string'
4502
+ }
4503
+ },
4504
+ url: {
4505
+ type: 'string',
4506
+ description: 'Platform URL',
4507
+ example: 'https://www.binance.com'
4508
+ },
4509
+ type: {
4510
+ type: 'string',
4511
+ description: 'Platform type',
4512
+ enum: [
4513
+ 'BANK',
4514
+ 'BROKERAGE',
4515
+ 'CRYPTO_EXCHANGE',
4516
+ 'PAYMENT',
4517
+ 'INVESTMENT',
4518
+ 'INSURANCE',
4519
+ 'OTHER'
4520
+ ],
4521
+ example: 'CRYPTO_EXCHANGE'
4522
+ },
4523
+ logoUrl: {
4524
+ type: 'string',
4525
+ description: 'Platform logo URL',
4526
+ example: 'https://example.com/logos/binance.png'
4527
+ },
4528
+ isActive: {
4529
+ type: 'boolean',
4530
+ description: 'Whether the platform is active'
4531
+ }
4532
+ }
4533
+ } as const;
4534
+
3217
4535
  export const $ProviderSyncConfigDto = {
3218
4536
  type: 'object',
3219
4537
  properties: {
@@ -3379,6 +4697,16 @@ export const $ProcessNlpDto = {
3379
4697
  description:
3380
4698
  'Session ID for multi-turn conversation (auto-generated if not provided)',
3381
4699
  example: 'session_abc123'
4700
+ },
4701
+ parsedData: {
4702
+ type: 'object',
4703
+ description:
4704
+ 'Parsed data from previous NLP response for session recovery. Send back the parsedData received in confirm_payee/confirm responses.',
4705
+ example: {
4706
+ amount: 35,
4707
+ currency: 'CNY',
4708
+ payee: 'Starbucks'
4709
+ }
3382
4710
  }
3383
4711
  },
3384
4712
  required: ['message']