@firela/api-types 0.0.0-canary.b3b7767b → 0.0.0-canary.da5984a1

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: {
@@ -409,7 +583,8 @@ export const $PostingResponseDto = {
409
583
  },
410
584
  units: {
411
585
  type: 'string',
412
- description: 'Amount (may be null if interpolated)',
586
+ description:
587
+ 'Amount as decimal string. Typed optional but always present in responses: interpolation fills any MISSING posting before it is persisted or returned.',
413
588
  example: '100.50'
414
589
  },
415
590
  currency: {
@@ -607,6 +782,65 @@ export const $ApiProblemResponseDto = {
607
782
  required: ['type', 'title', 'status', 'detail']
608
783
  } as const;
609
784
 
785
+ export const $BatchCreateTransactionDto = {
786
+ type: 'object',
787
+ properties: {
788
+ transactions: {
789
+ description: 'Array of transactions to create',
790
+ minItems: 1,
791
+ maxItems: 100,
792
+ type: 'array',
793
+ items: {
794
+ $ref: '#/components/schemas/CreateTransactionDto'
795
+ }
796
+ }
797
+ },
798
+ required: ['transactions']
799
+ } as const;
800
+
801
+ export const $BatchTransactionErrorDto = {
802
+ type: 'object',
803
+ properties: {
804
+ index: {
805
+ type: 'number',
806
+ description: 'Index of failed transaction in the input array',
807
+ example: 0
808
+ },
809
+ error: {
810
+ type: 'string',
811
+ description: 'Error message describing the failure',
812
+ example: 'Transaction does not balance'
813
+ },
814
+ errorCode: {
815
+ type: 'string',
816
+ description: 'Structured error code for programmatic handling',
817
+ example: 'INSUFFICIENT_QUANTITY'
818
+ }
819
+ },
820
+ required: ['index', 'error']
821
+ } as const;
822
+
823
+ export const $BatchTransactionResponseDto = {
824
+ type: 'object',
825
+ properties: {
826
+ succeeded: {
827
+ description: 'Successfully created transactions',
828
+ type: 'array',
829
+ items: {
830
+ $ref: '#/components/schemas/TransactionResponseDto'
831
+ }
832
+ },
833
+ failed: {
834
+ description: 'Failed transactions with error details',
835
+ type: 'array',
836
+ items: {
837
+ $ref: '#/components/schemas/BatchTransactionErrorDto'
838
+ }
839
+ }
840
+ },
841
+ required: ['succeeded', 'failed']
842
+ } as const;
843
+
610
844
  export const $PostingDetailDto = {
611
845
  type: 'object',
612
846
  properties: {
@@ -627,7 +861,8 @@ export const $PostingDetailDto = {
627
861
  },
628
862
  units: {
629
863
  type: 'string',
630
- description: 'Amount (may be null if interpolated)',
864
+ description:
865
+ 'Amount as decimal string. Typed optional but always present in responses: interpolation fills any MISSING posting before it is persisted or returned.',
631
866
  example: '100.50'
632
867
  },
633
868
  currency: {
@@ -819,6 +1054,37 @@ export const $TransactionListResponseDto = {
819
1054
  required: ['data', 'total', 'limit', 'offset']
820
1055
  } as const;
821
1056
 
1057
+ export const $TagSuggestionDto = {
1058
+ type: 'object',
1059
+ properties: {
1060
+ tag: {
1061
+ type: 'string',
1062
+ description: 'Tag name',
1063
+ example: 'Monthly'
1064
+ },
1065
+ count: {
1066
+ type: 'number',
1067
+ description: 'Usage count across ACTIVE transactions',
1068
+ example: 12
1069
+ }
1070
+ },
1071
+ required: ['tag', 'count']
1072
+ } as const;
1073
+
1074
+ export const $TagSuggestionsResponseDto = {
1075
+ type: 'object',
1076
+ properties: {
1077
+ data: {
1078
+ description: 'Tag suggestions sorted as requested',
1079
+ type: 'array',
1080
+ items: {
1081
+ $ref: '#/components/schemas/TagSuggestionDto'
1082
+ }
1083
+ }
1084
+ },
1085
+ required: ['data']
1086
+ } as const;
1087
+
822
1088
  export const $UpdateTransactionDto = {
823
1089
  type: 'object',
824
1090
  properties: {
@@ -876,157 +1142,31 @@ export const $UpdateTransactionDto = {
876
1142
  }
877
1143
  } as const;
878
1144
 
879
- export const $AccountStandardResponseDto = {
1145
+ export const $BalanceResponseDto = {
880
1146
  type: 'object',
881
1147
  properties: {
882
- path: {
883
- type: 'string',
884
- description: 'Account path (hierarchical, colon-separated)',
885
- example: 'Assets:CN:Bank:ICBC:Checking'
886
- },
887
- type: {
1148
+ account: {
888
1149
  type: 'string',
889
- description: 'Account type in Beancount hierarchy',
890
- enum: ['Assets', 'Liabilities', 'Income', 'Expenses', 'Equity'],
891
- example: 'Assets'
1150
+ description: 'Account name',
1151
+ example: 'Assets:Bank:Checking'
892
1152
  },
893
- i18nKey: {
1153
+ balance: {
894
1154
  type: 'string',
895
- description: 'i18n key for localized display name',
896
- example: 'account.assets.cn.bank.icbc.checking'
1155
+ description: 'Balance amount (decimal string for precision)',
1156
+ example: '12345.67'
897
1157
  },
898
- description: {
1158
+ currency: {
899
1159
  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
- }
1160
+ description: 'Currency code',
1161
+ example: 'USD'
910
1162
  },
911
- icon: {
1163
+ date: {
912
1164
  type: 'string',
913
- description: 'Icon identifier for UI display',
914
- example: 'bank-icbc'
1165
+ description: 'Date of the balance calculation (ISO 8601)',
1166
+ example: '2024-12-31T00:00:00.000Z'
915
1167
  }
916
1168
  },
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 $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']
1169
+ required: ['account', 'balance', 'currency', 'date']
1030
1170
  } as const;
1031
1171
 
1032
1172
  export const $MultiCurrencyBalanceResponseDto = {
@@ -1136,8 +1276,10 @@ export const $ReviewSummaryDto = {
1136
1276
  },
1137
1277
  confidenceLevel: {
1138
1278
  type: 'string',
1139
- description: 'Confidence level derived from score',
1140
- enum: ['HIGH', 'MEDIUM', 'LOW']
1279
+ description:
1280
+ 'Confidence level derived from score. Null for error-type reviews (ACCOUNT_VALIDATION/PIPELINE_ERROR) which carry no confidence.',
1281
+ enum: ['HIGH', 'MEDIUM', 'LOW'],
1282
+ nullable: true
1141
1283
  },
1142
1284
  summaryKey: {
1143
1285
  type: 'string',
@@ -1319,8 +1461,10 @@ export const $ReviewDetailDto = {
1319
1461
  },
1320
1462
  confidenceLevel: {
1321
1463
  type: 'string',
1322
- description: 'Confidence level derived from score',
1323
- enum: ['HIGH', 'MEDIUM', 'LOW']
1464
+ description:
1465
+ 'Confidence level derived from score. Null for error-type reviews (ACCOUNT_VALIDATION/PIPELINE_ERROR) which carry no confidence.',
1466
+ enum: ['HIGH', 'MEDIUM', 'LOW'],
1467
+ nullable: true
1324
1468
  },
1325
1469
  summaryKey: {
1326
1470
  type: 'string',
@@ -1418,6 +1562,182 @@ export const $ReviewDetailDto = {
1418
1562
  ]
1419
1563
  } as const;
1420
1564
 
1565
+ export const $ResolveReviewDto = {
1566
+ type: 'object',
1567
+ properties: {
1568
+ action: {
1569
+ type: 'string',
1570
+ description:
1571
+ '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',
1572
+ example: 'ACCEPT'
1573
+ },
1574
+ data: {
1575
+ type: 'object',
1576
+ description:
1577
+ 'Additional data for the decision (e.g., selected account ID)',
1578
+ example: {
1579
+ accountId: 'acc-123'
1580
+ }
1581
+ }
1582
+ },
1583
+ required: ['action']
1584
+ } as const;
1585
+
1586
+ export const $ResolveResultDto = {
1587
+ type: 'object',
1588
+ properties: {
1589
+ success: {
1590
+ type: 'boolean',
1591
+ description: 'Whether resolution was successful'
1592
+ },
1593
+ messageKey: {
1594
+ type: 'string',
1595
+ description:
1596
+ 'i18n message key for result message (e.g., review.payee.result.mapped)'
1597
+ },
1598
+ messageParams: {
1599
+ type: 'object',
1600
+ description:
1601
+ 'Parameters for message interpolation (e.g., { name: "PayeeName" })',
1602
+ additionalProperties: {
1603
+ type: 'string'
1604
+ }
1605
+ },
1606
+ resolutionId: {
1607
+ type: 'string',
1608
+ description: 'Resolution ID for undo'
1609
+ },
1610
+ canUndo: {
1611
+ type: 'boolean',
1612
+ description: 'Whether this decision can be undone'
1613
+ },
1614
+ undoDeadline: {
1615
+ format: 'date-time',
1616
+ type: 'string',
1617
+ description: 'Deadline for undo (24h from resolution)'
1618
+ },
1619
+ learnedRuleId: {
1620
+ type: 'string',
1621
+ description:
1622
+ 'Rule ID if learning was triggered (ACCEPT_AND_LEARN actions). Use this to deep-link to the rule management page.',
1623
+ example: 'rule_01HXK5V8N2M3P4Q5R6S7T8U9V0'
1624
+ }
1625
+ },
1626
+ required: ['success', 'resolutionId', 'canUndo', 'undoDeadline']
1627
+ } as const;
1628
+
1629
+ export const $UndoResultDto = {
1630
+ type: 'object',
1631
+ properties: {
1632
+ success: {
1633
+ type: 'boolean',
1634
+ description: 'Whether undo was successful'
1635
+ },
1636
+ message: {
1637
+ type: 'string',
1638
+ description: 'Message'
1639
+ },
1640
+ reviewId: {
1641
+ type: 'string',
1642
+ description: 'Review item ID that was restored'
1643
+ }
1644
+ },
1645
+ required: ['success', 'reviewId']
1646
+ } as const;
1647
+
1648
+ export const $BatchResolveDto = {
1649
+ type: 'object',
1650
+ properties: {
1651
+ reviewIds: {
1652
+ description: 'Review item IDs to resolve',
1653
+ example: ['review-1', 'review-2', 'review-3'],
1654
+ type: 'array',
1655
+ items: {
1656
+ type: 'string'
1657
+ }
1658
+ },
1659
+ action: {
1660
+ type: 'string',
1661
+ description: 'Decision action to apply to all items',
1662
+ example: 'ACCEPT'
1663
+ },
1664
+ data: {
1665
+ type: 'object',
1666
+ description: 'Additional data for the decision'
1667
+ }
1668
+ },
1669
+ required: ['reviewIds', 'action']
1670
+ } as const;
1671
+
1672
+ export const $BatchResolveResultDto = {
1673
+ type: 'object',
1674
+ properties: {
1675
+ successCount: {
1676
+ type: 'number',
1677
+ description: 'Number of successfully resolved items'
1678
+ },
1679
+ failedCount: {
1680
+ type: 'number',
1681
+ description: 'Number of failed items'
1682
+ },
1683
+ results: {
1684
+ description: 'Details for each item',
1685
+ type: 'array',
1686
+ items: {
1687
+ type: 'string'
1688
+ }
1689
+ }
1690
+ },
1691
+ required: ['successCount', 'failedCount', 'results']
1692
+ } as const;
1693
+
1694
+ export const $CreatePayeeDto = {
1695
+ type: 'object',
1696
+ properties: {
1697
+ payee: {
1698
+ type: 'string',
1699
+ description:
1700
+ "User's original payee name (e.g., 'Starbucks', 'McDonald'). This is the raw payee string as entered by the user.",
1701
+ example: 'Starbucks',
1702
+ maxLength: 200
1703
+ },
1704
+ payeeProfileId: {
1705
+ type: 'string',
1706
+ description:
1707
+ 'Optional reference to global PayeeProfile for standardized data (merchant info, i18n keys, categories)',
1708
+ example: 'uuid-123',
1709
+ format: 'uuid'
1710
+ },
1711
+ customCategory: {
1712
+ type: 'string',
1713
+ description:
1714
+ "User's custom category for this payee (overrides PayeeProfile category)",
1715
+ example: 'Dining:Coffee',
1716
+ maxLength: 100
1717
+ },
1718
+ customTags: {
1719
+ description:
1720
+ "User's custom tags for this payee (e.g., ['favorite', 'work_meal'])",
1721
+ example: ['favorite', 'work_meal'],
1722
+ type: 'array',
1723
+ items: {
1724
+ type: 'string'
1725
+ }
1726
+ },
1727
+ meta: {
1728
+ type: 'object',
1729
+ description:
1730
+ 'Metadata for extended information (location, notes, contact info, etc.)',
1731
+ example: {
1732
+ location: 'Zhongguancun',
1733
+ note: 'Near subway station',
1734
+ favorite: true
1735
+ }
1736
+ }
1737
+ },
1738
+ required: ['payee']
1739
+ } as const;
1740
+
1421
1741
  export const $PayeeResponseDto = {
1422
1742
  type: 'object',
1423
1743
  properties: {
@@ -1437,14 +1757,14 @@ export const $PayeeResponseDto = {
1437
1757
  example: 'Starbucks'
1438
1758
  },
1439
1759
  payeeProfileId: {
1440
- type: 'object',
1760
+ type: 'string',
1441
1761
  description:
1442
1762
  'Reference to global PayeeProfile (merchant info, i18n keys, categories)',
1443
1763
  example: 'uuid-789',
1444
1764
  nullable: true
1445
1765
  },
1446
1766
  customCategory: {
1447
- type: 'object',
1767
+ type: 'string',
1448
1768
  description:
1449
1769
  "User's custom category (overrides PayeeProfile category if set)",
1450
1770
  example: 'Dining:Coffee',
@@ -1568,29 +1888,194 @@ export const $PayeeStatsResponseDto = {
1568
1888
  required: ['payee', 'transactionCount', 'lastUsedAt']
1569
1889
  } as const;
1570
1890
 
1571
- export const $PayeeProfileResponseDto = {
1891
+ export const $UpdatePayeeDto = {
1572
1892
  type: 'object',
1573
1893
  properties: {
1574
- id: {
1894
+ payeeProfileId: {
1575
1895
  type: 'string',
1576
- description: 'Unique identifier (UUID)',
1577
- example: '550e8400-e29b-41d4-a716-446655440000'
1896
+ description:
1897
+ 'Optional reference to global PayeeProfile for standardized data (merchant info, i18n keys, categories)',
1898
+ example: 'uuid-123',
1899
+ format: 'uuid'
1578
1900
  },
1579
- canonical: {
1901
+ customCategory: {
1580
1902
  type: 'string',
1581
- description: 'Canonical payee name (unique, case-insensitive)',
1582
- example: 'Starbucks'
1903
+ description:
1904
+ "User's custom category for this payee (overrides PayeeProfile category)",
1905
+ example: 'Dining:Coffee',
1906
+ maxLength: 100
1583
1907
  },
1584
- aliases: {
1585
- description: 'Multi-language aliases',
1586
- example: ['Starbucks Coffee', 'SBUX'],
1587
- type: 'array',
1908
+ customTags: {
1909
+ description:
1910
+ "User's custom tags for this payee (e.g., ['favorite', 'work_meal'])",
1911
+ example: ['favorite', 'work_meal'],
1912
+ type: 'array',
1913
+ items: {
1914
+ type: 'string'
1915
+ }
1916
+ },
1917
+ meta: {
1918
+ type: 'object',
1919
+ description:
1920
+ 'Metadata for extended information (location, notes, contact info, etc.). Will merge with existing metadata.',
1921
+ example: {
1922
+ location: 'Zhongguancun',
1923
+ note: 'Updated note',
1924
+ favorite: true
1925
+ }
1926
+ },
1927
+ isActive: {
1928
+ type: 'boolean',
1929
+ description:
1930
+ 'Enable or disable this payee. Disabled payees will not appear in autocomplete suggestions.',
1931
+ example: true
1932
+ }
1933
+ }
1934
+ } as const;
1935
+
1936
+ export const $CreatePayeeProfileDto = {
1937
+ type: 'object',
1938
+ properties: {
1939
+ canonical: {
1940
+ type: 'string',
1941
+ description:
1942
+ 'Canonical payee name (unique, case-insensitive). This is the primary identifier for the payee.',
1943
+ example: 'Starbucks',
1944
+ maxLength: 200
1945
+ },
1946
+ aliases: {
1947
+ description:
1948
+ 'Multi-language aliases for the payee. Used for matching user input in different languages.',
1949
+ example: ['Starbucks Coffee', 'SBUX'],
1950
+ type: 'array',
1588
1951
  items: {
1589
1952
  type: 'string'
1590
1953
  }
1591
1954
  },
1592
1955
  i18nKey: {
1956
+ type: 'string',
1957
+ description:
1958
+ 'Translation key for i18n integration (XLIFF translation system)',
1959
+ example: 'payee.starbucks',
1960
+ maxLength: 100
1961
+ },
1962
+ category: {
1963
+ type: 'string',
1964
+ description: 'Payee category classification',
1965
+ enum: [
1966
+ 'RESTAURANT',
1967
+ 'CAFE',
1968
+ 'FAST_FOOD',
1969
+ 'BAR',
1970
+ 'SUPERMARKET',
1971
+ 'CONVENIENCE_STORE',
1972
+ 'SHOPPING_MALL',
1973
+ 'ONLINE_SHOPPING',
1974
+ 'TAXI',
1975
+ 'RIDE_SHARING',
1976
+ 'PUBLIC_TRANSPORT',
1977
+ 'PARKING',
1978
+ 'GAS_STATION',
1979
+ 'UTILITIES',
1980
+ 'TELECOM',
1981
+ 'STREAMING',
1982
+ 'HEALTHCARE',
1983
+ 'EDUCATION',
1984
+ 'ENTERTAINMENT',
1985
+ 'SPORTS',
1986
+ 'TRAVEL',
1987
+ 'HOTEL',
1988
+ 'OTHER'
1989
+ ],
1990
+ example: 'CAFE'
1991
+ },
1992
+ subCategory: {
1993
+ type: 'string',
1994
+ description: 'Sub-category for more specific classification',
1995
+ example: 'coffee_chain',
1996
+ maxLength: 100
1997
+ },
1998
+ countries: {
1999
+ description:
2000
+ 'Country/region codes where the payee operates (ISO 3166-1 alpha-2)',
2001
+ example: ['CN', 'US', 'JP'],
2002
+ type: 'array',
2003
+ items: {
2004
+ type: 'string'
2005
+ }
2006
+ },
2007
+ primaryCountry: {
2008
+ type: 'string',
2009
+ description: 'Primary operating country (ISO 3166-1 alpha-2)',
2010
+ example: 'US',
2011
+ maxLength: 2
2012
+ },
2013
+ keywords: {
2014
+ description: 'Search keywords for fuzzy matching',
2015
+ example: ['coffee', 'cafe', 'drinks'],
2016
+ type: 'array',
2017
+ items: {
2018
+ type: 'string'
2019
+ }
2020
+ },
2021
+ logoUrl: {
2022
+ type: 'string',
2023
+ description: 'Payee logo URL',
2024
+ example: 'https://example.com/logo.png'
2025
+ },
2026
+ website: {
2027
+ type: 'string',
2028
+ description: 'Official website URL',
2029
+ example: 'https://www.starbucks.com'
2030
+ },
2031
+ description: {
2032
+ type: 'string',
2033
+ description: 'Payee description',
2034
+ example: 'Global coffeehouse chain headquartered in Seattle',
2035
+ maxLength: 1000
2036
+ },
2037
+ meta: {
1593
2038
  type: 'object',
2039
+ description:
2040
+ 'Extended metadata (business hours, contact info, additional details)',
2041
+ example: {
2042
+ businessHours: '07:00-22:00',
2043
+ phone: '+1-800-782-7282'
2044
+ }
2045
+ },
2046
+ dataSource: {
2047
+ type: 'string',
2048
+ description: 'Data source for this profile',
2049
+ enum: ['MANUAL', 'IMPORT', 'API', 'CROWDSOURCED'],
2050
+ default: 'MANUAL'
2051
+ }
2052
+ },
2053
+ required: ['canonical', 'category']
2054
+ } as const;
2055
+
2056
+ export const $PayeeProfileResponseDto = {
2057
+ type: 'object',
2058
+ properties: {
2059
+ id: {
2060
+ type: 'string',
2061
+ description: 'Unique identifier (UUID)',
2062
+ example: '550e8400-e29b-41d4-a716-446655440000'
2063
+ },
2064
+ canonical: {
2065
+ type: 'string',
2066
+ description: 'Canonical payee name (unique, case-insensitive)',
2067
+ example: 'Starbucks'
2068
+ },
2069
+ aliases: {
2070
+ description: 'Multi-language aliases',
2071
+ example: ['Starbucks Coffee', 'SBUX'],
2072
+ type: 'array',
2073
+ items: {
2074
+ type: 'string'
2075
+ }
2076
+ },
2077
+ i18nKey: {
2078
+ type: 'string',
1594
2079
  description: 'Translation key for i18n',
1595
2080
  example: 'payee.starbucks',
1596
2081
  nullable: true
@@ -1626,7 +2111,7 @@ export const $PayeeProfileResponseDto = {
1626
2111
  example: 'CAFE'
1627
2112
  },
1628
2113
  subCategory: {
1629
- type: 'object',
2114
+ type: 'string',
1630
2115
  description: 'Sub-category',
1631
2116
  example: 'coffee_chain',
1632
2117
  nullable: true
@@ -1640,7 +2125,7 @@ export const $PayeeProfileResponseDto = {
1640
2125
  }
1641
2126
  },
1642
2127
  primaryCountry: {
1643
- type: 'object',
2128
+ type: 'string',
1644
2129
  description: 'Primary operating country',
1645
2130
  example: 'US',
1646
2131
  nullable: true
@@ -1654,19 +2139,19 @@ export const $PayeeProfileResponseDto = {
1654
2139
  }
1655
2140
  },
1656
2141
  logoUrl: {
1657
- type: 'object',
2142
+ type: 'string',
1658
2143
  description: 'Logo URL',
1659
2144
  example: 'https://example.com/logo.png',
1660
2145
  nullable: true
1661
2146
  },
1662
2147
  website: {
1663
- type: 'object',
2148
+ type: 'string',
1664
2149
  description: 'Official website',
1665
2150
  example: 'https://www.starbucks.com',
1666
2151
  nullable: true
1667
2152
  },
1668
2153
  description: {
1669
- type: 'object',
2154
+ type: 'string',
1670
2155
  description: 'Description',
1671
2156
  example: 'Global coffeehouse chain',
1672
2157
  nullable: true
@@ -1682,9 +2167,10 @@ export const $PayeeProfileResponseDto = {
1682
2167
  example: 'MANUAL'
1683
2168
  },
1684
2169
  verifiedAt: {
1685
- type: 'object',
2170
+ type: 'string',
1686
2171
  description: 'Verification timestamp (null if not verified)',
1687
2172
  example: '2025-01-01T00:00:00.000Z',
2173
+ format: 'date-time',
1688
2174
  nullable: true
1689
2175
  },
1690
2176
  isActive: {
@@ -1739,6 +2225,164 @@ export const $PayeeProfileListResponseDto = {
1739
2225
  required: ['items', 'total']
1740
2226
  } as const;
1741
2227
 
2228
+ export const $UpdatePayeeProfileDto = {
2229
+ type: 'object',
2230
+ properties: {
2231
+ aliases: {
2232
+ description:
2233
+ 'Multi-language aliases for the payee. Used for matching user input in different languages.',
2234
+ example: ['Starbucks Coffee', 'SBUX'],
2235
+ type: 'array',
2236
+ items: {
2237
+ type: 'string'
2238
+ }
2239
+ },
2240
+ i18nKey: {
2241
+ type: 'string',
2242
+ description:
2243
+ 'Translation key for i18n integration (XLIFF translation system)',
2244
+ example: 'payee.starbucks',
2245
+ maxLength: 100
2246
+ },
2247
+ category: {
2248
+ type: 'string',
2249
+ description: 'Payee category classification',
2250
+ enum: [
2251
+ 'RESTAURANT',
2252
+ 'CAFE',
2253
+ 'FAST_FOOD',
2254
+ 'BAR',
2255
+ 'SUPERMARKET',
2256
+ 'CONVENIENCE_STORE',
2257
+ 'SHOPPING_MALL',
2258
+ 'ONLINE_SHOPPING',
2259
+ 'TAXI',
2260
+ 'RIDE_SHARING',
2261
+ 'PUBLIC_TRANSPORT',
2262
+ 'PARKING',
2263
+ 'GAS_STATION',
2264
+ 'UTILITIES',
2265
+ 'TELECOM',
2266
+ 'STREAMING',
2267
+ 'HEALTHCARE',
2268
+ 'EDUCATION',
2269
+ 'ENTERTAINMENT',
2270
+ 'SPORTS',
2271
+ 'TRAVEL',
2272
+ 'HOTEL',
2273
+ 'OTHER'
2274
+ ],
2275
+ example: 'CAFE'
2276
+ },
2277
+ subCategory: {
2278
+ type: 'string',
2279
+ description: 'Sub-category for more specific classification',
2280
+ example: 'coffee_chain',
2281
+ maxLength: 100
2282
+ },
2283
+ countries: {
2284
+ description:
2285
+ 'Country/region codes where the payee operates (ISO 3166-1 alpha-2)',
2286
+ example: ['CN', 'US', 'JP'],
2287
+ type: 'array',
2288
+ items: {
2289
+ type: 'string'
2290
+ }
2291
+ },
2292
+ primaryCountry: {
2293
+ type: 'string',
2294
+ description: 'Primary operating country (ISO 3166-1 alpha-2)',
2295
+ example: 'US',
2296
+ maxLength: 2
2297
+ },
2298
+ keywords: {
2299
+ description: 'Search keywords for fuzzy matching',
2300
+ example: ['coffee', 'cafe', 'drinks'],
2301
+ type: 'array',
2302
+ items: {
2303
+ type: 'string'
2304
+ }
2305
+ },
2306
+ logoUrl: {
2307
+ type: 'string',
2308
+ description: 'Payee logo URL',
2309
+ example: 'https://example.com/logo.png'
2310
+ },
2311
+ website: {
2312
+ type: 'string',
2313
+ description: 'Official website URL',
2314
+ example: 'https://www.starbucks.com'
2315
+ },
2316
+ description: {
2317
+ type: 'string',
2318
+ description: 'Payee description',
2319
+ example: 'Global coffeehouse chain headquartered in Seattle',
2320
+ maxLength: 1000
2321
+ },
2322
+ meta: {
2323
+ type: 'object',
2324
+ description:
2325
+ 'Extended metadata (business hours, contact info, additional details)',
2326
+ example: {
2327
+ businessHours: '07:00-22:00',
2328
+ phone: '+1-800-782-7282'
2329
+ }
2330
+ },
2331
+ dataSource: {
2332
+ type: 'string',
2333
+ description: 'Data source for this profile',
2334
+ enum: ['MANUAL', 'IMPORT', 'API', 'CROWDSOURCED'],
2335
+ default: 'MANUAL'
2336
+ },
2337
+ isActive: {
2338
+ type: 'boolean',
2339
+ description: 'Whether the payee profile is active (soft delete)',
2340
+ example: true
2341
+ },
2342
+ verifiedAt: {
2343
+ type: 'string',
2344
+ description:
2345
+ 'Verification timestamp. Set to current time to verify, or null to unverify.',
2346
+ example: '2025-01-01T00:00:00.000Z',
2347
+ format: 'date-time',
2348
+ nullable: true
2349
+ }
2350
+ }
2351
+ } as const;
2352
+
2353
+ export const $CreateCommodityDto = {
2354
+ type: 'object',
2355
+ properties: {
2356
+ symbol: {
2357
+ type: 'string',
2358
+ description:
2359
+ 'Commodity symbol (e.g., AAPL, USD, BTC) - corresponds to Beancount currency field',
2360
+ example: 'AAPL',
2361
+ maxLength: 50
2362
+ },
2363
+ date: {
2364
+ type: 'string',
2365
+ description:
2366
+ 'Commodity definition date (ISO 8601, required per Beancount spec). Represents when this commodity was first defined in the accounting system.',
2367
+ example: '2024-01-01',
2368
+ format: 'date'
2369
+ },
2370
+ metadata: {
2371
+ type: 'object',
2372
+ description:
2373
+ 'Metadata (corresponds to Beancount meta field). Can contain name, assetClass, precision, note, tags, etc.',
2374
+ example: {
2375
+ name: 'Apple Inc.',
2376
+ assetClass: 'stock',
2377
+ precision: 2,
2378
+ note: 'Long-term investment',
2379
+ tags: ['tech', 'dividend']
2380
+ }
2381
+ }
2382
+ },
2383
+ required: ['symbol', 'date']
2384
+ } as const;
2385
+
1742
2386
  export const $CommodityResponseDto = {
1743
2387
  type: 'object',
1744
2388
  properties: {
@@ -1748,7 +2392,7 @@ export const $CommodityResponseDto = {
1748
2392
  example: 'uuid-123-456'
1749
2393
  },
1750
2394
  userId: {
1751
- type: 'object',
2395
+ type: 'string',
1752
2396
  description: 'User ID (owner of the commodity)',
1753
2397
  example: 'user-123',
1754
2398
  nullable: true
@@ -1777,13 +2421,6 @@ export const $CommodityResponseDto = {
1777
2421
  source: 'AUTO_CREATED'
1778
2422
  }
1779
2423
  },
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
2424
  createdAt: {
1788
2425
  format: 'date-time',
1789
2426
  type: 'string',
@@ -1810,13 +2447,137 @@ export const $CommodityListResponseDto = {
1810
2447
  $ref: '#/components/schemas/CommodityResponseDto'
1811
2448
  }
1812
2449
  },
1813
- total: {
1814
- type: 'number',
1815
- description: 'Total number of commodities',
1816
- example: 42
2450
+ total: {
2451
+ type: 'number',
2452
+ description: 'Total number of commodities',
2453
+ example: 42
2454
+ }
2455
+ },
2456
+ required: ['items', 'total']
2457
+ } as const;
2458
+
2459
+ export const $UpdateCommodityDto = {
2460
+ type: 'object',
2461
+ properties: {
2462
+ date: {
2463
+ type: 'string',
2464
+ description:
2465
+ 'Commodity definition date (ISO 8601). Represents when this commodity was first defined in the accounting system.',
2466
+ example: '2024-01-01',
2467
+ format: 'date'
2468
+ },
2469
+ metadata: {
2470
+ type: 'object',
2471
+ description:
2472
+ 'Metadata (corresponds to Beancount meta field). Will merge with existing metadata. Can contain name, assetClass, precision, note, tags, etc.',
2473
+ example: {
2474
+ name: 'Updated Apple Inc.',
2475
+ assetClass: 'equity',
2476
+ precision: 4,
2477
+ note: 'Updated investment strategy',
2478
+ lastReviewed: '2024-11-03'
2479
+ }
2480
+ }
2481
+ }
2482
+ } as const;
2483
+
2484
+ export const $CreateRecurringRuleDto = {
2485
+ type: 'object',
2486
+ properties: {
2487
+ name: {
2488
+ type: 'string',
2489
+ description: 'Rule name (unique per user)',
2490
+ maxLength: 100
2491
+ },
2492
+ icon: {
2493
+ type: 'string',
2494
+ description: 'Icon emoji',
2495
+ maxLength: 10
2496
+ },
2497
+ frequency: {
2498
+ type: 'string',
2499
+ description: 'Recurring frequency',
2500
+ enum: [
2501
+ 'WEEKLY',
2502
+ 'BIWEEKLY',
2503
+ 'MONTHLY',
2504
+ 'BIMONTHLY',
2505
+ 'QUARTERLY',
2506
+ 'YEARLY',
2507
+ 'CUSTOM'
2508
+ ]
2509
+ },
2510
+ expectedAmount: {
2511
+ type: 'number',
2512
+ description: 'Expected amount (positive number)',
2513
+ minimum: 0
2514
+ },
2515
+ expectedDay: {
2516
+ type: 'number',
2517
+ description: 'Expected day of month (1-31)',
2518
+ minimum: 1,
2519
+ maximum: 31
2520
+ },
2521
+ customIntervalDays: {
2522
+ type: 'number',
2523
+ description: 'Custom interval in days (required for CUSTOM frequency)',
2524
+ minimum: 1
2525
+ },
2526
+ currency: {
2527
+ type: 'string',
2528
+ description: 'Currency code',
2529
+ default: 'CNY',
2530
+ maxLength: 10
2531
+ },
2532
+ matchPayeePattern: {
2533
+ type: 'string',
2534
+ description: 'Payee matching pattern (supports wildcards)',
2535
+ maxLength: 200
2536
+ },
2537
+ matchAmountTolerance: {
2538
+ type: 'number',
2539
+ description: 'Amount tolerance percentage (0-1)',
2540
+ default: 0.075,
2541
+ minimum: 0,
2542
+ maximum: 1
2543
+ },
2544
+ defaultExpenseAccount: {
2545
+ type: 'string',
2546
+ description: 'Default expense account for auto-create',
2547
+ maxLength: 200
2548
+ },
2549
+ defaultPaymentAccount: {
2550
+ type: 'string',
2551
+ description: 'Default payment account for auto-create',
2552
+ maxLength: 200
2553
+ },
2554
+ defaultPayee: {
2555
+ type: 'string',
2556
+ description: 'Default payee for auto-create',
2557
+ maxLength: 200
2558
+ },
2559
+ autoCreate: {
2560
+ type: 'boolean',
2561
+ description: 'Auto-create transaction when expected date arrives',
2562
+ default: false
2563
+ },
2564
+ startDate: {
2565
+ type: 'string',
2566
+ description: 'Rule start date (ISO format)'
2567
+ },
2568
+ endDate: {
2569
+ type: 'string',
2570
+ description: 'Rule end date (ISO format)'
1817
2571
  }
1818
2572
  },
1819
- required: ['items', 'total']
2573
+ required: [
2574
+ 'name',
2575
+ 'frequency',
2576
+ 'expectedAmount',
2577
+ 'currency',
2578
+ 'matchAmountTolerance',
2579
+ 'autoCreate'
2580
+ ]
1820
2581
  } as const;
1821
2582
 
1822
2583
  export const $RecurringRuleResponseDto = {
@@ -1930,6 +2691,37 @@ export const $RecurringRuleResponseDto = {
1930
2691
  ]
1931
2692
  } as const;
1932
2693
 
2694
+ export const $CreateRuleFromTransactionDto = {
2695
+ type: 'object',
2696
+ properties: {
2697
+ frequency: {
2698
+ type: 'string',
2699
+ description: 'Recurring frequency',
2700
+ enum: [
2701
+ 'WEEKLY',
2702
+ 'BIWEEKLY',
2703
+ 'MONTHLY',
2704
+ 'BIMONTHLY',
2705
+ 'QUARTERLY',
2706
+ 'YEARLY',
2707
+ 'CUSTOM'
2708
+ ],
2709
+ example: 'MONTHLY'
2710
+ },
2711
+ name: {
2712
+ type: 'string',
2713
+ description: 'Optional name override (default: transaction payee)',
2714
+ maxLength: 100
2715
+ },
2716
+ icon: {
2717
+ type: 'string',
2718
+ description: 'Optional icon emoji',
2719
+ maxLength: 10
2720
+ }
2721
+ },
2722
+ required: ['frequency']
2723
+ } as const;
2724
+
1933
2725
  export const $RecurringRuleWithStatsResponseDto = {
1934
2726
  type: 'object',
1935
2727
  properties: {
@@ -2088,6 +2880,94 @@ export const $RecurringRuleWithStatsResponseDto = {
2088
2880
  ]
2089
2881
  } as const;
2090
2882
 
2883
+ export const $UpdateRecurringRuleDto = {
2884
+ type: 'object',
2885
+ properties: {
2886
+ name: {
2887
+ type: 'string',
2888
+ description: 'Rule name',
2889
+ maxLength: 100
2890
+ },
2891
+ icon: {
2892
+ type: 'string',
2893
+ description: 'Icon emoji',
2894
+ maxLength: 10
2895
+ },
2896
+ frequency: {
2897
+ type: 'string',
2898
+ description: 'Recurring frequency',
2899
+ enum: [
2900
+ 'WEEKLY',
2901
+ 'BIWEEKLY',
2902
+ 'MONTHLY',
2903
+ 'BIMONTHLY',
2904
+ 'QUARTERLY',
2905
+ 'YEARLY',
2906
+ 'CUSTOM'
2907
+ ]
2908
+ },
2909
+ expectedAmount: {
2910
+ type: 'number',
2911
+ description: 'Expected amount',
2912
+ minimum: 0
2913
+ },
2914
+ expectedDay: {
2915
+ type: 'number',
2916
+ description: 'Expected day of month (1-31)',
2917
+ minimum: 1,
2918
+ maximum: 31
2919
+ },
2920
+ customIntervalDays: {
2921
+ type: 'number',
2922
+ description: 'Custom interval in days',
2923
+ minimum: 1
2924
+ },
2925
+ currency: {
2926
+ type: 'string',
2927
+ description: 'Currency code',
2928
+ maxLength: 10
2929
+ },
2930
+ matchPayeePattern: {
2931
+ type: 'string',
2932
+ description: 'Payee matching pattern',
2933
+ maxLength: 200
2934
+ },
2935
+ matchAmountTolerance: {
2936
+ type: 'number',
2937
+ description: 'Amount tolerance percentage (0-1)',
2938
+ minimum: 0,
2939
+ maximum: 1
2940
+ },
2941
+ defaultExpenseAccount: {
2942
+ type: 'string',
2943
+ description: 'Default expense account',
2944
+ maxLength: 200
2945
+ },
2946
+ defaultPaymentAccount: {
2947
+ type: 'string',
2948
+ description: 'Default payment account',
2949
+ maxLength: 200
2950
+ },
2951
+ defaultPayee: {
2952
+ type: 'string',
2953
+ description: 'Default payee',
2954
+ maxLength: 200
2955
+ },
2956
+ autoCreate: {
2957
+ type: 'boolean',
2958
+ description: 'Auto-create transaction'
2959
+ },
2960
+ isActive: {
2961
+ type: 'boolean',
2962
+ description: 'Rule active status'
2963
+ },
2964
+ endDate: {
2965
+ type: 'string',
2966
+ description: 'Rule end date (ISO format)'
2967
+ }
2968
+ }
2969
+ } as const;
2970
+
2091
2971
  export const $ExpectedTransactionRuleDto = {
2092
2972
  type: 'object',
2093
2973
  properties: {
@@ -2204,6 +3084,50 @@ export const $ExpectedTransactionListResponseDto = {
2204
3084
  required: ['items', 'total']
2205
3085
  } as const;
2206
3086
 
3087
+ export const $ConfirmMatchDto = {
3088
+ type: 'object',
3089
+ properties: {
3090
+ transactionId: {
3091
+ type: 'string',
3092
+ description: 'Transaction ID to match with'
3093
+ }
3094
+ },
3095
+ required: ['transactionId']
3096
+ } as const;
3097
+
3098
+ export const $EnterNowDto = {
3099
+ type: 'object',
3100
+ properties: {
3101
+ expenseAccount: {
3102
+ type: 'string',
3103
+ description:
3104
+ 'Override expense account (uses rule default if not provided)',
3105
+ maxLength: 200
3106
+ },
3107
+ paymentAccount: {
3108
+ type: 'string',
3109
+ description:
3110
+ 'Override payment account (uses rule default if not provided)',
3111
+ maxLength: 200
3112
+ },
3113
+ amount: {
3114
+ type: 'number',
3115
+ description: 'Override amount (uses expected amount if not provided)',
3116
+ minimum: 0
3117
+ },
3118
+ payee: {
3119
+ type: 'string',
3120
+ description: 'Override payee (uses rule default if not provided)',
3121
+ maxLength: 200
3122
+ },
3123
+ narration: {
3124
+ type: 'string',
3125
+ description: 'Optional narration',
3126
+ maxLength: 500
3127
+ }
3128
+ }
3129
+ } as const;
3130
+
2207
3131
  export const $ForecastItemDto = {
2208
3132
  type: 'object',
2209
3133
  properties: {
@@ -2228,7 +3152,7 @@ export const $ForecastItemDto = {
2228
3152
  example: '2024-04-01'
2229
3153
  },
2230
3154
  icon: {
2231
- type: 'object',
3155
+ type: 'string',
2232
3156
  description: 'Rule icon emoji',
2233
3157
  example: '🏠',
2234
3158
  nullable: true
@@ -2328,6 +3252,107 @@ export const $ForecastResponseDto = {
2328
3252
  ]
2329
3253
  } as const;
2330
3254
 
3255
+ export const $CreateTransactionRuleDto = {
3256
+ type: 'object',
3257
+ properties: {
3258
+ name: {
3259
+ type: 'string',
3260
+ minLength: 1,
3261
+ maxLength: 100
3262
+ },
3263
+ description: {
3264
+ type: 'string',
3265
+ maxLength: 500
3266
+ },
3267
+ narrationKeywords: {
3268
+ items: {
3269
+ type: 'array'
3270
+ },
3271
+ maxItems: 50,
3272
+ type: 'array'
3273
+ },
3274
+ payeeKeywords: {
3275
+ items: {
3276
+ type: 'array'
3277
+ },
3278
+ maxItems: 50,
3279
+ type: 'array'
3280
+ },
3281
+ categoryKeywords: {
3282
+ items: {
3283
+ type: 'array'
3284
+ },
3285
+ maxItems: 50,
3286
+ type: 'array'
3287
+ },
3288
+ methodKeywords: {
3289
+ items: {
3290
+ type: 'array'
3291
+ },
3292
+ maxItems: 50,
3293
+ description: 'Payment method keywords (e.g., HuaBei, YuEBao)',
3294
+ type: 'array'
3295
+ },
3296
+ categoryAccount: {
3297
+ type: 'string',
3298
+ maxLength: 200,
3299
+ description:
3300
+ 'Destination account for expenses/income (e.g., Expenses:Food:Coffee)'
3301
+ },
3302
+ matchLogic: {
3303
+ type: 'string',
3304
+ enum: ['OR', 'AND'],
3305
+ default: 'OR'
3306
+ },
3307
+ amountMin: {
3308
+ type: 'number',
3309
+ minimum: 0,
3310
+ description: 'Minimum transaction amount (inclusive)'
3311
+ },
3312
+ amountMax: {
3313
+ type: 'number',
3314
+ minimum: 0,
3315
+ description: 'Maximum transaction amount (inclusive)'
3316
+ },
3317
+ priority: {
3318
+ type: 'number',
3319
+ default: 50,
3320
+ minimum: 0,
3321
+ maximum: 1000
3322
+ },
3323
+ additionalTags: {
3324
+ items: {
3325
+ type: 'array'
3326
+ },
3327
+ maxItems: 20,
3328
+ type: 'array'
3329
+ },
3330
+ additionalMetadata: {
3331
+ type: 'object'
3332
+ },
3333
+ upsertByPayee: {
3334
+ type: 'boolean',
3335
+ description:
3336
+ 'If true, update existing rule with matching payeeKeywords[0] instead of creating new rule'
3337
+ }
3338
+ },
3339
+ required: ['name', 'matchLogic', 'priority']
3340
+ } as const;
3341
+
3342
+ export const $AmountRangeDto = {
3343
+ type: 'object',
3344
+ properties: {
3345
+ min: {
3346
+ type: 'number',
3347
+ description: 'Minimum amount'
3348
+ },
3349
+ max: {
3350
+ type: 'number',
3351
+ description: 'Maximum amount'
3352
+ }
3353
+ }
3354
+ } as const;
3355
+
2331
3356
  export const $TransactionRuleResponseDto = {
2332
3357
  type: 'object',
2333
3358
  properties: {
@@ -2382,12 +3407,12 @@ export const $TransactionRuleResponseDto = {
2382
3407
  example: 'OR'
2383
3408
  },
2384
3409
  amountRange: {
2385
- type: 'object',
2386
3410
  description: 'Amount range for matching',
2387
- example: {
2388
- min: 0,
2389
- max: 100
2390
- }
3411
+ allOf: [
3412
+ {
3413
+ $ref: '#/components/schemas/AmountRangeDto'
3414
+ }
3415
+ ]
2391
3416
  },
2392
3417
  priority: {
2393
3418
  type: 'number',
@@ -2402,6 +3427,7 @@ export const $TransactionRuleResponseDto = {
2402
3427
  type: 'string',
2403
3428
  description: 'Learning source: NLP, REVIEW_CENTER, or null for manual',
2404
3429
  enum: ['NLP', 'REVIEW_CENTER'],
3430
+ nullable: true,
2405
3431
  example: 'REVIEW_CENTER'
2406
3432
  },
2407
3433
  autoApplyEnabled: {
@@ -2423,7 +3449,9 @@ export const $TransactionRuleResponseDto = {
2423
3449
  additionalMetadata: {
2424
3450
  type: 'object',
2425
3451
  description: 'Additional metadata',
2426
- example: {}
3452
+ additionalProperties: {
3453
+ type: 'string'
3454
+ }
2427
3455
  },
2428
3456
  createdAt: {
2429
3457
  format: 'date-time',
@@ -2596,6 +3624,64 @@ export const $ValidateRuleResponseDto = {
2596
3624
  required: ['valid', 'errors', 'warnings']
2597
3625
  } as const;
2598
3626
 
3627
+ export const $BulkCreateRulesDto = {
3628
+ type: 'object',
3629
+ properties: {
3630
+ rules: {
3631
+ items: {
3632
+ type: 'array'
3633
+ },
3634
+ description: 'Array of rules to import',
3635
+ type: 'array'
3636
+ },
3637
+ conflictStrategy: {
3638
+ type: 'string',
3639
+ enum: ['replace', 'skip'],
3640
+ default: 'skip',
3641
+ description:
3642
+ 'Conflict handling strategy: skip (default) ignores duplicates, replace soft-deletes existing rule'
3643
+ }
3644
+ },
3645
+ required: ['rules', 'conflictStrategy']
3646
+ } as const;
3647
+
3648
+ export const $BulkCreateRulesResponseDto = {
3649
+ type: 'object',
3650
+ properties: {
3651
+ successCount: {
3652
+ type: 'number',
3653
+ description: 'Number of successfully created rules'
3654
+ },
3655
+ failureCount: {
3656
+ type: 'number',
3657
+ description: 'Number of failed rules'
3658
+ },
3659
+ errors: {
3660
+ type: 'array',
3661
+ description: 'Error details for failed rules',
3662
+ items: {
3663
+ type: 'object',
3664
+ properties: {
3665
+ index: {
3666
+ type: 'number'
3667
+ },
3668
+ message: {
3669
+ type: 'string'
3670
+ }
3671
+ }
3672
+ }
3673
+ },
3674
+ createdRuleIds: {
3675
+ description: 'IDs of successfully created rules',
3676
+ type: 'array',
3677
+ items: {
3678
+ type: 'string'
3679
+ }
3680
+ }
3681
+ },
3682
+ required: ['successCount', 'failureCount', 'errors', 'createdRuleIds']
3683
+ } as const;
3684
+
2599
3685
  export const $ExportRulesResponseDto = {
2600
3686
  type: 'object',
2601
3687
  properties: {
@@ -2676,6 +3762,89 @@ export const $RuleStatisticsResponseDto = {
2676
3762
  ]
2677
3763
  } as const;
2678
3764
 
3765
+ export const $UpdateTransactionRuleDto = {
3766
+ type: 'object',
3767
+ properties: {
3768
+ name: {
3769
+ type: 'string',
3770
+ minLength: 1,
3771
+ maxLength: 100
3772
+ },
3773
+ description: {
3774
+ type: 'string',
3775
+ maxLength: 500
3776
+ },
3777
+ narrationKeywords: {
3778
+ items: {
3779
+ type: 'array'
3780
+ },
3781
+ maxItems: 50,
3782
+ type: 'array'
3783
+ },
3784
+ payeeKeywords: {
3785
+ items: {
3786
+ type: 'array'
3787
+ },
3788
+ maxItems: 50,
3789
+ type: 'array'
3790
+ },
3791
+ categoryKeywords: {
3792
+ items: {
3793
+ type: 'array'
3794
+ },
3795
+ maxItems: 50,
3796
+ type: 'array'
3797
+ },
3798
+ methodKeywords: {
3799
+ items: {
3800
+ type: 'array'
3801
+ },
3802
+ maxItems: 50,
3803
+ description: 'Payment method keywords (e.g., HuaBei, YuEBao)',
3804
+ type: 'array'
3805
+ },
3806
+ categoryAccount: {
3807
+ type: 'string',
3808
+ maxLength: 200,
3809
+ description:
3810
+ 'Destination account for expenses/income (e.g., Expenses:Food:Coffee)'
3811
+ },
3812
+ matchLogic: {
3813
+ type: 'string',
3814
+ enum: ['OR', 'AND']
3815
+ },
3816
+ amountMin: {
3817
+ type: 'number',
3818
+ minimum: 0,
3819
+ description: 'Minimum transaction amount (inclusive)'
3820
+ },
3821
+ amountMax: {
3822
+ type: 'number',
3823
+ minimum: 0,
3824
+ description: 'Maximum transaction amount (inclusive)'
3825
+ },
3826
+ priority: {
3827
+ type: 'number',
3828
+ minimum: 0,
3829
+ maximum: 1000
3830
+ },
3831
+ enabled: {
3832
+ type: 'boolean',
3833
+ description: 'Enable or disable the rule'
3834
+ },
3835
+ additionalTags: {
3836
+ items: {
3837
+ type: 'array'
3838
+ },
3839
+ maxItems: 20,
3840
+ type: 'array'
3841
+ },
3842
+ additionalMetadata: {
3843
+ type: 'object'
3844
+ }
3845
+ }
3846
+ } as const;
3847
+
2679
3848
  export const $TestRuleDto = {
2680
3849
  type: 'object',
2681
3850
  properties: {
@@ -2868,6 +4037,17 @@ export const $UpdateUserSettingDto = {
2868
4037
  }
2869
4038
  } as const;
2870
4039
 
4040
+ export const $UpdatePropertyDto = {
4041
+ type: 'object',
4042
+ properties: {
4043
+ value: {
4044
+ type: 'string',
4045
+ description: 'Property value'
4046
+ }
4047
+ },
4048
+ required: ['value']
4049
+ } as const;
4050
+
2871
4051
  export const $FileImportDto = {
2872
4052
  type: 'object',
2873
4053
  properties: {
@@ -3167,7 +4347,8 @@ export const $ImporterConfigDto = {
3167
4347
  'cmbc-credit',
3168
4348
  'icbc',
3169
4349
  'icbc-credit',
3170
- 'hsbc-hk'
4350
+ 'hsbc-hk-credit',
4351
+ 'hsbc-hk-debit'
3171
4352
  ]
3172
4353
  },
3173
4354
  version: {
@@ -3213,6 +4394,181 @@ export const $ImporterConfigDto = {
3213
4394
  ]
3214
4395
  } as const;
3215
4396
 
4397
+ export const $UpdateMapperDefaultsDto = {
4398
+ type: 'object',
4399
+ properties: {
4400
+ sourceAccount: {
4401
+ type: 'string',
4402
+ description: 'Source account for transactions (Beancount format)',
4403
+ example: 'Assets:Alipay:Balance',
4404
+ pattern: '^[A-Z][a-zA-Z0-9-]*:[a-zA-Z0-9-:]+$'
4405
+ },
4406
+ currency: {
4407
+ type: 'string',
4408
+ description: 'Default currency (ISO 4217 code)',
4409
+ example: 'CNY',
4410
+ minLength: 3,
4411
+ maxLength: 3,
4412
+ pattern: '^[A-Z]{3}$'
4413
+ },
4414
+ expenseAccount: {
4415
+ type: 'string',
4416
+ description: 'Default expense account (optional)',
4417
+ example: 'Expenses:Unknown',
4418
+ pattern: '^[A-Z][a-zA-Z0-9-]*:[a-zA-Z0-9-:]+$'
4419
+ },
4420
+ incomeAccount: {
4421
+ type: 'string',
4422
+ description: 'Default income account (optional)',
4423
+ example: 'Income:Unknown',
4424
+ pattern: '^[A-Z][a-zA-Z0-9-]*:[a-zA-Z0-9-:]+$'
4425
+ },
4426
+ methodAccountMapping: {
4427
+ type: 'object',
4428
+ description:
4429
+ '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).',
4430
+ example: {
4431
+ HuaBei: 'Liabilities:Alipay:Huabei',
4432
+ CreditCard: 'Liabilities:CreditCard'
4433
+ }
4434
+ }
4435
+ }
4436
+ } as const;
4437
+
4438
+ export const $UpdateConfigDataDto = {
4439
+ type: 'object',
4440
+ properties: {
4441
+ defaults: {
4442
+ description: 'Mapper defaults configuration',
4443
+ allOf: [
4444
+ {
4445
+ $ref: '#/components/schemas/UpdateMapperDefaultsDto'
4446
+ }
4447
+ ]
4448
+ }
4449
+ }
4450
+ } as const;
4451
+
4452
+ export const $UpdateImporterConfigDto = {
4453
+ type: 'object',
4454
+ properties: {
4455
+ data: {
4456
+ description: 'Configuration data (v1 schema)',
4457
+ allOf: [
4458
+ {
4459
+ $ref: '#/components/schemas/UpdateConfigDataDto'
4460
+ }
4461
+ ]
4462
+ }
4463
+ }
4464
+ } as const;
4465
+
4466
+ export const $CreatePlatformDto = {
4467
+ type: 'object',
4468
+ properties: {
4469
+ name: {
4470
+ type: 'string',
4471
+ description: 'Platform name',
4472
+ example: 'Binance'
4473
+ },
4474
+ canonical: {
4475
+ type: 'string',
4476
+ description: 'Platform canonical identifier (lowercase, kebab-case)',
4477
+ example: 'binance'
4478
+ },
4479
+ aliases: {
4480
+ description: 'Platform aliases (multi-language names for lookup)',
4481
+ example: ['Binance', 'Binance Exchange', 'BNB'],
4482
+ type: 'array',
4483
+ items: {
4484
+ type: 'string'
4485
+ }
4486
+ },
4487
+ url: {
4488
+ type: 'string',
4489
+ description: 'Platform URL',
4490
+ example: 'https://www.binance.com'
4491
+ },
4492
+ type: {
4493
+ type: 'string',
4494
+ description: 'Platform type',
4495
+ enum: [
4496
+ 'BANK',
4497
+ 'BROKERAGE',
4498
+ 'CRYPTO_EXCHANGE',
4499
+ 'PAYMENT',
4500
+ 'INVESTMENT',
4501
+ 'INSURANCE',
4502
+ 'OTHER'
4503
+ ],
4504
+ example: 'CRYPTO_EXCHANGE'
4505
+ },
4506
+ logoUrl: {
4507
+ type: 'string',
4508
+ description: 'Platform logo URL',
4509
+ example: 'https://example.com/logos/binance.png'
4510
+ },
4511
+ isActive: {
4512
+ type: 'boolean',
4513
+ description: 'Whether the platform is active',
4514
+ default: true
4515
+ }
4516
+ },
4517
+ required: ['name', 'canonical', 'aliases', 'url', 'type']
4518
+ } as const;
4519
+
4520
+ export const $UpdatePlatformDto = {
4521
+ type: 'object',
4522
+ properties: {
4523
+ name: {
4524
+ type: 'string',
4525
+ description: 'Platform name',
4526
+ example: 'Binance'
4527
+ },
4528
+ canonical: {
4529
+ type: 'string',
4530
+ description: 'Platform canonical identifier (lowercase, kebab-case)',
4531
+ example: 'binance'
4532
+ },
4533
+ aliases: {
4534
+ description: 'Platform aliases (multi-language names for lookup)',
4535
+ example: ['Binance', 'Binance Exchange', 'BNB'],
4536
+ type: 'array',
4537
+ items: {
4538
+ type: 'string'
4539
+ }
4540
+ },
4541
+ url: {
4542
+ type: 'string',
4543
+ description: 'Platform URL',
4544
+ example: 'https://www.binance.com'
4545
+ },
4546
+ type: {
4547
+ type: 'string',
4548
+ description: 'Platform type',
4549
+ enum: [
4550
+ 'BANK',
4551
+ 'BROKERAGE',
4552
+ 'CRYPTO_EXCHANGE',
4553
+ 'PAYMENT',
4554
+ 'INVESTMENT',
4555
+ 'INSURANCE',
4556
+ 'OTHER'
4557
+ ],
4558
+ example: 'CRYPTO_EXCHANGE'
4559
+ },
4560
+ logoUrl: {
4561
+ type: 'string',
4562
+ description: 'Platform logo URL',
4563
+ example: 'https://example.com/logos/binance.png'
4564
+ },
4565
+ isActive: {
4566
+ type: 'boolean',
4567
+ description: 'Whether the platform is active'
4568
+ }
4569
+ }
4570
+ } as const;
4571
+
3216
4572
  export const $ProviderSyncConfigDto = {
3217
4573
  type: 'object',
3218
4574
  properties: {
@@ -3378,6 +4734,16 @@ export const $ProcessNlpDto = {
3378
4734
  description:
3379
4735
  'Session ID for multi-turn conversation (auto-generated if not provided)',
3380
4736
  example: 'session_abc123'
4737
+ },
4738
+ parsedData: {
4739
+ type: 'object',
4740
+ description:
4741
+ 'Parsed data from previous NLP response for session recovery. Send back the parsedData received in confirm_payee/confirm responses.',
4742
+ example: {
4743
+ amount: 35,
4744
+ currency: 'CNY',
4745
+ payee: 'Starbucks'
4746
+ }
3381
4747
  }
3382
4748
  },
3383
4749
  required: ['message']