@firela/api-types 0.0.0-canary.f2efa2bf → 0.0.0-canary.f9057067

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.
@@ -17,6 +17,8 @@ import type {
17
17
  AccountControllerCloseResponse,
18
18
  AccountControllerReopenData,
19
19
  AccountControllerReopenResponse,
20
+ AccountControllerAddOpeningBalanceData,
21
+ AccountControllerAddOpeningBalanceResponse,
20
22
  AccountStandardsControllerGetTemplatesData,
21
23
  AccountStandardsControllerGetTemplatesResponse,
22
24
  AccountStandardsControllerGetTemplateMetadataData,
@@ -97,6 +99,18 @@ import type {
97
99
  CommodityControllerGetOrCreateResponse,
98
100
  CommodityControllerBulkCreateData,
99
101
  CommodityControllerBulkCreateResponse,
102
+ PriceControllerCreateData,
103
+ PriceControllerCreateResponse,
104
+ PriceControllerFindAllData,
105
+ PriceControllerFindAllResponse,
106
+ PriceControllerFindOneData,
107
+ PriceControllerFindOneResponse,
108
+ PriceControllerUpdateData,
109
+ PriceControllerUpdateResponse,
110
+ PriceControllerDeleteData,
111
+ PriceControllerDeleteResponse,
112
+ PriceControllerBulkCreateData,
113
+ PriceControllerBulkCreateResponse,
100
114
  RecurringRuleControllerCreateData,
101
115
  RecurringRuleControllerCreateResponse,
102
116
  RecurringRuleControllerFindAllData,
@@ -129,26 +143,14 @@ import type {
129
143
  ExpectedTransactionControllerEnterNowResponse,
130
144
  ForecastControllerGetForecastData,
131
145
  ForecastControllerGetForecastResponse,
132
- TransactionRuleControllerCreateData,
133
- TransactionRuleControllerCreateResponse,
134
- TransactionRuleControllerListData,
135
- TransactionRuleControllerListResponse,
136
- TransactionRuleControllerValidateData,
137
- TransactionRuleControllerValidateResponse,
138
- TransactionRuleControllerBulkCreateData,
139
- TransactionRuleControllerBulkCreateResponse,
140
- TransactionRuleControllerExportData,
141
- TransactionRuleControllerExportResponse,
142
- TransactionRuleControllerGetStatisticsData,
143
- TransactionRuleControllerGetStatisticsResponse,
144
- TransactionRuleControllerGetDetailData,
145
- TransactionRuleControllerGetDetailResponse,
146
- TransactionRuleControllerUpdateData,
147
- TransactionRuleControllerUpdateResponse,
148
- TransactionRuleControllerDeleteData,
149
- TransactionRuleControllerDeleteResponse,
150
- TransactionRuleControllerTestData,
151
- TransactionRuleControllerTestResponse,
146
+ ReportingControllerGetPortfolioTrendsData,
147
+ ReportingControllerGetPortfolioTrendsResponse,
148
+ ReportingControllerGetCashFlowTrendsData,
149
+ ReportingControllerGetCashFlowTrendsResponse,
150
+ ReportingControllerGenerateSnapshotData,
151
+ ReportingControllerGenerateSnapshotResponse,
152
+ ReportingControllerBackfillSnapshotsData,
153
+ ReportingControllerBackfillSnapshotsResponse,
152
154
  UserControllerDeleteOwnUserData,
153
155
  UserControllerDeleteOwnUserResponse,
154
156
  UserControllerGetUserData,
@@ -171,6 +173,50 @@ import type {
171
173
  PropertyControllerUpdateResponse,
172
174
  PropertyControllerDeleteData,
173
175
  PropertyControllerDeleteResponse,
176
+ TransactionRuleControllerCreateData,
177
+ TransactionRuleControllerCreateResponse,
178
+ TransactionRuleControllerListData,
179
+ TransactionRuleControllerListResponse,
180
+ TransactionRuleControllerValidateData,
181
+ TransactionRuleControllerValidateResponse,
182
+ TransactionRuleControllerBulkCreateData,
183
+ TransactionRuleControllerBulkCreateResponse,
184
+ TransactionRuleControllerExportData,
185
+ TransactionRuleControllerExportResponse,
186
+ TransactionRuleControllerGetStatisticsData,
187
+ TransactionRuleControllerGetStatisticsResponse,
188
+ TransactionRuleControllerGetDetailData,
189
+ TransactionRuleControllerGetDetailResponse,
190
+ TransactionRuleControllerUpdateData,
191
+ TransactionRuleControllerUpdateResponse,
192
+ TransactionRuleControllerDeleteData,
193
+ TransactionRuleControllerDeleteResponse,
194
+ TransactionRuleControllerTestData,
195
+ TransactionRuleControllerTestResponse,
196
+ CategoryCatalogControllerListData,
197
+ CategoryCatalogControllerListResponse,
198
+ EventControllerCreateData,
199
+ EventControllerCreateResponse,
200
+ EventControllerFindAllData,
201
+ EventControllerFindAllResponse,
202
+ EventControllerFindOneData,
203
+ EventControllerFindOneResponse,
204
+ EventControllerUpdateData,
205
+ EventControllerUpdateResponse,
206
+ EventControllerDeleteData,
207
+ EventControllerDeleteResponse,
208
+ EventControllerGetSliceData,
209
+ EventControllerGetSliceResponse,
210
+ OnboardingControllerBootstrapData,
211
+ OnboardingControllerBootstrapResponse,
212
+ ReconciliationControllerComputeData,
213
+ ReconciliationControllerComputeResponse,
214
+ ReconciliationControllerAssertData,
215
+ ReconciliationControllerAssertResponse,
216
+ ReconciliationControllerPadData,
217
+ ReconciliationControllerPadResponse,
218
+ ReconciliationControllerHistoryData,
219
+ ReconciliationControllerHistoryResponse,
174
220
  ExportControllerExportBeancountResponse,
175
221
  FileImportControllerImportFileData,
176
222
  FileImportControllerImportFileResponse,
@@ -184,22 +230,20 @@ import type {
184
230
  ImporterConfigControllerUpdateConfigResponse,
185
231
  ImporterConfigControllerResetConfigData,
186
232
  ImporterConfigControllerResetConfigResponse,
187
- PlatformControllerFindAllResponse,
188
- PlatformControllerCreateData,
189
- PlatformControllerCreateResponse,
190
- PlatformControllerGetPlatformListResponse,
191
- PlatformControllerMatchPlatformsData,
192
- PlatformControllerMatchPlatformsResponse,
193
- PlatformControllerUpdateData,
194
- PlatformControllerUpdateResponse,
195
- PlatformControllerDeleteData,
196
- PlatformControllerDeleteResponse,
197
233
  ProviderSyncControllerSyncData,
198
234
  ProviderSyncControllerSyncResponse,
199
235
  ProviderSyncControllerGetSupportedProvidersData,
200
236
  ProviderSyncControllerGetSupportedProvidersResponse,
201
237
  ProviderSyncControllerIsProviderSupportedData,
202
238
  ProviderSyncControllerIsProviderSupportedResponse,
239
+ ExternalAccountLinkControllerCreateData,
240
+ ExternalAccountLinkControllerCreateResponse,
241
+ ExternalAccountLinkControllerFindAllData,
242
+ ExternalAccountLinkControllerFindAllResponse,
243
+ ExternalAccountLinkControllerFindOneData,
244
+ ExternalAccountLinkControllerFindOneResponse,
245
+ ExternalAccountLinkControllerRemoveData,
246
+ ExternalAccountLinkControllerRemoveResponse,
203
247
  TelemetryControllerReportTelemetryData,
204
248
  TelemetryControllerReportTelemetryResponse,
205
249
  TelemetryControllerReportCoverageMissData,
@@ -212,32 +256,27 @@ import type {
212
256
  NlpControllerClearSessionResponse,
213
257
  NlpControllerGetSessionData,
214
258
  NlpControllerGetSessionResponse,
259
+ PlatformControllerFindAllResponse,
260
+ PlatformControllerCreateData,
261
+ PlatformControllerCreateResponse,
262
+ PlatformControllerGetPlatformListData,
263
+ PlatformControllerGetPlatformListResponse,
264
+ PlatformControllerMatchPlatformsData,
265
+ PlatformControllerMatchPlatformsResponse,
266
+ PlatformControllerUpdateData,
267
+ PlatformControllerUpdateResponse,
268
+ PlatformControllerDeleteData,
269
+ PlatformControllerDeleteResponse,
215
270
  DashboardControllerGetNetWorthData,
216
271
  DashboardControllerGetNetWorthResponse,
217
272
  DashboardControllerGetAccountsData,
218
273
  DashboardControllerGetAccountsResponse,
219
274
  DashboardControllerGetCashFlowData,
220
275
  DashboardControllerGetCashFlowResponse,
276
+ DashboardControllerGetExpensesData,
277
+ DashboardControllerGetExpensesResponse,
221
278
  HoldingPnlControllerGetHoldingPnlData,
222
279
  HoldingPnlControllerGetHoldingPnlResponse,
223
- PriceControllerCreateData,
224
- PriceControllerCreateResponse,
225
- PriceControllerFindAllData,
226
- PriceControllerFindAllResponse,
227
- PriceControllerFindOneData,
228
- PriceControllerFindOneResponse,
229
- PriceControllerUpdateData,
230
- PriceControllerUpdateResponse,
231
- PriceControllerDeleteData,
232
- PriceControllerDeleteResponse,
233
- PriceControllerBulkCreateData,
234
- PriceControllerBulkCreateResponse,
235
- ReportingControllerGetPortfolioTrendsData,
236
- ReportingControllerGetPortfolioTrendsResponse,
237
- ReportingControllerGenerateSnapshotData,
238
- ReportingControllerGenerateSnapshotResponse,
239
- ReportingControllerBackfillSnapshotsData,
240
- ReportingControllerBackfillSnapshotsResponse,
241
280
  ApiKeysControllerCreateApiKeyResponse,
242
281
  AuthControllerAccessTokenLoginData,
243
282
  AuthControllerAccessTokenLoginResponse,
@@ -252,15 +291,21 @@ import type {
252
291
  HealthControllerResetCircuitBreakerData,
253
292
  HealthControllerResetCircuitBreakerResponse,
254
293
  HealthControllerGetMetricsResponse,
255
- InfoControllerGetInfoResponse
294
+ InfoControllerGetInfoResponse,
295
+ SymbolControllerSearchData,
296
+ SymbolControllerSearchResponse,
297
+ SymbolControllerGetQuoteData,
298
+ SymbolControllerGetQuoteResponse
256
299
  } from './types.gen';
257
300
 
258
301
  export class BeanAccountsService {
259
302
  /**
303
+ * Create a new account
304
+ * Creates a new account (Beancount Open directive)
260
305
  * @param data The data for the request.
261
306
  * @param data.region Region code for tenant context
262
307
  * @param data.requestBody
263
- * @returns unknown
308
+ * @returns AccountResponseDto Account created successfully
264
309
  * @throws ApiError
265
310
  */
266
311
  public static accountControllerCreate(
@@ -273,7 +318,10 @@ export class BeanAccountsService {
273
318
  region: data.region
274
319
  },
275
320
  body: data.requestBody,
276
- mediaType: 'application/json'
321
+ mediaType: 'application/json',
322
+ errors: {
323
+ 409: 'Account already exists'
324
+ }
277
325
  });
278
326
  }
279
327
 
@@ -285,7 +333,7 @@ export class BeanAccountsService {
285
333
  * @param data.type Filter by account type
286
334
  * @param data.status Filter by status
287
335
  * @param data.isCustom Filter by custom (user-created) accounts only
288
- * @param data.search Search term for path or i18nKey
336
+ * @param data.search Search term for account path
289
337
  * @param data.limit Maximum number of results
290
338
  * @param data.offset Number of results to skip
291
339
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -337,11 +385,13 @@ export class BeanAccountsService {
337
385
  }
338
386
 
339
387
  /**
388
+ * Update account
389
+ * Updates account metadata (path cannot be changed)
340
390
  * @param data The data for the request.
341
- * @param data.id
391
+ * @param data.id Account UUID
342
392
  * @param data.region Region code for tenant context
343
393
  * @param data.requestBody
344
- * @returns unknown
394
+ * @returns AccountResponseDto Account updated successfully
345
395
  * @throws ApiError
346
396
  */
347
397
  public static accountControllerUpdate(
@@ -355,15 +405,20 @@ export class BeanAccountsService {
355
405
  region: data.region
356
406
  },
357
407
  body: data.requestBody,
358
- mediaType: 'application/json'
408
+ mediaType: 'application/json',
409
+ errors: {
410
+ 404: 'Account not found'
411
+ }
359
412
  });
360
413
  }
361
414
 
362
415
  /**
416
+ * Delete account
417
+ * Deletes an account (only if no active transactions; voided/superseded residual postings are cleaned up)
363
418
  * @param data The data for the request.
364
- * @param data.id
419
+ * @param data.id Account UUID
365
420
  * @param data.region Region code for tenant context
366
- * @returns unknown
421
+ * @returns void Account deleted successfully
367
422
  * @throws ApiError
368
423
  */
369
424
  public static accountControllerDelete(
@@ -375,16 +430,22 @@ export class BeanAccountsService {
375
430
  path: {
376
431
  id: data.id,
377
432
  region: data.region
433
+ },
434
+ errors: {
435
+ 404: 'Account not found',
436
+ 409: 'Account has active transactions and cannot be deleted'
378
437
  }
379
438
  });
380
439
  }
381
440
 
382
441
  /**
442
+ * Close account
443
+ * Closes an account (Beancount Close directive)
383
444
  * @param data The data for the request.
384
- * @param data.id
445
+ * @param data.id Account UUID
385
446
  * @param data.region Region code for tenant context
386
447
  * @param data.requestBody
387
- * @returns unknown
448
+ * @returns AccountResponseDto Account closed successfully
388
449
  * @throws ApiError
389
450
  */
390
451
  public static accountControllerClose(
@@ -398,16 +459,22 @@ export class BeanAccountsService {
398
459
  region: data.region
399
460
  },
400
461
  body: data.requestBody,
401
- mediaType: 'application/json'
462
+ mediaType: 'application/json',
463
+ errors: {
464
+ 400: 'Account is already closed',
465
+ 404: 'Account not found'
466
+ }
402
467
  });
403
468
  }
404
469
 
405
470
  /**
471
+ * Reopen account
472
+ * Reopens a previously closed account
406
473
  * @param data The data for the request.
407
- * @param data.id
474
+ * @param data.id Account UUID
408
475
  * @param data.region Region code for tenant context
409
476
  * @param data.requestBody
410
- * @returns unknown
477
+ * @returns AccountResponseDto Account reopened successfully
411
478
  * @throws ApiError
412
479
  */
413
480
  public static accountControllerReopen(
@@ -421,7 +488,40 @@ export class BeanAccountsService {
421
488
  region: data.region
422
489
  },
423
490
  body: data.requestBody,
424
- mediaType: 'application/json'
491
+ mediaType: 'application/json',
492
+ errors: {
493
+ 400: 'Account is not closed',
494
+ 404: 'Account not found'
495
+ }
496
+ });
497
+ }
498
+
499
+ /**
500
+ * Post an opening-balance transaction
501
+ * Posts a double-entry opening-balance transaction against Equity:Opening-Balances for an existing Assets/Liabilities account. At most one active opening balance per account.
502
+ * @param data The data for the request.
503
+ * @param data.id Account UUID
504
+ * @param data.region Region code for tenant context
505
+ * @param data.requestBody
506
+ * @returns OpeningBalanceResultDto Opening-balance transaction created
507
+ * @throws ApiError
508
+ */
509
+ public static accountControllerAddOpeningBalance(
510
+ data: AccountControllerAddOpeningBalanceData
511
+ ): CancelablePromise<AccountControllerAddOpeningBalanceResponse> {
512
+ return __request(OpenAPI, {
513
+ method: 'POST',
514
+ url: '/api/v1/{region}/bean/accounts/{id}/opening-balance',
515
+ path: {
516
+ id: data.id,
517
+ region: data.region
518
+ },
519
+ body: data.requestBody,
520
+ mediaType: 'application/json',
521
+ errors: {
522
+ 404: 'Account not found',
523
+ 409: 'An opening balance already exists for this account'
524
+ }
425
525
  });
426
526
  }
427
527
  }
@@ -455,7 +555,7 @@ export class BeanAccountStandardsService {
455
555
 
456
556
  /**
457
557
  * Get template metadata for an account path
458
- * Returns extendable status and root type for a template path.
558
+ * Returns root type for a template path.
459
559
  * @param data The data for the request.
460
560
  * @param data.region Region code for tenant context
461
561
  * @param data.path Account path to check
@@ -541,6 +641,7 @@ export class BeanTransactionsService {
541
641
  * @param data.status Filter by transaction status
542
642
  * @param data.search Search in narration and payee fields (max 200 chars)
543
643
  * @param data.accountId Filter by account ID (transactions with postings to this account)
644
+ * @param data.category Filter by ADR-0075 functional category (Group segment); matches any posting to an Expenses/Income account whose derived Group segment equals this value
544
645
  * @returns TransactionListResponseDto Transaction list
545
646
  * @throws ApiError
546
647
  */
@@ -560,7 +661,8 @@ export class BeanTransactionsService {
560
661
  dateTo: data.dateTo,
561
662
  status: data.status,
562
663
  search: data.search,
563
- accountId: data.accountId
664
+ accountId: data.accountId,
665
+ category: data.category
564
666
  },
565
667
  errors: {
566
668
  400: 'Validation failed',
@@ -748,7 +850,7 @@ export class BeanBalancesService {
748
850
  * Query account balance
749
851
  * Calculate account balance at a specific date for a single currency
750
852
  * @param data The data for the request.
751
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
853
+ * @param data.account Account name (e.g., "Assets:Checking")
752
854
  * @param data.region Region code for tenant context
753
855
  * @param data.date Date to calculate balance at (ISO 8601 format)
754
856
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -1469,112 +1571,279 @@ export class BeanCommoditiesService {
1469
1571
  }
1470
1572
  }
1471
1573
 
1472
- export class RecurringRulesService {
1574
+ export class BeanPricesService {
1473
1575
  /**
1474
- * Create a new recurring rule
1475
- * Creates a new recurring transaction rule for the authenticated user
1576
+ * Create a new price
1577
+ * Creates a new price entry for the authenticated user
1476
1578
  * @param data The data for the request.
1477
1579
  * @param data.region Region code for tenant context
1478
1580
  * @param data.requestBody
1479
- * @returns RecurringRuleResponseDto Rule created successfully
1581
+ * @returns PriceResponseDto Price created successfully
1480
1582
  * @throws ApiError
1481
1583
  */
1482
- public static recurringRuleControllerCreate(
1483
- data: RecurringRuleControllerCreateData
1484
- ): CancelablePromise<RecurringRuleControllerCreateResponse> {
1584
+ public static priceControllerCreate(
1585
+ data: PriceControllerCreateData
1586
+ ): CancelablePromise<PriceControllerCreateResponse> {
1485
1587
  return __request(OpenAPI, {
1486
1588
  method: 'POST',
1487
- url: '/api/v1/{region}/bean/recurring-rules',
1589
+ url: '/api/v1/{region}/bean/prices',
1488
1590
  path: {
1489
1591
  region: data.region
1490
1592
  },
1491
1593
  body: data.requestBody,
1492
1594
  mediaType: 'application/json',
1493
1595
  errors: {
1494
- 400: 'Invalid input data (e.g., autoCreate without accounts)',
1495
- 409: 'Rule with same name already exists'
1596
+ 404: 'Currency or quoteCurrency commodity not found',
1597
+ 409: 'Price already exists for this currency pair and date'
1496
1598
  }
1497
1599
  });
1498
1600
  }
1499
1601
 
1500
1602
  /**
1501
- * List recurring rules
1502
- * Returns all recurring rules for the authenticated user with optional filtering
1603
+ * List user prices
1604
+ * Returns all price entries for the authenticated user with optional filtering
1503
1605
  * @param data The data for the request.
1504
1606
  * @param data.region Region code for tenant context
1505
- * @param data.isActive Filter by active status
1506
- * @param data.frequency Filter by frequency (WEEKLY, MONTHLY, etc.)
1507
- * @param data.hasAutoCreate Filter by autoCreate enabled
1508
- * @returns RecurringRuleResponseDto Rules retrieved successfully
1607
+ * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
1608
+ * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
1609
+ * @param data.dateFrom Filter prices from this date (ISO 8601 format)
1610
+ * @param data.dateTo Filter prices to this date (ISO 8601 format)
1611
+ * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
1612
+ * @param data.page Page number for pagination (default: 1)
1613
+ * @param data.limit Number of items per page (default: 20, max: 100)
1614
+ * @returns PriceListResponseDto Prices retrieved successfully
1509
1615
  * @throws ApiError
1510
1616
  */
1511
- public static recurringRuleControllerFindAll(
1512
- data: RecurringRuleControllerFindAllData
1513
- ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
1617
+ public static priceControllerFindAll(
1618
+ data: PriceControllerFindAllData
1619
+ ): CancelablePromise<PriceControllerFindAllResponse> {
1514
1620
  return __request(OpenAPI, {
1515
1621
  method: 'GET',
1516
- url: '/api/v1/{region}/bean/recurring-rules',
1622
+ url: '/api/v1/{region}/bean/prices',
1517
1623
  path: {
1518
1624
  region: data.region
1519
1625
  },
1520
1626
  query: {
1521
- isActive: data.isActive,
1522
- frequency: data.frequency,
1523
- hasAutoCreate: data.hasAutoCreate
1627
+ currency: data.currency,
1628
+ quoteCurrency: data.quoteCurrency,
1629
+ dateFrom: data.dateFrom,
1630
+ dateTo: data.dateTo,
1631
+ search: data.search,
1632
+ page: data.page,
1633
+ limit: data.limit
1524
1634
  }
1525
1635
  });
1526
1636
  }
1527
1637
 
1528
1638
  /**
1529
- * Create recurring rule from transaction
1530
- * Auto-creates a recurring rule using transaction data. User only confirms frequency.
1639
+ * Get price by ID
1640
+ * Returns a single price entry by its ID
1531
1641
  * @param data The data for the request.
1532
- * @param data.transactionId Source transaction ID
1642
+ * @param data.id Price ID
1533
1643
  * @param data.region Region code for tenant context
1534
- * @param data.requestBody
1535
- * @returns RecurringRuleResponseDto Rule created successfully
1644
+ * @returns PriceResponseDto Price retrieved successfully
1536
1645
  * @throws ApiError
1537
1646
  */
1538
- public static recurringRuleControllerCreateFromTransaction(
1539
- data: RecurringRuleControllerCreateFromTransactionData
1540
- ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
1647
+ public static priceControllerFindOne(
1648
+ data: PriceControllerFindOneData
1649
+ ): CancelablePromise<PriceControllerFindOneResponse> {
1541
1650
  return __request(OpenAPI, {
1542
- method: 'POST',
1543
- url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
1651
+ method: 'GET',
1652
+ url: '/api/v1/{region}/bean/prices/{id}',
1544
1653
  path: {
1545
- transactionId: data.transactionId,
1654
+ id: data.id,
1546
1655
  region: data.region
1547
1656
  },
1548
- body: data.requestBody,
1549
- mediaType: 'application/json',
1550
1657
  errors: {
1551
- 404: 'Transaction not found',
1552
- 409: 'Rule with same name already exists or transaction already linked'
1658
+ 404: 'Price not found'
1553
1659
  }
1554
1660
  });
1555
1661
  }
1556
1662
 
1557
1663
  /**
1558
- * Get recurring rule by ID
1559
- * Returns a specific recurring rule with its details
1664
+ * Update a price
1665
+ * Updates an existing price entry
1560
1666
  * @param data The data for the request.
1561
- * @param data.id Rule ID
1667
+ * @param data.id Price ID
1562
1668
  * @param data.region Region code for tenant context
1563
- * @returns RecurringRuleResponseDto Rule retrieved successfully
1669
+ * @param data.requestBody
1670
+ * @returns PriceResponseDto Price updated successfully
1564
1671
  * @throws ApiError
1565
1672
  */
1566
- public static recurringRuleControllerFindOne(
1567
- data: RecurringRuleControllerFindOneData
1568
- ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
1673
+ public static priceControllerUpdate(
1674
+ data: PriceControllerUpdateData
1675
+ ): CancelablePromise<PriceControllerUpdateResponse> {
1569
1676
  return __request(OpenAPI, {
1570
- method: 'GET',
1571
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
1677
+ method: 'PUT',
1678
+ url: '/api/v1/{region}/bean/prices/{id}',
1572
1679
  path: {
1573
1680
  id: data.id,
1574
1681
  region: data.region
1575
1682
  },
1683
+ body: data.requestBody,
1684
+ mediaType: 'application/json',
1576
1685
  errors: {
1577
- 404: 'Rule not found'
1686
+ 404: 'Price not found',
1687
+ 409: 'Updated price conflicts with existing price'
1688
+ }
1689
+ });
1690
+ }
1691
+
1692
+ /**
1693
+ * Delete a price
1694
+ * Deletes a price entry (hard delete)
1695
+ * @param data The data for the request.
1696
+ * @param data.id Price ID
1697
+ * @param data.region Region code for tenant context
1698
+ * @returns void Price deleted successfully
1699
+ * @throws ApiError
1700
+ */
1701
+ public static priceControllerDelete(
1702
+ data: PriceControllerDeleteData
1703
+ ): CancelablePromise<PriceControllerDeleteResponse> {
1704
+ return __request(OpenAPI, {
1705
+ method: 'DELETE',
1706
+ url: '/api/v1/{region}/bean/prices/{id}',
1707
+ path: {
1708
+ id: data.id,
1709
+ region: data.region
1710
+ },
1711
+ errors: {
1712
+ 404: 'Price not found'
1713
+ }
1714
+ });
1715
+ }
1716
+
1717
+ /**
1718
+ * Bulk create prices
1719
+ * Creates multiple price entries at once (skips duplicates)
1720
+ * @param data The data for the request.
1721
+ * @param data.region Region code for tenant context
1722
+ * @param data.requestBody
1723
+ * @returns PriceResponseDto Prices created successfully
1724
+ * @throws ApiError
1725
+ */
1726
+ public static priceControllerBulkCreate(
1727
+ data: PriceControllerBulkCreateData
1728
+ ): CancelablePromise<PriceControllerBulkCreateResponse> {
1729
+ return __request(OpenAPI, {
1730
+ method: 'POST',
1731
+ url: '/api/v1/{region}/bean/prices/bulk',
1732
+ path: {
1733
+ region: data.region
1734
+ },
1735
+ body: data.requestBody,
1736
+ mediaType: 'application/json'
1737
+ });
1738
+ }
1739
+ }
1740
+
1741
+ export class RecurringRulesService {
1742
+ /**
1743
+ * Create a new recurring rule
1744
+ * Creates a new recurring transaction rule for the authenticated user
1745
+ * @param data The data for the request.
1746
+ * @param data.region Region code for tenant context
1747
+ * @param data.requestBody
1748
+ * @returns RecurringRuleResponseDto Rule created successfully
1749
+ * @throws ApiError
1750
+ */
1751
+ public static recurringRuleControllerCreate(
1752
+ data: RecurringRuleControllerCreateData
1753
+ ): CancelablePromise<RecurringRuleControllerCreateResponse> {
1754
+ return __request(OpenAPI, {
1755
+ method: 'POST',
1756
+ url: '/api/v1/{region}/bean/recurring-rules',
1757
+ path: {
1758
+ region: data.region
1759
+ },
1760
+ body: data.requestBody,
1761
+ mediaType: 'application/json',
1762
+ errors: {
1763
+ 400: 'Invalid input data (e.g., autoCreate without accounts)',
1764
+ 409: 'Rule with same name already exists'
1765
+ }
1766
+ });
1767
+ }
1768
+
1769
+ /**
1770
+ * List recurring rules
1771
+ * Returns all recurring rules for the authenticated user with optional filtering
1772
+ * @param data The data for the request.
1773
+ * @param data.region Region code for tenant context
1774
+ * @param data.isActive Filter by active status
1775
+ * @param data.frequency Filter by frequency (WEEKLY, MONTHLY, etc.)
1776
+ * @param data.hasAutoCreate Filter by autoCreate enabled
1777
+ * @returns RecurringRuleResponseDto Rules retrieved successfully
1778
+ * @throws ApiError
1779
+ */
1780
+ public static recurringRuleControllerFindAll(
1781
+ data: RecurringRuleControllerFindAllData
1782
+ ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
1783
+ return __request(OpenAPI, {
1784
+ method: 'GET',
1785
+ url: '/api/v1/{region}/bean/recurring-rules',
1786
+ path: {
1787
+ region: data.region
1788
+ },
1789
+ query: {
1790
+ isActive: data.isActive,
1791
+ frequency: data.frequency,
1792
+ hasAutoCreate: data.hasAutoCreate
1793
+ }
1794
+ });
1795
+ }
1796
+
1797
+ /**
1798
+ * Create recurring rule from transaction
1799
+ * Auto-creates a recurring rule using transaction data. User only confirms frequency.
1800
+ * @param data The data for the request.
1801
+ * @param data.transactionId Source transaction ID
1802
+ * @param data.region Region code for tenant context
1803
+ * @param data.requestBody
1804
+ * @returns RecurringRuleResponseDto Rule created successfully
1805
+ * @throws ApiError
1806
+ */
1807
+ public static recurringRuleControllerCreateFromTransaction(
1808
+ data: RecurringRuleControllerCreateFromTransactionData
1809
+ ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
1810
+ return __request(OpenAPI, {
1811
+ method: 'POST',
1812
+ url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
1813
+ path: {
1814
+ transactionId: data.transactionId,
1815
+ region: data.region
1816
+ },
1817
+ body: data.requestBody,
1818
+ mediaType: 'application/json',
1819
+ errors: {
1820
+ 404: 'Transaction not found',
1821
+ 409: 'Rule with same name already exists or transaction already linked'
1822
+ }
1823
+ });
1824
+ }
1825
+
1826
+ /**
1827
+ * Get recurring rule by ID
1828
+ * Returns a specific recurring rule with its details
1829
+ * @param data The data for the request.
1830
+ * @param data.id Rule ID
1831
+ * @param data.region Region code for tenant context
1832
+ * @returns RecurringRuleResponseDto Rule retrieved successfully
1833
+ * @throws ApiError
1834
+ */
1835
+ public static recurringRuleControllerFindOne(
1836
+ data: RecurringRuleControllerFindOneData
1837
+ ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
1838
+ return __request(OpenAPI, {
1839
+ method: 'GET',
1840
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
1841
+ path: {
1842
+ id: data.id,
1843
+ region: data.region
1844
+ },
1845
+ errors: {
1846
+ 404: 'Rule not found'
1578
1847
  }
1579
1848
  });
1580
1849
  }
@@ -1899,279 +2168,158 @@ export class RecurringForecastService {
1899
2168
  }
1900
2169
  }
1901
2170
 
1902
- export class BeanTransactionRulesService {
2171
+ export class ReportingService {
1903
2172
  /**
1904
- * Create a new transaction rule (or upsert if upsertByPayee=true)
1905
- * Creates a new rule. If upsertByPayee=true, updates existing rule matching payeeKeywords[0] instead of creating duplicate.
2173
+ * Get portfolio value trends
2174
+ *
2175
+ * Returns time series data of portfolio net worth.
2176
+ *
2177
+ * **Multi-currency Support:**
2178
+ * - `series[].byCurrency` - Currency breakdown for each data point
2179
+ * - `byCurrency` - Separate time series grouped by currency
2180
+ * - `warnings` - Exchange rate warnings if conversion failed
2181
+ *
2182
+ * **Parameters:**
2183
+ * - `period`: Time period (1m, 3m, 6m, 1y)
2184
+ * - `granularity`: Data granularity (day, week, month)
2185
+ *
1906
2186
  * @param data The data for the request.
1907
2187
  * @param data.region Region code for tenant context
1908
- * @param data.requestBody
1909
- * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2188
+ * @param data.period Time period
2189
+ * @param data.granularity Data granularity
2190
+ * @returns PortfolioTrendsResponseDto Trends retrieved successfully
1910
2191
  * @throws ApiError
1911
2192
  */
1912
- public static transactionRuleControllerCreate(
1913
- data: TransactionRuleControllerCreateData
1914
- ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2193
+ public static reportingControllerGetPortfolioTrends(
2194
+ data: ReportingControllerGetPortfolioTrendsData
2195
+ ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
1915
2196
  return __request(OpenAPI, {
1916
- method: 'POST',
1917
- url: '/api/v1/{region}/bean/transaction-rules',
2197
+ method: 'GET',
2198
+ url: '/api/v1/{region}/reporting/portfolio/trends',
1918
2199
  path: {
1919
2200
  region: data.region
1920
2201
  },
1921
- body: data.requestBody,
1922
- mediaType: 'application/json',
2202
+ query: {
2203
+ period: data.period,
2204
+ granularity: data.granularity
2205
+ },
1923
2206
  errors: {
1924
- 400: 'Validation failed',
1925
- 401: 'Unauthorized',
1926
- 409: 'Resource conflict - another process is updating this rule'
2207
+ 401: 'User not authenticated'
1927
2208
  }
1928
2209
  });
1929
2210
  }
1930
2211
 
1931
2212
  /**
1932
- * Get all transaction rules for user
2213
+ * Get cash-flow trends
2214
+ *
2215
+ * Monthly income / expense / netSavings over a fixed N-month window
2216
+ * (current month + N−1 prior). Missing months are zero-filled (flow metric).
2217
+ *
2218
+ * **Parameters:**
2219
+ * - `period`: 1m | 3m | 6m | 1y (default 6m)
2220
+ * - `granularity`: accepted for API symmetry; v1 returns month buckets
2221
+ *
1933
2222
  * @param data The data for the request.
1934
2223
  * @param data.region Region code for tenant context
1935
- * @param data.limit Max results per page (default: 20, max: 100)
1936
- * @param data.offset Pagination offset (default: 0)
1937
- * @param data.enabled Filter by enabled status
1938
- * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
1939
- * @param data.autoApplyEnabled Filter by auto-apply status
1940
- * @returns TransactionRuleListResponseDto List of rules
2224
+ * @param data.period Time period
2225
+ * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
2226
+ * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
1941
2227
  * @throws ApiError
1942
2228
  */
1943
- public static transactionRuleControllerList(
1944
- data: TransactionRuleControllerListData
1945
- ): CancelablePromise<TransactionRuleControllerListResponse> {
2229
+ public static reportingControllerGetCashFlowTrends(
2230
+ data: ReportingControllerGetCashFlowTrendsData
2231
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
1946
2232
  return __request(OpenAPI, {
1947
2233
  method: 'GET',
1948
- url: '/api/v1/{region}/bean/transaction-rules',
2234
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
1949
2235
  path: {
1950
2236
  region: data.region
1951
2237
  },
1952
2238
  query: {
1953
- limit: data.limit,
1954
- offset: data.offset,
1955
- enabled: data.enabled,
1956
- learningSource: data.learningSource,
1957
- autoApplyEnabled: data.autoApplyEnabled
2239
+ period: data.period,
2240
+ granularity: data.granularity
1958
2241
  },
1959
2242
  errors: {
1960
- 401: 'Unauthorized'
2243
+ 401: 'User not authenticated'
1961
2244
  }
1962
2245
  });
1963
2246
  }
1964
2247
 
1965
2248
  /**
1966
- * Validate transaction rule configuration
2249
+ * Generate portfolio snapshot
2250
+ *
2251
+ * Manually generate a portfolio snapshot for a specific date.
2252
+ *
2253
+ * **Multi-currency Support:**
2254
+ * - Fetches balances grouped by currency
2255
+ * - Uses user's baseCurrency setting for conversion
2256
+ * - Stores exchange rates and warnings
2257
+ *
2258
+ * **Use Cases:**
2259
+ * - Testing snapshot generation
2260
+ * - Force regeneration after data correction
2261
+ * - Initial setup for new users
2262
+ *
1967
2263
  * @param data The data for the request.
1968
2264
  * @param data.region Region code for tenant context
1969
- * @param data.requestBody
1970
- * @returns ValidateRuleResponseDto Validation result
2265
+ * @param data.requestBody Optional date (defaults to today)
2266
+ * @returns GenerateSnapshotResponse Snapshot generated successfully
1971
2267
  * @throws ApiError
1972
2268
  */
1973
- public static transactionRuleControllerValidate(
1974
- data: TransactionRuleControllerValidateData
1975
- ): CancelablePromise<TransactionRuleControllerValidateResponse> {
2269
+ public static reportingControllerGenerateSnapshot(
2270
+ data: ReportingControllerGenerateSnapshotData
2271
+ ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
1976
2272
  return __request(OpenAPI, {
1977
2273
  method: 'POST',
1978
- url: '/api/v1/{region}/bean/transaction-rules/validate',
2274
+ url: '/api/v1/{region}/reporting/snapshots/generate',
1979
2275
  path: {
1980
2276
  region: data.region
1981
2277
  },
1982
2278
  body: data.requestBody,
1983
2279
  mediaType: 'application/json',
1984
2280
  errors: {
1985
- 400: 'Validation failed',
1986
- 401: 'Unauthorized'
1987
- }
1988
- });
1989
- }
1990
-
1991
- /**
1992
- * Bulk create transaction rules
1993
- * @param data The data for the request.
1994
- * @param data.region Region code for tenant context
1995
- * @param data.requestBody
1996
- * @returns BulkCreateRulesResponseDto Bulk create completed
1997
- * @throws ApiError
1998
- */
1999
- public static transactionRuleControllerBulkCreate(
2000
- data: TransactionRuleControllerBulkCreateData
2001
- ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
2002
- return __request(OpenAPI, {
2003
- method: 'POST',
2004
- url: '/api/v1/{region}/bean/transaction-rules/bulk',
2005
- path: {
2006
- region: data.region
2007
- },
2008
- body: data.requestBody,
2009
- mediaType: 'application/json',
2010
- errors: {
2011
- 400: 'Invalid bulk create data',
2012
- 401: 'Unauthorized'
2013
- }
2014
- });
2015
- }
2016
-
2017
- /**
2018
- * Export transaction rules
2019
- * @param data The data for the request.
2020
- * @param data.format Export format (currently only JSON supported)
2021
- * @param data.region Region code for tenant context
2022
- * @returns ExportRulesResponseDto Exported rules
2023
- * @throws ApiError
2024
- */
2025
- public static transactionRuleControllerExport(
2026
- data: TransactionRuleControllerExportData
2027
- ): CancelablePromise<TransactionRuleControllerExportResponse> {
2028
- return __request(OpenAPI, {
2029
- method: 'GET',
2030
- url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2031
- path: {
2032
- format: data.format,
2033
- region: data.region
2034
- },
2035
- errors: {
2036
- 400: 'Unsupported format',
2037
- 401: 'Unauthorized'
2038
- }
2039
- });
2040
- }
2041
-
2042
- /**
2043
- * Get transaction rule statistics
2044
- * @param data The data for the request.
2045
- * @param data.period Statistics time period
2046
- * @param data.region Region code for tenant context
2047
- * @returns RuleStatisticsResponseDto Rule statistics
2048
- * @throws ApiError
2049
- */
2050
- public static transactionRuleControllerGetStatistics(
2051
- data: TransactionRuleControllerGetStatisticsData
2052
- ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
2053
- return __request(OpenAPI, {
2054
- method: 'GET',
2055
- url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
2056
- path: {
2057
- period: data.period,
2058
- region: data.region
2059
- },
2060
- errors: {
2061
- 401: 'Unauthorized'
2062
- }
2063
- });
2064
- }
2065
-
2066
- /**
2067
- * Get transaction rule detail
2068
- * @param data The data for the request.
2069
- * @param data.ruleId Rule ID
2070
- * @param data.region Region code for tenant context
2071
- * @returns TransactionRuleResponseDto Rule details
2072
- * @throws ApiError
2073
- */
2074
- public static transactionRuleControllerGetDetail(
2075
- data: TransactionRuleControllerGetDetailData
2076
- ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
2077
- return __request(OpenAPI, {
2078
- method: 'GET',
2079
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2080
- path: {
2081
- ruleId: data.ruleId,
2082
- region: data.region
2083
- },
2084
- errors: {
2085
- 401: 'Unauthorized',
2086
- 403: 'Forbidden - not owner of rule',
2087
- 404: 'Rule not found'
2088
- }
2089
- });
2090
- }
2091
-
2092
- /**
2093
- * Update a transaction rule
2094
- * @param data The data for the request.
2095
- * @param data.ruleId Rule ID to update
2096
- * @param data.region Region code for tenant context
2097
- * @param data.requestBody
2098
- * @returns TransactionRuleResponseDto Rule updated successfully
2099
- * @throws ApiError
2100
- */
2101
- public static transactionRuleControllerUpdate(
2102
- data: TransactionRuleControllerUpdateData
2103
- ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2104
- return __request(OpenAPI, {
2105
- method: 'PUT',
2106
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2107
- path: {
2108
- ruleId: data.ruleId,
2109
- region: data.region
2110
- },
2111
- body: data.requestBody,
2112
- mediaType: 'application/json',
2113
- errors: {
2114
- 400: 'Validation failed',
2115
- 401: 'Unauthorized',
2116
- 403: 'Forbidden - not owner of rule',
2117
- 404: 'Rule not found',
2118
- 409: 'Resource conflict - rule is being modified by another process'
2119
- }
2120
- });
2121
- }
2122
-
2123
- /**
2124
- * Delete a transaction rule
2125
- * @param data The data for the request.
2126
- * @param data.ruleId Rule ID to delete
2127
- * @param data.region Region code for tenant context
2128
- * @returns void Rule deleted successfully
2129
- * @throws ApiError
2130
- */
2131
- public static transactionRuleControllerDelete(
2132
- data: TransactionRuleControllerDeleteData
2133
- ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2134
- return __request(OpenAPI, {
2135
- method: 'DELETE',
2136
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2137
- path: {
2138
- ruleId: data.ruleId,
2139
- region: data.region
2140
- },
2141
- errors: {
2142
- 401: 'Unauthorized',
2143
- 403: 'Forbidden - not owner of rule',
2144
- 404: 'Rule not found',
2145
- 409: 'Resource conflict - rule is being modified by another process'
2281
+ 400: 'Invalid date format',
2282
+ 401: 'User not authenticated'
2146
2283
  }
2147
2284
  });
2148
2285
  }
2149
2286
 
2150
2287
  /**
2151
- * Test rule matching
2288
+ * Backfill portfolio snapshots
2289
+ *
2290
+ * Generate snapshots for a date range (historical data backfill).
2291
+ *
2292
+ * **Multi-currency Support:**
2293
+ * - Each snapshot includes multi-currency data
2294
+ * - Uses exchange rates available at generation time
2295
+ * - Warnings stored for missing exchange rates
2296
+ *
2297
+ * **Best Practices:**
2298
+ * - Use for initial setup after account configuration
2299
+ * - Run during low-traffic periods for large date ranges
2300
+ * - Existing snapshots are skipped (not regenerated)
2301
+ *
2152
2302
  * @param data The data for the request.
2153
- * @param data.ruleId Rule ID to test
2154
2303
  * @param data.region Region code for tenant context
2155
2304
  * @param data.requestBody
2156
- * @returns TestRuleResponseDto Test result
2305
+ * @returns BackfillSnapshotsResponse Backfill completed successfully
2157
2306
  * @throws ApiError
2158
2307
  */
2159
- public static transactionRuleControllerTest(
2160
- data: TransactionRuleControllerTestData
2161
- ): CancelablePromise<TransactionRuleControllerTestResponse> {
2308
+ public static reportingControllerBackfillSnapshots(
2309
+ data: ReportingControllerBackfillSnapshotsData
2310
+ ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
2162
2311
  return __request(OpenAPI, {
2163
2312
  method: 'POST',
2164
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2313
+ url: '/api/v1/{region}/reporting/snapshots/backfill',
2165
2314
  path: {
2166
- ruleId: data.ruleId,
2167
2315
  region: data.region
2168
2316
  },
2169
2317
  body: data.requestBody,
2170
2318
  mediaType: 'application/json',
2171
2319
  errors: {
2172
- 401: 'Unauthorized',
2173
- 403: 'Forbidden - not owner of rule',
2174
- 404: 'Rule not found'
2320
+ 400: 'Invalid date format or range',
2321
+ 401: 'User not authenticated',
2322
+ 409: 'Backfill already in progress for this user'
2175
2323
  }
2176
2324
  });
2177
2325
  }
@@ -2203,7 +2351,7 @@ export class UsersService {
2203
2351
  * Get current authenticated user
2204
2352
  * @param data The data for the request.
2205
2353
  * @param data.acceptLanguage
2206
- * @returns unknown User retrieved successfully
2354
+ * @returns UserResponseDto User retrieved successfully
2207
2355
  * @throws ApiError
2208
2356
  */
2209
2357
  public static userControllerGetUser(
@@ -2223,7 +2371,7 @@ export class UsersService {
2223
2371
  * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
2224
2372
  * @param data The data for the request.
2225
2373
  * @param data.requestBody
2226
- * @returns unknown User created successfully
2374
+ * @returns SignupResponseDto User created successfully
2227
2375
  * @throws ApiError
2228
2376
  */
2229
2377
  public static userControllerSignupUser(
@@ -2432,286 +2580,793 @@ export class PropertiesService {
2432
2580
  }
2433
2581
  }
2434
2582
 
2435
- export class BeanExportService {
2436
- /**
2437
- * Export Beancount ledger as ZIP
2438
- * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
2439
- * @returns unknown
2440
- * @throws ApiError
2441
- */
2442
- public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
2443
- return __request(OpenAPI, {
2444
- method: 'GET',
2445
- url: '/api/v1/{region}/bean/export/beancount'
2446
- });
2447
- }
2448
- }
2449
-
2450
- export class BeanImportService {
2583
+ export class BeanTransactionRulesService {
2451
2584
  /**
2452
- * Import a bill file
2453
- * Upload and process a bill file (CSV, PDF, OFX, etc.). The system automatically identifies the file type, extracts transactions, validates them, and stores only validated transactions to the database. Maximum file size: 50MB. Only 1 import per user at a time (concurrent imports rejected with 429).
2585
+ * Create a new transaction rule (or upsert if upsertByPayee=true)
2586
+ * Creates a new rule. If upsertByPayee=true, updates existing rule matching payeeKeywords[0] instead of creating duplicate.
2454
2587
  * @param data The data for the request.
2455
2588
  * @param data.region Region code for tenant context
2456
- * @param data.formData Bill file to import
2457
- * @returns ImportResultDto File imported successfully
2589
+ * @param data.requestBody
2590
+ * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2458
2591
  * @throws ApiError
2459
2592
  */
2460
- public static fileImportControllerImportFile(
2461
- data: FileImportControllerImportFileData
2462
- ): CancelablePromise<FileImportControllerImportFileResponse> {
2593
+ public static transactionRuleControllerCreate(
2594
+ data: TransactionRuleControllerCreateData
2595
+ ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2463
2596
  return __request(OpenAPI, {
2464
2597
  method: 'POST',
2465
- url: '/api/v1/{region}/bean/import/file',
2598
+ url: '/api/v1/{region}/bean/transaction-rules',
2466
2599
  path: {
2467
2600
  region: data.region
2468
2601
  },
2469
- formData: data.formData,
2470
- mediaType: 'multipart/form-data',
2602
+ body: data.requestBody,
2603
+ mediaType: 'application/json',
2471
2604
  errors: {
2472
- 400: 'Bad request - file-format-unsupported or file-import-failed',
2473
- 413: 'Payload too large - file exceeds 50MB limit',
2474
- 429: 'Too many requests - user already has import in progress',
2475
- 500: 'Internal server error - DATABASE_ERROR'
2605
+ 400: 'Validation failed',
2606
+ 401: 'Unauthorized',
2607
+ 409: 'Resource conflict - another process is updating this rule'
2476
2608
  }
2477
2609
  });
2478
2610
  }
2479
2611
 
2480
2612
  /**
2481
- * Identify file type
2482
- * Upload a file to check if it can be processed by any registered importer. Does not perform actual import - useful for pre-validation. Uses user-specific importer configuration.
2613
+ * Get all transaction rules for user
2483
2614
  * @param data The data for the request.
2484
2615
  * @param data.region Region code for tenant context
2485
- * @param data.formData File to identify
2486
- * @returns IdentifyResultDto File identification result
2616
+ * @param data.limit Max results per page (default: 20, max: 100)
2617
+ * @param data.offset Pagination offset (default: 0)
2618
+ * @param data.enabled Filter by enabled status
2619
+ * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
2620
+ * @param data.autoApplyEnabled Filter by auto-apply status
2621
+ * @returns TransactionRuleListResponseDto List of rules
2487
2622
  * @throws ApiError
2488
2623
  */
2489
- public static fileImportControllerIdentifyFile(
2490
- data: FileImportControllerIdentifyFileData
2491
- ): CancelablePromise<FileImportControllerIdentifyFileResponse> {
2624
+ public static transactionRuleControllerList(
2625
+ data: TransactionRuleControllerListData
2626
+ ): CancelablePromise<TransactionRuleControllerListResponse> {
2492
2627
  return __request(OpenAPI, {
2493
- method: 'POST',
2494
- url: '/api/v1/{region}/bean/import/identify',
2628
+ method: 'GET',
2629
+ url: '/api/v1/{region}/bean/transaction-rules',
2630
+ path: {
2631
+ region: data.region
2632
+ },
2633
+ query: {
2634
+ limit: data.limit,
2635
+ offset: data.offset,
2636
+ enabled: data.enabled,
2637
+ learningSource: data.learningSource,
2638
+ autoApplyEnabled: data.autoApplyEnabled
2639
+ },
2640
+ errors: {
2641
+ 401: 'Unauthorized'
2642
+ }
2643
+ });
2644
+ }
2645
+
2646
+ /**
2647
+ * Validate transaction rule configuration
2648
+ * @param data The data for the request.
2649
+ * @param data.region Region code for tenant context
2650
+ * @param data.requestBody
2651
+ * @returns ValidateRuleResponseDto Validation result
2652
+ * @throws ApiError
2653
+ */
2654
+ public static transactionRuleControllerValidate(
2655
+ data: TransactionRuleControllerValidateData
2656
+ ): CancelablePromise<TransactionRuleControllerValidateResponse> {
2657
+ return __request(OpenAPI, {
2658
+ method: 'POST',
2659
+ url: '/api/v1/{region}/bean/transaction-rules/validate',
2660
+ path: {
2661
+ region: data.region
2662
+ },
2663
+ body: data.requestBody,
2664
+ mediaType: 'application/json',
2665
+ errors: {
2666
+ 400: 'Validation failed',
2667
+ 401: 'Unauthorized'
2668
+ }
2669
+ });
2670
+ }
2671
+
2672
+ /**
2673
+ * Bulk create transaction rules
2674
+ * @param data The data for the request.
2675
+ * @param data.region Region code for tenant context
2676
+ * @param data.requestBody
2677
+ * @returns BulkCreateRulesResponseDto Bulk create completed
2678
+ * @throws ApiError
2679
+ */
2680
+ public static transactionRuleControllerBulkCreate(
2681
+ data: TransactionRuleControllerBulkCreateData
2682
+ ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
2683
+ return __request(OpenAPI, {
2684
+ method: 'POST',
2685
+ url: '/api/v1/{region}/bean/transaction-rules/bulk',
2686
+ path: {
2687
+ region: data.region
2688
+ },
2689
+ body: data.requestBody,
2690
+ mediaType: 'application/json',
2691
+ errors: {
2692
+ 400: 'Invalid bulk create data',
2693
+ 401: 'Unauthorized'
2694
+ }
2695
+ });
2696
+ }
2697
+
2698
+ /**
2699
+ * Export transaction rules
2700
+ * @param data The data for the request.
2701
+ * @param data.format Export format (currently only JSON supported)
2702
+ * @param data.region Region code for tenant context
2703
+ * @returns ExportRulesResponseDto Exported rules
2704
+ * @throws ApiError
2705
+ */
2706
+ public static transactionRuleControllerExport(
2707
+ data: TransactionRuleControllerExportData
2708
+ ): CancelablePromise<TransactionRuleControllerExportResponse> {
2709
+ return __request(OpenAPI, {
2710
+ method: 'GET',
2711
+ url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2712
+ path: {
2713
+ format: data.format,
2714
+ region: data.region
2715
+ },
2716
+ errors: {
2717
+ 400: 'Unsupported format',
2718
+ 401: 'Unauthorized'
2719
+ }
2720
+ });
2721
+ }
2722
+
2723
+ /**
2724
+ * Get transaction rule statistics
2725
+ * @param data The data for the request.
2726
+ * @param data.period Statistics time period
2727
+ * @param data.region Region code for tenant context
2728
+ * @returns RuleStatisticsResponseDto Rule statistics
2729
+ * @throws ApiError
2730
+ */
2731
+ public static transactionRuleControllerGetStatistics(
2732
+ data: TransactionRuleControllerGetStatisticsData
2733
+ ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
2734
+ return __request(OpenAPI, {
2735
+ method: 'GET',
2736
+ url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
2737
+ path: {
2738
+ period: data.period,
2739
+ region: data.region
2740
+ },
2741
+ errors: {
2742
+ 401: 'Unauthorized'
2743
+ }
2744
+ });
2745
+ }
2746
+
2747
+ /**
2748
+ * Get transaction rule detail
2749
+ * @param data The data for the request.
2750
+ * @param data.ruleId Rule ID
2751
+ * @param data.region Region code for tenant context
2752
+ * @returns TransactionRuleResponseDto Rule details
2753
+ * @throws ApiError
2754
+ */
2755
+ public static transactionRuleControllerGetDetail(
2756
+ data: TransactionRuleControllerGetDetailData
2757
+ ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
2758
+ return __request(OpenAPI, {
2759
+ method: 'GET',
2760
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2761
+ path: {
2762
+ ruleId: data.ruleId,
2763
+ region: data.region
2764
+ },
2765
+ errors: {
2766
+ 401: 'Unauthorized',
2767
+ 403: 'Forbidden - not owner of rule',
2768
+ 404: 'Rule not found'
2769
+ }
2770
+ });
2771
+ }
2772
+
2773
+ /**
2774
+ * Update a transaction rule
2775
+ * @param data The data for the request.
2776
+ * @param data.ruleId Rule ID to update
2777
+ * @param data.region Region code for tenant context
2778
+ * @param data.requestBody
2779
+ * @returns TransactionRuleResponseDto Rule updated successfully
2780
+ * @throws ApiError
2781
+ */
2782
+ public static transactionRuleControllerUpdate(
2783
+ data: TransactionRuleControllerUpdateData
2784
+ ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2785
+ return __request(OpenAPI, {
2786
+ method: 'PUT',
2787
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2788
+ path: {
2789
+ ruleId: data.ruleId,
2790
+ region: data.region
2791
+ },
2792
+ body: data.requestBody,
2793
+ mediaType: 'application/json',
2794
+ errors: {
2795
+ 400: 'Validation failed',
2796
+ 401: 'Unauthorized',
2797
+ 403: 'Forbidden - not owner of rule',
2798
+ 404: 'Rule not found',
2799
+ 409: 'Resource conflict - rule is being modified by another process'
2800
+ }
2801
+ });
2802
+ }
2803
+
2804
+ /**
2805
+ * Delete a transaction rule
2806
+ * @param data The data for the request.
2807
+ * @param data.ruleId Rule ID to delete
2808
+ * @param data.region Region code for tenant context
2809
+ * @returns void Rule deleted successfully
2810
+ * @throws ApiError
2811
+ */
2812
+ public static transactionRuleControllerDelete(
2813
+ data: TransactionRuleControllerDeleteData
2814
+ ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2815
+ return __request(OpenAPI, {
2816
+ method: 'DELETE',
2817
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2818
+ path: {
2819
+ ruleId: data.ruleId,
2820
+ region: data.region
2821
+ },
2822
+ errors: {
2823
+ 401: 'Unauthorized',
2824
+ 403: 'Forbidden - not owner of rule',
2825
+ 404: 'Rule not found',
2826
+ 409: 'Resource conflict - rule is being modified by another process'
2827
+ }
2828
+ });
2829
+ }
2830
+
2831
+ /**
2832
+ * Test rule matching
2833
+ * @param data The data for the request.
2834
+ * @param data.ruleId Rule ID to test
2835
+ * @param data.region Region code for tenant context
2836
+ * @param data.requestBody
2837
+ * @returns TestRuleResponseDto Test result
2838
+ * @throws ApiError
2839
+ */
2840
+ public static transactionRuleControllerTest(
2841
+ data: TransactionRuleControllerTestData
2842
+ ): CancelablePromise<TransactionRuleControllerTestResponse> {
2843
+ return __request(OpenAPI, {
2844
+ method: 'POST',
2845
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2846
+ path: {
2847
+ ruleId: data.ruleId,
2848
+ region: data.region
2849
+ },
2850
+ body: data.requestBody,
2851
+ mediaType: 'application/json',
2852
+ errors: {
2853
+ 401: 'Unauthorized',
2854
+ 403: 'Forbidden - not owner of rule',
2855
+ 404: 'Rule not found'
2856
+ }
2857
+ });
2858
+ }
2859
+ }
2860
+
2861
+ export class BeanCategoryCatalogService {
2862
+ /**
2863
+ * List category catalog for a region
2864
+ * Returns the region-scoped category slugs (expense/income/investment/banking/transfer/payment) for the NLP result picker. CN-exclusive payment instruments (huabei/baitiao) appear only under /cn.
2865
+ * @param data The data for the request.
2866
+ * @param data.region Region code for tenant context
2867
+ * @param data.scenario Filter by scenario
2868
+ * @param data.routeBearing Filter by routeBearing (entity-router route() consumes it)
2869
+ * @returns CategoryCatalogListResponseDto Category catalog retrieved successfully
2870
+ * @throws ApiError
2871
+ */
2872
+ public static categoryCatalogControllerList(
2873
+ data: CategoryCatalogControllerListData
2874
+ ): CancelablePromise<CategoryCatalogControllerListResponse> {
2875
+ return __request(OpenAPI, {
2876
+ method: 'GET',
2877
+ url: '/api/v1/{region}/bean/categories',
2878
+ path: {
2879
+ region: data.region
2880
+ },
2881
+ query: {
2882
+ scenario: data.scenario,
2883
+ routeBearing: data.routeBearing
2884
+ }
2885
+ });
2886
+ }
2887
+ }
2888
+
2889
+ export class LifeEventsService {
2890
+ /**
2891
+ * Create a new life event
2892
+ * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
2893
+ * @param data The data for the request.
2894
+ * @param data.region Region code for tenant context (decorative for life events)
2895
+ * @param data.requestBody
2896
+ * @returns EventResponseDto Life event created successfully
2897
+ * @throws ApiError
2898
+ */
2899
+ public static eventControllerCreate(
2900
+ data: EventControllerCreateData
2901
+ ): CancelablePromise<EventControllerCreateResponse> {
2902
+ return __request(OpenAPI, {
2903
+ method: 'POST',
2904
+ url: '/api/v1/{region}/bean/events',
2905
+ path: {
2906
+ region: data.region
2907
+ },
2908
+ body: data.requestBody,
2909
+ mediaType: 'application/json',
2910
+ errors: {
2911
+ 409: 'Life event already exists for this (userId, type, date) combination'
2912
+ }
2913
+ });
2914
+ }
2915
+
2916
+ /**
2917
+ * List user life events
2918
+ * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2919
+ * @param data The data for the request.
2920
+ * @param data.region Region code for tenant context (decorative for life events)
2921
+ * @param data.type Filter by life event type (exact match)
2922
+ * @param data.q Search term for description (case-insensitive partial match)
2923
+ * @param data.from Filter life events from this date (ISO 8601 format)
2924
+ * @param data.to Filter life events to this date (ISO 8601 format)
2925
+ * @param data.page Page number for pagination (default: 1)
2926
+ * @param data.limit Number of items per page (default: 20, max: 100)
2927
+ * @returns EventListResponseDto Life events retrieved successfully
2928
+ * @throws ApiError
2929
+ */
2930
+ public static eventControllerFindAll(
2931
+ data: EventControllerFindAllData
2932
+ ): CancelablePromise<EventControllerFindAllResponse> {
2933
+ return __request(OpenAPI, {
2934
+ method: 'GET',
2935
+ url: '/api/v1/{region}/bean/events',
2936
+ path: {
2937
+ region: data.region
2938
+ },
2939
+ query: {
2940
+ type: data.type,
2941
+ q: data.q,
2942
+ from: data.from,
2943
+ to: data.to,
2944
+ page: data.page,
2945
+ limit: data.limit
2946
+ }
2947
+ });
2948
+ }
2949
+
2950
+ /**
2951
+ * Get life event by ID
2952
+ * Returns a single life event by its ID. Returns ETag header.
2953
+ * @param data The data for the request.
2954
+ * @param data.id Life event ID
2955
+ * @param data.region Region code for tenant context (decorative for life events)
2956
+ * @returns EventResponseDto Life event retrieved successfully
2957
+ * @throws ApiError
2958
+ */
2959
+ public static eventControllerFindOne(
2960
+ data: EventControllerFindOneData
2961
+ ): CancelablePromise<EventControllerFindOneResponse> {
2962
+ return __request(OpenAPI, {
2963
+ method: 'GET',
2964
+ url: '/api/v1/{region}/bean/events/{id}',
2965
+ path: {
2966
+ id: data.id,
2967
+ region: data.region
2968
+ },
2969
+ errors: {
2970
+ 404: 'Life event not found'
2971
+ }
2972
+ });
2973
+ }
2974
+
2975
+ /**
2976
+ * Update a life event
2977
+ * Updates an existing life event. If If-Match header is provided, performs optimistic concurrency check; mismatched updatedAt returns 412.
2978
+ * @param data The data for the request.
2979
+ * @param data.id Life event ID
2980
+ * @param data.region Region code for tenant context (decorative for life events)
2981
+ * @param data.requestBody
2982
+ * @returns EventResponseDto Life event updated successfully
2983
+ * @throws ApiError
2984
+ */
2985
+ public static eventControllerUpdate(
2986
+ data: EventControllerUpdateData
2987
+ ): CancelablePromise<EventControllerUpdateResponse> {
2988
+ return __request(OpenAPI, {
2989
+ method: 'PUT',
2990
+ url: '/api/v1/{region}/bean/events/{id}',
2495
2991
  path: {
2992
+ id: data.id,
2496
2993
  region: data.region
2497
2994
  },
2498
- formData: data.formData,
2499
- mediaType: 'multipart/form-data',
2995
+ body: data.requestBody,
2996
+ mediaType: 'application/json',
2500
2997
  errors: {
2501
- 400: 'Bad request - No file uploaded'
2998
+ 400: 'If-Match header is not a valid ISO 8601 date',
2999
+ 404: 'Life event not found',
3000
+ 409: 'Updated event conflicts with an existing (userId, type, date) combination',
3001
+ 412: 'If-Match precondition failed (updatedAt mismatch)'
2502
3002
  }
2503
3003
  });
2504
3004
  }
2505
3005
 
2506
3006
  /**
3007
+ * Delete a life event
3008
+ * Deletes a life event entry (hard delete). Returns 204.
2507
3009
  * @param data The data for the request.
2508
- * @param data.region Region code for tenant context
2509
- * @returns unknown
3010
+ * @param data.id Life event ID
3011
+ * @param data.region Region code for tenant context (decorative for life events)
3012
+ * @returns void Life event deleted successfully
2510
3013
  * @throws ApiError
2511
3014
  */
2512
- public static fileImportControllerImportBeancount(
2513
- data: FileImportControllerImportBeancountData
2514
- ): CancelablePromise<FileImportControllerImportBeancountResponse> {
3015
+ public static eventControllerDelete(
3016
+ data: EventControllerDeleteData
3017
+ ): CancelablePromise<EventControllerDeleteResponse> {
2515
3018
  return __request(OpenAPI, {
2516
- method: 'POST',
2517
- url: '/api/v1/{region}/bean/import/beancount',
3019
+ method: 'DELETE',
3020
+ url: '/api/v1/{region}/bean/events/{id}',
2518
3021
  path: {
3022
+ id: data.id,
2519
3023
  region: data.region
3024
+ },
3025
+ errors: {
3026
+ 404: 'Life event not found'
2520
3027
  }
2521
3028
  });
2522
3029
  }
2523
3030
 
2524
3031
  /**
2525
- * Get importer configuration
2526
- * Returns the current configuration for the specified importer. Creates default configuration if none exists.
3032
+ * Slice time-series by a life event (Phase 79)
3033
+ * Returns aggregated time-series for postings matching accountPattern within the half-open date range of the given life event.
2527
3034
  * @param data The data for the request.
2528
- * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
2529
- * @param data.region Region code for tenant context
2530
- * @returns ImporterConfigDto Configuration retrieved successfully
3035
+ * @param data.id Life event ID
3036
+ * @param data.accountPattern
3037
+ * @param data.granularity
3038
+ * @param data.region Region code for tenant context (decorative for life events)
3039
+ * @returns unknown Time-series sliced by the life event range
2531
3040
  * @throws ApiError
2532
3041
  */
2533
- public static importerConfigControllerGetConfig(
2534
- data: ImporterConfigControllerGetConfigData
2535
- ): CancelablePromise<ImporterConfigControllerGetConfigResponse> {
3042
+ public static eventControllerGetSlice(
3043
+ data: EventControllerGetSliceData
3044
+ ): CancelablePromise<EventControllerGetSliceResponse> {
2536
3045
  return __request(OpenAPI, {
2537
3046
  method: 'GET',
2538
- url: '/api/v1/{region}/bean/import/config/{importerId}',
3047
+ url: '/api/v1/{region}/bean/events/{id}/slice',
2539
3048
  path: {
2540
- importerId: data.importerId,
3049
+ id: data.id,
2541
3050
  region: data.region
2542
3051
  },
3052
+ query: {
3053
+ accountPattern: data.accountPattern,
3054
+ granularity: data.granularity
3055
+ },
2543
3056
  errors: {
2544
- 400: 'Invalid input - Unsupported importer',
2545
- 401: 'Unauthorized - Authentication required'
3057
+ 400: 'accountPattern query param is empty',
3058
+ 404: 'Life event not found'
2546
3059
  }
2547
3060
  });
2548
3061
  }
3062
+ }
2549
3063
 
3064
+ export class OnboardingService {
2550
3065
  /**
2551
- * Update importer configuration
2552
- * Updates the configuration for the specified importer. Partial updates are supported.
3066
+ * Bootstrap core accounts + register asset accounts with opening balances (ADR-0113)
2553
3067
  * @param data The data for the request.
2554
- * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
2555
3068
  * @param data.region Region code for tenant context
2556
- * @param data.requestBody Partial configuration update. Only provided fields will be updated.
2557
- * @returns ImporterConfigDto Configuration updated successfully
3069
+ * @param data.requestBody
3070
+ * @returns unknown Onboarding bootstrap result.
2558
3071
  * @throws ApiError
2559
3072
  */
2560
- public static importerConfigControllerUpdateConfig(
2561
- data: ImporterConfigControllerUpdateConfigData
2562
- ): CancelablePromise<ImporterConfigControllerUpdateConfigResponse> {
3073
+ public static onboardingControllerBootstrap(
3074
+ data: OnboardingControllerBootstrapData
3075
+ ): CancelablePromise<OnboardingControllerBootstrapResponse> {
2563
3076
  return __request(OpenAPI, {
2564
- method: 'PUT',
2565
- url: '/api/v1/{region}/bean/import/config/{importerId}',
3077
+ method: 'POST',
3078
+ url: '/api/v1/{region}/bean/onboarding',
2566
3079
  path: {
2567
- importerId: data.importerId,
2568
3080
  region: data.region
2569
3081
  },
2570
3082
  body: data.requestBody,
2571
3083
  mediaType: 'application/json',
2572
3084
  errors: {
2573
- 400: 'Invalid input - Validation failed',
2574
- 404: 'Configuration not found'
3085
+ 422: 'Invalid region/account path/duplicate paths.'
2575
3086
  }
2576
3087
  });
2577
3088
  }
3089
+ }
2578
3090
 
3091
+ export class BalanceReconciliationService {
2579
3092
  /**
2580
- * Reset configuration to default
2581
- * Resets the configuration for the specified importer to default values. This operation overwrites all existing configuration.
3093
+ * Preview reconciliation (book vs actual)
3094
+ * Computes book balance, diff, Beancount-inferred tolerance, and suggested action without persisting.
2582
3095
  * @param data The data for the request.
2583
- * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
2584
- * @param data.region Region code for tenant context
2585
- * @returns ImporterConfigDto Configuration reset successfully
3096
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3097
+ * @param data.requestBody
3098
+ * @returns ReconciliationComputeResultDto Reconciliation preview
2586
3099
  * @throws ApiError
2587
3100
  */
2588
- public static importerConfigControllerResetConfig(
2589
- data: ImporterConfigControllerResetConfigData
2590
- ): CancelablePromise<ImporterConfigControllerResetConfigResponse> {
3101
+ public static reconciliationControllerCompute(
3102
+ data: ReconciliationControllerComputeData
3103
+ ): CancelablePromise<ReconciliationControllerComputeResponse> {
2591
3104
  return __request(OpenAPI, {
2592
3105
  method: 'POST',
2593
- url: '/api/v1/{region}/bean/import/config/{importerId}/reset',
3106
+ url: '/api/v1/{region}/bean/reconciliations',
2594
3107
  path: {
2595
- importerId: data.importerId,
2596
3108
  region: data.region
2597
3109
  },
3110
+ body: data.requestBody,
3111
+ mediaType: 'application/json',
2598
3112
  errors: {
2599
- 400: 'Invalid input - Unsupported importer'
3113
+ 404: 'Account not found'
2600
3114
  }
2601
3115
  });
2602
3116
  }
2603
- }
2604
3117
 
2605
- export class BeanPlatformsService {
2606
3118
  /**
2607
- * Get all platforms with statistics
2608
- * @returns unknown List of platforms with binding and account counts
3119
+ * Record a balance assertion
3120
+ * Persists the reconciliation as a BeanBalance assertion (amount = actual, diffAmount = book − actual). Re-reconciling the same day/currency upserts.
3121
+ * @param data The data for the request.
3122
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3123
+ * @param data.requestBody
3124
+ * @returns ReconciliationRecordDto Balance assertion recorded
2609
3125
  * @throws ApiError
2610
3126
  */
2611
- public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
3127
+ public static reconciliationControllerAssert(
3128
+ data: ReconciliationControllerAssertData
3129
+ ): CancelablePromise<ReconciliationControllerAssertResponse> {
2612
3130
  return __request(OpenAPI, {
2613
- method: 'GET',
2614
- url: '/api/v1/bean/platforms'
3131
+ method: 'POST',
3132
+ url: '/api/v1/{region}/bean/reconciliations/assert',
3133
+ path: {
3134
+ region: data.region
3135
+ },
3136
+ body: data.requestBody,
3137
+ mediaType: 'application/json',
3138
+ errors: {
3139
+ 404: 'Account not found'
3140
+ }
2615
3141
  });
2616
3142
  }
2617
3143
 
2618
3144
  /**
2619
- * Create a new platform
3145
+ * Generate a pad adjusting entry
3146
+ * When book is outside tolerance, synthesizes a Beancount pad transaction (flag P) booking the diff from source_account and persists it. Source defaults to Equity:Opening-Balances.
2620
3147
  * @param data The data for the request.
3148
+ * @param data.region Region code for tenant context (decorative for reconciliation)
2621
3149
  * @param data.requestBody
2622
- * @returns unknown Platform created successfully
3150
+ * @returns PadResultDto Pad adjusting entry generated
2623
3151
  * @throws ApiError
2624
3152
  */
2625
- public static platformControllerCreate(
2626
- data: PlatformControllerCreateData
2627
- ): CancelablePromise<PlatformControllerCreateResponse> {
3153
+ public static reconciliationControllerPad(
3154
+ data: ReconciliationControllerPadData
3155
+ ): CancelablePromise<ReconciliationControllerPadResponse> {
2628
3156
  return __request(OpenAPI, {
2629
3157
  method: 'POST',
2630
- url: '/api/v1/bean/platforms',
3158
+ url: '/api/v1/{region}/bean/reconciliations/pad',
3159
+ path: {
3160
+ region: data.region
3161
+ },
2631
3162
  body: data.requestBody,
2632
3163
  mediaType: 'application/json',
2633
3164
  errors: {
2634
- 409: 'Platform already exists'
3165
+ 400: 'Book already within tolerance — no pad needed',
3166
+ 404: 'Account not found'
2635
3167
  }
2636
3168
  });
2637
3169
  }
2638
3170
 
2639
3171
  /**
2640
- * Get platform list for current user
2641
- * @returns unknown List of platforms with user binding status
3172
+ * List reconciliation history for an account
3173
+ * Returns recorded balance assertions (most recent first). The latest drives the account-detail "Last <date>" badge.
3174
+ * @param data The data for the request.
3175
+ * @param data.accountId BeanAccount id
3176
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3177
+ * @returns ReconciliationRecordDto Reconciliation history
2642
3178
  * @throws ApiError
2643
3179
  */
2644
- public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3180
+ public static reconciliationControllerHistory(
3181
+ data: ReconciliationControllerHistoryData
3182
+ ): CancelablePromise<ReconciliationControllerHistoryResponse> {
2645
3183
  return __request(OpenAPI, {
2646
3184
  method: 'GET',
2647
- url: '/api/v1/bean/platforms/list'
3185
+ url: '/api/v1/{region}/bean/accounts/{accountId}/reconciliations',
3186
+ path: {
3187
+ accountId: data.accountId,
3188
+ region: data.region
3189
+ },
3190
+ errors: {
3191
+ 404: 'Account not found'
3192
+ }
2648
3193
  });
2649
3194
  }
3195
+ }
2650
3196
 
3197
+ export class BeanExportService {
2651
3198
  /**
2652
- * Match platforms by name or alias
3199
+ * Export Beancount ledger as ZIP
3200
+ * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
3201
+ * @returns unknown
3202
+ * @throws ApiError
3203
+ */
3204
+ public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
3205
+ return __request(OpenAPI, {
3206
+ method: 'GET',
3207
+ url: '/api/v1/{region}/bean/export/beancount'
3208
+ });
3209
+ }
3210
+ }
3211
+
3212
+ export class BeanImportService {
3213
+ /**
3214
+ * Import a bill file
3215
+ * Upload and process a bill file (CSV, PDF, OFX, etc.). The system automatically identifies the file type, extracts transactions, validates them, and stores only validated transactions to the database. Maximum file size: 50MB. Only 1 import per user at a time (concurrent imports rejected with 429).
2653
3216
  * @param data The data for the request.
2654
- * @param data.q Search query — Chinese name, English name, or abbreviation
2655
- * @param data.region Region code for category override lookup
2656
- * @returns unknown List of matching platforms with suggested segment names
3217
+ * @param data.region Region code for tenant context
3218
+ * @param data.formData Bill file to import
3219
+ * @returns ImportResultDto File imported successfully
2657
3220
  * @throws ApiError
2658
3221
  */
2659
- public static platformControllerMatchPlatforms(
2660
- data: PlatformControllerMatchPlatformsData
2661
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3222
+ public static fileImportControllerImportFile(
3223
+ data: FileImportControllerImportFileData
3224
+ ): CancelablePromise<FileImportControllerImportFileResponse> {
3225
+ return __request(OpenAPI, {
3226
+ method: 'POST',
3227
+ url: '/api/v1/{region}/bean/import/file',
3228
+ path: {
3229
+ region: data.region
3230
+ },
3231
+ formData: data.formData,
3232
+ mediaType: 'multipart/form-data',
3233
+ errors: {
3234
+ 400: 'Bad request - file-format-unsupported or file-import-failed',
3235
+ 413: 'Payload too large - file exceeds 50MB limit',
3236
+ 429: 'Too many requests - user already has import in progress',
3237
+ 500: 'Internal server error - DATABASE_ERROR'
3238
+ }
3239
+ });
3240
+ }
3241
+
3242
+ /**
3243
+ * Identify file type
3244
+ * Upload a file to check if it can be processed by any registered importer. Does not perform actual import - useful for pre-validation. Uses user-specific importer configuration.
3245
+ * @param data The data for the request.
3246
+ * @param data.region Region code for tenant context
3247
+ * @param data.formData File to identify
3248
+ * @returns IdentifyResultDto File identification result
3249
+ * @throws ApiError
3250
+ */
3251
+ public static fileImportControllerIdentifyFile(
3252
+ data: FileImportControllerIdentifyFileData
3253
+ ): CancelablePromise<FileImportControllerIdentifyFileResponse> {
3254
+ return __request(OpenAPI, {
3255
+ method: 'POST',
3256
+ url: '/api/v1/{region}/bean/import/identify',
3257
+ path: {
3258
+ region: data.region
3259
+ },
3260
+ formData: data.formData,
3261
+ mediaType: 'multipart/form-data',
3262
+ errors: {
3263
+ 400: 'Bad request - No file uploaded'
3264
+ }
3265
+ });
3266
+ }
3267
+
3268
+ /**
3269
+ * Import a Beancount file in community format
3270
+ * Upload a .beancount file to import. The system parses community-format paths, converts to internal format using category metadata, auto-creates accounts, and imports transactions with deduplication. Maximum file size: 50MB. Only 1 import per user at a time.
3271
+ * @param data The data for the request.
3272
+ * @param data.region Region code for tenant context
3273
+ * @param data.formData Beancount file to import
3274
+ * @returns unknown Beancount file imported successfully
3275
+ * @throws ApiError
3276
+ */
3277
+ public static fileImportControllerImportBeancount(
3278
+ data: FileImportControllerImportBeancountData
3279
+ ): CancelablePromise<FileImportControllerImportBeancountResponse> {
3280
+ return __request(OpenAPI, {
3281
+ method: 'POST',
3282
+ url: '/api/v1/{region}/bean/import/beancount',
3283
+ path: {
3284
+ region: data.region
3285
+ },
3286
+ formData: data.formData,
3287
+ mediaType: 'multipart/form-data',
3288
+ errors: {
3289
+ 400: 'Bad request - invalid file or no file uploaded'
3290
+ }
3291
+ });
3292
+ }
3293
+
3294
+ /**
3295
+ * Get importer configuration
3296
+ * Returns the current configuration for the specified importer. Creates default configuration if none exists.
3297
+ * @param data The data for the request.
3298
+ * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
3299
+ * @param data.region Region code for tenant context
3300
+ * @returns ImporterConfigDto Configuration retrieved successfully
3301
+ * @throws ApiError
3302
+ */
3303
+ public static importerConfigControllerGetConfig(
3304
+ data: ImporterConfigControllerGetConfigData
3305
+ ): CancelablePromise<ImporterConfigControllerGetConfigResponse> {
2662
3306
  return __request(OpenAPI, {
2663
3307
  method: 'GET',
2664
- url: '/api/v1/bean/platforms/match',
2665
- query: {
2666
- q: data.q,
3308
+ url: '/api/v1/{region}/bean/import/config/{importerId}',
3309
+ path: {
3310
+ importerId: data.importerId,
2667
3311
  region: data.region
3312
+ },
3313
+ errors: {
3314
+ 400: 'Invalid input - Unsupported importer',
3315
+ 401: 'Unauthorized - Authentication required'
2668
3316
  }
2669
3317
  });
2670
3318
  }
2671
3319
 
2672
3320
  /**
2673
- * Update a platform
3321
+ * Update importer configuration
3322
+ * Updates the configuration for the specified importer. Partial updates are supported.
2674
3323
  * @param data The data for the request.
2675
- * @param data.id Platform ID
2676
- * @param data.requestBody
2677
- * @returns unknown Platform updated successfully
3324
+ * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
3325
+ * @param data.region Region code for tenant context
3326
+ * @param data.requestBody Partial configuration update. Only provided fields will be updated.
3327
+ * @returns ImporterConfigDto Configuration updated successfully
2678
3328
  * @throws ApiError
2679
3329
  */
2680
- public static platformControllerUpdate(
2681
- data: PlatformControllerUpdateData
2682
- ): CancelablePromise<PlatformControllerUpdateResponse> {
3330
+ public static importerConfigControllerUpdateConfig(
3331
+ data: ImporterConfigControllerUpdateConfigData
3332
+ ): CancelablePromise<ImporterConfigControllerUpdateConfigResponse> {
2683
3333
  return __request(OpenAPI, {
2684
3334
  method: 'PUT',
2685
- url: '/api/v1/bean/platforms/{id}',
3335
+ url: '/api/v1/{region}/bean/import/config/{importerId}',
2686
3336
  path: {
2687
- id: data.id
3337
+ importerId: data.importerId,
3338
+ region: data.region
2688
3339
  },
2689
3340
  body: data.requestBody,
2690
3341
  mediaType: 'application/json',
2691
3342
  errors: {
2692
- 404: 'Platform not found'
3343
+ 400: 'Invalid input - Validation failed',
3344
+ 404: 'Configuration not found'
2693
3345
  }
2694
3346
  });
2695
3347
  }
2696
3348
 
2697
3349
  /**
2698
- * Delete a platform
3350
+ * Reset configuration to default
3351
+ * Resets the configuration for the specified importer to default values. This operation overwrites all existing configuration.
2699
3352
  * @param data The data for the request.
2700
- * @param data.id Platform ID
2701
- * @returns void Platform deleted successfully
3353
+ * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
3354
+ * @param data.region Region code for tenant context
3355
+ * @returns ImporterConfigDto Configuration reset successfully
2702
3356
  * @throws ApiError
2703
3357
  */
2704
- public static platformControllerDelete(
2705
- data: PlatformControllerDeleteData
2706
- ): CancelablePromise<PlatformControllerDeleteResponse> {
3358
+ public static importerConfigControllerResetConfig(
3359
+ data: ImporterConfigControllerResetConfigData
3360
+ ): CancelablePromise<ImporterConfigControllerResetConfigResponse> {
2707
3361
  return __request(OpenAPI, {
2708
- method: 'DELETE',
2709
- url: '/api/v1/bean/platforms/{id}',
3362
+ method: 'POST',
3363
+ url: '/api/v1/{region}/bean/import/config/{importerId}/reset',
2710
3364
  path: {
2711
- id: data.id
3365
+ importerId: data.importerId,
3366
+ region: data.region
2712
3367
  },
2713
3368
  errors: {
2714
- 404: 'Platform not found'
3369
+ 400: 'Invalid input - Unsupported importer'
2715
3370
  }
2716
3371
  });
2717
3372
  }
@@ -2719,11 +3374,33 @@ export class BeanPlatformsService {
2719
3374
 
2720
3375
  export class ProviderSyncService {
2721
3376
  /**
3377
+ * Sync transactions from financial data provider
3378
+ *
3379
+ * Accepts raw transactions from external financial data providers, transforms them to Beancount format, and processes them through the ingestion pipeline.
3380
+ *
3381
+ * **Supported Providers:**
3382
+ * - **plaid**: Plaid API (US, Canada, Europe)
3383
+ * - **teller**: Teller API (US)
3384
+ * - **truelayer**: TrueLayer Open Banking (UK, Europe)
3385
+ * - **gocardless**: GoCardless Bank Account Data (Europe)
3386
+ * - **simplefin**: SimpleFIN (Self-hosted)
3387
+ * - **yodlee**: Yodlee (Global)
3388
+ * - **beancount-direct**: Beancount format transactions
3389
+ * - **parsed-bill**: Client-side parsed bill transactions
3390
+ *
3391
+ * **Processing Flow:**
3392
+ * 1. Transform raw data via provider adapter
3393
+ * 2. Validate transaction format
3394
+ * 3. Deduplicate using originalId
3395
+ * 4. Classify using rule engine
3396
+ * 5. Route low-confidence to Review Center
3397
+ * 6. Persist validated transactions
3398
+ *
2722
3399
  * @param data The data for the request.
2723
- * @param data.providerName
3400
+ * @param data.providerName Provider name
2724
3401
  * @param data.region Region code for tenant context
2725
3402
  * @param data.requestBody
2726
- * @returns unknown
3403
+ * @returns ProviderSyncResponseDto Sync completed successfully
2727
3404
  * @throws ApiError
2728
3405
  */
2729
3406
  public static providerSyncControllerSync(
@@ -2737,7 +3414,12 @@ export class ProviderSyncService {
2737
3414
  region: data.region
2738
3415
  },
2739
3416
  body: data.requestBody,
2740
- mediaType: 'application/json'
3417
+ mediaType: 'application/json',
3418
+ errors: {
3419
+ 400: 'Invalid request data',
3420
+ 401: 'Missing or invalid authentication',
3421
+ 404: 'Provider not supported'
3422
+ }
2741
3423
  });
2742
3424
  }
2743
3425
 
@@ -2790,6 +3472,101 @@ export class ProviderSyncService {
2790
3472
  }
2791
3473
  }
2792
3474
 
3475
+ export class ExternalAccountLinksService {
3476
+ /**
3477
+ * Create an external account → BeanAccount mapping (ADR-0113)
3478
+ * @param data The data for the request.
3479
+ * @param data.region Region code for tenant context
3480
+ * @param data.requestBody
3481
+ * @returns ExternalAccountLinkResponseDto Link created.
3482
+ * @throws ApiError
3483
+ */
3484
+ public static externalAccountLinkControllerCreate(
3485
+ data: ExternalAccountLinkControllerCreateData
3486
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
3487
+ return __request(OpenAPI, {
3488
+ method: 'POST',
3489
+ url: '/api/v1/{region}/bean/external-account-links',
3490
+ path: {
3491
+ region: data.region
3492
+ },
3493
+ body: data.requestBody,
3494
+ mediaType: 'application/json',
3495
+ errors: {
3496
+ 422: 'beanAccountId not owned, or an active link already exists.'
3497
+ }
3498
+ });
3499
+ }
3500
+
3501
+ /**
3502
+ * List the user's active external account links
3503
+ * @param data The data for the request.
3504
+ * @param data.provider
3505
+ * @param data.region Region code for tenant context
3506
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
3507
+ * @throws ApiError
3508
+ */
3509
+ public static externalAccountLinkControllerFindAll(
3510
+ data: ExternalAccountLinkControllerFindAllData
3511
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
3512
+ return __request(OpenAPI, {
3513
+ method: 'GET',
3514
+ url: '/api/v1/{region}/bean/external-account-links',
3515
+ path: {
3516
+ region: data.region
3517
+ },
3518
+ query: {
3519
+ provider: data.provider
3520
+ }
3521
+ });
3522
+ }
3523
+
3524
+ /**
3525
+ * Get a single external account link
3526
+ * @param data The data for the request.
3527
+ * @param data.id
3528
+ * @param data.region Region code for tenant context
3529
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
3530
+ * @throws ApiError
3531
+ */
3532
+ public static externalAccountLinkControllerFindOne(
3533
+ data: ExternalAccountLinkControllerFindOneData
3534
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
3535
+ return __request(OpenAPI, {
3536
+ method: 'GET',
3537
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3538
+ path: {
3539
+ id: data.id,
3540
+ region: data.region
3541
+ },
3542
+ errors: {
3543
+ 422: 'Link not found or not owned by the user.'
3544
+ }
3545
+ });
3546
+ }
3547
+
3548
+ /**
3549
+ * Soft-delete (disconnect) an external account link
3550
+ * @param data The data for the request.
3551
+ * @param data.id
3552
+ * @param data.region Region code for tenant context
3553
+ * @returns void Link soft-deleted; historical transactions are unaffected.
3554
+ * @throws ApiError
3555
+ */
3556
+ public static externalAccountLinkControllerRemove(
3557
+ data: ExternalAccountLinkControllerRemoveData
3558
+ ): CancelablePromise<ExternalAccountLinkControllerRemoveResponse> {
3559
+ return __request(OpenAPI, {
3560
+ method: 'DELETE',
3561
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3562
+ path: {
3563
+ id: data.id,
3564
+ region: data.region
3565
+ }
3566
+ });
3567
+ }
3568
+ }
3569
+
2793
3570
  export class ImportTelemetryService {
2794
3571
  /**
2795
3572
  * Receive anonymous parser failure telemetry
@@ -2867,10 +3644,12 @@ export class ImportTelemetryService {
2867
3644
 
2868
3645
  export class BeanNlpService {
2869
3646
  /**
3647
+ * Process natural language input
3648
+ * Parse natural language text (Chinese/English) describing a transaction. Supports multi-turn dialogue for collecting missing information. When confidence < 0.75, returns "confirm" action requiring user verification. User can reply with confirmation words (确认/yes/ok) or provide corrections. Examples: "yesterday Starbucks spent 35 yuan", "today lunch 28 yuan", "spent $50 at Walmart"
2870
3649
  * @param data The data for the request.
2871
3650
  * @param data.region Region code for tenant context
2872
- * @param data.requestBody
2873
- * @returns unknown
3651
+ * @param data.requestBody Natural language transaction input with optional session ID
3652
+ * @returns NlpResponseDto NLP processing result - either created transaction or asking for more info
2874
3653
  * @throws ApiError
2875
3654
  */
2876
3655
  public static nlpControllerProcessNaturalLanguage(
@@ -2883,7 +3662,11 @@ export class BeanNlpService {
2883
3662
  region: data.region
2884
3663
  },
2885
3664
  body: data.requestBody,
2886
- mediaType: 'application/json'
3665
+ mediaType: 'application/json',
3666
+ errors: {
3667
+ 400: 'Invalid input',
3668
+ 401: 'Unauthorized'
3669
+ }
2887
3670
  });
2888
3671
  }
2889
3672
 
@@ -2942,411 +3725,277 @@ export class BeanNlpService {
2942
3725
  }
2943
3726
  }
2944
3727
 
2945
- export class DashboardService {
2946
- /**
2947
- * Get net worth overview
2948
- * Returns total net worth with breakdown of assets and liabilities
2949
- * @param data The data for the request.
2950
- * @param data.region Region code for tenant context
2951
- * @param data.date Date for balance calculation (ISO 8601 format)
2952
- * @returns NetWorthResponseDto Net worth retrieved successfully
2953
- * @throws ApiError
2954
- */
2955
- public static dashboardControllerGetNetWorth(
2956
- data: DashboardControllerGetNetWorthData
2957
- ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
2958
- return __request(OpenAPI, {
2959
- method: 'GET',
2960
- url: '/api/v1/{region}/dashboard/net-worth',
2961
- path: {
2962
- region: data.region
2963
- },
2964
- query: {
2965
- date: data.date
2966
- },
2967
- errors: {
2968
- 401: 'User not authenticated'
2969
- }
2970
- });
2971
- }
2972
-
3728
+ export class BeanPlatformsService {
2973
3729
  /**
2974
- * Get accounts grouped by platform
2975
- * Returns accounts with balances grouped by financial platform
2976
- * @param data The data for the request.
2977
- * @param data.region Region code for tenant context
2978
- * @param data.groupBy Grouping strategy
2979
- * @param data.date Date for balance calculation (ISO 8601 format)
2980
- * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
2981
- * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3730
+ * Get all platforms with statistics
3731
+ * @returns unknown List of platforms with binding and account counts
2982
3732
  * @throws ApiError
2983
3733
  */
2984
- public static dashboardControllerGetAccounts(
2985
- data: DashboardControllerGetAccountsData
2986
- ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3734
+ public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
2987
3735
  return __request(OpenAPI, {
2988
3736
  method: 'GET',
2989
- url: '/api/v1/{region}/dashboard/accounts',
2990
- path: {
2991
- region: data.region
2992
- },
2993
- query: {
2994
- groupBy: data.groupBy,
2995
- date: data.date,
2996
- accountId: data.accountId
2997
- },
2998
- errors: {
2999
- 401: 'User not authenticated'
3000
- }
3737
+ url: '/api/v1/bean/platforms'
3001
3738
  });
3002
3739
  }
3003
3740
 
3004
3741
  /**
3005
- * Get cash flow summary
3006
- * Returns income, expenses, and savings for a monthly period
3742
+ * Create a new platform
3007
3743
  * @param data The data for the request.
3008
- * @param data.period Period in YYYY-MM format
3009
- * @param data.region Region code for tenant context
3010
- * @returns CashFlowResponseDto Cash flow retrieved successfully
3744
+ * @param data.requestBody
3745
+ * @returns unknown Platform created successfully
3011
3746
  * @throws ApiError
3012
3747
  */
3013
- public static dashboardControllerGetCashFlow(
3014
- data: DashboardControllerGetCashFlowData
3015
- ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3748
+ public static platformControllerCreate(
3749
+ data: PlatformControllerCreateData
3750
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3016
3751
  return __request(OpenAPI, {
3017
- method: 'GET',
3018
- url: '/api/v1/{region}/dashboard/cash-flow',
3019
- path: {
3020
- region: data.region
3021
- },
3022
- query: {
3023
- period: data.period
3024
- },
3752
+ method: 'POST',
3753
+ url: '/api/v1/bean/platforms',
3754
+ body: data.requestBody,
3755
+ mediaType: 'application/json',
3025
3756
  errors: {
3026
- 400: 'Invalid period format',
3027
- 401: 'User not authenticated'
3757
+ 409: 'Platform already exists'
3028
3758
  }
3029
3759
  });
3030
3760
  }
3031
- }
3032
3761
 
3033
- export class InvestmentService {
3034
3762
  /**
3035
- * Get per-holding unrealized + realized P&L
3036
- * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3763
+ * Get platform list for current user
3037
3764
  * @param data The data for the request.
3038
- * @param data.region Region code for tenant context
3039
- * @param data.asOf As-of date (ISO 8601), defaults to today
3040
- * @param data.accountId Scope to a single account
3041
- * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3042
- * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3765
+ * @param data.region Region code (ISO 3166-1 alpha-2) that biases within-type-bucket ordering (local-region platforms first). Case-insensitive — stored/compared UPPERCASE ("cn" == "CN").
3766
+ * @returns PlatformListItemDto List of platforms with user binding status
3043
3767
  * @throws ApiError
3044
3768
  */
3045
- public static holdingPnlControllerGetHoldingPnl(
3046
- data: HoldingPnlControllerGetHoldingPnlData
3047
- ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3769
+ public static platformControllerGetPlatformList(
3770
+ data: PlatformControllerGetPlatformListData = {}
3771
+ ): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3048
3772
  return __request(OpenAPI, {
3049
3773
  method: 'GET',
3050
- url: '/api/v1/{region}/investment/holdings/pnl',
3051
- path: {
3052
- region: data.region
3053
- },
3774
+ url: '/api/v1/bean/platforms/list',
3054
3775
  query: {
3055
- asOf: data.asOf,
3056
- accountId: data.accountId,
3057
- method: data.method
3058
- },
3059
- errors: {
3060
- 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3061
- 401: 'User not authenticated'
3062
- }
3063
- });
3064
- }
3065
- }
3066
-
3067
- export class BeanPricesService {
3068
- /**
3069
- * Create a new price
3070
- * Creates a new price entry for the authenticated user
3071
- * @param data The data for the request.
3072
- * @param data.region Region code for tenant context
3073
- * @param data.requestBody
3074
- * @returns PriceResponseDto Price created successfully
3075
- * @throws ApiError
3076
- */
3077
- public static priceControllerCreate(
3078
- data: PriceControllerCreateData
3079
- ): CancelablePromise<PriceControllerCreateResponse> {
3080
- return __request(OpenAPI, {
3081
- method: 'POST',
3082
- url: '/api/v1/{region}/bean/prices',
3083
- path: {
3084
3776
  region: data.region
3085
- },
3086
- body: data.requestBody,
3087
- mediaType: 'application/json',
3088
- errors: {
3089
- 404: 'Currency or quoteCurrency commodity not found',
3090
- 409: 'Price already exists for this currency pair and date'
3091
3777
  }
3092
3778
  });
3093
3779
  }
3094
3780
 
3095
3781
  /**
3096
- * List user prices
3097
- * Returns all price entries for the authenticated user with optional filtering
3782
+ * Match platforms by name or alias
3098
3783
  * @param data The data for the request.
3099
- * @param data.region Region code for tenant context
3100
- * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
3101
- * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
3102
- * @param data.dateFrom Filter prices from this date (ISO 8601 format)
3103
- * @param data.dateTo Filter prices to this date (ISO 8601 format)
3104
- * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
3105
- * @param data.page Page number for pagination (default: 1)
3106
- * @param data.limit Number of items per page (default: 20, max: 100)
3107
- * @returns PriceListResponseDto Prices retrieved successfully
3784
+ * @param data.q Search query — Chinese name, English name, or abbreviation
3785
+ * @param data.region Region code (ISO 3166-1 alpha-2) that biases within-tier ordering (local-region platforms first); also the intended categoryOverrides key. Case-insensitive — stored/compared UPPERCASE ("cn" == "CN").
3786
+ * @returns PlatformMatchResponseDto Matching platforms with overall match type and truncation flag
3108
3787
  * @throws ApiError
3109
3788
  */
3110
- public static priceControllerFindAll(
3111
- data: PriceControllerFindAllData
3112
- ): CancelablePromise<PriceControllerFindAllResponse> {
3789
+ public static platformControllerMatchPlatforms(
3790
+ data: PlatformControllerMatchPlatformsData
3791
+ ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3113
3792
  return __request(OpenAPI, {
3114
3793
  method: 'GET',
3115
- url: '/api/v1/{region}/bean/prices',
3116
- path: {
3117
- region: data.region
3118
- },
3794
+ url: '/api/v1/bean/platforms/match',
3119
3795
  query: {
3120
- currency: data.currency,
3121
- quoteCurrency: data.quoteCurrency,
3122
- dateFrom: data.dateFrom,
3123
- dateTo: data.dateTo,
3124
- search: data.search,
3125
- page: data.page,
3126
- limit: data.limit
3796
+ q: data.q,
3797
+ region: data.region
3127
3798
  }
3128
3799
  });
3129
3800
  }
3130
3801
 
3131
3802
  /**
3132
- * Get price by ID
3133
- * Returns a single price entry by its ID
3803
+ * Update a platform
3134
3804
  * @param data The data for the request.
3135
- * @param data.id Price ID
3136
- * @param data.region Region code for tenant context
3137
- * @returns PriceResponseDto Price retrieved successfully
3805
+ * @param data.id Platform ID
3806
+ * @param data.requestBody
3807
+ * @returns unknown Platform updated successfully
3138
3808
  * @throws ApiError
3139
3809
  */
3140
- public static priceControllerFindOne(
3141
- data: PriceControllerFindOneData
3142
- ): CancelablePromise<PriceControllerFindOneResponse> {
3810
+ public static platformControllerUpdate(
3811
+ data: PlatformControllerUpdateData
3812
+ ): CancelablePromise<PlatformControllerUpdateResponse> {
3143
3813
  return __request(OpenAPI, {
3144
- method: 'GET',
3145
- url: '/api/v1/{region}/bean/prices/{id}',
3814
+ method: 'PUT',
3815
+ url: '/api/v1/bean/platforms/{id}',
3146
3816
  path: {
3147
- id: data.id,
3148
- region: data.region
3817
+ id: data.id
3149
3818
  },
3819
+ body: data.requestBody,
3820
+ mediaType: 'application/json',
3150
3821
  errors: {
3151
- 404: 'Price not found'
3822
+ 404: 'Platform not found'
3152
3823
  }
3153
3824
  });
3154
3825
  }
3155
3826
 
3156
3827
  /**
3157
- * Update a price
3158
- * Updates an existing price entry
3828
+ * Delete a platform
3159
3829
  * @param data The data for the request.
3160
- * @param data.id Price ID
3161
- * @param data.region Region code for tenant context
3162
- * @param data.requestBody
3163
- * @returns PriceResponseDto Price updated successfully
3830
+ * @param data.id Platform ID
3831
+ * @returns void Platform deleted successfully
3164
3832
  * @throws ApiError
3165
3833
  */
3166
- public static priceControllerUpdate(
3167
- data: PriceControllerUpdateData
3168
- ): CancelablePromise<PriceControllerUpdateResponse> {
3834
+ public static platformControllerDelete(
3835
+ data: PlatformControllerDeleteData
3836
+ ): CancelablePromise<PlatformControllerDeleteResponse> {
3169
3837
  return __request(OpenAPI, {
3170
- method: 'PUT',
3171
- url: '/api/v1/{region}/bean/prices/{id}',
3838
+ method: 'DELETE',
3839
+ url: '/api/v1/bean/platforms/{id}',
3172
3840
  path: {
3173
- id: data.id,
3174
- region: data.region
3841
+ id: data.id
3175
3842
  },
3176
- body: data.requestBody,
3177
- mediaType: 'application/json',
3178
3843
  errors: {
3179
- 404: 'Price not found',
3180
- 409: 'Updated price conflicts with existing price'
3844
+ 404: 'Platform not found'
3181
3845
  }
3182
3846
  });
3183
3847
  }
3848
+ }
3184
3849
 
3850
+ export class DashboardService {
3185
3851
  /**
3186
- * Delete a price
3187
- * Deletes a price entry (hard delete)
3852
+ * Get net worth overview
3853
+ * Returns total net worth with breakdown of assets and liabilities
3188
3854
  * @param data The data for the request.
3189
- * @param data.id Price ID
3190
3855
  * @param data.region Region code for tenant context
3191
- * @returns void Price deleted successfully
3856
+ * @param data.date Date for balance calculation (ISO 8601 format)
3857
+ * @returns NetWorthResponseDto Net worth retrieved successfully
3192
3858
  * @throws ApiError
3193
3859
  */
3194
- public static priceControllerDelete(
3195
- data: PriceControllerDeleteData
3196
- ): CancelablePromise<PriceControllerDeleteResponse> {
3860
+ public static dashboardControllerGetNetWorth(
3861
+ data: DashboardControllerGetNetWorthData
3862
+ ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3197
3863
  return __request(OpenAPI, {
3198
- method: 'DELETE',
3199
- url: '/api/v1/{region}/bean/prices/{id}',
3864
+ method: 'GET',
3865
+ url: '/api/v1/{region}/dashboard/net-worth',
3200
3866
  path: {
3201
- id: data.id,
3202
3867
  region: data.region
3203
3868
  },
3869
+ query: {
3870
+ date: data.date
3871
+ },
3204
3872
  errors: {
3205
- 404: 'Price not found'
3873
+ 401: 'User not authenticated'
3206
3874
  }
3207
3875
  });
3208
3876
  }
3209
3877
 
3210
3878
  /**
3211
- * Bulk create prices
3212
- * Creates multiple price entries at once (skips duplicates)
3879
+ * Get accounts grouped by platform
3880
+ * Returns accounts with balances grouped by financial platform
3213
3881
  * @param data The data for the request.
3214
3882
  * @param data.region Region code for tenant context
3215
- * @param data.requestBody
3216
- * @returns PriceResponseDto Prices created successfully
3883
+ * @param data.groupBy Grouping strategy
3884
+ * @param data.date Date for balance calculation (ISO 8601 format)
3885
+ * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3886
+ * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3217
3887
  * @throws ApiError
3218
3888
  */
3219
- public static priceControllerBulkCreate(
3220
- data: PriceControllerBulkCreateData
3221
- ): CancelablePromise<PriceControllerBulkCreateResponse> {
3889
+ public static dashboardControllerGetAccounts(
3890
+ data: DashboardControllerGetAccountsData
3891
+ ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3222
3892
  return __request(OpenAPI, {
3223
- method: 'POST',
3224
- url: '/api/v1/{region}/bean/prices/bulk',
3893
+ method: 'GET',
3894
+ url: '/api/v1/{region}/dashboard/accounts',
3225
3895
  path: {
3226
3896
  region: data.region
3227
3897
  },
3228
- body: data.requestBody,
3229
- mediaType: 'application/json'
3898
+ query: {
3899
+ groupBy: data.groupBy,
3900
+ date: data.date,
3901
+ accountId: data.accountId
3902
+ },
3903
+ errors: {
3904
+ 401: 'User not authenticated'
3905
+ }
3230
3906
  });
3231
3907
  }
3232
- }
3233
3908
 
3234
- export class ReportingService {
3235
3909
  /**
3236
- * Get portfolio value trends
3237
- *
3238
- * Returns time series data of portfolio net worth.
3239
- *
3240
- * **Multi-currency Support:**
3241
- * - `series[].byCurrency` - Currency breakdown for each data point
3242
- * - `byCurrency` - Separate time series grouped by currency
3243
- * - `warnings` - Exchange rate warnings if conversion failed
3244
- *
3245
- * **Parameters:**
3246
- * - `period`: Time period (1m, 3m, 6m, 1y)
3247
- * - `granularity`: Data granularity (day, week, month)
3248
- *
3910
+ * Get cash flow summary
3911
+ * Returns income, expenses, and savings for a monthly period
3249
3912
  * @param data The data for the request.
3913
+ * @param data.period Period in YYYY-MM format
3250
3914
  * @param data.region Region code for tenant context
3251
- * @param data.period Time period
3252
- * @param data.granularity Data granularity
3253
- * @returns PortfolioTrendsResponseDto Trends retrieved successfully
3915
+ * @returns CashFlowResponseDto Cash flow retrieved successfully
3254
3916
  * @throws ApiError
3255
3917
  */
3256
- public static reportingControllerGetPortfolioTrends(
3257
- data: ReportingControllerGetPortfolioTrendsData
3258
- ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
3918
+ public static dashboardControllerGetCashFlow(
3919
+ data: DashboardControllerGetCashFlowData
3920
+ ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3259
3921
  return __request(OpenAPI, {
3260
3922
  method: 'GET',
3261
- url: '/api/v1/{region}/reporting/portfolio/trends',
3923
+ url: '/api/v1/{region}/dashboard/cash-flow',
3262
3924
  path: {
3263
3925
  region: data.region
3264
3926
  },
3265
3927
  query: {
3266
- period: data.period,
3267
- granularity: data.granularity
3928
+ period: data.period
3268
3929
  },
3269
3930
  errors: {
3931
+ 400: 'Invalid period format',
3270
3932
  401: 'User not authenticated'
3271
3933
  }
3272
3934
  });
3273
3935
  }
3274
3936
 
3275
3937
  /**
3276
- * Generate portfolio snapshot
3277
- *
3278
- * Manually generate a portfolio snapshot for a specific date.
3279
- *
3280
- * **Multi-currency Support:**
3281
- * - Fetches balances grouped by currency
3282
- * - Uses user's baseCurrency setting for conversion
3283
- * - Stores exchange rates and warnings
3284
- *
3285
- * **Use Cases:**
3286
- * - Testing snapshot generation
3287
- * - Force regeneration after data correction
3288
- * - Initial setup for new users
3289
- *
3938
+ * Get expenses/income grouped by functional category
3939
+ * Returns amounts pre-aggregated by functional category (account-path Group segment) with server-side multi-currency conversion. flow=expense (default) aggregates ^Expenses: accounts; flow=income aggregates ^Income: accounts (issue #518)
3290
3940
  * @param data The data for the request.
3291
3941
  * @param data.region Region code for tenant context
3292
- * @param data.requestBody Optional date (defaults to today)
3293
- * @returns GenerateSnapshotResponse Snapshot generated successfully
3942
+ * @param data.groupBy Grouping strategy
3943
+ * @param data.period Time window (1m = current calendar month)
3944
+ * @param data.flow Account root to aggregate (expense → ^Expenses:, income → ^Income:)
3945
+ * @returns ExpensesByCategoryResponseDto Expenses retrieved successfully
3294
3946
  * @throws ApiError
3295
3947
  */
3296
- public static reportingControllerGenerateSnapshot(
3297
- data: ReportingControllerGenerateSnapshotData
3298
- ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
3948
+ public static dashboardControllerGetExpenses(
3949
+ data: DashboardControllerGetExpensesData
3950
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3299
3951
  return __request(OpenAPI, {
3300
- method: 'POST',
3301
- url: '/api/v1/{region}/reporting/snapshots/generate',
3952
+ method: 'GET',
3953
+ url: '/api/v1/{region}/dashboard/expenses',
3302
3954
  path: {
3303
3955
  region: data.region
3304
3956
  },
3305
- body: data.requestBody,
3306
- mediaType: 'application/json',
3957
+ query: {
3958
+ groupBy: data.groupBy,
3959
+ period: data.period,
3960
+ flow: data.flow
3961
+ },
3307
3962
  errors: {
3308
- 400: 'Invalid date format',
3963
+ 400: 'Invalid groupBy or period',
3309
3964
  401: 'User not authenticated'
3310
3965
  }
3311
3966
  });
3312
3967
  }
3968
+ }
3313
3969
 
3970
+ export class InvestmentService {
3314
3971
  /**
3315
- * Backfill portfolio snapshots
3316
- *
3317
- * Generate snapshots for a date range (historical data backfill).
3318
- *
3319
- * **Multi-currency Support:**
3320
- * - Each snapshot includes multi-currency data
3321
- * - Uses exchange rates available at generation time
3322
- * - Warnings stored for missing exchange rates
3323
- *
3324
- * **Best Practices:**
3325
- * - Use for initial setup after account configuration
3326
- * - Run during low-traffic periods for large date ranges
3327
- * - Existing snapshots are skipped (not regenerated)
3328
- *
3972
+ * Get per-holding unrealized + realized P&L
3973
+ * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3329
3974
  * @param data The data for the request.
3330
3975
  * @param data.region Region code for tenant context
3331
- * @param data.requestBody
3332
- * @returns BackfillSnapshotsResponse Backfill completed successfully
3976
+ * @param data.asOf As-of date (ISO 8601), defaults to today
3977
+ * @param data.accountId Scope to a single account
3978
+ * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3979
+ * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3333
3980
  * @throws ApiError
3334
3981
  */
3335
- public static reportingControllerBackfillSnapshots(
3336
- data: ReportingControllerBackfillSnapshotsData
3337
- ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
3982
+ public static holdingPnlControllerGetHoldingPnl(
3983
+ data: HoldingPnlControllerGetHoldingPnlData
3984
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3338
3985
  return __request(OpenAPI, {
3339
- method: 'POST',
3340
- url: '/api/v1/{region}/reporting/snapshots/backfill',
3986
+ method: 'GET',
3987
+ url: '/api/v1/{region}/investment/holdings/pnl',
3341
3988
  path: {
3342
3989
  region: data.region
3343
3990
  },
3344
- body: data.requestBody,
3345
- mediaType: 'application/json',
3991
+ query: {
3992
+ asOf: data.asOf,
3993
+ accountId: data.accountId,
3994
+ method: data.method
3995
+ },
3346
3996
  errors: {
3347
- 400: 'Invalid date format or range',
3348
- 401: 'User not authenticated',
3349
- 409: 'Backfill already in progress for this user'
3997
+ 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3998
+ 401: 'User not authenticated'
3350
3999
  }
3351
4000
  });
3352
4001
  }
@@ -3375,7 +4024,7 @@ export class AuthService {
3375
4024
  * Anonymous login with access token
3376
4025
  * @param data The data for the request.
3377
4026
  * @param data.requestBody
3378
- * @returns unknown Login successful
4027
+ * @returns AnonymousLoginResponseDto Login successful
3379
4028
  * @throws ApiError
3380
4029
  */
3381
4030
  public static authControllerAccessTokenLogin(
@@ -3562,3 +4211,53 @@ export class InfoService {
3562
4211
  });
3563
4212
  }
3564
4213
  }
4214
+
4215
+ export class MarketDataService {
4216
+ /**
4217
+ * Search market symbols by name or code
4218
+ * Ranked search over the openbb catalog. Empty `q` returns [].
4219
+ * @param data The data for the request.
4220
+ * @param data.q Search term — matched against symbol and instrument name. Empty string returns [].
4221
+ * @param data.limit Maximum number of results (clamped 1..50)
4222
+ * @param data.exchange Filter by exchange code (e.g. US, HK, SS, SZ)
4223
+ * @param data.assetType Filter by OpenBB asset_type (e.g. stock, etf)
4224
+ * @returns SymbolSearchResultDto Ranked search results
4225
+ * @throws ApiError
4226
+ */
4227
+ public static symbolControllerSearch(
4228
+ data: SymbolControllerSearchData
4229
+ ): CancelablePromise<SymbolControllerSearchResponse> {
4230
+ return __request(OpenAPI, {
4231
+ method: 'GET',
4232
+ url: '/api/v1/market/symbols/search',
4233
+ query: {
4234
+ q: data.q,
4235
+ limit: data.limit,
4236
+ exchange: data.exchange,
4237
+ assetType: data.assetType
4238
+ }
4239
+ });
4240
+ }
4241
+
4242
+ /**
4243
+ * Get a market symbol quote
4244
+ * @param data The data for the request.
4245
+ * @param data.symbol
4246
+ * @returns SymbolQuoteDto Symbol quote
4247
+ * @throws ApiError
4248
+ */
4249
+ public static symbolControllerGetQuote(
4250
+ data: SymbolControllerGetQuoteData
4251
+ ): CancelablePromise<SymbolControllerGetQuoteResponse> {
4252
+ return __request(OpenAPI, {
4253
+ method: 'GET',
4254
+ url: '/api/v1/market/symbols/{symbol}/quote',
4255
+ path: {
4256
+ symbol: data.symbol
4257
+ },
4258
+ errors: {
4259
+ 404: 'Symbol not found in the openbb catalog'
4260
+ }
4261
+ });
4262
+ }
4263
+ }