@firela/api-types 0.0.0-canary.19fa1e7e → 0.0.0-canary.1e97a18b

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,28 @@ 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,
174
198
  EventControllerCreateData,
175
199
  EventControllerCreateResponse,
176
200
  EventControllerFindAllData,
@@ -183,6 +207,16 @@ import type {
183
207
  EventControllerDeleteResponse,
184
208
  EventControllerGetSliceData,
185
209
  EventControllerGetSliceResponse,
210
+ OnboardingControllerBootstrapData,
211
+ OnboardingControllerBootstrapResponse,
212
+ ReconciliationControllerComputeData,
213
+ ReconciliationControllerComputeResponse,
214
+ ReconciliationControllerAssertData,
215
+ ReconciliationControllerAssertResponse,
216
+ ReconciliationControllerPadData,
217
+ ReconciliationControllerPadResponse,
218
+ ReconciliationControllerHistoryData,
219
+ ReconciliationControllerHistoryResponse,
186
220
  ExportControllerExportBeancountResponse,
187
221
  FileImportControllerImportFileData,
188
222
  FileImportControllerImportFileResponse,
@@ -196,22 +230,20 @@ import type {
196
230
  ImporterConfigControllerUpdateConfigResponse,
197
231
  ImporterConfigControllerResetConfigData,
198
232
  ImporterConfigControllerResetConfigResponse,
199
- PlatformControllerFindAllResponse,
200
- PlatformControllerCreateData,
201
- PlatformControllerCreateResponse,
202
- PlatformControllerGetPlatformListResponse,
203
- PlatformControllerMatchPlatformsData,
204
- PlatformControllerMatchPlatformsResponse,
205
- PlatformControllerUpdateData,
206
- PlatformControllerUpdateResponse,
207
- PlatformControllerDeleteData,
208
- PlatformControllerDeleteResponse,
209
233
  ProviderSyncControllerSyncData,
210
234
  ProviderSyncControllerSyncResponse,
211
235
  ProviderSyncControllerGetSupportedProvidersData,
212
236
  ProviderSyncControllerGetSupportedProvidersResponse,
213
237
  ProviderSyncControllerIsProviderSupportedData,
214
238
  ProviderSyncControllerIsProviderSupportedResponse,
239
+ ExternalAccountLinkControllerCreateData,
240
+ ExternalAccountLinkControllerCreateResponse,
241
+ ExternalAccountLinkControllerFindAllData,
242
+ ExternalAccountLinkControllerFindAllResponse,
243
+ ExternalAccountLinkControllerFindOneData,
244
+ ExternalAccountLinkControllerFindOneResponse,
245
+ ExternalAccountLinkControllerRemoveData,
246
+ ExternalAccountLinkControllerRemoveResponse,
215
247
  TelemetryControllerReportTelemetryData,
216
248
  TelemetryControllerReportTelemetryResponse,
217
249
  TelemetryControllerReportCoverageMissData,
@@ -224,6 +256,17 @@ import type {
224
256
  NlpControllerClearSessionResponse,
225
257
  NlpControllerGetSessionData,
226
258
  NlpControllerGetSessionResponse,
259
+ PlatformControllerFindAllResponse,
260
+ PlatformControllerCreateData,
261
+ PlatformControllerCreateResponse,
262
+ PlatformControllerGetPlatformListData,
263
+ PlatformControllerGetPlatformListResponse,
264
+ PlatformControllerMatchPlatformsData,
265
+ PlatformControllerMatchPlatformsResponse,
266
+ PlatformControllerUpdateData,
267
+ PlatformControllerUpdateResponse,
268
+ PlatformControllerDeleteData,
269
+ PlatformControllerDeleteResponse,
227
270
  DashboardControllerGetNetWorthData,
228
271
  DashboardControllerGetNetWorthResponse,
229
272
  DashboardControllerGetAccountsData,
@@ -234,26 +277,6 @@ import type {
234
277
  DashboardControllerGetExpensesResponse,
235
278
  HoldingPnlControllerGetHoldingPnlData,
236
279
  HoldingPnlControllerGetHoldingPnlResponse,
237
- PriceControllerCreateData,
238
- PriceControllerCreateResponse,
239
- PriceControllerFindAllData,
240
- PriceControllerFindAllResponse,
241
- PriceControllerFindOneData,
242
- PriceControllerFindOneResponse,
243
- PriceControllerUpdateData,
244
- PriceControllerUpdateResponse,
245
- PriceControllerDeleteData,
246
- PriceControllerDeleteResponse,
247
- PriceControllerBulkCreateData,
248
- PriceControllerBulkCreateResponse,
249
- ReportingControllerGetPortfolioTrendsData,
250
- ReportingControllerGetPortfolioTrendsResponse,
251
- ReportingControllerGetCashFlowTrendsData,
252
- ReportingControllerGetCashFlowTrendsResponse,
253
- ReportingControllerGenerateSnapshotData,
254
- ReportingControllerGenerateSnapshotResponse,
255
- ReportingControllerBackfillSnapshotsData,
256
- ReportingControllerBackfillSnapshotsResponse,
257
280
  ApiKeysControllerCreateApiKeyResponse,
258
281
  AuthControllerAccessTokenLoginData,
259
282
  AuthControllerAccessTokenLoginResponse,
@@ -268,7 +291,11 @@ import type {
268
291
  HealthControllerResetCircuitBreakerData,
269
292
  HealthControllerResetCircuitBreakerResponse,
270
293
  HealthControllerGetMetricsResponse,
271
- InfoControllerGetInfoResponse
294
+ InfoControllerGetInfoResponse,
295
+ SymbolControllerSearchData,
296
+ SymbolControllerSearchResponse,
297
+ SymbolControllerGetQuoteData,
298
+ SymbolControllerGetQuoteResponse
272
299
  } from './types.gen';
273
300
 
274
301
  export class BeanAccountsService {
@@ -306,7 +333,7 @@ export class BeanAccountsService {
306
333
  * @param data.type Filter by account type
307
334
  * @param data.status Filter by status
308
335
  * @param data.isCustom Filter by custom (user-created) accounts only
309
- * @param data.search Search term for path or i18nKey
336
+ * @param data.search Search term for account path
310
337
  * @param data.limit Maximum number of results
311
338
  * @param data.offset Number of results to skip
312
339
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -387,7 +414,7 @@ export class BeanAccountsService {
387
414
 
388
415
  /**
389
416
  * Delete account
390
- * Deletes an account (only if no transactions)
417
+ * Deletes an account (only if no active transactions; voided/superseded residual postings are cleaned up)
391
418
  * @param data The data for the request.
392
419
  * @param data.id Account UUID
393
420
  * @param data.region Region code for tenant context
@@ -406,7 +433,7 @@ export class BeanAccountsService {
406
433
  },
407
434
  errors: {
408
435
  404: 'Account not found',
409
- 409: 'Account has transactions and cannot be deleted'
436
+ 409: 'Account has active transactions and cannot be deleted'
410
437
  }
411
438
  });
412
439
  }
@@ -468,6 +495,35 @@ export class BeanAccountsService {
468
495
  }
469
496
  });
470
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
+ }
525
+ });
526
+ }
471
527
  }
472
528
 
473
529
  export class BeanAccountStandardsService {
@@ -499,7 +555,7 @@ export class BeanAccountStandardsService {
499
555
 
500
556
  /**
501
557
  * Get template metadata for an account path
502
- * Returns extendable status and root type for a template path.
558
+ * Returns root type for a template path.
503
559
  * @param data The data for the request.
504
560
  * @param data.region Region code for tenant context
505
561
  * @param data.path Account path to check
@@ -794,7 +850,7 @@ export class BeanBalancesService {
794
850
  * Query account balance
795
851
  * Calculate account balance at a specific date for a single currency
796
852
  * @param data The data for the request.
797
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
853
+ * @param data.account Account name (e.g., "Assets:Checking")
798
854
  * @param data.region Region code for tenant context
799
855
  * @param data.date Date to calculate balance at (ISO 8601 format)
800
856
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -1515,153 +1571,320 @@ export class BeanCommoditiesService {
1515
1571
  }
1516
1572
  }
1517
1573
 
1518
- export class RecurringRulesService {
1574
+ export class BeanPricesService {
1519
1575
  /**
1520
- * Create a new recurring rule
1521
- * 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
1522
1578
  * @param data The data for the request.
1523
1579
  * @param data.region Region code for tenant context
1524
1580
  * @param data.requestBody
1525
- * @returns RecurringRuleResponseDto Rule created successfully
1581
+ * @returns PriceResponseDto Price created successfully
1526
1582
  * @throws ApiError
1527
1583
  */
1528
- public static recurringRuleControllerCreate(
1529
- data: RecurringRuleControllerCreateData
1530
- ): CancelablePromise<RecurringRuleControllerCreateResponse> {
1584
+ public static priceControllerCreate(
1585
+ data: PriceControllerCreateData
1586
+ ): CancelablePromise<PriceControllerCreateResponse> {
1531
1587
  return __request(OpenAPI, {
1532
1588
  method: 'POST',
1533
- url: '/api/v1/{region}/bean/recurring-rules',
1589
+ url: '/api/v1/{region}/bean/prices',
1534
1590
  path: {
1535
1591
  region: data.region
1536
1592
  },
1537
1593
  body: data.requestBody,
1538
1594
  mediaType: 'application/json',
1539
1595
  errors: {
1540
- 400: 'Invalid input data (e.g., autoCreate without accounts)',
1541
- 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'
1542
1598
  }
1543
1599
  });
1544
1600
  }
1545
1601
 
1546
1602
  /**
1547
- * List recurring rules
1548
- * 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
1549
1605
  * @param data The data for the request.
1550
1606
  * @param data.region Region code for tenant context
1551
- * @param data.isActive Filter by active status
1552
- * @param data.frequency Filter by frequency (WEEKLY, MONTHLY, etc.)
1553
- * @param data.hasAutoCreate Filter by autoCreate enabled
1554
- * @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
1555
1615
  * @throws ApiError
1556
1616
  */
1557
- public static recurringRuleControllerFindAll(
1558
- data: RecurringRuleControllerFindAllData
1559
- ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
1617
+ public static priceControllerFindAll(
1618
+ data: PriceControllerFindAllData
1619
+ ): CancelablePromise<PriceControllerFindAllResponse> {
1560
1620
  return __request(OpenAPI, {
1561
1621
  method: 'GET',
1562
- url: '/api/v1/{region}/bean/recurring-rules',
1622
+ url: '/api/v1/{region}/bean/prices',
1563
1623
  path: {
1564
1624
  region: data.region
1565
1625
  },
1566
1626
  query: {
1567
- isActive: data.isActive,
1568
- frequency: data.frequency,
1569
- 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
1570
1634
  }
1571
1635
  });
1572
1636
  }
1573
1637
 
1574
1638
  /**
1575
- * Create recurring rule from transaction
1576
- * 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
1577
1641
  * @param data The data for the request.
1578
- * @param data.transactionId Source transaction ID
1642
+ * @param data.id Price ID
1579
1643
  * @param data.region Region code for tenant context
1580
- * @param data.requestBody
1581
- * @returns RecurringRuleResponseDto Rule created successfully
1644
+ * @returns PriceResponseDto Price retrieved successfully
1582
1645
  * @throws ApiError
1583
1646
  */
1584
- public static recurringRuleControllerCreateFromTransaction(
1585
- data: RecurringRuleControllerCreateFromTransactionData
1586
- ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
1647
+ public static priceControllerFindOne(
1648
+ data: PriceControllerFindOneData
1649
+ ): CancelablePromise<PriceControllerFindOneResponse> {
1587
1650
  return __request(OpenAPI, {
1588
- method: 'POST',
1589
- url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
1651
+ method: 'GET',
1652
+ url: '/api/v1/{region}/bean/prices/{id}',
1590
1653
  path: {
1591
- transactionId: data.transactionId,
1654
+ id: data.id,
1592
1655
  region: data.region
1593
1656
  },
1594
- body: data.requestBody,
1595
- mediaType: 'application/json',
1596
1657
  errors: {
1597
- 404: 'Transaction not found',
1598
- 409: 'Rule with same name already exists or transaction already linked'
1658
+ 404: 'Price not found'
1599
1659
  }
1600
1660
  });
1601
1661
  }
1602
1662
 
1603
1663
  /**
1604
- * Get recurring rule by ID
1605
- * Returns a specific recurring rule with its details
1664
+ * Update a price
1665
+ * Updates an existing price entry
1606
1666
  * @param data The data for the request.
1607
- * @param data.id Rule ID
1667
+ * @param data.id Price ID
1608
1668
  * @param data.region Region code for tenant context
1609
- * @returns RecurringRuleResponseDto Rule retrieved successfully
1669
+ * @param data.requestBody
1670
+ * @returns PriceResponseDto Price updated successfully
1610
1671
  * @throws ApiError
1611
1672
  */
1612
- public static recurringRuleControllerFindOne(
1613
- data: RecurringRuleControllerFindOneData
1614
- ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
1673
+ public static priceControllerUpdate(
1674
+ data: PriceControllerUpdateData
1675
+ ): CancelablePromise<PriceControllerUpdateResponse> {
1615
1676
  return __request(OpenAPI, {
1616
- method: 'GET',
1617
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
1677
+ method: 'PUT',
1678
+ url: '/api/v1/{region}/bean/prices/{id}',
1618
1679
  path: {
1619
1680
  id: data.id,
1620
1681
  region: data.region
1621
1682
  },
1683
+ body: data.requestBody,
1684
+ mediaType: 'application/json',
1622
1685
  errors: {
1623
- 404: 'Rule not found'
1686
+ 404: 'Price not found',
1687
+ 409: 'Updated price conflicts with existing price'
1624
1688
  }
1625
1689
  });
1626
1690
  }
1627
1691
 
1628
1692
  /**
1629
- * Update recurring rule
1630
- * Updates an existing recurring rule
1693
+ * Delete a price
1694
+ * Deletes a price entry (hard delete)
1631
1695
  * @param data The data for the request.
1632
- * @param data.id Rule ID
1696
+ * @param data.id Price ID
1633
1697
  * @param data.region Region code for tenant context
1634
- * @param data.requestBody
1635
- * @returns RecurringRuleResponseDto Rule updated successfully
1698
+ * @returns void Price deleted successfully
1636
1699
  * @throws ApiError
1637
1700
  */
1638
- public static recurringRuleControllerUpdate(
1639
- data: RecurringRuleControllerUpdateData
1640
- ): CancelablePromise<RecurringRuleControllerUpdateResponse> {
1701
+ public static priceControllerDelete(
1702
+ data: PriceControllerDeleteData
1703
+ ): CancelablePromise<PriceControllerDeleteResponse> {
1641
1704
  return __request(OpenAPI, {
1642
- method: 'PATCH',
1643
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
1705
+ method: 'DELETE',
1706
+ url: '/api/v1/{region}/bean/prices/{id}',
1644
1707
  path: {
1645
1708
  id: data.id,
1646
1709
  region: data.region
1647
1710
  },
1648
- body: data.requestBody,
1649
- mediaType: 'application/json',
1650
1711
  errors: {
1651
- 400: 'Invalid input data',
1652
- 404: 'Rule not found'
1712
+ 404: 'Price not found'
1653
1713
  }
1654
1714
  });
1655
1715
  }
1656
1716
 
1657
1717
  /**
1658
- * Delete recurring rule
1659
- * Soft deletes a recurring rule (sets isActive to false)
1718
+ * Bulk create prices
1719
+ * Creates multiple price entries at once (skips duplicates)
1660
1720
  * @param data The data for the request.
1661
- * @param data.id Rule ID
1662
1721
  * @param data.region Region code for tenant context
1663
- * @returns void Rule deleted successfully
1664
- * @throws ApiError
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'
1847
+ }
1848
+ });
1849
+ }
1850
+
1851
+ /**
1852
+ * Update recurring rule
1853
+ * Updates an existing recurring rule
1854
+ * @param data The data for the request.
1855
+ * @param data.id Rule ID
1856
+ * @param data.region Region code for tenant context
1857
+ * @param data.requestBody
1858
+ * @returns RecurringRuleResponseDto Rule updated successfully
1859
+ * @throws ApiError
1860
+ */
1861
+ public static recurringRuleControllerUpdate(
1862
+ data: RecurringRuleControllerUpdateData
1863
+ ): CancelablePromise<RecurringRuleControllerUpdateResponse> {
1864
+ return __request(OpenAPI, {
1865
+ method: 'PATCH',
1866
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
1867
+ path: {
1868
+ id: data.id,
1869
+ region: data.region
1870
+ },
1871
+ body: data.requestBody,
1872
+ mediaType: 'application/json',
1873
+ errors: {
1874
+ 400: 'Invalid input data',
1875
+ 404: 'Rule not found'
1876
+ }
1877
+ });
1878
+ }
1879
+
1880
+ /**
1881
+ * Delete recurring rule
1882
+ * Soft deletes a recurring rule (sets isActive to false)
1883
+ * @param data The data for the request.
1884
+ * @param data.id Rule ID
1885
+ * @param data.region Region code for tenant context
1886
+ * @returns void Rule deleted successfully
1887
+ * @throws ApiError
1665
1888
  */
1666
1889
  public static recurringRuleControllerDelete(
1667
1890
  data: RecurringRuleControllerDeleteData
@@ -1945,279 +2168,158 @@ export class RecurringForecastService {
1945
2168
  }
1946
2169
  }
1947
2170
 
1948
- export class BeanTransactionRulesService {
2171
+ export class ReportingService {
1949
2172
  /**
1950
- * Create a new transaction rule (or upsert if upsertByPayee=true)
1951
- * 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
+ *
1952
2186
  * @param data The data for the request.
1953
2187
  * @param data.region Region code for tenant context
1954
- * @param data.requestBody
1955
- * @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
1956
2191
  * @throws ApiError
1957
2192
  */
1958
- public static transactionRuleControllerCreate(
1959
- data: TransactionRuleControllerCreateData
1960
- ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2193
+ public static reportingControllerGetPortfolioTrends(
2194
+ data: ReportingControllerGetPortfolioTrendsData
2195
+ ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
1961
2196
  return __request(OpenAPI, {
1962
- method: 'POST',
1963
- url: '/api/v1/{region}/bean/transaction-rules',
2197
+ method: 'GET',
2198
+ url: '/api/v1/{region}/reporting/portfolio/trends',
1964
2199
  path: {
1965
2200
  region: data.region
1966
2201
  },
1967
- body: data.requestBody,
1968
- mediaType: 'application/json',
2202
+ query: {
2203
+ period: data.period,
2204
+ granularity: data.granularity
2205
+ },
1969
2206
  errors: {
1970
- 400: 'Validation failed',
1971
- 401: 'Unauthorized',
1972
- 409: 'Resource conflict - another process is updating this rule'
2207
+ 401: 'User not authenticated'
1973
2208
  }
1974
2209
  });
1975
2210
  }
1976
2211
 
1977
2212
  /**
1978
- * 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
+ *
1979
2222
  * @param data The data for the request.
1980
2223
  * @param data.region Region code for tenant context
1981
- * @param data.limit Max results per page (default: 20, max: 100)
1982
- * @param data.offset Pagination offset (default: 0)
1983
- * @param data.enabled Filter by enabled status
1984
- * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
1985
- * @param data.autoApplyEnabled Filter by auto-apply status
1986
- * @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
1987
2227
  * @throws ApiError
1988
2228
  */
1989
- public static transactionRuleControllerList(
1990
- data: TransactionRuleControllerListData
1991
- ): CancelablePromise<TransactionRuleControllerListResponse> {
2229
+ public static reportingControllerGetCashFlowTrends(
2230
+ data: ReportingControllerGetCashFlowTrendsData
2231
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
1992
2232
  return __request(OpenAPI, {
1993
2233
  method: 'GET',
1994
- url: '/api/v1/{region}/bean/transaction-rules',
2234
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
1995
2235
  path: {
1996
2236
  region: data.region
1997
2237
  },
1998
2238
  query: {
1999
- limit: data.limit,
2000
- offset: data.offset,
2001
- enabled: data.enabled,
2002
- learningSource: data.learningSource,
2003
- autoApplyEnabled: data.autoApplyEnabled
2239
+ period: data.period,
2240
+ granularity: data.granularity
2004
2241
  },
2005
2242
  errors: {
2006
- 401: 'Unauthorized'
2243
+ 401: 'User not authenticated'
2007
2244
  }
2008
2245
  });
2009
2246
  }
2010
2247
 
2011
2248
  /**
2012
- * Validate transaction rule configuration
2013
- * @param data The data for the request.
2014
- * @param data.region Region code for tenant context
2015
- * @param data.requestBody
2016
- * @returns ValidateRuleResponseDto Validation result
2017
- * @throws ApiError
2018
- */
2019
- public static transactionRuleControllerValidate(
2020
- data: TransactionRuleControllerValidateData
2021
- ): CancelablePromise<TransactionRuleControllerValidateResponse> {
2022
- return __request(OpenAPI, {
2023
- method: 'POST',
2024
- url: '/api/v1/{region}/bean/transaction-rules/validate',
2025
- path: {
2026
- region: data.region
2027
- },
2028
- body: data.requestBody,
2029
- mediaType: 'application/json',
2030
- errors: {
2031
- 400: 'Validation failed',
2032
- 401: 'Unauthorized'
2033
- }
2034
- });
2035
- }
2036
-
2037
- /**
2038
- * Bulk create transaction rules
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
+ *
2039
2263
  * @param data The data for the request.
2040
2264
  * @param data.region Region code for tenant context
2041
- * @param data.requestBody
2042
- * @returns BulkCreateRulesResponseDto Bulk create completed
2265
+ * @param data.requestBody Optional date (defaults to today)
2266
+ * @returns GenerateSnapshotResponse Snapshot generated successfully
2043
2267
  * @throws ApiError
2044
2268
  */
2045
- public static transactionRuleControllerBulkCreate(
2046
- data: TransactionRuleControllerBulkCreateData
2047
- ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
2269
+ public static reportingControllerGenerateSnapshot(
2270
+ data: ReportingControllerGenerateSnapshotData
2271
+ ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
2048
2272
  return __request(OpenAPI, {
2049
2273
  method: 'POST',
2050
- url: '/api/v1/{region}/bean/transaction-rules/bulk',
2051
- path: {
2052
- region: data.region
2053
- },
2054
- body: data.requestBody,
2055
- mediaType: 'application/json',
2056
- errors: {
2057
- 400: 'Invalid bulk create data',
2058
- 401: 'Unauthorized'
2059
- }
2060
- });
2061
- }
2062
-
2063
- /**
2064
- * Export transaction rules
2065
- * @param data The data for the request.
2066
- * @param data.format Export format (currently only JSON supported)
2067
- * @param data.region Region code for tenant context
2068
- * @returns ExportRulesResponseDto Exported rules
2069
- * @throws ApiError
2070
- */
2071
- public static transactionRuleControllerExport(
2072
- data: TransactionRuleControllerExportData
2073
- ): CancelablePromise<TransactionRuleControllerExportResponse> {
2074
- return __request(OpenAPI, {
2075
- method: 'GET',
2076
- url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2077
- path: {
2078
- format: data.format,
2079
- region: data.region
2080
- },
2081
- errors: {
2082
- 400: 'Unsupported format',
2083
- 401: 'Unauthorized'
2084
- }
2085
- });
2086
- }
2087
-
2088
- /**
2089
- * Get transaction rule statistics
2090
- * @param data The data for the request.
2091
- * @param data.period Statistics time period
2092
- * @param data.region Region code for tenant context
2093
- * @returns RuleStatisticsResponseDto Rule statistics
2094
- * @throws ApiError
2095
- */
2096
- public static transactionRuleControllerGetStatistics(
2097
- data: TransactionRuleControllerGetStatisticsData
2098
- ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
2099
- return __request(OpenAPI, {
2100
- method: 'GET',
2101
- url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
2102
- path: {
2103
- period: data.period,
2104
- region: data.region
2105
- },
2106
- errors: {
2107
- 401: 'Unauthorized'
2108
- }
2109
- });
2110
- }
2111
-
2112
- /**
2113
- * Get transaction rule detail
2114
- * @param data The data for the request.
2115
- * @param data.ruleId Rule ID
2116
- * @param data.region Region code for tenant context
2117
- * @returns TransactionRuleResponseDto Rule details
2118
- * @throws ApiError
2119
- */
2120
- public static transactionRuleControllerGetDetail(
2121
- data: TransactionRuleControllerGetDetailData
2122
- ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
2123
- return __request(OpenAPI, {
2124
- method: 'GET',
2125
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2126
- path: {
2127
- ruleId: data.ruleId,
2128
- region: data.region
2129
- },
2130
- errors: {
2131
- 401: 'Unauthorized',
2132
- 403: 'Forbidden - not owner of rule',
2133
- 404: 'Rule not found'
2134
- }
2135
- });
2136
- }
2137
-
2138
- /**
2139
- * Update a transaction rule
2140
- * @param data The data for the request.
2141
- * @param data.ruleId Rule ID to update
2142
- * @param data.region Region code for tenant context
2143
- * @param data.requestBody
2144
- * @returns TransactionRuleResponseDto Rule updated successfully
2145
- * @throws ApiError
2146
- */
2147
- public static transactionRuleControllerUpdate(
2148
- data: TransactionRuleControllerUpdateData
2149
- ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2150
- return __request(OpenAPI, {
2151
- method: 'PUT',
2152
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2274
+ url: '/api/v1/{region}/reporting/snapshots/generate',
2153
2275
  path: {
2154
- ruleId: data.ruleId,
2155
2276
  region: data.region
2156
2277
  },
2157
2278
  body: data.requestBody,
2158
2279
  mediaType: 'application/json',
2159
2280
  errors: {
2160
- 400: 'Validation failed',
2161
- 401: 'Unauthorized',
2162
- 403: 'Forbidden - not owner of rule',
2163
- 404: 'Rule not found',
2164
- 409: 'Resource conflict - rule is being modified by another process'
2165
- }
2166
- });
2167
- }
2168
-
2169
- /**
2170
- * Delete a transaction rule
2171
- * @param data The data for the request.
2172
- * @param data.ruleId Rule ID to delete
2173
- * @param data.region Region code for tenant context
2174
- * @returns void Rule deleted successfully
2175
- * @throws ApiError
2176
- */
2177
- public static transactionRuleControllerDelete(
2178
- data: TransactionRuleControllerDeleteData
2179
- ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2180
- return __request(OpenAPI, {
2181
- method: 'DELETE',
2182
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2183
- path: {
2184
- ruleId: data.ruleId,
2185
- region: data.region
2186
- },
2187
- errors: {
2188
- 401: 'Unauthorized',
2189
- 403: 'Forbidden - not owner of rule',
2190
- 404: 'Rule not found',
2191
- 409: 'Resource conflict - rule is being modified by another process'
2281
+ 400: 'Invalid date format',
2282
+ 401: 'User not authenticated'
2192
2283
  }
2193
2284
  });
2194
2285
  }
2195
2286
 
2196
2287
  /**
2197
- * 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
+ *
2198
2302
  * @param data The data for the request.
2199
- * @param data.ruleId Rule ID to test
2200
2303
  * @param data.region Region code for tenant context
2201
2304
  * @param data.requestBody
2202
- * @returns TestRuleResponseDto Test result
2305
+ * @returns BackfillSnapshotsResponse Backfill completed successfully
2203
2306
  * @throws ApiError
2204
2307
  */
2205
- public static transactionRuleControllerTest(
2206
- data: TransactionRuleControllerTestData
2207
- ): CancelablePromise<TransactionRuleControllerTestResponse> {
2308
+ public static reportingControllerBackfillSnapshots(
2309
+ data: ReportingControllerBackfillSnapshotsData
2310
+ ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
2208
2311
  return __request(OpenAPI, {
2209
2312
  method: 'POST',
2210
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2313
+ url: '/api/v1/{region}/reporting/snapshots/backfill',
2211
2314
  path: {
2212
- ruleId: data.ruleId,
2213
2315
  region: data.region
2214
2316
  },
2215
2317
  body: data.requestBody,
2216
2318
  mediaType: 'application/json',
2217
2319
  errors: {
2218
- 401: 'Unauthorized',
2219
- 403: 'Forbidden - not owner of rule',
2220
- 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'
2221
2323
  }
2222
2324
  });
2223
2325
  }
@@ -2249,7 +2351,7 @@ export class UsersService {
2249
2351
  * Get current authenticated user
2250
2352
  * @param data The data for the request.
2251
2353
  * @param data.acceptLanguage
2252
- * @returns unknown User retrieved successfully
2354
+ * @returns UserResponseDto User retrieved successfully
2253
2355
  * @throws ApiError
2254
2356
  */
2255
2357
  public static userControllerGetUser(
@@ -2269,7 +2371,7 @@ export class UsersService {
2269
2371
  * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
2270
2372
  * @param data The data for the request.
2271
2373
  * @param data.requestBody
2272
- * @returns unknown User created successfully
2374
+ * @returns SignupResponseDto User created successfully
2273
2375
  * @throws ApiError
2274
2376
  */
2275
2377
  public static userControllerSignupUser(
@@ -2478,52 +2580,358 @@ export class PropertiesService {
2478
2580
  }
2479
2581
  }
2480
2582
 
2481
- export class LifeEventsService {
2583
+ export class BeanTransactionRulesService {
2482
2584
  /**
2483
- * Create a new life event
2484
- * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
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.
2485
2587
  * @param data The data for the request.
2486
- * @param data.region Region code for tenant context (decorative for life events)
2588
+ * @param data.region Region code for tenant context
2487
2589
  * @param data.requestBody
2488
- * @returns EventResponseDto Life event created successfully
2590
+ * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2489
2591
  * @throws ApiError
2490
2592
  */
2491
- public static eventControllerCreate(
2492
- data: EventControllerCreateData
2493
- ): CancelablePromise<EventControllerCreateResponse> {
2593
+ public static transactionRuleControllerCreate(
2594
+ data: TransactionRuleControllerCreateData
2595
+ ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2494
2596
  return __request(OpenAPI, {
2495
2597
  method: 'POST',
2496
- url: '/api/v1/{region}/bean/events',
2598
+ url: '/api/v1/{region}/bean/transaction-rules',
2497
2599
  path: {
2498
2600
  region: data.region
2499
2601
  },
2500
2602
  body: data.requestBody,
2501
2603
  mediaType: 'application/json',
2502
2604
  errors: {
2503
- 409: 'Life event already exists for this (userId, type, date) combination'
2605
+ 400: 'Validation failed',
2606
+ 401: 'Unauthorized',
2607
+ 409: 'Resource conflict - another process is updating this rule'
2504
2608
  }
2505
2609
  });
2506
2610
  }
2507
2611
 
2508
2612
  /**
2509
- * List user life events
2510
- * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2613
+ * Get all transaction rules for user
2511
2614
  * @param data The data for the request.
2512
- * @param data.region Region code for tenant context (decorative for life events)
2513
- * @param data.type Filter by life event type (exact match)
2514
- * @param data.q Search term for description (case-insensitive partial match)
2515
- * @param data.from Filter life events from this date (ISO 8601 format)
2516
- * @param data.to Filter life events to this date (ISO 8601 format)
2517
- * @param data.page Page number for pagination (default: 1)
2518
- * @param data.limit Number of items per page (default: 20, max: 100)
2519
- * @returns EventListResponseDto Life events retrieved successfully
2615
+ * @param data.region Region code for tenant context
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
2520
2622
  * @throws ApiError
2521
2623
  */
2522
- public static eventControllerFindAll(
2523
- data: EventControllerFindAllData
2524
- ): CancelablePromise<EventControllerFindAllResponse> {
2525
- return __request(OpenAPI, {
2526
- method: 'GET',
2624
+ public static transactionRuleControllerList(
2625
+ data: TransactionRuleControllerListData
2626
+ ): CancelablePromise<TransactionRuleControllerListResponse> {
2627
+ return __request(OpenAPI, {
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',
2527
2935
  url: '/api/v1/{region}/bean/events',
2528
2936
  path: {
2529
2937
  region: data.region
@@ -2653,6 +3061,139 @@ export class LifeEventsService {
2653
3061
  }
2654
3062
  }
2655
3063
 
3064
+ export class OnboardingService {
3065
+ /**
3066
+ * Bootstrap core accounts + register asset accounts with opening balances (ADR-0113)
3067
+ * @param data The data for the request.
3068
+ * @param data.region Region code for tenant context
3069
+ * @param data.requestBody
3070
+ * @returns unknown Onboarding bootstrap result.
3071
+ * @throws ApiError
3072
+ */
3073
+ public static onboardingControllerBootstrap(
3074
+ data: OnboardingControllerBootstrapData
3075
+ ): CancelablePromise<OnboardingControllerBootstrapResponse> {
3076
+ return __request(OpenAPI, {
3077
+ method: 'POST',
3078
+ url: '/api/v1/{region}/bean/onboarding',
3079
+ path: {
3080
+ region: data.region
3081
+ },
3082
+ body: data.requestBody,
3083
+ mediaType: 'application/json',
3084
+ errors: {
3085
+ 422: 'Invalid region/account path/duplicate paths.'
3086
+ }
3087
+ });
3088
+ }
3089
+ }
3090
+
3091
+ export class BalanceReconciliationService {
3092
+ /**
3093
+ * Preview reconciliation (book vs actual)
3094
+ * Computes book balance, diff, Beancount-inferred tolerance, and suggested action without persisting.
3095
+ * @param data The data for the request.
3096
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3097
+ * @param data.requestBody
3098
+ * @returns ReconciliationComputeResultDto Reconciliation preview
3099
+ * @throws ApiError
3100
+ */
3101
+ public static reconciliationControllerCompute(
3102
+ data: ReconciliationControllerComputeData
3103
+ ): CancelablePromise<ReconciliationControllerComputeResponse> {
3104
+ return __request(OpenAPI, {
3105
+ method: 'POST',
3106
+ url: '/api/v1/{region}/bean/reconciliations',
3107
+ path: {
3108
+ region: data.region
3109
+ },
3110
+ body: data.requestBody,
3111
+ mediaType: 'application/json',
3112
+ errors: {
3113
+ 404: 'Account not found'
3114
+ }
3115
+ });
3116
+ }
3117
+
3118
+ /**
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
3125
+ * @throws ApiError
3126
+ */
3127
+ public static reconciliationControllerAssert(
3128
+ data: ReconciliationControllerAssertData
3129
+ ): CancelablePromise<ReconciliationControllerAssertResponse> {
3130
+ return __request(OpenAPI, {
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
+ }
3141
+ });
3142
+ }
3143
+
3144
+ /**
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.
3147
+ * @param data The data for the request.
3148
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3149
+ * @param data.requestBody
3150
+ * @returns PadResultDto Pad adjusting entry generated
3151
+ * @throws ApiError
3152
+ */
3153
+ public static reconciliationControllerPad(
3154
+ data: ReconciliationControllerPadData
3155
+ ): CancelablePromise<ReconciliationControllerPadResponse> {
3156
+ return __request(OpenAPI, {
3157
+ method: 'POST',
3158
+ url: '/api/v1/{region}/bean/reconciliations/pad',
3159
+ path: {
3160
+ region: data.region
3161
+ },
3162
+ body: data.requestBody,
3163
+ mediaType: 'application/json',
3164
+ errors: {
3165
+ 400: 'Book already within tolerance — no pad needed',
3166
+ 404: 'Account not found'
3167
+ }
3168
+ });
3169
+ }
3170
+
3171
+ /**
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
3178
+ * @throws ApiError
3179
+ */
3180
+ public static reconciliationControllerHistory(
3181
+ data: ReconciliationControllerHistoryData
3182
+ ): CancelablePromise<ReconciliationControllerHistoryResponse> {
3183
+ return __request(OpenAPI, {
3184
+ method: 'GET',
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
+ }
3193
+ });
3194
+ }
3195
+ }
3196
+
2656
3197
  export class BeanExportService {
2657
3198
  /**
2658
3199
  * Export Beancount ledger as ZIP
@@ -2831,216 +3372,196 @@ export class BeanImportService {
2831
3372
  }
2832
3373
  }
2833
3374
 
2834
- export class BeanPlatformsService {
2835
- /**
2836
- * Get all platforms with statistics
2837
- * @returns unknown List of platforms with binding and account counts
2838
- * @throws ApiError
2839
- */
2840
- public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
2841
- return __request(OpenAPI, {
2842
- method: 'GET',
2843
- url: '/api/v1/bean/platforms'
2844
- });
2845
- }
2846
-
3375
+ export class ProviderSyncService {
2847
3376
  /**
2848
- * Create a new platform
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
+ *
2849
3399
  * @param data The data for the request.
3400
+ * @param data.providerName Provider name
3401
+ * @param data.region Region code for tenant context
2850
3402
  * @param data.requestBody
2851
- * @returns unknown Platform created successfully
3403
+ * @returns ProviderSyncResponseDto Sync completed successfully
2852
3404
  * @throws ApiError
2853
3405
  */
2854
- public static platformControllerCreate(
2855
- data: PlatformControllerCreateData
2856
- ): CancelablePromise<PlatformControllerCreateResponse> {
3406
+ public static providerSyncControllerSync(
3407
+ data: ProviderSyncControllerSyncData
3408
+ ): CancelablePromise<ProviderSyncControllerSyncResponse> {
2857
3409
  return __request(OpenAPI, {
2858
3410
  method: 'POST',
2859
- url: '/api/v1/bean/platforms',
3411
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3412
+ path: {
3413
+ providerName: data.providerName,
3414
+ region: data.region
3415
+ },
2860
3416
  body: data.requestBody,
2861
3417
  mediaType: 'application/json',
2862
3418
  errors: {
2863
- 409: 'Platform already exists'
3419
+ 400: 'Invalid request data',
3420
+ 401: 'Missing or invalid authentication',
3421
+ 404: 'Provider not supported'
2864
3422
  }
2865
3423
  });
2866
3424
  }
2867
3425
 
2868
3426
  /**
2869
- * Get platform list for current user
2870
- * @returns unknown List of platforms with user binding status
2871
- * @throws ApiError
2872
- */
2873
- public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
2874
- return __request(OpenAPI, {
2875
- method: 'GET',
2876
- url: '/api/v1/bean/platforms/list'
2877
- });
2878
- }
2879
-
2880
- /**
2881
- * Match platforms by name or alias
3427
+ * Get supported providers
3428
+ * Returns a list of all providers supported by the sync endpoint.
2882
3429
  * @param data The data for the request.
2883
- * @param data.q Search query — Chinese name, English name, or abbreviation
2884
- * @param data.region Region code for category override lookup
2885
- * @returns unknown List of matching platforms with suggested segment names
3430
+ * @param data.region Region code for tenant context
3431
+ * @returns SupportedProvidersResponseDto List of supported providers
2886
3432
  * @throws ApiError
2887
3433
  */
2888
- public static platformControllerMatchPlatforms(
2889
- data: PlatformControllerMatchPlatformsData
2890
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3434
+ public static providerSyncControllerGetSupportedProviders(
3435
+ data: ProviderSyncControllerGetSupportedProvidersData
3436
+ ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
2891
3437
  return __request(OpenAPI, {
2892
3438
  method: 'GET',
2893
- url: '/api/v1/bean/platforms/match',
2894
- query: {
2895
- q: data.q,
2896
- region: data.region
2897
- }
2898
- });
2899
- }
2900
-
2901
- /**
2902
- * Update a platform
2903
- * @param data The data for the request.
2904
- * @param data.id Platform ID
2905
- * @param data.requestBody
2906
- * @returns unknown Platform updated successfully
2907
- * @throws ApiError
2908
- */
2909
- public static platformControllerUpdate(
2910
- data: PlatformControllerUpdateData
2911
- ): CancelablePromise<PlatformControllerUpdateResponse> {
2912
- return __request(OpenAPI, {
2913
- method: 'PUT',
2914
- url: '/api/v1/bean/platforms/{id}',
3439
+ url: '/api/v1/{region}/bean/import/provider/supported',
2915
3440
  path: {
2916
- id: data.id
3441
+ region: data.region
2917
3442
  },
2918
- body: data.requestBody,
2919
- mediaType: 'application/json',
2920
3443
  errors: {
2921
- 404: 'Platform not found'
3444
+ 401: 'Missing or invalid authentication'
2922
3445
  }
2923
3446
  });
2924
3447
  }
2925
3448
 
2926
3449
  /**
2927
- * Delete a platform
3450
+ * Check if provider is supported
3451
+ * Returns whether a specific provider is supported.
2928
3452
  * @param data The data for the request.
2929
- * @param data.id Platform ID
2930
- * @returns void Platform deleted successfully
3453
+ * @param data.providerName Provider name to check
3454
+ * @param data.region Region code for tenant context
3455
+ * @returns unknown Provider support status
2931
3456
  * @throws ApiError
2932
3457
  */
2933
- public static platformControllerDelete(
2934
- data: PlatformControllerDeleteData
2935
- ): CancelablePromise<PlatformControllerDeleteResponse> {
3458
+ public static providerSyncControllerIsProviderSupported(
3459
+ data: ProviderSyncControllerIsProviderSupportedData
3460
+ ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
2936
3461
  return __request(OpenAPI, {
2937
- method: 'DELETE',
2938
- url: '/api/v1/bean/platforms/{id}',
3462
+ method: 'GET',
3463
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
2939
3464
  path: {
2940
- id: data.id
3465
+ providerName: data.providerName,
3466
+ region: data.region
2941
3467
  },
2942
3468
  errors: {
2943
- 404: 'Platform not found'
3469
+ 401: 'Missing or invalid authentication'
2944
3470
  }
2945
3471
  });
2946
3472
  }
2947
- }
2948
-
2949
- export class ProviderSyncService {
2950
- /**
2951
- * Sync transactions from financial data provider
2952
- *
2953
- * Accepts raw transactions from external financial data providers, transforms them to Beancount format, and processes them through the ingestion pipeline.
2954
- *
2955
- * **Supported Providers:**
2956
- * - **plaid**: Plaid API (US, Canada, Europe)
2957
- * - **teller**: Teller API (US)
2958
- * - **truelayer**: TrueLayer Open Banking (UK, Europe)
2959
- * - **gocardless**: GoCardless Bank Account Data (Europe)
2960
- * - **simplefin**: SimpleFIN (Self-hosted)
2961
- * - **yodlee**: Yodlee (Global)
2962
- * - **beancount-direct**: Beancount format transactions
2963
- * - **parsed-bill**: Client-side parsed bill transactions
2964
- *
2965
- * **Processing Flow:**
2966
- * 1. Transform raw data via provider adapter
2967
- * 2. Validate transaction format
2968
- * 3. Deduplicate using originalId
2969
- * 4. Classify using rule engine
2970
- * 5. Route low-confidence to Review Center
2971
- * 6. Persist validated transactions
2972
- *
3473
+ }
3474
+
3475
+ export class ExternalAccountLinksService {
3476
+ /**
3477
+ * Create an external account → BeanAccount mapping (ADR-0113)
2973
3478
  * @param data The data for the request.
2974
- * @param data.providerName Provider name
2975
3479
  * @param data.region Region code for tenant context
2976
3480
  * @param data.requestBody
2977
- * @returns ProviderSyncResponseDto Sync completed successfully
3481
+ * @returns ExternalAccountLinkResponseDto Link created.
2978
3482
  * @throws ApiError
2979
3483
  */
2980
- public static providerSyncControllerSync(
2981
- data: ProviderSyncControllerSyncData
2982
- ): CancelablePromise<ProviderSyncControllerSyncResponse> {
3484
+ public static externalAccountLinkControllerCreate(
3485
+ data: ExternalAccountLinkControllerCreateData
3486
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
2983
3487
  return __request(OpenAPI, {
2984
3488
  method: 'POST',
2985
- url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3489
+ url: '/api/v1/{region}/bean/external-account-links',
2986
3490
  path: {
2987
- providerName: data.providerName,
2988
3491
  region: data.region
2989
3492
  },
2990
3493
  body: data.requestBody,
2991
3494
  mediaType: 'application/json',
2992
3495
  errors: {
2993
- 400: 'Invalid request data',
2994
- 401: 'Missing or invalid authentication',
2995
- 404: 'Provider not supported'
3496
+ 422: 'beanAccountId not owned, or an active link already exists.'
2996
3497
  }
2997
3498
  });
2998
3499
  }
2999
3500
 
3000
3501
  /**
3001
- * Get supported providers
3002
- * Returns a list of all providers supported by the sync endpoint.
3502
+ * List the user's active external account links
3003
3503
  * @param data The data for the request.
3504
+ * @param data.provider
3004
3505
  * @param data.region Region code for tenant context
3005
- * @returns SupportedProvidersResponseDto List of supported providers
3506
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
3006
3507
  * @throws ApiError
3007
3508
  */
3008
- public static providerSyncControllerGetSupportedProviders(
3009
- data: ProviderSyncControllerGetSupportedProvidersData
3010
- ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
3509
+ public static externalAccountLinkControllerFindAll(
3510
+ data: ExternalAccountLinkControllerFindAllData
3511
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
3011
3512
  return __request(OpenAPI, {
3012
3513
  method: 'GET',
3013
- url: '/api/v1/{region}/bean/import/provider/supported',
3514
+ url: '/api/v1/{region}/bean/external-account-links',
3014
3515
  path: {
3015
3516
  region: data.region
3016
3517
  },
3017
- errors: {
3018
- 401: 'Missing or invalid authentication'
3518
+ query: {
3519
+ provider: data.provider
3019
3520
  }
3020
3521
  });
3021
3522
  }
3022
3523
 
3023
3524
  /**
3024
- * Check if provider is supported
3025
- * Returns whether a specific provider is supported.
3525
+ * Get a single external account link
3026
3526
  * @param data The data for the request.
3027
- * @param data.providerName Provider name to check
3527
+ * @param data.id
3028
3528
  * @param data.region Region code for tenant context
3029
- * @returns unknown Provider support status
3529
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
3030
3530
  * @throws ApiError
3031
3531
  */
3032
- public static providerSyncControllerIsProviderSupported(
3033
- data: ProviderSyncControllerIsProviderSupportedData
3034
- ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
3532
+ public static externalAccountLinkControllerFindOne(
3533
+ data: ExternalAccountLinkControllerFindOneData
3534
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
3035
3535
  return __request(OpenAPI, {
3036
3536
  method: 'GET',
3037
- url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3537
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3038
3538
  path: {
3039
- providerName: data.providerName,
3539
+ id: data.id,
3040
3540
  region: data.region
3041
3541
  },
3042
3542
  errors: {
3043
- 401: 'Missing or invalid authentication'
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
3044
3565
  }
3045
3566
  });
3046
3567
  }
@@ -3204,359 +3725,180 @@ export class BeanNlpService {
3204
3725
  }
3205
3726
  }
3206
3727
 
3207
- export class DashboardService {
3208
- /**
3209
- * Get net worth overview
3210
- * Returns total net worth with breakdown of assets and liabilities
3211
- * @param data The data for the request.
3212
- * @param data.region Region code for tenant context
3213
- * @param data.date Date for balance calculation (ISO 8601 format)
3214
- * @returns NetWorthResponseDto Net worth retrieved successfully
3215
- * @throws ApiError
3216
- */
3217
- public static dashboardControllerGetNetWorth(
3218
- data: DashboardControllerGetNetWorthData
3219
- ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3220
- return __request(OpenAPI, {
3221
- method: 'GET',
3222
- url: '/api/v1/{region}/dashboard/net-worth',
3223
- path: {
3224
- region: data.region
3225
- },
3226
- query: {
3227
- date: data.date
3228
- },
3229
- errors: {
3230
- 401: 'User not authenticated'
3231
- }
3232
- });
3233
- }
3234
-
3235
- /**
3236
- * Get accounts grouped by platform
3237
- * Returns accounts with balances grouped by financial platform
3238
- * @param data The data for the request.
3239
- * @param data.region Region code for tenant context
3240
- * @param data.groupBy Grouping strategy
3241
- * @param data.date Date for balance calculation (ISO 8601 format)
3242
- * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3243
- * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3244
- * @throws ApiError
3245
- */
3246
- public static dashboardControllerGetAccounts(
3247
- data: DashboardControllerGetAccountsData
3248
- ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3249
- return __request(OpenAPI, {
3250
- method: 'GET',
3251
- url: '/api/v1/{region}/dashboard/accounts',
3252
- path: {
3253
- region: data.region
3254
- },
3255
- query: {
3256
- groupBy: data.groupBy,
3257
- date: data.date,
3258
- accountId: data.accountId
3259
- },
3260
- errors: {
3261
- 401: 'User not authenticated'
3262
- }
3263
- });
3264
- }
3265
-
3266
- /**
3267
- * Get cash flow summary
3268
- * Returns income, expenses, and savings for a monthly period
3269
- * @param data The data for the request.
3270
- * @param data.period Period in YYYY-MM format
3271
- * @param data.region Region code for tenant context
3272
- * @returns CashFlowResponseDto Cash flow retrieved successfully
3273
- * @throws ApiError
3274
- */
3275
- public static dashboardControllerGetCashFlow(
3276
- data: DashboardControllerGetCashFlowData
3277
- ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3278
- return __request(OpenAPI, {
3279
- method: 'GET',
3280
- url: '/api/v1/{region}/dashboard/cash-flow',
3281
- path: {
3282
- region: data.region
3283
- },
3284
- query: {
3285
- period: data.period
3286
- },
3287
- errors: {
3288
- 400: 'Invalid period format',
3289
- 401: 'User not authenticated'
3290
- }
3291
- });
3292
- }
3293
-
3294
- /**
3295
- * Get expenses grouped by functional category
3296
- * Returns expenses pre-aggregated by functional category (account-path Group segment) with server-side multi-currency conversion
3297
- * @param data The data for the request.
3298
- * @param data.region Region code for tenant context
3299
- * @param data.groupBy Grouping strategy
3300
- * @param data.period Time window (1m = current calendar month)
3301
- * @returns ExpensesByCategoryResponseDto Expenses retrieved successfully
3302
- * @throws ApiError
3303
- */
3304
- public static dashboardControllerGetExpenses(
3305
- data: DashboardControllerGetExpensesData
3306
- ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3307
- return __request(OpenAPI, {
3308
- method: 'GET',
3309
- url: '/api/v1/{region}/dashboard/expenses',
3310
- path: {
3311
- region: data.region
3312
- },
3313
- query: {
3314
- groupBy: data.groupBy,
3315
- period: data.period
3316
- },
3317
- errors: {
3318
- 400: 'Invalid groupBy or period',
3319
- 401: 'User not authenticated'
3320
- }
3321
- });
3322
- }
3323
- }
3324
-
3325
- export class InvestmentService {
3728
+ export class BeanPlatformsService {
3326
3729
  /**
3327
- * Get per-holding unrealized + realized P&L
3328
- * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3329
- * @param data The data for the request.
3330
- * @param data.region Region code for tenant context
3331
- * @param data.asOf As-of date (ISO 8601), defaults to today
3332
- * @param data.accountId Scope to a single account
3333
- * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3334
- * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3730
+ * Get all platforms with statistics
3731
+ * @returns unknown List of platforms with binding and account counts
3335
3732
  * @throws ApiError
3336
3733
  */
3337
- public static holdingPnlControllerGetHoldingPnl(
3338
- data: HoldingPnlControllerGetHoldingPnlData
3339
- ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3734
+ public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
3340
3735
  return __request(OpenAPI, {
3341
3736
  method: 'GET',
3342
- url: '/api/v1/{region}/investment/holdings/pnl',
3343
- path: {
3344
- region: data.region
3345
- },
3346
- query: {
3347
- asOf: data.asOf,
3348
- accountId: data.accountId,
3349
- method: data.method
3350
- },
3351
- errors: {
3352
- 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3353
- 401: 'User not authenticated'
3354
- }
3737
+ url: '/api/v1/bean/platforms'
3355
3738
  });
3356
3739
  }
3357
- }
3358
3740
 
3359
- export class BeanPricesService {
3360
3741
  /**
3361
- * Create a new price
3362
- * Creates a new price entry for the authenticated user
3742
+ * Create a new platform
3363
3743
  * @param data The data for the request.
3364
- * @param data.region Region code for tenant context
3365
3744
  * @param data.requestBody
3366
- * @returns PriceResponseDto Price created successfully
3745
+ * @returns unknown Platform created successfully
3367
3746
  * @throws ApiError
3368
3747
  */
3369
- public static priceControllerCreate(
3370
- data: PriceControllerCreateData
3371
- ): CancelablePromise<PriceControllerCreateResponse> {
3748
+ public static platformControllerCreate(
3749
+ data: PlatformControllerCreateData
3750
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3372
3751
  return __request(OpenAPI, {
3373
3752
  method: 'POST',
3374
- url: '/api/v1/{region}/bean/prices',
3375
- path: {
3376
- region: data.region
3377
- },
3753
+ url: '/api/v1/bean/platforms',
3378
3754
  body: data.requestBody,
3379
3755
  mediaType: 'application/json',
3380
3756
  errors: {
3381
- 404: 'Currency or quoteCurrency commodity not found',
3382
- 409: 'Price already exists for this currency pair and date'
3757
+ 409: 'Platform already exists'
3383
3758
  }
3384
3759
  });
3385
3760
  }
3386
3761
 
3387
3762
  /**
3388
- * List user prices
3389
- * Returns all price entries for the authenticated user with optional filtering
3763
+ * Get platform list for current user
3390
3764
  * @param data The data for the request.
3391
- * @param data.region Region code for tenant context
3392
- * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
3393
- * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
3394
- * @param data.dateFrom Filter prices from this date (ISO 8601 format)
3395
- * @param data.dateTo Filter prices to this date (ISO 8601 format)
3396
- * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
3397
- * @param data.page Page number for pagination (default: 1)
3398
- * @param data.limit Number of items per page (default: 20, max: 100)
3399
- * @returns PriceListResponseDto Prices 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
3400
3767
  * @throws ApiError
3401
3768
  */
3402
- public static priceControllerFindAll(
3403
- data: PriceControllerFindAllData
3404
- ): CancelablePromise<PriceControllerFindAllResponse> {
3769
+ public static platformControllerGetPlatformList(
3770
+ data: PlatformControllerGetPlatformListData = {}
3771
+ ): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3405
3772
  return __request(OpenAPI, {
3406
3773
  method: 'GET',
3407
- url: '/api/v1/{region}/bean/prices',
3408
- path: {
3409
- region: data.region
3410
- },
3774
+ url: '/api/v1/bean/platforms/list',
3411
3775
  query: {
3412
- currency: data.currency,
3413
- quoteCurrency: data.quoteCurrency,
3414
- dateFrom: data.dateFrom,
3415
- dateTo: data.dateTo,
3416
- search: data.search,
3417
- page: data.page,
3418
- limit: data.limit
3776
+ region: data.region
3419
3777
  }
3420
3778
  });
3421
3779
  }
3422
3780
 
3423
3781
  /**
3424
- * Get price by ID
3425
- * Returns a single price entry by its ID
3782
+ * Match platforms by name or alias
3426
3783
  * @param data The data for the request.
3427
- * @param data.id Price ID
3428
- * @param data.region Region code for tenant context
3429
- * @returns PriceResponseDto Price 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
3430
3787
  * @throws ApiError
3431
3788
  */
3432
- public static priceControllerFindOne(
3433
- data: PriceControllerFindOneData
3434
- ): CancelablePromise<PriceControllerFindOneResponse> {
3789
+ public static platformControllerMatchPlatforms(
3790
+ data: PlatformControllerMatchPlatformsData
3791
+ ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3435
3792
  return __request(OpenAPI, {
3436
3793
  method: 'GET',
3437
- url: '/api/v1/{region}/bean/prices/{id}',
3438
- path: {
3439
- id: data.id,
3794
+ url: '/api/v1/bean/platforms/match',
3795
+ query: {
3796
+ q: data.q,
3440
3797
  region: data.region
3441
- },
3442
- errors: {
3443
- 404: 'Price not found'
3444
3798
  }
3445
3799
  });
3446
3800
  }
3447
3801
 
3448
3802
  /**
3449
- * Update a price
3450
- * Updates an existing price entry
3803
+ * Update a platform
3451
3804
  * @param data The data for the request.
3452
- * @param data.id Price ID
3453
- * @param data.region Region code for tenant context
3805
+ * @param data.id Platform ID
3454
3806
  * @param data.requestBody
3455
- * @returns PriceResponseDto Price updated successfully
3807
+ * @returns unknown Platform updated successfully
3456
3808
  * @throws ApiError
3457
3809
  */
3458
- public static priceControllerUpdate(
3459
- data: PriceControllerUpdateData
3460
- ): CancelablePromise<PriceControllerUpdateResponse> {
3810
+ public static platformControllerUpdate(
3811
+ data: PlatformControllerUpdateData
3812
+ ): CancelablePromise<PlatformControllerUpdateResponse> {
3461
3813
  return __request(OpenAPI, {
3462
3814
  method: 'PUT',
3463
- url: '/api/v1/{region}/bean/prices/{id}',
3815
+ url: '/api/v1/bean/platforms/{id}',
3464
3816
  path: {
3465
- id: data.id,
3466
- region: data.region
3817
+ id: data.id
3467
3818
  },
3468
3819
  body: data.requestBody,
3469
3820
  mediaType: 'application/json',
3470
3821
  errors: {
3471
- 404: 'Price not found',
3472
- 409: 'Updated price conflicts with existing price'
3822
+ 404: 'Platform not found'
3473
3823
  }
3474
3824
  });
3475
3825
  }
3476
3826
 
3477
3827
  /**
3478
- * Delete a price
3479
- * Deletes a price entry (hard delete)
3828
+ * Delete a platform
3480
3829
  * @param data The data for the request.
3481
- * @param data.id Price ID
3482
- * @param data.region Region code for tenant context
3483
- * @returns void Price deleted successfully
3830
+ * @param data.id Platform ID
3831
+ * @returns void Platform deleted successfully
3484
3832
  * @throws ApiError
3485
3833
  */
3486
- public static priceControllerDelete(
3487
- data: PriceControllerDeleteData
3488
- ): CancelablePromise<PriceControllerDeleteResponse> {
3834
+ public static platformControllerDelete(
3835
+ data: PlatformControllerDeleteData
3836
+ ): CancelablePromise<PlatformControllerDeleteResponse> {
3489
3837
  return __request(OpenAPI, {
3490
3838
  method: 'DELETE',
3491
- url: '/api/v1/{region}/bean/prices/{id}',
3839
+ url: '/api/v1/bean/platforms/{id}',
3492
3840
  path: {
3493
- id: data.id,
3494
- region: data.region
3841
+ id: data.id
3495
3842
  },
3496
3843
  errors: {
3497
- 404: 'Price not found'
3844
+ 404: 'Platform not found'
3498
3845
  }
3499
3846
  });
3500
3847
  }
3848
+ }
3501
3849
 
3850
+ export class DashboardService {
3502
3851
  /**
3503
- * Bulk create prices
3504
- * Creates multiple price entries at once (skips duplicates)
3852
+ * Get net worth overview
3853
+ * Returns total net worth with breakdown of assets and liabilities
3505
3854
  * @param data The data for the request.
3506
3855
  * @param data.region Region code for tenant context
3507
- * @param data.requestBody
3508
- * @returns PriceResponseDto Prices created successfully
3856
+ * @param data.date Date for balance calculation (ISO 8601 format)
3857
+ * @returns NetWorthResponseDto Net worth retrieved successfully
3509
3858
  * @throws ApiError
3510
3859
  */
3511
- public static priceControllerBulkCreate(
3512
- data: PriceControllerBulkCreateData
3513
- ): CancelablePromise<PriceControllerBulkCreateResponse> {
3860
+ public static dashboardControllerGetNetWorth(
3861
+ data: DashboardControllerGetNetWorthData
3862
+ ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3514
3863
  return __request(OpenAPI, {
3515
- method: 'POST',
3516
- url: '/api/v1/{region}/bean/prices/bulk',
3864
+ method: 'GET',
3865
+ url: '/api/v1/{region}/dashboard/net-worth',
3517
3866
  path: {
3518
3867
  region: data.region
3519
3868
  },
3520
- body: data.requestBody,
3521
- mediaType: 'application/json'
3869
+ query: {
3870
+ date: data.date
3871
+ },
3872
+ errors: {
3873
+ 401: 'User not authenticated'
3874
+ }
3522
3875
  });
3523
3876
  }
3524
- }
3525
3877
 
3526
- export class ReportingService {
3527
3878
  /**
3528
- * Get portfolio value trends
3529
- *
3530
- * Returns time series data of portfolio net worth.
3531
- *
3532
- * **Multi-currency Support:**
3533
- * - `series[].byCurrency` - Currency breakdown for each data point
3534
- * - `byCurrency` - Separate time series grouped by currency
3535
- * - `warnings` - Exchange rate warnings if conversion failed
3536
- *
3537
- * **Parameters:**
3538
- * - `period`: Time period (1m, 3m, 6m, 1y)
3539
- * - `granularity`: Data granularity (day, week, month)
3540
- *
3879
+ * Get accounts grouped by platform
3880
+ * Returns accounts with balances grouped by financial platform
3541
3881
  * @param data The data for the request.
3542
3882
  * @param data.region Region code for tenant context
3543
- * @param data.period Time period
3544
- * @param data.granularity Data granularity
3545
- * @returns PortfolioTrendsResponseDto Trends retrieved 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.
3546
3887
  * @throws ApiError
3547
3888
  */
3548
- public static reportingControllerGetPortfolioTrends(
3549
- data: ReportingControllerGetPortfolioTrendsData
3550
- ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
3889
+ public static dashboardControllerGetAccounts(
3890
+ data: DashboardControllerGetAccountsData
3891
+ ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3551
3892
  return __request(OpenAPI, {
3552
3893
  method: 'GET',
3553
- url: '/api/v1/{region}/reporting/portfolio/trends',
3894
+ url: '/api/v1/{region}/dashboard/accounts',
3554
3895
  path: {
3555
3896
  region: data.region
3556
3897
  },
3557
3898
  query: {
3558
- period: data.period,
3559
- granularity: data.granularity
3899
+ groupBy: data.groupBy,
3900
+ date: data.date,
3901
+ accountId: data.accountId
3560
3902
  },
3561
3903
  errors: {
3562
3904
  401: 'User not authenticated'
@@ -3565,116 +3907,95 @@ export class ReportingService {
3565
3907
  }
3566
3908
 
3567
3909
  /**
3568
- * Get cash-flow trends
3569
- *
3570
- * Monthly income / expense / netSavings over a fixed N-month window
3571
- * (current month + N−1 prior). Missing months are zero-filled (flow metric).
3572
- *
3573
- * **Parameters:**
3574
- * - `period`: 1m | 3m | 6m | 1y (default 6m)
3575
- * - `granularity`: accepted for API symmetry; v1 returns month buckets
3576
- *
3910
+ * Get cash flow summary
3911
+ * Returns income, expenses, and savings for a monthly period
3577
3912
  * @param data The data for the request.
3913
+ * @param data.period Period in YYYY-MM format
3578
3914
  * @param data.region Region code for tenant context
3579
- * @param data.period Time period
3580
- * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
3581
- * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
3915
+ * @returns CashFlowResponseDto Cash flow retrieved successfully
3582
3916
  * @throws ApiError
3583
3917
  */
3584
- public static reportingControllerGetCashFlowTrends(
3585
- data: ReportingControllerGetCashFlowTrendsData
3586
- ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
3918
+ public static dashboardControllerGetCashFlow(
3919
+ data: DashboardControllerGetCashFlowData
3920
+ ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3587
3921
  return __request(OpenAPI, {
3588
3922
  method: 'GET',
3589
- url: '/api/v1/{region}/reporting/cash-flow/trends',
3923
+ url: '/api/v1/{region}/dashboard/cash-flow',
3590
3924
  path: {
3591
3925
  region: data.region
3592
3926
  },
3593
3927
  query: {
3594
- period: data.period,
3595
- granularity: data.granularity
3928
+ period: data.period
3596
3929
  },
3597
3930
  errors: {
3931
+ 400: 'Invalid period format',
3598
3932
  401: 'User not authenticated'
3599
3933
  }
3600
3934
  });
3601
3935
  }
3602
3936
 
3603
3937
  /**
3604
- * Generate portfolio snapshot
3605
- *
3606
- * Manually generate a portfolio snapshot for a specific date.
3607
- *
3608
- * **Multi-currency Support:**
3609
- * - Fetches balances grouped by currency
3610
- * - Uses user's baseCurrency setting for conversion
3611
- * - Stores exchange rates and warnings
3612
- *
3613
- * **Use Cases:**
3614
- * - Testing snapshot generation
3615
- * - Force regeneration after data correction
3616
- * - Initial setup for new users
3617
- *
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)
3618
3940
  * @param data The data for the request.
3619
3941
  * @param data.region Region code for tenant context
3620
- * @param data.requestBody Optional date (defaults to today)
3621
- * @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
3622
3946
  * @throws ApiError
3623
3947
  */
3624
- public static reportingControllerGenerateSnapshot(
3625
- data: ReportingControllerGenerateSnapshotData
3626
- ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
3948
+ public static dashboardControllerGetExpenses(
3949
+ data: DashboardControllerGetExpensesData
3950
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3627
3951
  return __request(OpenAPI, {
3628
- method: 'POST',
3629
- url: '/api/v1/{region}/reporting/snapshots/generate',
3952
+ method: 'GET',
3953
+ url: '/api/v1/{region}/dashboard/expenses',
3630
3954
  path: {
3631
3955
  region: data.region
3632
3956
  },
3633
- body: data.requestBody,
3634
- mediaType: 'application/json',
3957
+ query: {
3958
+ groupBy: data.groupBy,
3959
+ period: data.period,
3960
+ flow: data.flow
3961
+ },
3635
3962
  errors: {
3636
- 400: 'Invalid date format',
3963
+ 400: 'Invalid groupBy or period',
3637
3964
  401: 'User not authenticated'
3638
3965
  }
3639
3966
  });
3640
3967
  }
3968
+ }
3641
3969
 
3970
+ export class InvestmentService {
3642
3971
  /**
3643
- * Backfill portfolio snapshots
3644
- *
3645
- * Generate snapshots for a date range (historical data backfill).
3646
- *
3647
- * **Multi-currency Support:**
3648
- * - Each snapshot includes multi-currency data
3649
- * - Uses exchange rates available at generation time
3650
- * - Warnings stored for missing exchange rates
3651
- *
3652
- * **Best Practices:**
3653
- * - Use for initial setup after account configuration
3654
- * - Run during low-traffic periods for large date ranges
3655
- * - Existing snapshots are skipped (not regenerated)
3656
- *
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).
3657
3974
  * @param data The data for the request.
3658
3975
  * @param data.region Region code for tenant context
3659
- * @param data.requestBody
3660
- * @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
3661
3980
  * @throws ApiError
3662
3981
  */
3663
- public static reportingControllerBackfillSnapshots(
3664
- data: ReportingControllerBackfillSnapshotsData
3665
- ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
3982
+ public static holdingPnlControllerGetHoldingPnl(
3983
+ data: HoldingPnlControllerGetHoldingPnlData
3984
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3666
3985
  return __request(OpenAPI, {
3667
- method: 'POST',
3668
- url: '/api/v1/{region}/reporting/snapshots/backfill',
3986
+ method: 'GET',
3987
+ url: '/api/v1/{region}/investment/holdings/pnl',
3669
3988
  path: {
3670
3989
  region: data.region
3671
3990
  },
3672
- body: data.requestBody,
3673
- mediaType: 'application/json',
3991
+ query: {
3992
+ asOf: data.asOf,
3993
+ accountId: data.accountId,
3994
+ method: data.method
3995
+ },
3674
3996
  errors: {
3675
- 400: 'Invalid date format or range',
3676
- 401: 'User not authenticated',
3677
- 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'
3678
3999
  }
3679
4000
  });
3680
4001
  }
@@ -3703,7 +4024,7 @@ export class AuthService {
3703
4024
  * Anonymous login with access token
3704
4025
  * @param data The data for the request.
3705
4026
  * @param data.requestBody
3706
- * @returns unknown Login successful
4027
+ * @returns AnonymousLoginResponseDto Login successful
3707
4028
  * @throws ApiError
3708
4029
  */
3709
4030
  public static authControllerAccessTokenLogin(
@@ -3890,3 +4211,53 @@ export class InfoService {
3890
4211
  });
3891
4212
  }
3892
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
+ }