@firela/api-types 0.0.0-canary.2e2a26ba → 0.0.0-canary.30542238

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.
@@ -124,6 +124,8 @@ export const $AccountResponseDto = {
124
124
  'STUDENT_LOAN',
125
125
  'CREDIT_CARD',
126
126
  'PERSONAL_LOAN',
127
+ 'ACCOUNTS_PAYABLE',
128
+ 'TAX_PAYABLE',
127
129
  'OTHER'
128
130
  ],
129
131
  nullable: true,
@@ -395,9 +397,47 @@ export const $AccountStandardResponseDto = {
395
397
  type: 'string',
396
398
  description: 'Icon identifier for UI display',
397
399
  example: 'bank-icbc'
400
+ },
401
+ productCategory: {
402
+ type: 'string',
403
+ description:
404
+ 'Onboarding product category (coarse grouping derived from assetSubClass)',
405
+ enum: [
406
+ 'cash',
407
+ 'investment',
408
+ 'credit_card',
409
+ 'loan',
410
+ 'payable_tax',
411
+ 'other'
412
+ ],
413
+ example: 'investment'
414
+ },
415
+ assetClass: {
416
+ type: 'string',
417
+ description:
418
+ 'Asset class (LIQUIDITY/EQUITY/.../LIABILITY), derived at read time from classification rules',
419
+ enum: [
420
+ 'LIQUIDITY',
421
+ 'EQUITY',
422
+ 'FIXED_INCOME',
423
+ 'PRECIOUS_METALS',
424
+ 'COMMODITY',
425
+ 'INSURANCE',
426
+ 'ALTERNATIVE_INVESTMENT',
427
+ 'PERSONAL_ASSETS',
428
+ 'LIABILITY',
429
+ 'REAL_ESTATE',
430
+ 'INDEX'
431
+ ]
432
+ },
433
+ assetSubClass: {
434
+ type: 'string',
435
+ description:
436
+ 'Asset sub-class (product type, derived at read time from classification rules)',
437
+ example: 'STOCK'
398
438
  }
399
439
  },
400
- required: ['path', 'type', 'description', 'tags', 'icon']
440
+ required: ['path', 'type', 'description', 'tags', 'icon', 'productCategory']
401
441
  } as const;
402
442
 
403
443
  export const $AccountStandardListResponseDto = {
@@ -736,7 +776,7 @@ export const $PostingResponseDto = {
736
776
  units: {
737
777
  type: 'string',
738
778
  description:
739
- 'Amount as decimal string. Typed optional but always present in responses: interpolation fills any MISSING posting before it is persisted or returned.',
779
+ 'Amount as decimal string. Typed optional but always present in responses: interpolation fills any MISSING posting before it is persisted or returned. Carries the raw Beancount sign (credit-normal accounts such as Income post negative — the accounting truth, ADR-0126); renderers must not infer economic semantics from this sign.',
740
780
  example: '100.50'
741
781
  },
742
782
  currency: {
@@ -1102,7 +1142,7 @@ export const $PostingDetailDto = {
1102
1142
  units: {
1103
1143
  type: 'string',
1104
1144
  description:
1105
- 'Amount as decimal string. Typed optional but always present in responses: interpolation fills any MISSING posting before it is persisted or returned.',
1145
+ 'Amount as decimal string. Typed optional but always present in responses: interpolation fills any MISSING posting before it is persisted or returned. Carries the raw Beancount sign (credit-normal accounts such as Income post negative — the accounting truth, ADR-0126); renderers must not infer economic semantics from this sign.',
1106
1146
  example: '100.50'
1107
1147
  },
1108
1148
  currency: {
@@ -1286,6 +1326,147 @@ export const $TransactionDetailDto = {
1286
1326
  ]
1287
1327
  } as const;
1288
1328
 
1329
+ export const $TransactionListItemDto = {
1330
+ type: 'object',
1331
+ properties: {
1332
+ id: {
1333
+ type: 'string',
1334
+ description: 'Transaction ID',
1335
+ example: 'clh1234567890abcdef'
1336
+ },
1337
+ date: {
1338
+ type: 'string',
1339
+ description: 'Transaction date',
1340
+ example: '2024-11-28'
1341
+ },
1342
+ flag: {
1343
+ type: 'string',
1344
+ description: 'Transaction flag',
1345
+ enum: [
1346
+ 'CLEARED',
1347
+ 'PENDING',
1348
+ 'PADDING',
1349
+ 'SUMMARIZE',
1350
+ 'TRANSFER',
1351
+ 'CONVERSIONS'
1352
+ ],
1353
+ example: 'CLEARED'
1354
+ },
1355
+ customFlag: {
1356
+ type: 'string',
1357
+ description: 'Custom flag (if not using standard flags)',
1358
+ example: 'R'
1359
+ },
1360
+ payee: {
1361
+ type: 'string',
1362
+ description: 'Payee name',
1363
+ example: 'Whole Foods Market'
1364
+ },
1365
+ narration: {
1366
+ type: 'string',
1367
+ description: 'Transaction narration',
1368
+ example: 'Grocery shopping'
1369
+ },
1370
+ tags: {
1371
+ description: 'Transaction tags',
1372
+ example: ['groceries'],
1373
+ type: 'array',
1374
+ items: {
1375
+ type: 'string'
1376
+ }
1377
+ },
1378
+ links: {
1379
+ description: 'Transaction links',
1380
+ example: ['invoice-2024-001'],
1381
+ type: 'array',
1382
+ items: {
1383
+ type: 'string'
1384
+ }
1385
+ },
1386
+ meta: {
1387
+ type: 'object',
1388
+ description: 'Transaction metadata'
1389
+ },
1390
+ status: {
1391
+ type: 'string',
1392
+ description: 'Transaction status',
1393
+ enum: ['ACTIVE', 'VOIDED', 'SUPERSEDED'],
1394
+ example: 'ACTIVE'
1395
+ },
1396
+ sourceType: {
1397
+ type: 'string',
1398
+ description:
1399
+ 'Source type (free-form string from transaction metadata, e.g. import, api)'
1400
+ },
1401
+ sourcePlatform: {
1402
+ type: 'string',
1403
+ description: 'Source platform (e.g., alipay, wechat)',
1404
+ example: 'alipay'
1405
+ },
1406
+ postings: {
1407
+ description: 'Transaction postings',
1408
+ type: 'array',
1409
+ items: {
1410
+ $ref: '#/components/schemas/PostingDetailDto'
1411
+ }
1412
+ },
1413
+ createdAt: {
1414
+ type: 'string',
1415
+ description: 'Created at timestamp',
1416
+ example: '2024-11-28T10:30:00.000Z'
1417
+ },
1418
+ voidedAt: {
1419
+ type: 'string',
1420
+ description: 'Voided at timestamp (if voided)',
1421
+ example: '2024-11-29T15:00:00.000Z'
1422
+ },
1423
+ voidedBy: {
1424
+ type: 'string',
1425
+ description: 'User ID who voided this transaction',
1426
+ example: 'clh1234567890abcdef'
1427
+ },
1428
+ correctionReason: {
1429
+ type: 'string',
1430
+ description: 'Correction reason (if voided or superseded)',
1431
+ example: 'Duplicate entry'
1432
+ },
1433
+ supersededBy: {
1434
+ type: 'string',
1435
+ description:
1436
+ 'ID of the transaction that supersedes this one (set when status=SUPERSEDED)',
1437
+ example: 'clh1234567890abcdef'
1438
+ },
1439
+ originalTxn: {
1440
+ type: 'string',
1441
+ description:
1442
+ 'ID of the transaction this one corrected/replaced (back-link on the replacement)',
1443
+ example: 'clh1234567890abcdef'
1444
+ },
1445
+ viewpointAmount: {
1446
+ type: 'string',
1447
+ description:
1448
+ 'Row amount under the request viewpoint (ADR-0126). Category viewpoint (category + flow): per-leg sign-normalized sum over the category account set (Income-root legs negated, Expenses-root identity) — positive under normal booking but NOT clamped (explicit negative expense legs and net-flip refund months stay negative). No viewpoint (plain list / search, no accountId): wallet money-flow net = raw-sign sum over cost-less Assets/Liabilities legs (income positive, expenses negative, transfers net ~0); color cue is the wallet sign (net < 0 = wealth-decreasing). Status-orthogonal: audit views match too (ADR-0128 amount-as-matching-key). Omitted under the account viewpoint (incl. dual) and for rows with no wallet leg.',
1449
+ example: '10000.00'
1450
+ },
1451
+ viewpointCurrency: {
1452
+ type: 'string',
1453
+ description:
1454
+ 'Currency of viewpointAmount. A row spanning multiple currencies takes the largest-magnitude currency group (known simplification, ADR-0126).',
1455
+ example: 'CNY'
1456
+ }
1457
+ },
1458
+ required: [
1459
+ 'id',
1460
+ 'date',
1461
+ 'narration',
1462
+ 'tags',
1463
+ 'links',
1464
+ 'status',
1465
+ 'postings',
1466
+ 'createdAt'
1467
+ ]
1468
+ } as const;
1469
+
1289
1470
  export const $BalanceByCurrencyDto = {
1290
1471
  type: 'object',
1291
1472
  properties: {
@@ -1331,7 +1512,7 @@ export const $TransactionListSummaryDto = {
1331
1512
  totalAmount: {
1332
1513
  type: 'string',
1333
1514
  description:
1334
- 'Partial converted total in base currency (rated currencies only, raw Beancount sign). When warnings is non-empty this excludes currencies missing an FX rate; may be "0.00" if ALL non-base currencies lack a rate. Converted at the dateTo (or current) available rate.',
1515
+ 'Partial converted total in base currency (rated currencies only). Sign by viewpoint (ADR-0126): account viewpoint keeps the raw Beancount sign (income negative); category viewpoint is per-leg sign-normalized (Income legs negated, Expenses legs identity — positive under normal booking, not clamped). When warnings is non-empty this excludes currencies missing an FX rate; may be "0.00" if ALL non-base currencies lack a rate. Converted at the dateTo (or current) available rate.',
1335
1516
  example: '-6000.00'
1336
1517
  },
1337
1518
  currency: {
@@ -1357,6 +1538,26 @@ export const $TransactionListSummaryDto = {
1357
1538
  required: ['totalAmount', 'currency', 'balanceByCurrency']
1358
1539
  } as const;
1359
1540
 
1541
+ export const $TransactionListViewpointDto = {
1542
+ type: 'object',
1543
+ properties: {
1544
+ type: {
1545
+ type: 'string',
1546
+ description:
1547
+ 'Viewpoint type (only category drill-down carries a viewpoint today)',
1548
+ enum: ['category'],
1549
+ example: 'category'
1550
+ },
1551
+ flow: {
1552
+ type: 'string',
1553
+ description: 'Flow root the category account set is restricted to',
1554
+ enum: ['income', 'expense'],
1555
+ example: 'expense'
1556
+ }
1557
+ },
1558
+ required: ['type', 'flow']
1559
+ } as const;
1560
+
1360
1561
  export const $TransactionListResponseDto = {
1361
1562
  type: 'object',
1362
1563
  properties: {
@@ -1364,7 +1565,7 @@ export const $TransactionListResponseDto = {
1364
1565
  description: 'List of transactions',
1365
1566
  type: 'array',
1366
1567
  items: {
1367
- $ref: '#/components/schemas/TransactionDetailDto'
1568
+ $ref: '#/components/schemas/TransactionListItemDto'
1368
1569
  }
1369
1570
  },
1370
1571
  total: {
@@ -1390,6 +1591,15 @@ export const $TransactionListResponseDto = {
1390
1591
  $ref: '#/components/schemas/TransactionListSummaryDto'
1391
1592
  }
1392
1593
  ]
1594
+ },
1595
+ viewpoint: {
1596
+ description:
1597
+ 'Viewpoint metadata (ADR-0126). Present only for a single category filter (category + flow, no accountId); dual-perspective requests are viewpoint-less (raw signs, no viewpointAmount).',
1598
+ allOf: [
1599
+ {
1600
+ $ref: '#/components/schemas/TransactionListViewpointDto'
1601
+ }
1602
+ ]
1393
1603
  }
1394
1604
  },
1395
1605
  required: ['data', 'total', 'limit', 'offset']
@@ -4083,6 +4293,50 @@ export const $DeleteOwnUserDto = {
4083
4293
  required: ['accessToken']
4084
4294
  } as const;
4085
4295
 
4296
+ export const $UserSettingsResponseDto = {
4297
+ type: 'object',
4298
+ properties: {
4299
+ baseCurrency: {
4300
+ type: 'string',
4301
+ description:
4302
+ 'Base currency (ISO 4217) for net-worth/report aggregation. Independent of region (ADR-0006).',
4303
+ example: 'USD',
4304
+ nullable: true
4305
+ }
4306
+ },
4307
+ required: ['baseCurrency']
4308
+ } as const;
4309
+
4310
+ export const $UserResponseDto = {
4311
+ type: 'object',
4312
+ properties: {
4313
+ id: {
4314
+ type: 'string',
4315
+ description: 'User ID'
4316
+ },
4317
+ role: {
4318
+ type: 'string',
4319
+ description: 'Assigned user role'
4320
+ },
4321
+ permissions: {
4322
+ description: 'Permission strings',
4323
+ type: 'array',
4324
+ items: {
4325
+ type: 'string'
4326
+ }
4327
+ },
4328
+ settings: {
4329
+ description: 'User settings',
4330
+ allOf: [
4331
+ {
4332
+ $ref: '#/components/schemas/UserSettingsResponseDto'
4333
+ }
4334
+ ]
4335
+ }
4336
+ },
4337
+ required: ['id', 'role', 'permissions', 'settings']
4338
+ } as const;
4339
+
4086
4340
  export const $SignupDto = {
4087
4341
  type: 'object',
4088
4342
  properties: {
@@ -4888,6 +5142,69 @@ export const $TestRuleResponseDto = {
4888
5142
  required: ['ruleId', 'matches', 'confidence', 'matchDetails']
4889
5143
  } as const;
4890
5144
 
5145
+ export const $CategoryCatalogEntryDto = {
5146
+ type: 'object',
5147
+ properties: {
5148
+ slug: {
5149
+ type: 'string',
5150
+ description: 'Category slug (single source-of-truth)',
5151
+ example: 'food'
5152
+ },
5153
+ scenario: {
5154
+ type: 'string',
5155
+ description: 'Display scenario group (maps to frontend picker _scenario)',
5156
+ enum: [
5157
+ 'expense',
5158
+ 'income',
5159
+ 'investment',
5160
+ 'banking',
5161
+ 'transfer',
5162
+ 'payment'
5163
+ ],
5164
+ example: 'expense'
5165
+ },
5166
+ icon: {
5167
+ type: 'string',
5168
+ description: 'Lucide icon name',
5169
+ example: 'utensils'
5170
+ },
5171
+ regions: {
5172
+ description: "Applicable regions ('*' = all, 'cn' = CN-only)",
5173
+ example: ['*'],
5174
+ type: 'array',
5175
+ items: {
5176
+ type: 'string'
5177
+ }
5178
+ }
5179
+ },
5180
+ required: ['slug', 'scenario', 'icon', 'regions']
5181
+ } as const;
5182
+
5183
+ export const $CategoryCatalogListResponseDto = {
5184
+ type: 'object',
5185
+ properties: {
5186
+ items: {
5187
+ description: 'Category entries (region-scoped, query-filtered)',
5188
+ type: 'array',
5189
+ items: {
5190
+ $ref: '#/components/schemas/CategoryCatalogEntryDto'
5191
+ }
5192
+ },
5193
+ total: {
5194
+ type: 'number',
5195
+ description:
5196
+ 'Total category entries for the region (before query filtering)',
5197
+ example: 30
5198
+ },
5199
+ region: {
5200
+ type: 'string',
5201
+ description: 'Region code',
5202
+ example: 'cn'
5203
+ }
5204
+ },
5205
+ required: ['items', 'total', 'region']
5206
+ } as const;
5207
+
4891
5208
  export const $CreateBeanEventDto = {
4892
5209
  type: 'object',
4893
5210
  properties: {
@@ -5630,7 +5947,8 @@ export const $UpdateMapperDefaultsDto = {
5630
5947
  type: 'string',
5631
5948
  description: 'Source account for transactions (Beancount format)',
5632
5949
  example: 'Assets:CN:Alipay:Balance',
5633
- pattern: '^[A-Z][a-zA-Z0-9-]*:[a-zA-Z0-9-:]+$'
5950
+ pattern:
5951
+ '^(Assets|Liabilities|Income|Expenses|Equity)(:[A-Za-z0-9][A-Za-z0-9-]*)+$'
5634
5952
  },
5635
5953
  currency: {
5636
5954
  type: 'string',
@@ -5644,13 +5962,15 @@ export const $UpdateMapperDefaultsDto = {
5644
5962
  type: 'string',
5645
5963
  description: 'Default expense account (optional)',
5646
5964
  example: 'Expenses:Unknown',
5647
- pattern: '^[A-Z][a-zA-Z0-9-]*:[a-zA-Z0-9-:]+$'
5965
+ pattern:
5966
+ '^(Assets|Liabilities|Income|Expenses|Equity)(:[A-Za-z0-9][A-Za-z0-9-]*)+$'
5648
5967
  },
5649
5968
  incomeAccount: {
5650
5969
  type: 'string',
5651
5970
  description: 'Default income account (optional)',
5652
5971
  example: 'Income:Unknown',
5653
- pattern: '^[A-Z][a-zA-Z0-9-]*:[a-zA-Z0-9-:]+$'
5972
+ pattern:
5973
+ '^(Assets|Liabilities|Income|Expenses|Equity)(:[A-Za-z0-9][A-Za-z0-9-]*)+$'
5654
5974
  },
5655
5975
  methodAccountMapping: {
5656
5976
  type: 'object',
@@ -5707,12 +6027,14 @@ export const $ProviderSyncConfigDto = {
5707
6027
  },
5708
6028
  defaultExpenseAccount: {
5709
6029
  type: 'string',
5710
- description: 'Default expense account for the second posting',
6030
+ description:
6031
+ 'Default expense account for the second posting. Omit when no real default exists; the pipeline routes to Review via the Uncategorized sentinel (#618).',
5711
6032
  example: 'Expenses:Unknown'
5712
6033
  },
5713
6034
  defaultIncomeAccount: {
5714
6035
  type: 'string',
5715
- description: 'Default income account for the second posting',
6036
+ description:
6037
+ 'Default income account for the second posting. Omit when no real default exists; the pipeline routes to Review via the Uncategorized sentinel (#618).',
5716
6038
  example: 'Income:Unknown'
5717
6039
  },
5718
6040
  filterPending: {
@@ -5727,12 +6049,7 @@ export const $ProviderSyncConfigDto = {
5727
6049
  example: 'acc_gocardless_001'
5728
6050
  }
5729
6051
  },
5730
- required: [
5731
- 'sourceAccount',
5732
- 'defaultCurrency',
5733
- 'defaultExpenseAccount',
5734
- 'defaultIncomeAccount'
5735
- ]
6052
+ required: ['sourceAccount', 'defaultCurrency']
5736
6053
  } as const;
5737
6054
 
5738
6055
  export const $ProviderSyncDto = {
@@ -5942,15 +6259,105 @@ export const $UncoveredFormatMissDto = {
5942
6259
  properties: {}
5943
6260
  } as const;
5944
6261
 
6262
+ export const $ClientParsedDataDto = {
6263
+ type: 'object',
6264
+ properties: {
6265
+ amount: {
6266
+ type: 'number',
6267
+ description: 'Transaction amount',
6268
+ example: 35
6269
+ },
6270
+ currency: {
6271
+ type: 'string',
6272
+ description: 'Currency code',
6273
+ example: 'CNY'
6274
+ },
6275
+ date: {
6276
+ type: 'string',
6277
+ description: 'Transaction date (ISO 8601)',
6278
+ example: '2026-08-15'
6279
+ },
6280
+ payee: {
6281
+ type: 'string',
6282
+ description: 'Payee/merchant name',
6283
+ example: 'Starbucks'
6284
+ },
6285
+ narration: {
6286
+ type: 'string',
6287
+ description: 'Transaction narration'
6288
+ },
6289
+ category: {
6290
+ type: 'string',
6291
+ description: 'Category slug',
6292
+ example: 'food_restaurant'
6293
+ },
6294
+ incomeType: {
6295
+ type: 'string',
6296
+ description: 'Income type',
6297
+ example: 'Salary'
6298
+ },
6299
+ incomeSource: {
6300
+ type: 'string',
6301
+ description: 'Income source',
6302
+ example: 'Anthropic Inc.'
6303
+ },
6304
+ symbol: {
6305
+ type: 'string',
6306
+ description: 'Security symbol code (e.g., 600519, AAPL)',
6307
+ example: 'AAPL'
6308
+ },
6309
+ quantity: {
6310
+ type: 'number',
6311
+ description: 'Quantity of shares/units',
6312
+ example: 100
6313
+ },
6314
+ price: {
6315
+ type: 'number',
6316
+ description: 'Unit price per share/unit',
6317
+ example: 1900
6318
+ },
6319
+ investmentAction: {
6320
+ type: 'string',
6321
+ description: 'Investment action',
6322
+ enum: ['buy', 'sell'],
6323
+ example: 'buy'
6324
+ },
6325
+ paymentSource: {
6326
+ type: 'string',
6327
+ description: 'Payment source: asset (default) or liability (credit card)',
6328
+ enum: ['asset', 'liability'],
6329
+ example: 'asset'
6330
+ },
6331
+ liabilityHint: {
6332
+ type: 'string',
6333
+ description: 'Liability account hint (CreditCard/Huabei/Baitiao)',
6334
+ example: 'CreditCard'
6335
+ },
6336
+ warning: {
6337
+ type: 'string',
6338
+ description:
6339
+ 'Display-only warning from the prior response; accepted but ignored.',
6340
+ example: 'Cross-currency settlement applies.'
6341
+ }
6342
+ }
6343
+ } as const;
6344
+
5945
6345
  export const $ProcessNlpDto = {
5946
6346
  type: 'object',
5947
6347
  properties: {
5948
6348
  message: {
5949
6349
  type: 'string',
5950
- description: 'Natural language text describing a transaction (Chinese)',
5951
- example: 'yesterday Starbucks spent 35 yuan',
6350
+ description:
6351
+ 'Natural language text describing a transaction. Optional when `confirm` is true (structured confirm); otherwise required.',
6352
+ example: 'Starbucks 35',
5952
6353
  maxLength: 500
5953
6354
  },
6355
+ confirm: {
6356
+ type: 'boolean',
6357
+ description:
6358
+ 'Structured confirm signal — bypasses NL confirm-word matching when true. Send parsedData field edits alongside. The NL word-list path is the fallback.',
6359
+ example: true
6360
+ },
5954
6361
  sessionId: {
5955
6362
  type: 'string',
5956
6363
  description:
@@ -5958,14 +6365,18 @@ export const $ProcessNlpDto = {
5958
6365
  example: 'session_abc123'
5959
6366
  },
5960
6367
  parsedData: {
5961
- type: 'object',
5962
6368
  description:
5963
6369
  'Parsed data from previous NLP response for session recovery. Send back the parsedData received in confirm_payee/confirm responses.',
5964
6370
  example: {
5965
6371
  amount: 35,
5966
6372
  currency: 'CNY',
5967
6373
  payee: 'Starbucks'
5968
- }
6374
+ },
6375
+ allOf: [
6376
+ {
6377
+ $ref: '#/components/schemas/ClientParsedDataDto'
6378
+ }
6379
+ ]
5969
6380
  },
5970
6381
  selectedRuleId: {
5971
6382
  type: 'string',
@@ -5976,11 +6387,10 @@ export const $ProcessNlpDto = {
5976
6387
  selectedAccount: {
5977
6388
  type: 'string',
5978
6389
  description:
5979
- 'confirm_account echo-back: account path selected from the prior confirm_account response (suggestedAccount, similarAccounts[i], or a typed path). Applied directly when the session is confirming_account — no NL re-parse.',
6390
+ 'confirm_account echo-back: account path selected from the prior confirm_account response (suggestedAccount, similarAccounts[i].path, or a typed path). Applied directly when the session is confirming_account — no NL re-parse.',
5980
6391
  example: 'Expenses:Food:Coffee'
5981
6392
  }
5982
- },
5983
- required: ['message']
6393
+ }
5984
6394
  } as const;
5985
6395
 
5986
6396
  export const $NlpTransactionInfoDto = {
@@ -6292,6 +6702,24 @@ export const $NlpRuleConfirmationDataDto = {
6292
6702
  ]
6293
6703
  } as const;
6294
6704
 
6705
+ export const $NlpAccountCandidateDto = {
6706
+ type: 'object',
6707
+ properties: {
6708
+ path: {
6709
+ type: 'string',
6710
+ description: 'Canonical beancount account path (echo back on selection)',
6711
+ example: 'Expenses:Food:Dining'
6712
+ },
6713
+ name: {
6714
+ type: 'string',
6715
+ description:
6716
+ 'Localized display name (ADR-0114 read-time projection, user locale)',
6717
+ example: '餐饮'
6718
+ }
6719
+ },
6720
+ required: ['path', 'name']
6721
+ } as const;
6722
+
6295
6723
  export const $NlpAccountConfirmationDataDto = {
6296
6724
  type: 'object',
6297
6725
  properties: {
@@ -6307,10 +6735,11 @@ export const $NlpAccountConfirmationDataDto = {
6307
6735
  example: 'Expenses:Food:Drinks'
6308
6736
  },
6309
6737
  similarAccounts: {
6310
- description: 'Similar accounts for user selection',
6738
+ description:
6739
+ 'Similar accounts for user selection (path + localized name, #680)',
6311
6740
  type: 'array',
6312
6741
  items: {
6313
- type: 'string'
6742
+ $ref: '#/components/schemas/NlpAccountCandidateDto'
6314
6743
  }
6315
6744
  },
6316
6745
  errorMessage: {
@@ -6497,7 +6926,8 @@ export const $NlpSuggestedAccountDto = {
6497
6926
  },
6498
6927
  confidence: {
6499
6928
  type: 'number',
6500
- description: 'Confidence score for this suggestion (0-1)',
6929
+ description:
6930
+ 'Confidence score for this suggestion (0-1). Present = predicted (confirm/confirm_rule/confirm_account); omitted = actual persisted account (created). (#586)',
6501
6931
  example: 0.9
6502
6932
  }
6503
6933
  },
@@ -6533,23 +6963,31 @@ export const $NlpDefaultAccountsDto = {
6533
6963
  properties: {
6534
6964
  asset: {
6535
6965
  type: 'string',
6536
- description: 'Default asset account',
6537
- example: 'Assets:Checking'
6966
+ description:
6967
+ 'Default OPEN asset account (MRU when multiple), or null when none/ambiguous',
6968
+ example: 'Assets:Checking',
6969
+ nullable: true
6538
6970
  },
6539
6971
  expense: {
6540
6972
  type: 'string',
6541
- description: 'Default expense account',
6542
- example: 'Expenses:Uncategorized'
6973
+ description:
6974
+ 'Default OPEN expense account (MRU when multiple), or null when none/ambiguous',
6975
+ example: 'Expenses:Food:Coffee',
6976
+ nullable: true
6543
6977
  },
6544
6978
  income: {
6545
6979
  type: 'string',
6546
- description: 'Default income account',
6547
- example: 'Income:Uncategorized'
6980
+ description:
6981
+ 'Default OPEN income account (MRU when multiple), or null when none/ambiguous',
6982
+ example: 'Income:Salary',
6983
+ nullable: true
6548
6984
  },
6549
6985
  liability: {
6550
6986
  type: 'string',
6551
- description: 'Default liability account',
6552
- example: 'Liabilities:CreditCard'
6987
+ description:
6988
+ 'Default OPEN liability account (MRU when multiple), or null when none/ambiguous',
6989
+ example: 'Liabilities:CreditCard',
6990
+ nullable: true
6553
6991
  }
6554
6992
  },
6555
6993
  required: ['asset', 'expense', 'income', 'liability']
@@ -6589,7 +7027,7 @@ export const $NlpResponseDto = {
6589
7027
  type: 'string',
6590
7028
  description:
6591
7029
  'Asset sub-type (only present when intent is "asset"). Determines which asset-related form to render.',
6592
- enum: ['transfer', 'banking', 'investment'],
7030
+ enum: ['transfer', 'banking', 'investment', 'lend', 'lend_collect'],
6593
7031
  example: 'investment'
6594
7032
  },
6595
7033
  liabilitySubType: {
@@ -6737,7 +7175,7 @@ export const $NlpResponseDto = {
6737
7175
  },
6738
7176
  suggestedAccounts: {
6739
7177
  description:
6740
- 'Suggested accounts for this transaction. Contains recommended source and destination accounts based on the detected intent and rules.',
7178
+ 'Suggested accounts for this transaction (#586). confirm/confirm_rule/confirm_account: predicted (source/destination carry confidence); created: actual persisted accounts (confidence omitted). confirm_account destination is the suggested replacement, never the invalid account.',
6741
7179
  allOf: [
6742
7180
  {
6743
7181
  $ref: '#/components/schemas/NlpSuggestedAccountsDto'
@@ -6746,7 +7184,7 @@ export const $NlpResponseDto = {
6746
7184
  },
6747
7185
  defaultAccounts: {
6748
7186
  description:
6749
- 'Default accounts for the user/region. These are fallback accounts used when no specific suggestion is available.',
7187
+ 'Default fallback accounts for the user/region (#586). v1 returns universal constants; per-user personalization is planned.',
6750
7188
  allOf: [
6751
7189
  {
6752
7190
  $ref: '#/components/schemas/NlpDefaultAccountsDto'
@@ -6792,13 +7230,26 @@ export const $PlatformListItemDto = {
6792
7230
  suggestedSegment: {
6793
7231
  type: 'string',
6794
7232
  description:
6795
- 'Suggested path segment — canonical with first char uppercased (ACC_COMP_NAME_RE)'
7233
+ 'Suggested path segment — canonical PascalCased per hyphen-part, hyphens preserved (e.g. "Apple-Pay")'
6796
7234
  },
6797
7235
  logoUrl: {
6798
7236
  type: 'string',
6799
7237
  description: 'Logo URL',
6800
7238
  nullable: true
6801
7239
  },
7240
+ countryCode: {
7241
+ type: 'string',
7242
+ description: 'ISO 3166-1 alpha-2 (UPPERCASE); null = global platform',
7243
+ example: 'CN',
7244
+ nullable: true
7245
+ },
7246
+ category: {
7247
+ type: 'string',
7248
+ description:
7249
+ 'Region-aware category (institution vocab, e.g. DigitalWallet/Bank). null = no region-aware suggestion; fall back to type.',
7250
+ nullable: true,
7251
+ example: 'DigitalWallet'
7252
+ },
6802
7253
  isBound: {
6803
7254
  type: 'boolean',
6804
7255
  description: 'Whether user has accounts using this platform'
@@ -6812,6 +7263,8 @@ export const $PlatformListItemDto = {
6812
7263
  'canonical',
6813
7264
  'suggestedSegment',
6814
7265
  'logoUrl',
7266
+ 'countryCode',
7267
+ 'category',
6815
7268
  'isBound'
6816
7269
  ]
6817
7270
  } as const;
@@ -6847,13 +7300,26 @@ export const $PlatformMatchResultDto = {
6847
7300
  suggestedSegment: {
6848
7301
  type: 'string',
6849
7302
  description:
6850
- 'Suggested path segment — canonical, already in ACCOUNT_RE format'
7303
+ 'Suggested path segment — canonical PascalCased per hyphen-part, hyphens preserved (e.g. "Apple-Pay")'
6851
7304
  },
6852
7305
  logoUrl: {
6853
7306
  type: 'string',
6854
7307
  description: 'Logo URL',
6855
7308
  nullable: true
6856
7309
  },
7310
+ countryCode: {
7311
+ type: 'string',
7312
+ description: 'ISO 3166-1 alpha-2 (UPPERCASE); null = global platform',
7313
+ example: 'CN',
7314
+ nullable: true
7315
+ },
7316
+ category: {
7317
+ type: 'string',
7318
+ description:
7319
+ 'Region-aware category (institution vocab, e.g. DigitalWallet/Bank). null = no region-aware suggestion; fall back to type.',
7320
+ nullable: true,
7321
+ example: 'DigitalWallet'
7322
+ },
6857
7323
  matchType: {
6858
7324
  type: 'string',
6859
7325
  description: "How this row matched: 'exact' > 'prefix' > 'substring'",
@@ -6867,6 +7333,8 @@ export const $PlatformMatchResultDto = {
6867
7333
  'type',
6868
7334
  'suggestedSegment',
6869
7335
  'logoUrl',
7336
+ 'countryCode',
7337
+ 'category',
6870
7338
  'matchType'
6871
7339
  ]
6872
7340
  } as const;
@@ -8116,6 +8584,216 @@ export const $AnonymousLoginResponseDto = {
8116
8584
  required: ['authToken']
8117
8585
  } as const;
8118
8586
 
8587
+ export const $ParserContributionMetaDto = {
8588
+ type: 'object',
8589
+ properties: {
8590
+ institution: {
8591
+ type: 'string',
8592
+ description: 'Institution slug (lowercase kebab-case)',
8593
+ pattern: '^[a-z0-9]+(-[a-z0-9]+)*$',
8594
+ example: 'icbc'
8595
+ },
8596
+ region: {
8597
+ type: 'string',
8598
+ enum: [
8599
+ 'cn',
8600
+ 'us',
8601
+ 'de',
8602
+ 'fr',
8603
+ 'gb',
8604
+ 'hk',
8605
+ 'jp',
8606
+ 'sg',
8607
+ 'au',
8608
+ 'ca',
8609
+ 'other'
8610
+ ]
8611
+ },
8612
+ accountType: {
8613
+ type: 'string',
8614
+ enum: ['checking', 'savings', 'credit', 'debit', 'investment']
8615
+ },
8616
+ format: {
8617
+ type: 'string',
8618
+ enum: ['csv', 'xlsx', 'pdf', 'ofx', 'qif']
8619
+ },
8620
+ institutionDisplayName: {
8621
+ type: 'string',
8622
+ example: '中国工商银行'
8623
+ },
8624
+ encoding: {
8625
+ type: 'string',
8626
+ example: 'utf-8'
8627
+ },
8628
+ delimiter: {
8629
+ type: 'string',
8630
+ description: 'CSV delimiter character: ",", ";", "\\t" or "|"'
8631
+ },
8632
+ headerRows: {
8633
+ type: 'number',
8634
+ default: 1,
8635
+ description: 'Header row count; the client omits the field when it is 1'
8636
+ },
8637
+ notes: {
8638
+ type: 'string',
8639
+ maxLength: 2000
8640
+ }
8641
+ },
8642
+ required: ['institution', 'region', 'accountType', 'format']
8643
+ } as const;
8644
+
8645
+ export const $ParserContributionSamplesDto = {
8646
+ type: 'object',
8647
+ properties: {
8648
+ rows: {
8649
+ description:
8650
+ 'Client-sanitized sample rows (key = column name, value = cell)',
8651
+ type: 'array',
8652
+ items: {
8653
+ type: 'object'
8654
+ }
8655
+ },
8656
+ rawHeaders: {
8657
+ type: 'array',
8658
+ items: {
8659
+ type: 'string'
8660
+ }
8661
+ }
8662
+ },
8663
+ required: ['rows']
8664
+ } as const;
8665
+
8666
+ export const $FieldHintDto = {
8667
+ type: 'object',
8668
+ properties: {
8669
+ columnName: {
8670
+ type: 'string',
8671
+ example: '交易日期'
8672
+ },
8673
+ format: {
8674
+ type: 'string',
8675
+ description: 'Date format, e.g. yyyy-MM-dd HH:mm',
8676
+ example: 'yyyy-MM-dd'
8677
+ },
8678
+ signConvention: {
8679
+ type: 'string',
8680
+ enum: ['negative-expense', 'positive-expense', 'separate-columns']
8681
+ },
8682
+ creditColumn: {
8683
+ type: 'string'
8684
+ },
8685
+ debitColumn: {
8686
+ type: 'string'
8687
+ }
8688
+ },
8689
+ required: ['columnName']
8690
+ } as const;
8691
+
8692
+ export const $ParserContributionFieldHintsDto = {
8693
+ type: 'object',
8694
+ properties: {
8695
+ date: {
8696
+ $ref: '#/components/schemas/FieldHintDto'
8697
+ },
8698
+ amount: {
8699
+ $ref: '#/components/schemas/FieldHintDto'
8700
+ },
8701
+ description: {
8702
+ $ref: '#/components/schemas/FieldHintDto'
8703
+ },
8704
+ balance: {
8705
+ $ref: '#/components/schemas/FieldHintDto'
8706
+ },
8707
+ payee: {
8708
+ $ref: '#/components/schemas/FieldHintDto'
8709
+ },
8710
+ reference: {
8711
+ $ref: '#/components/schemas/FieldHintDto'
8712
+ },
8713
+ category: {
8714
+ $ref: '#/components/schemas/FieldHintDto'
8715
+ }
8716
+ },
8717
+ required: ['date', 'amount']
8718
+ } as const;
8719
+
8720
+ export const $ExpectedTransactionDto = {
8721
+ type: 'object',
8722
+ properties: {
8723
+ date: {
8724
+ type: 'string',
8725
+ example: '2026-08-01'
8726
+ },
8727
+ amount: {
8728
+ type: 'number',
8729
+ example: -45.5
8730
+ },
8731
+ description: {
8732
+ type: 'string',
8733
+ example: '星巴克-***店'
8734
+ },
8735
+ payee: {
8736
+ type: 'string'
8737
+ },
8738
+ category: {
8739
+ type: 'string'
8740
+ }
8741
+ },
8742
+ required: ['date', 'amount', 'description']
8743
+ } as const;
8744
+
8745
+ export const $ParserContributionExamplesDto = {
8746
+ type: 'object',
8747
+ properties: {
8748
+ expectedTransactions: {
8749
+ type: 'array',
8750
+ items: {
8751
+ $ref: '#/components/schemas/ExpectedTransactionDto'
8752
+ }
8753
+ }
8754
+ },
8755
+ required: ['expectedTransactions']
8756
+ } as const;
8757
+
8758
+ export const $ParserContributionRequestDto = {
8759
+ type: 'object',
8760
+ properties: {
8761
+ meta: {
8762
+ $ref: '#/components/schemas/ParserContributionMetaDto'
8763
+ },
8764
+ samples: {
8765
+ $ref: '#/components/schemas/ParserContributionSamplesDto'
8766
+ },
8767
+ fieldHints: {
8768
+ $ref: '#/components/schemas/ParserContributionFieldHintsDto'
8769
+ },
8770
+ examples: {
8771
+ description: 'Omitted entirely by the client when empty',
8772
+ allOf: [
8773
+ {
8774
+ $ref: '#/components/schemas/ParserContributionExamplesDto'
8775
+ }
8776
+ ]
8777
+ }
8778
+ },
8779
+ required: ['meta', 'samples', 'fieldHints']
8780
+ } as const;
8781
+
8782
+ export const $ParserContributionRelayResponseDto = {
8783
+ type: 'object',
8784
+ properties: {
8785
+ issueUrl: {
8786
+ type: 'string',
8787
+ example: 'https://github.com/fire-zu/firela-vlt/issues/42'
8788
+ },
8789
+ issueNumber: {
8790
+ type: 'number',
8791
+ example: 42
8792
+ }
8793
+ },
8794
+ required: ['issueUrl', 'issueNumber']
8795
+ } as const;
8796
+
8119
8797
  export const $SymbolSearchResultDto = {
8120
8798
  type: 'object',
8121
8799
  properties: {