@firela/api-types 0.0.0-canary.45a6cc23 → 0.0.0-canary.4e161540

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,26 @@ 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,
174
196
  EventControllerCreateData,
175
197
  EventControllerCreateResponse,
176
198
  EventControllerFindAllData,
@@ -183,6 +205,16 @@ import type {
183
205
  EventControllerDeleteResponse,
184
206
  EventControllerGetSliceData,
185
207
  EventControllerGetSliceResponse,
208
+ OnboardingControllerBootstrapData,
209
+ OnboardingControllerBootstrapResponse,
210
+ ReconciliationControllerComputeData,
211
+ ReconciliationControllerComputeResponse,
212
+ ReconciliationControllerAssertData,
213
+ ReconciliationControllerAssertResponse,
214
+ ReconciliationControllerPadData,
215
+ ReconciliationControllerPadResponse,
216
+ ReconciliationControllerHistoryData,
217
+ ReconciliationControllerHistoryResponse,
186
218
  ExportControllerExportBeancountResponse,
187
219
  FileImportControllerImportFileData,
188
220
  FileImportControllerImportFileResponse,
@@ -196,22 +228,20 @@ import type {
196
228
  ImporterConfigControllerUpdateConfigResponse,
197
229
  ImporterConfigControllerResetConfigData,
198
230
  ImporterConfigControllerResetConfigResponse,
199
- PlatformControllerFindAllResponse,
200
- PlatformControllerCreateData,
201
- PlatformControllerCreateResponse,
202
- PlatformControllerGetPlatformListResponse,
203
- PlatformControllerMatchPlatformsData,
204
- PlatformControllerMatchPlatformsResponse,
205
- PlatformControllerUpdateData,
206
- PlatformControllerUpdateResponse,
207
- PlatformControllerDeleteData,
208
- PlatformControllerDeleteResponse,
209
231
  ProviderSyncControllerSyncData,
210
232
  ProviderSyncControllerSyncResponse,
211
233
  ProviderSyncControllerGetSupportedProvidersData,
212
234
  ProviderSyncControllerGetSupportedProvidersResponse,
213
235
  ProviderSyncControllerIsProviderSupportedData,
214
236
  ProviderSyncControllerIsProviderSupportedResponse,
237
+ ExternalAccountLinkControllerCreateData,
238
+ ExternalAccountLinkControllerCreateResponse,
239
+ ExternalAccountLinkControllerFindAllData,
240
+ ExternalAccountLinkControllerFindAllResponse,
241
+ ExternalAccountLinkControllerFindOneData,
242
+ ExternalAccountLinkControllerFindOneResponse,
243
+ ExternalAccountLinkControllerRemoveData,
244
+ ExternalAccountLinkControllerRemoveResponse,
215
245
  TelemetryControllerReportTelemetryData,
216
246
  TelemetryControllerReportTelemetryResponse,
217
247
  TelemetryControllerReportCoverageMissData,
@@ -224,6 +254,17 @@ import type {
224
254
  NlpControllerClearSessionResponse,
225
255
  NlpControllerGetSessionData,
226
256
  NlpControllerGetSessionResponse,
257
+ PlatformControllerFindAllResponse,
258
+ PlatformControllerCreateData,
259
+ PlatformControllerCreateResponse,
260
+ PlatformControllerGetPlatformListData,
261
+ PlatformControllerGetPlatformListResponse,
262
+ PlatformControllerMatchPlatformsData,
263
+ PlatformControllerMatchPlatformsResponse,
264
+ PlatformControllerUpdateData,
265
+ PlatformControllerUpdateResponse,
266
+ PlatformControllerDeleteData,
267
+ PlatformControllerDeleteResponse,
227
268
  DashboardControllerGetNetWorthData,
228
269
  DashboardControllerGetNetWorthResponse,
229
270
  DashboardControllerGetAccountsData,
@@ -234,26 +275,6 @@ import type {
234
275
  DashboardControllerGetExpensesResponse,
235
276
  HoldingPnlControllerGetHoldingPnlData,
236
277
  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
278
  ApiKeysControllerCreateApiKeyResponse,
258
279
  AuthControllerAccessTokenLoginData,
259
280
  AuthControllerAccessTokenLoginResponse,
@@ -268,7 +289,11 @@ import type {
268
289
  HealthControllerResetCircuitBreakerData,
269
290
  HealthControllerResetCircuitBreakerResponse,
270
291
  HealthControllerGetMetricsResponse,
271
- InfoControllerGetInfoResponse
292
+ InfoControllerGetInfoResponse,
293
+ SymbolControllerSearchData,
294
+ SymbolControllerSearchResponse,
295
+ SymbolControllerGetQuoteData,
296
+ SymbolControllerGetQuoteResponse
272
297
  } from './types.gen';
273
298
 
274
299
  export class BeanAccountsService {
@@ -306,7 +331,7 @@ export class BeanAccountsService {
306
331
  * @param data.type Filter by account type
307
332
  * @param data.status Filter by status
308
333
  * @param data.isCustom Filter by custom (user-created) accounts only
309
- * @param data.search Search term for path or i18nKey
334
+ * @param data.search Search term for account path
310
335
  * @param data.limit Maximum number of results
311
336
  * @param data.offset Number of results to skip
312
337
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -387,7 +412,7 @@ export class BeanAccountsService {
387
412
 
388
413
  /**
389
414
  * Delete account
390
- * Deletes an account (only if no transactions)
415
+ * Deletes an account (only if no active transactions; voided/superseded residual postings are cleaned up)
391
416
  * @param data The data for the request.
392
417
  * @param data.id Account UUID
393
418
  * @param data.region Region code for tenant context
@@ -406,7 +431,7 @@ export class BeanAccountsService {
406
431
  },
407
432
  errors: {
408
433
  404: 'Account not found',
409
- 409: 'Account has transactions and cannot be deleted'
434
+ 409: 'Account has active transactions and cannot be deleted'
410
435
  }
411
436
  });
412
437
  }
@@ -468,6 +493,35 @@ export class BeanAccountsService {
468
493
  }
469
494
  });
470
495
  }
496
+
497
+ /**
498
+ * Post an opening-balance transaction
499
+ * 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.
500
+ * @param data The data for the request.
501
+ * @param data.id Account UUID
502
+ * @param data.region Region code for tenant context
503
+ * @param data.requestBody
504
+ * @returns OpeningBalanceResultDto Opening-balance transaction created
505
+ * @throws ApiError
506
+ */
507
+ public static accountControllerAddOpeningBalance(
508
+ data: AccountControllerAddOpeningBalanceData
509
+ ): CancelablePromise<AccountControllerAddOpeningBalanceResponse> {
510
+ return __request(OpenAPI, {
511
+ method: 'POST',
512
+ url: '/api/v1/{region}/bean/accounts/{id}/opening-balance',
513
+ path: {
514
+ id: data.id,
515
+ region: data.region
516
+ },
517
+ body: data.requestBody,
518
+ mediaType: 'application/json',
519
+ errors: {
520
+ 404: 'Account not found',
521
+ 409: 'An opening balance already exists for this account'
522
+ }
523
+ });
524
+ }
471
525
  }
472
526
 
473
527
  export class BeanAccountStandardsService {
@@ -499,7 +553,7 @@ export class BeanAccountStandardsService {
499
553
 
500
554
  /**
501
555
  * Get template metadata for an account path
502
- * Returns extendable status and root type for a template path.
556
+ * Returns root type for a template path.
503
557
  * @param data The data for the request.
504
558
  * @param data.region Region code for tenant context
505
559
  * @param data.path Account path to check
@@ -794,7 +848,7 @@ export class BeanBalancesService {
794
848
  * Query account balance
795
849
  * Calculate account balance at a specific date for a single currency
796
850
  * @param data The data for the request.
797
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
851
+ * @param data.account Account name (e.g., "Assets:Checking")
798
852
  * @param data.region Region code for tenant context
799
853
  * @param data.date Date to calculate balance at (ISO 8601 format)
800
854
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -1515,153 +1569,320 @@ export class BeanCommoditiesService {
1515
1569
  }
1516
1570
  }
1517
1571
 
1518
- export class RecurringRulesService {
1572
+ export class BeanPricesService {
1519
1573
  /**
1520
- * Create a new recurring rule
1521
- * Creates a new recurring transaction rule for the authenticated user
1574
+ * Create a new price
1575
+ * Creates a new price entry for the authenticated user
1522
1576
  * @param data The data for the request.
1523
1577
  * @param data.region Region code for tenant context
1524
1578
  * @param data.requestBody
1525
- * @returns RecurringRuleResponseDto Rule created successfully
1579
+ * @returns PriceResponseDto Price created successfully
1526
1580
  * @throws ApiError
1527
1581
  */
1528
- public static recurringRuleControllerCreate(
1529
- data: RecurringRuleControllerCreateData
1530
- ): CancelablePromise<RecurringRuleControllerCreateResponse> {
1582
+ public static priceControllerCreate(
1583
+ data: PriceControllerCreateData
1584
+ ): CancelablePromise<PriceControllerCreateResponse> {
1531
1585
  return __request(OpenAPI, {
1532
1586
  method: 'POST',
1533
- url: '/api/v1/{region}/bean/recurring-rules',
1587
+ url: '/api/v1/{region}/bean/prices',
1534
1588
  path: {
1535
1589
  region: data.region
1536
1590
  },
1537
1591
  body: data.requestBody,
1538
1592
  mediaType: 'application/json',
1539
1593
  errors: {
1540
- 400: 'Invalid input data (e.g., autoCreate without accounts)',
1541
- 409: 'Rule with same name already exists'
1594
+ 404: 'Currency or quoteCurrency commodity not found',
1595
+ 409: 'Price already exists for this currency pair and date'
1542
1596
  }
1543
1597
  });
1544
1598
  }
1545
1599
 
1546
1600
  /**
1547
- * List recurring rules
1548
- * Returns all recurring rules for the authenticated user with optional filtering
1601
+ * List user prices
1602
+ * Returns all price entries for the authenticated user with optional filtering
1549
1603
  * @param data The data for the request.
1550
1604
  * @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
1605
+ * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
1606
+ * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
1607
+ * @param data.dateFrom Filter prices from this date (ISO 8601 format)
1608
+ * @param data.dateTo Filter prices to this date (ISO 8601 format)
1609
+ * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
1610
+ * @param data.page Page number for pagination (default: 1)
1611
+ * @param data.limit Number of items per page (default: 20, max: 100)
1612
+ * @returns PriceListResponseDto Prices retrieved successfully
1555
1613
  * @throws ApiError
1556
1614
  */
1557
- public static recurringRuleControllerFindAll(
1558
- data: RecurringRuleControllerFindAllData
1559
- ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
1615
+ public static priceControllerFindAll(
1616
+ data: PriceControllerFindAllData
1617
+ ): CancelablePromise<PriceControllerFindAllResponse> {
1560
1618
  return __request(OpenAPI, {
1561
1619
  method: 'GET',
1562
- url: '/api/v1/{region}/bean/recurring-rules',
1620
+ url: '/api/v1/{region}/bean/prices',
1563
1621
  path: {
1564
1622
  region: data.region
1565
1623
  },
1566
1624
  query: {
1567
- isActive: data.isActive,
1568
- frequency: data.frequency,
1569
- hasAutoCreate: data.hasAutoCreate
1625
+ currency: data.currency,
1626
+ quoteCurrency: data.quoteCurrency,
1627
+ dateFrom: data.dateFrom,
1628
+ dateTo: data.dateTo,
1629
+ search: data.search,
1630
+ page: data.page,
1631
+ limit: data.limit
1570
1632
  }
1571
1633
  });
1572
1634
  }
1573
1635
 
1574
1636
  /**
1575
- * Create recurring rule from transaction
1576
- * Auto-creates a recurring rule using transaction data. User only confirms frequency.
1637
+ * Get price by ID
1638
+ * Returns a single price entry by its ID
1577
1639
  * @param data The data for the request.
1578
- * @param data.transactionId Source transaction ID
1640
+ * @param data.id Price ID
1579
1641
  * @param data.region Region code for tenant context
1580
- * @param data.requestBody
1581
- * @returns RecurringRuleResponseDto Rule created successfully
1642
+ * @returns PriceResponseDto Price retrieved successfully
1582
1643
  * @throws ApiError
1583
1644
  */
1584
- public static recurringRuleControllerCreateFromTransaction(
1585
- data: RecurringRuleControllerCreateFromTransactionData
1586
- ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
1645
+ public static priceControllerFindOne(
1646
+ data: PriceControllerFindOneData
1647
+ ): CancelablePromise<PriceControllerFindOneResponse> {
1587
1648
  return __request(OpenAPI, {
1588
- method: 'POST',
1589
- url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
1649
+ method: 'GET',
1650
+ url: '/api/v1/{region}/bean/prices/{id}',
1590
1651
  path: {
1591
- transactionId: data.transactionId,
1652
+ id: data.id,
1592
1653
  region: data.region
1593
1654
  },
1594
- body: data.requestBody,
1595
- mediaType: 'application/json',
1596
1655
  errors: {
1597
- 404: 'Transaction not found',
1598
- 409: 'Rule with same name already exists or transaction already linked'
1656
+ 404: 'Price not found'
1599
1657
  }
1600
1658
  });
1601
1659
  }
1602
1660
 
1603
1661
  /**
1604
- * Get recurring rule by ID
1605
- * Returns a specific recurring rule with its details
1662
+ * Update a price
1663
+ * Updates an existing price entry
1606
1664
  * @param data The data for the request.
1607
- * @param data.id Rule ID
1665
+ * @param data.id Price ID
1608
1666
  * @param data.region Region code for tenant context
1609
- * @returns RecurringRuleResponseDto Rule retrieved successfully
1667
+ * @param data.requestBody
1668
+ * @returns PriceResponseDto Price updated successfully
1610
1669
  * @throws ApiError
1611
1670
  */
1612
- public static recurringRuleControllerFindOne(
1613
- data: RecurringRuleControllerFindOneData
1614
- ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
1671
+ public static priceControllerUpdate(
1672
+ data: PriceControllerUpdateData
1673
+ ): CancelablePromise<PriceControllerUpdateResponse> {
1615
1674
  return __request(OpenAPI, {
1616
- method: 'GET',
1617
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
1675
+ method: 'PUT',
1676
+ url: '/api/v1/{region}/bean/prices/{id}',
1618
1677
  path: {
1619
1678
  id: data.id,
1620
1679
  region: data.region
1621
1680
  },
1681
+ body: data.requestBody,
1682
+ mediaType: 'application/json',
1622
1683
  errors: {
1623
- 404: 'Rule not found'
1684
+ 404: 'Price not found',
1685
+ 409: 'Updated price conflicts with existing price'
1624
1686
  }
1625
1687
  });
1626
1688
  }
1627
1689
 
1628
1690
  /**
1629
- * Update recurring rule
1630
- * Updates an existing recurring rule
1691
+ * Delete a price
1692
+ * Deletes a price entry (hard delete)
1631
1693
  * @param data The data for the request.
1632
- * @param data.id Rule ID
1694
+ * @param data.id Price ID
1633
1695
  * @param data.region Region code for tenant context
1634
- * @param data.requestBody
1635
- * @returns RecurringRuleResponseDto Rule updated successfully
1696
+ * @returns void Price deleted successfully
1636
1697
  * @throws ApiError
1637
1698
  */
1638
- public static recurringRuleControllerUpdate(
1639
- data: RecurringRuleControllerUpdateData
1640
- ): CancelablePromise<RecurringRuleControllerUpdateResponse> {
1699
+ public static priceControllerDelete(
1700
+ data: PriceControllerDeleteData
1701
+ ): CancelablePromise<PriceControllerDeleteResponse> {
1641
1702
  return __request(OpenAPI, {
1642
- method: 'PATCH',
1643
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
1703
+ method: 'DELETE',
1704
+ url: '/api/v1/{region}/bean/prices/{id}',
1644
1705
  path: {
1645
1706
  id: data.id,
1646
1707
  region: data.region
1647
1708
  },
1648
- body: data.requestBody,
1649
- mediaType: 'application/json',
1650
1709
  errors: {
1651
- 400: 'Invalid input data',
1652
- 404: 'Rule not found'
1710
+ 404: 'Price not found'
1653
1711
  }
1654
1712
  });
1655
1713
  }
1656
1714
 
1657
1715
  /**
1658
- * Delete recurring rule
1659
- * Soft deletes a recurring rule (sets isActive to false)
1716
+ * Bulk create prices
1717
+ * Creates multiple price entries at once (skips duplicates)
1660
1718
  * @param data The data for the request.
1661
- * @param data.id Rule ID
1662
1719
  * @param data.region Region code for tenant context
1663
- * @returns void Rule deleted successfully
1664
- * @throws ApiError
1720
+ * @param data.requestBody
1721
+ * @returns PriceResponseDto Prices created successfully
1722
+ * @throws ApiError
1723
+ */
1724
+ public static priceControllerBulkCreate(
1725
+ data: PriceControllerBulkCreateData
1726
+ ): CancelablePromise<PriceControllerBulkCreateResponse> {
1727
+ return __request(OpenAPI, {
1728
+ method: 'POST',
1729
+ url: '/api/v1/{region}/bean/prices/bulk',
1730
+ path: {
1731
+ region: data.region
1732
+ },
1733
+ body: data.requestBody,
1734
+ mediaType: 'application/json'
1735
+ });
1736
+ }
1737
+ }
1738
+
1739
+ export class RecurringRulesService {
1740
+ /**
1741
+ * Create a new recurring rule
1742
+ * Creates a new recurring transaction rule for the authenticated user
1743
+ * @param data The data for the request.
1744
+ * @param data.region Region code for tenant context
1745
+ * @param data.requestBody
1746
+ * @returns RecurringRuleResponseDto Rule created successfully
1747
+ * @throws ApiError
1748
+ */
1749
+ public static recurringRuleControllerCreate(
1750
+ data: RecurringRuleControllerCreateData
1751
+ ): CancelablePromise<RecurringRuleControllerCreateResponse> {
1752
+ return __request(OpenAPI, {
1753
+ method: 'POST',
1754
+ url: '/api/v1/{region}/bean/recurring-rules',
1755
+ path: {
1756
+ region: data.region
1757
+ },
1758
+ body: data.requestBody,
1759
+ mediaType: 'application/json',
1760
+ errors: {
1761
+ 400: 'Invalid input data (e.g., autoCreate without accounts)',
1762
+ 409: 'Rule with same name already exists'
1763
+ }
1764
+ });
1765
+ }
1766
+
1767
+ /**
1768
+ * List recurring rules
1769
+ * Returns all recurring rules for the authenticated user with optional filtering
1770
+ * @param data The data for the request.
1771
+ * @param data.region Region code for tenant context
1772
+ * @param data.isActive Filter by active status
1773
+ * @param data.frequency Filter by frequency (WEEKLY, MONTHLY, etc.)
1774
+ * @param data.hasAutoCreate Filter by autoCreate enabled
1775
+ * @returns RecurringRuleResponseDto Rules retrieved successfully
1776
+ * @throws ApiError
1777
+ */
1778
+ public static recurringRuleControllerFindAll(
1779
+ data: RecurringRuleControllerFindAllData
1780
+ ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
1781
+ return __request(OpenAPI, {
1782
+ method: 'GET',
1783
+ url: '/api/v1/{region}/bean/recurring-rules',
1784
+ path: {
1785
+ region: data.region
1786
+ },
1787
+ query: {
1788
+ isActive: data.isActive,
1789
+ frequency: data.frequency,
1790
+ hasAutoCreate: data.hasAutoCreate
1791
+ }
1792
+ });
1793
+ }
1794
+
1795
+ /**
1796
+ * Create recurring rule from transaction
1797
+ * Auto-creates a recurring rule using transaction data. User only confirms frequency.
1798
+ * @param data The data for the request.
1799
+ * @param data.transactionId Source transaction ID
1800
+ * @param data.region Region code for tenant context
1801
+ * @param data.requestBody
1802
+ * @returns RecurringRuleResponseDto Rule created successfully
1803
+ * @throws ApiError
1804
+ */
1805
+ public static recurringRuleControllerCreateFromTransaction(
1806
+ data: RecurringRuleControllerCreateFromTransactionData
1807
+ ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
1808
+ return __request(OpenAPI, {
1809
+ method: 'POST',
1810
+ url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
1811
+ path: {
1812
+ transactionId: data.transactionId,
1813
+ region: data.region
1814
+ },
1815
+ body: data.requestBody,
1816
+ mediaType: 'application/json',
1817
+ errors: {
1818
+ 404: 'Transaction not found',
1819
+ 409: 'Rule with same name already exists or transaction already linked'
1820
+ }
1821
+ });
1822
+ }
1823
+
1824
+ /**
1825
+ * Get recurring rule by ID
1826
+ * Returns a specific recurring rule with its details
1827
+ * @param data The data for the request.
1828
+ * @param data.id Rule ID
1829
+ * @param data.region Region code for tenant context
1830
+ * @returns RecurringRuleResponseDto Rule retrieved successfully
1831
+ * @throws ApiError
1832
+ */
1833
+ public static recurringRuleControllerFindOne(
1834
+ data: RecurringRuleControllerFindOneData
1835
+ ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
1836
+ return __request(OpenAPI, {
1837
+ method: 'GET',
1838
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
1839
+ path: {
1840
+ id: data.id,
1841
+ region: data.region
1842
+ },
1843
+ errors: {
1844
+ 404: 'Rule not found'
1845
+ }
1846
+ });
1847
+ }
1848
+
1849
+ /**
1850
+ * Update recurring rule
1851
+ * Updates an existing recurring rule
1852
+ * @param data The data for the request.
1853
+ * @param data.id Rule ID
1854
+ * @param data.region Region code for tenant context
1855
+ * @param data.requestBody
1856
+ * @returns RecurringRuleResponseDto Rule updated successfully
1857
+ * @throws ApiError
1858
+ */
1859
+ public static recurringRuleControllerUpdate(
1860
+ data: RecurringRuleControllerUpdateData
1861
+ ): CancelablePromise<RecurringRuleControllerUpdateResponse> {
1862
+ return __request(OpenAPI, {
1863
+ method: 'PATCH',
1864
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
1865
+ path: {
1866
+ id: data.id,
1867
+ region: data.region
1868
+ },
1869
+ body: data.requestBody,
1870
+ mediaType: 'application/json',
1871
+ errors: {
1872
+ 400: 'Invalid input data',
1873
+ 404: 'Rule not found'
1874
+ }
1875
+ });
1876
+ }
1877
+
1878
+ /**
1879
+ * Delete recurring rule
1880
+ * Soft deletes a recurring rule (sets isActive to false)
1881
+ * @param data The data for the request.
1882
+ * @param data.id Rule ID
1883
+ * @param data.region Region code for tenant context
1884
+ * @returns void Rule deleted successfully
1885
+ * @throws ApiError
1665
1886
  */
1666
1887
  public static recurringRuleControllerDelete(
1667
1888
  data: RecurringRuleControllerDeleteData
@@ -1945,279 +2166,158 @@ export class RecurringForecastService {
1945
2166
  }
1946
2167
  }
1947
2168
 
1948
- export class BeanTransactionRulesService {
2169
+ export class ReportingService {
1949
2170
  /**
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.
2171
+ * Get portfolio value trends
2172
+ *
2173
+ * Returns time series data of portfolio net worth.
2174
+ *
2175
+ * **Multi-currency Support:**
2176
+ * - `series[].byCurrency` - Currency breakdown for each data point
2177
+ * - `byCurrency` - Separate time series grouped by currency
2178
+ * - `warnings` - Exchange rate warnings if conversion failed
2179
+ *
2180
+ * **Parameters:**
2181
+ * - `period`: Time period (1m, 3m, 6m, 1y)
2182
+ * - `granularity`: Data granularity (day, week, month)
2183
+ *
1952
2184
  * @param data The data for the request.
1953
2185
  * @param data.region Region code for tenant context
1954
- * @param data.requestBody
1955
- * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2186
+ * @param data.period Time period
2187
+ * @param data.granularity Data granularity
2188
+ * @returns PortfolioTrendsResponseDto Trends retrieved successfully
1956
2189
  * @throws ApiError
1957
2190
  */
1958
- public static transactionRuleControllerCreate(
1959
- data: TransactionRuleControllerCreateData
1960
- ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2191
+ public static reportingControllerGetPortfolioTrends(
2192
+ data: ReportingControllerGetPortfolioTrendsData
2193
+ ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
1961
2194
  return __request(OpenAPI, {
1962
- method: 'POST',
1963
- url: '/api/v1/{region}/bean/transaction-rules',
2195
+ method: 'GET',
2196
+ url: '/api/v1/{region}/reporting/portfolio/trends',
1964
2197
  path: {
1965
2198
  region: data.region
1966
2199
  },
1967
- body: data.requestBody,
1968
- mediaType: 'application/json',
2200
+ query: {
2201
+ period: data.period,
2202
+ granularity: data.granularity
2203
+ },
1969
2204
  errors: {
1970
- 400: 'Validation failed',
1971
- 401: 'Unauthorized',
1972
- 409: 'Resource conflict - another process is updating this rule'
2205
+ 401: 'User not authenticated'
1973
2206
  }
1974
2207
  });
1975
2208
  }
1976
2209
 
1977
2210
  /**
1978
- * Get all transaction rules for user
2211
+ * Get cash-flow trends
2212
+ *
2213
+ * Monthly income / expense / netSavings over a fixed N-month window
2214
+ * (current month + N−1 prior). Missing months are zero-filled (flow metric).
2215
+ *
2216
+ * **Parameters:**
2217
+ * - `period`: 1m | 3m | 6m | 1y (default 6m)
2218
+ * - `granularity`: accepted for API symmetry; v1 returns month buckets
2219
+ *
1979
2220
  * @param data The data for the request.
1980
2221
  * @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
2222
+ * @param data.period Time period
2223
+ * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
2224
+ * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
1987
2225
  * @throws ApiError
1988
2226
  */
1989
- public static transactionRuleControllerList(
1990
- data: TransactionRuleControllerListData
1991
- ): CancelablePromise<TransactionRuleControllerListResponse> {
2227
+ public static reportingControllerGetCashFlowTrends(
2228
+ data: ReportingControllerGetCashFlowTrendsData
2229
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
1992
2230
  return __request(OpenAPI, {
1993
2231
  method: 'GET',
1994
- url: '/api/v1/{region}/bean/transaction-rules',
2232
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
1995
2233
  path: {
1996
2234
  region: data.region
1997
2235
  },
1998
2236
  query: {
1999
- limit: data.limit,
2000
- offset: data.offset,
2001
- enabled: data.enabled,
2002
- learningSource: data.learningSource,
2003
- autoApplyEnabled: data.autoApplyEnabled
2237
+ period: data.period,
2238
+ granularity: data.granularity
2004
2239
  },
2005
2240
  errors: {
2006
- 401: 'Unauthorized'
2241
+ 401: 'User not authenticated'
2007
2242
  }
2008
2243
  });
2009
2244
  }
2010
2245
 
2011
2246
  /**
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
2247
+ * Generate portfolio snapshot
2248
+ *
2249
+ * Manually generate a portfolio snapshot for a specific date.
2250
+ *
2251
+ * **Multi-currency Support:**
2252
+ * - Fetches balances grouped by currency
2253
+ * - Uses user's baseCurrency setting for conversion
2254
+ * - Stores exchange rates and warnings
2255
+ *
2256
+ * **Use Cases:**
2257
+ * - Testing snapshot generation
2258
+ * - Force regeneration after data correction
2259
+ * - Initial setup for new users
2260
+ *
2039
2261
  * @param data The data for the request.
2040
2262
  * @param data.region Region code for tenant context
2041
- * @param data.requestBody
2042
- * @returns BulkCreateRulesResponseDto Bulk create completed
2263
+ * @param data.requestBody Optional date (defaults to today)
2264
+ * @returns GenerateSnapshotResponse Snapshot generated successfully
2043
2265
  * @throws ApiError
2044
2266
  */
2045
- public static transactionRuleControllerBulkCreate(
2046
- data: TransactionRuleControllerBulkCreateData
2047
- ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
2267
+ public static reportingControllerGenerateSnapshot(
2268
+ data: ReportingControllerGenerateSnapshotData
2269
+ ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
2048
2270
  return __request(OpenAPI, {
2049
2271
  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}',
2272
+ url: '/api/v1/{region}/reporting/snapshots/generate',
2153
2273
  path: {
2154
- ruleId: data.ruleId,
2155
2274
  region: data.region
2156
2275
  },
2157
2276
  body: data.requestBody,
2158
2277
  mediaType: 'application/json',
2159
2278
  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'
2279
+ 400: 'Invalid date format',
2280
+ 401: 'User not authenticated'
2192
2281
  }
2193
2282
  });
2194
2283
  }
2195
2284
 
2196
2285
  /**
2197
- * Test rule matching
2286
+ * Backfill portfolio snapshots
2287
+ *
2288
+ * Generate snapshots for a date range (historical data backfill).
2289
+ *
2290
+ * **Multi-currency Support:**
2291
+ * - Each snapshot includes multi-currency data
2292
+ * - Uses exchange rates available at generation time
2293
+ * - Warnings stored for missing exchange rates
2294
+ *
2295
+ * **Best Practices:**
2296
+ * - Use for initial setup after account configuration
2297
+ * - Run during low-traffic periods for large date ranges
2298
+ * - Existing snapshots are skipped (not regenerated)
2299
+ *
2198
2300
  * @param data The data for the request.
2199
- * @param data.ruleId Rule ID to test
2200
2301
  * @param data.region Region code for tenant context
2201
2302
  * @param data.requestBody
2202
- * @returns TestRuleResponseDto Test result
2303
+ * @returns BackfillSnapshotsResponse Backfill completed successfully
2203
2304
  * @throws ApiError
2204
2305
  */
2205
- public static transactionRuleControllerTest(
2206
- data: TransactionRuleControllerTestData
2207
- ): CancelablePromise<TransactionRuleControllerTestResponse> {
2306
+ public static reportingControllerBackfillSnapshots(
2307
+ data: ReportingControllerBackfillSnapshotsData
2308
+ ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
2208
2309
  return __request(OpenAPI, {
2209
2310
  method: 'POST',
2210
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2311
+ url: '/api/v1/{region}/reporting/snapshots/backfill',
2211
2312
  path: {
2212
- ruleId: data.ruleId,
2213
2313
  region: data.region
2214
2314
  },
2215
2315
  body: data.requestBody,
2216
2316
  mediaType: 'application/json',
2217
2317
  errors: {
2218
- 401: 'Unauthorized',
2219
- 403: 'Forbidden - not owner of rule',
2220
- 404: 'Rule not found'
2318
+ 400: 'Invalid date format or range',
2319
+ 401: 'User not authenticated',
2320
+ 409: 'Backfill already in progress for this user'
2221
2321
  }
2222
2322
  });
2223
2323
  }
@@ -2269,7 +2369,7 @@ export class UsersService {
2269
2369
  * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
2270
2370
  * @param data The data for the request.
2271
2371
  * @param data.requestBody
2272
- * @returns unknown User created successfully
2372
+ * @returns SignupResponseDto User created successfully
2273
2373
  * @throws ApiError
2274
2374
  */
2275
2375
  public static userControllerSignupUser(
@@ -2478,52 +2578,330 @@ export class PropertiesService {
2478
2578
  }
2479
2579
  }
2480
2580
 
2481
- export class LifeEventsService {
2581
+ export class BeanTransactionRulesService {
2482
2582
  /**
2483
- * Create a new life event
2484
- * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
2583
+ * Create a new transaction rule (or upsert if upsertByPayee=true)
2584
+ * Creates a new rule. If upsertByPayee=true, updates existing rule matching payeeKeywords[0] instead of creating duplicate.
2485
2585
  * @param data The data for the request.
2486
- * @param data.region Region code for tenant context (decorative for life events)
2586
+ * @param data.region Region code for tenant context
2487
2587
  * @param data.requestBody
2488
- * @returns EventResponseDto Life event created successfully
2588
+ * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2489
2589
  * @throws ApiError
2490
2590
  */
2491
- public static eventControllerCreate(
2492
- data: EventControllerCreateData
2493
- ): CancelablePromise<EventControllerCreateResponse> {
2591
+ public static transactionRuleControllerCreate(
2592
+ data: TransactionRuleControllerCreateData
2593
+ ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2494
2594
  return __request(OpenAPI, {
2495
2595
  method: 'POST',
2496
- url: '/api/v1/{region}/bean/events',
2596
+ url: '/api/v1/{region}/bean/transaction-rules',
2497
2597
  path: {
2498
2598
  region: data.region
2499
2599
  },
2500
2600
  body: data.requestBody,
2501
2601
  mediaType: 'application/json',
2502
2602
  errors: {
2503
- 409: 'Life event already exists for this (userId, type, date) combination'
2603
+ 400: 'Validation failed',
2604
+ 401: 'Unauthorized',
2605
+ 409: 'Resource conflict - another process is updating this rule'
2504
2606
  }
2505
2607
  });
2506
2608
  }
2507
2609
 
2508
2610
  /**
2509
- * List user life events
2510
- * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2611
+ * Get all transaction rules for user
2511
2612
  * @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
2613
+ * @param data.region Region code for tenant context
2614
+ * @param data.limit Max results per page (default: 20, max: 100)
2615
+ * @param data.offset Pagination offset (default: 0)
2616
+ * @param data.enabled Filter by enabled status
2617
+ * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
2618
+ * @param data.autoApplyEnabled Filter by auto-apply status
2619
+ * @returns TransactionRuleListResponseDto List of rules
2520
2620
  * @throws ApiError
2521
2621
  */
2522
- public static eventControllerFindAll(
2523
- data: EventControllerFindAllData
2524
- ): CancelablePromise<EventControllerFindAllResponse> {
2525
- return __request(OpenAPI, {
2526
- method: 'GET',
2622
+ public static transactionRuleControllerList(
2623
+ data: TransactionRuleControllerListData
2624
+ ): CancelablePromise<TransactionRuleControllerListResponse> {
2625
+ return __request(OpenAPI, {
2626
+ method: 'GET',
2627
+ url: '/api/v1/{region}/bean/transaction-rules',
2628
+ path: {
2629
+ region: data.region
2630
+ },
2631
+ query: {
2632
+ limit: data.limit,
2633
+ offset: data.offset,
2634
+ enabled: data.enabled,
2635
+ learningSource: data.learningSource,
2636
+ autoApplyEnabled: data.autoApplyEnabled
2637
+ },
2638
+ errors: {
2639
+ 401: 'Unauthorized'
2640
+ }
2641
+ });
2642
+ }
2643
+
2644
+ /**
2645
+ * Validate transaction rule configuration
2646
+ * @param data The data for the request.
2647
+ * @param data.region Region code for tenant context
2648
+ * @param data.requestBody
2649
+ * @returns ValidateRuleResponseDto Validation result
2650
+ * @throws ApiError
2651
+ */
2652
+ public static transactionRuleControllerValidate(
2653
+ data: TransactionRuleControllerValidateData
2654
+ ): CancelablePromise<TransactionRuleControllerValidateResponse> {
2655
+ return __request(OpenAPI, {
2656
+ method: 'POST',
2657
+ url: '/api/v1/{region}/bean/transaction-rules/validate',
2658
+ path: {
2659
+ region: data.region
2660
+ },
2661
+ body: data.requestBody,
2662
+ mediaType: 'application/json',
2663
+ errors: {
2664
+ 400: 'Validation failed',
2665
+ 401: 'Unauthorized'
2666
+ }
2667
+ });
2668
+ }
2669
+
2670
+ /**
2671
+ * Bulk create transaction rules
2672
+ * @param data The data for the request.
2673
+ * @param data.region Region code for tenant context
2674
+ * @param data.requestBody
2675
+ * @returns BulkCreateRulesResponseDto Bulk create completed
2676
+ * @throws ApiError
2677
+ */
2678
+ public static transactionRuleControllerBulkCreate(
2679
+ data: TransactionRuleControllerBulkCreateData
2680
+ ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
2681
+ return __request(OpenAPI, {
2682
+ method: 'POST',
2683
+ url: '/api/v1/{region}/bean/transaction-rules/bulk',
2684
+ path: {
2685
+ region: data.region
2686
+ },
2687
+ body: data.requestBody,
2688
+ mediaType: 'application/json',
2689
+ errors: {
2690
+ 400: 'Invalid bulk create data',
2691
+ 401: 'Unauthorized'
2692
+ }
2693
+ });
2694
+ }
2695
+
2696
+ /**
2697
+ * Export transaction rules
2698
+ * @param data The data for the request.
2699
+ * @param data.format Export format (currently only JSON supported)
2700
+ * @param data.region Region code for tenant context
2701
+ * @returns ExportRulesResponseDto Exported rules
2702
+ * @throws ApiError
2703
+ */
2704
+ public static transactionRuleControllerExport(
2705
+ data: TransactionRuleControllerExportData
2706
+ ): CancelablePromise<TransactionRuleControllerExportResponse> {
2707
+ return __request(OpenAPI, {
2708
+ method: 'GET',
2709
+ url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2710
+ path: {
2711
+ format: data.format,
2712
+ region: data.region
2713
+ },
2714
+ errors: {
2715
+ 400: 'Unsupported format',
2716
+ 401: 'Unauthorized'
2717
+ }
2718
+ });
2719
+ }
2720
+
2721
+ /**
2722
+ * Get transaction rule statistics
2723
+ * @param data The data for the request.
2724
+ * @param data.period Statistics time period
2725
+ * @param data.region Region code for tenant context
2726
+ * @returns RuleStatisticsResponseDto Rule statistics
2727
+ * @throws ApiError
2728
+ */
2729
+ public static transactionRuleControllerGetStatistics(
2730
+ data: TransactionRuleControllerGetStatisticsData
2731
+ ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
2732
+ return __request(OpenAPI, {
2733
+ method: 'GET',
2734
+ url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
2735
+ path: {
2736
+ period: data.period,
2737
+ region: data.region
2738
+ },
2739
+ errors: {
2740
+ 401: 'Unauthorized'
2741
+ }
2742
+ });
2743
+ }
2744
+
2745
+ /**
2746
+ * Get transaction rule detail
2747
+ * @param data The data for the request.
2748
+ * @param data.ruleId Rule ID
2749
+ * @param data.region Region code for tenant context
2750
+ * @returns TransactionRuleResponseDto Rule details
2751
+ * @throws ApiError
2752
+ */
2753
+ public static transactionRuleControllerGetDetail(
2754
+ data: TransactionRuleControllerGetDetailData
2755
+ ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
2756
+ return __request(OpenAPI, {
2757
+ method: 'GET',
2758
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2759
+ path: {
2760
+ ruleId: data.ruleId,
2761
+ region: data.region
2762
+ },
2763
+ errors: {
2764
+ 401: 'Unauthorized',
2765
+ 403: 'Forbidden - not owner of rule',
2766
+ 404: 'Rule not found'
2767
+ }
2768
+ });
2769
+ }
2770
+
2771
+ /**
2772
+ * Update a transaction rule
2773
+ * @param data The data for the request.
2774
+ * @param data.ruleId Rule ID to update
2775
+ * @param data.region Region code for tenant context
2776
+ * @param data.requestBody
2777
+ * @returns TransactionRuleResponseDto Rule updated successfully
2778
+ * @throws ApiError
2779
+ */
2780
+ public static transactionRuleControllerUpdate(
2781
+ data: TransactionRuleControllerUpdateData
2782
+ ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2783
+ return __request(OpenAPI, {
2784
+ method: 'PUT',
2785
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2786
+ path: {
2787
+ ruleId: data.ruleId,
2788
+ region: data.region
2789
+ },
2790
+ body: data.requestBody,
2791
+ mediaType: 'application/json',
2792
+ errors: {
2793
+ 400: 'Validation failed',
2794
+ 401: 'Unauthorized',
2795
+ 403: 'Forbidden - not owner of rule',
2796
+ 404: 'Rule not found',
2797
+ 409: 'Resource conflict - rule is being modified by another process'
2798
+ }
2799
+ });
2800
+ }
2801
+
2802
+ /**
2803
+ * Delete a transaction rule
2804
+ * @param data The data for the request.
2805
+ * @param data.ruleId Rule ID to delete
2806
+ * @param data.region Region code for tenant context
2807
+ * @returns void Rule deleted successfully
2808
+ * @throws ApiError
2809
+ */
2810
+ public static transactionRuleControllerDelete(
2811
+ data: TransactionRuleControllerDeleteData
2812
+ ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2813
+ return __request(OpenAPI, {
2814
+ method: 'DELETE',
2815
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2816
+ path: {
2817
+ ruleId: data.ruleId,
2818
+ region: data.region
2819
+ },
2820
+ errors: {
2821
+ 401: 'Unauthorized',
2822
+ 403: 'Forbidden - not owner of rule',
2823
+ 404: 'Rule not found',
2824
+ 409: 'Resource conflict - rule is being modified by another process'
2825
+ }
2826
+ });
2827
+ }
2828
+
2829
+ /**
2830
+ * Test rule matching
2831
+ * @param data The data for the request.
2832
+ * @param data.ruleId Rule ID to test
2833
+ * @param data.region Region code for tenant context
2834
+ * @param data.requestBody
2835
+ * @returns TestRuleResponseDto Test result
2836
+ * @throws ApiError
2837
+ */
2838
+ public static transactionRuleControllerTest(
2839
+ data: TransactionRuleControllerTestData
2840
+ ): CancelablePromise<TransactionRuleControllerTestResponse> {
2841
+ return __request(OpenAPI, {
2842
+ method: 'POST',
2843
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2844
+ path: {
2845
+ ruleId: data.ruleId,
2846
+ region: data.region
2847
+ },
2848
+ body: data.requestBody,
2849
+ mediaType: 'application/json',
2850
+ errors: {
2851
+ 401: 'Unauthorized',
2852
+ 403: 'Forbidden - not owner of rule',
2853
+ 404: 'Rule not found'
2854
+ }
2855
+ });
2856
+ }
2857
+ }
2858
+
2859
+ export class LifeEventsService {
2860
+ /**
2861
+ * Create a new life event
2862
+ * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
2863
+ * @param data The data for the request.
2864
+ * @param data.region Region code for tenant context (decorative for life events)
2865
+ * @param data.requestBody
2866
+ * @returns EventResponseDto Life event created successfully
2867
+ * @throws ApiError
2868
+ */
2869
+ public static eventControllerCreate(
2870
+ data: EventControllerCreateData
2871
+ ): CancelablePromise<EventControllerCreateResponse> {
2872
+ return __request(OpenAPI, {
2873
+ method: 'POST',
2874
+ url: '/api/v1/{region}/bean/events',
2875
+ path: {
2876
+ region: data.region
2877
+ },
2878
+ body: data.requestBody,
2879
+ mediaType: 'application/json',
2880
+ errors: {
2881
+ 409: 'Life event already exists for this (userId, type, date) combination'
2882
+ }
2883
+ });
2884
+ }
2885
+
2886
+ /**
2887
+ * List user life events
2888
+ * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2889
+ * @param data The data for the request.
2890
+ * @param data.region Region code for tenant context (decorative for life events)
2891
+ * @param data.type Filter by life event type (exact match)
2892
+ * @param data.q Search term for description (case-insensitive partial match)
2893
+ * @param data.from Filter life events from this date (ISO 8601 format)
2894
+ * @param data.to Filter life events to this date (ISO 8601 format)
2895
+ * @param data.page Page number for pagination (default: 1)
2896
+ * @param data.limit Number of items per page (default: 20, max: 100)
2897
+ * @returns EventListResponseDto Life events retrieved successfully
2898
+ * @throws ApiError
2899
+ */
2900
+ public static eventControllerFindAll(
2901
+ data: EventControllerFindAllData
2902
+ ): CancelablePromise<EventControllerFindAllResponse> {
2903
+ return __request(OpenAPI, {
2904
+ method: 'GET',
2527
2905
  url: '/api/v1/{region}/bean/events',
2528
2906
  path: {
2529
2907
  region: data.region
@@ -2653,6 +3031,139 @@ export class LifeEventsService {
2653
3031
  }
2654
3032
  }
2655
3033
 
3034
+ export class OnboardingService {
3035
+ /**
3036
+ * Bootstrap core accounts + register asset accounts with opening balances (ADR-0113)
3037
+ * @param data The data for the request.
3038
+ * @param data.region Region code for tenant context
3039
+ * @param data.requestBody
3040
+ * @returns unknown Onboarding bootstrap result.
3041
+ * @throws ApiError
3042
+ */
3043
+ public static onboardingControllerBootstrap(
3044
+ data: OnboardingControllerBootstrapData
3045
+ ): CancelablePromise<OnboardingControllerBootstrapResponse> {
3046
+ return __request(OpenAPI, {
3047
+ method: 'POST',
3048
+ url: '/api/v1/{region}/bean/onboarding',
3049
+ path: {
3050
+ region: data.region
3051
+ },
3052
+ body: data.requestBody,
3053
+ mediaType: 'application/json',
3054
+ errors: {
3055
+ 422: 'Invalid region/account path/duplicate paths.'
3056
+ }
3057
+ });
3058
+ }
3059
+ }
3060
+
3061
+ export class BalanceReconciliationService {
3062
+ /**
3063
+ * Preview reconciliation (book vs actual)
3064
+ * Computes book balance, diff, Beancount-inferred tolerance, and suggested action without persisting.
3065
+ * @param data The data for the request.
3066
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3067
+ * @param data.requestBody
3068
+ * @returns ReconciliationComputeResultDto Reconciliation preview
3069
+ * @throws ApiError
3070
+ */
3071
+ public static reconciliationControllerCompute(
3072
+ data: ReconciliationControllerComputeData
3073
+ ): CancelablePromise<ReconciliationControllerComputeResponse> {
3074
+ return __request(OpenAPI, {
3075
+ method: 'POST',
3076
+ url: '/api/v1/{region}/bean/reconciliations',
3077
+ path: {
3078
+ region: data.region
3079
+ },
3080
+ body: data.requestBody,
3081
+ mediaType: 'application/json',
3082
+ errors: {
3083
+ 404: 'Account not found'
3084
+ }
3085
+ });
3086
+ }
3087
+
3088
+ /**
3089
+ * Record a balance assertion
3090
+ * Persists the reconciliation as a BeanBalance assertion (amount = actual, diffAmount = book − actual). Re-reconciling the same day/currency upserts.
3091
+ * @param data The data for the request.
3092
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3093
+ * @param data.requestBody
3094
+ * @returns ReconciliationRecordDto Balance assertion recorded
3095
+ * @throws ApiError
3096
+ */
3097
+ public static reconciliationControllerAssert(
3098
+ data: ReconciliationControllerAssertData
3099
+ ): CancelablePromise<ReconciliationControllerAssertResponse> {
3100
+ return __request(OpenAPI, {
3101
+ method: 'POST',
3102
+ url: '/api/v1/{region}/bean/reconciliations/assert',
3103
+ path: {
3104
+ region: data.region
3105
+ },
3106
+ body: data.requestBody,
3107
+ mediaType: 'application/json',
3108
+ errors: {
3109
+ 404: 'Account not found'
3110
+ }
3111
+ });
3112
+ }
3113
+
3114
+ /**
3115
+ * Generate a pad adjusting entry
3116
+ * 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.
3117
+ * @param data The data for the request.
3118
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3119
+ * @param data.requestBody
3120
+ * @returns PadResultDto Pad adjusting entry generated
3121
+ * @throws ApiError
3122
+ */
3123
+ public static reconciliationControllerPad(
3124
+ data: ReconciliationControllerPadData
3125
+ ): CancelablePromise<ReconciliationControllerPadResponse> {
3126
+ return __request(OpenAPI, {
3127
+ method: 'POST',
3128
+ url: '/api/v1/{region}/bean/reconciliations/pad',
3129
+ path: {
3130
+ region: data.region
3131
+ },
3132
+ body: data.requestBody,
3133
+ mediaType: 'application/json',
3134
+ errors: {
3135
+ 400: 'Book already within tolerance — no pad needed',
3136
+ 404: 'Account not found'
3137
+ }
3138
+ });
3139
+ }
3140
+
3141
+ /**
3142
+ * List reconciliation history for an account
3143
+ * Returns recorded balance assertions (most recent first). The latest drives the account-detail "Last <date>" badge.
3144
+ * @param data The data for the request.
3145
+ * @param data.accountId BeanAccount id
3146
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3147
+ * @returns ReconciliationRecordDto Reconciliation history
3148
+ * @throws ApiError
3149
+ */
3150
+ public static reconciliationControllerHistory(
3151
+ data: ReconciliationControllerHistoryData
3152
+ ): CancelablePromise<ReconciliationControllerHistoryResponse> {
3153
+ return __request(OpenAPI, {
3154
+ method: 'GET',
3155
+ url: '/api/v1/{region}/bean/accounts/{accountId}/reconciliations',
3156
+ path: {
3157
+ accountId: data.accountId,
3158
+ region: data.region
3159
+ },
3160
+ errors: {
3161
+ 404: 'Account not found'
3162
+ }
3163
+ });
3164
+ }
3165
+ }
3166
+
2656
3167
  export class BeanExportService {
2657
3168
  /**
2658
3169
  * Export Beancount ledger as ZIP
@@ -2831,216 +3342,196 @@ export class BeanImportService {
2831
3342
  }
2832
3343
  }
2833
3344
 
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
-
3345
+ export class ProviderSyncService {
2847
3346
  /**
2848
- * Create a new platform
3347
+ * Sync transactions from financial data provider
3348
+ *
3349
+ * Accepts raw transactions from external financial data providers, transforms them to Beancount format, and processes them through the ingestion pipeline.
3350
+ *
3351
+ * **Supported Providers:**
3352
+ * - **plaid**: Plaid API (US, Canada, Europe)
3353
+ * - **teller**: Teller API (US)
3354
+ * - **truelayer**: TrueLayer Open Banking (UK, Europe)
3355
+ * - **gocardless**: GoCardless Bank Account Data (Europe)
3356
+ * - **simplefin**: SimpleFIN (Self-hosted)
3357
+ * - **yodlee**: Yodlee (Global)
3358
+ * - **beancount-direct**: Beancount format transactions
3359
+ * - **parsed-bill**: Client-side parsed bill transactions
3360
+ *
3361
+ * **Processing Flow:**
3362
+ * 1. Transform raw data via provider adapter
3363
+ * 2. Validate transaction format
3364
+ * 3. Deduplicate using originalId
3365
+ * 4. Classify using rule engine
3366
+ * 5. Route low-confidence to Review Center
3367
+ * 6. Persist validated transactions
3368
+ *
2849
3369
  * @param data The data for the request.
3370
+ * @param data.providerName Provider name
3371
+ * @param data.region Region code for tenant context
2850
3372
  * @param data.requestBody
2851
- * @returns unknown Platform created successfully
3373
+ * @returns ProviderSyncResponseDto Sync completed successfully
2852
3374
  * @throws ApiError
2853
3375
  */
2854
- public static platformControllerCreate(
2855
- data: PlatformControllerCreateData
2856
- ): CancelablePromise<PlatformControllerCreateResponse> {
3376
+ public static providerSyncControllerSync(
3377
+ data: ProviderSyncControllerSyncData
3378
+ ): CancelablePromise<ProviderSyncControllerSyncResponse> {
2857
3379
  return __request(OpenAPI, {
2858
3380
  method: 'POST',
2859
- url: '/api/v1/bean/platforms',
3381
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3382
+ path: {
3383
+ providerName: data.providerName,
3384
+ region: data.region
3385
+ },
2860
3386
  body: data.requestBody,
2861
3387
  mediaType: 'application/json',
2862
3388
  errors: {
2863
- 409: 'Platform already exists'
3389
+ 400: 'Invalid request data',
3390
+ 401: 'Missing or invalid authentication',
3391
+ 404: 'Provider not supported'
2864
3392
  }
2865
3393
  });
2866
3394
  }
2867
3395
 
2868
3396
  /**
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
3397
+ * Get supported providers
3398
+ * Returns a list of all providers supported by the sync endpoint.
2882
3399
  * @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
3400
+ * @param data.region Region code for tenant context
3401
+ * @returns SupportedProvidersResponseDto List of supported providers
2886
3402
  * @throws ApiError
2887
3403
  */
2888
- public static platformControllerMatchPlatforms(
2889
- data: PlatformControllerMatchPlatformsData
2890
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3404
+ public static providerSyncControllerGetSupportedProviders(
3405
+ data: ProviderSyncControllerGetSupportedProvidersData
3406
+ ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
2891
3407
  return __request(OpenAPI, {
2892
3408
  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}',
3409
+ url: '/api/v1/{region}/bean/import/provider/supported',
2915
3410
  path: {
2916
- id: data.id
3411
+ region: data.region
2917
3412
  },
2918
- body: data.requestBody,
2919
- mediaType: 'application/json',
2920
3413
  errors: {
2921
- 404: 'Platform not found'
3414
+ 401: 'Missing or invalid authentication'
2922
3415
  }
2923
3416
  });
2924
3417
  }
2925
3418
 
2926
3419
  /**
2927
- * Delete a platform
3420
+ * Check if provider is supported
3421
+ * Returns whether a specific provider is supported.
2928
3422
  * @param data The data for the request.
2929
- * @param data.id Platform ID
2930
- * @returns void Platform deleted successfully
3423
+ * @param data.providerName Provider name to check
3424
+ * @param data.region Region code for tenant context
3425
+ * @returns unknown Provider support status
2931
3426
  * @throws ApiError
2932
3427
  */
2933
- public static platformControllerDelete(
2934
- data: PlatformControllerDeleteData
2935
- ): CancelablePromise<PlatformControllerDeleteResponse> {
3428
+ public static providerSyncControllerIsProviderSupported(
3429
+ data: ProviderSyncControllerIsProviderSupportedData
3430
+ ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
2936
3431
  return __request(OpenAPI, {
2937
- method: 'DELETE',
2938
- url: '/api/v1/bean/platforms/{id}',
3432
+ method: 'GET',
3433
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
2939
3434
  path: {
2940
- id: data.id
3435
+ providerName: data.providerName,
3436
+ region: data.region
2941
3437
  },
2942
3438
  errors: {
2943
- 404: 'Platform not found'
3439
+ 401: 'Missing or invalid authentication'
2944
3440
  }
2945
3441
  });
2946
3442
  }
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
- *
3443
+ }
3444
+
3445
+ export class ExternalAccountLinksService {
3446
+ /**
3447
+ * Create an external account → BeanAccount mapping (ADR-0113)
2973
3448
  * @param data The data for the request.
2974
- * @param data.providerName Provider name
2975
3449
  * @param data.region Region code for tenant context
2976
3450
  * @param data.requestBody
2977
- * @returns ProviderSyncResponseDto Sync completed successfully
3451
+ * @returns ExternalAccountLinkResponseDto Link created.
2978
3452
  * @throws ApiError
2979
3453
  */
2980
- public static providerSyncControllerSync(
2981
- data: ProviderSyncControllerSyncData
2982
- ): CancelablePromise<ProviderSyncControllerSyncResponse> {
3454
+ public static externalAccountLinkControllerCreate(
3455
+ data: ExternalAccountLinkControllerCreateData
3456
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
2983
3457
  return __request(OpenAPI, {
2984
3458
  method: 'POST',
2985
- url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3459
+ url: '/api/v1/{region}/bean/external-account-links',
2986
3460
  path: {
2987
- providerName: data.providerName,
2988
3461
  region: data.region
2989
3462
  },
2990
3463
  body: data.requestBody,
2991
3464
  mediaType: 'application/json',
2992
3465
  errors: {
2993
- 400: 'Invalid request data',
2994
- 401: 'Missing or invalid authentication',
2995
- 404: 'Provider not supported'
3466
+ 422: 'beanAccountId not owned, or an active link already exists.'
2996
3467
  }
2997
3468
  });
2998
3469
  }
2999
3470
 
3000
3471
  /**
3001
- * Get supported providers
3002
- * Returns a list of all providers supported by the sync endpoint.
3472
+ * List the user's active external account links
3003
3473
  * @param data The data for the request.
3474
+ * @param data.provider
3004
3475
  * @param data.region Region code for tenant context
3005
- * @returns SupportedProvidersResponseDto List of supported providers
3476
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
3006
3477
  * @throws ApiError
3007
3478
  */
3008
- public static providerSyncControllerGetSupportedProviders(
3009
- data: ProviderSyncControllerGetSupportedProvidersData
3010
- ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
3479
+ public static externalAccountLinkControllerFindAll(
3480
+ data: ExternalAccountLinkControllerFindAllData
3481
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
3011
3482
  return __request(OpenAPI, {
3012
3483
  method: 'GET',
3013
- url: '/api/v1/{region}/bean/import/provider/supported',
3484
+ url: '/api/v1/{region}/bean/external-account-links',
3014
3485
  path: {
3015
3486
  region: data.region
3016
3487
  },
3017
- errors: {
3018
- 401: 'Missing or invalid authentication'
3488
+ query: {
3489
+ provider: data.provider
3019
3490
  }
3020
3491
  });
3021
3492
  }
3022
3493
 
3023
3494
  /**
3024
- * Check if provider is supported
3025
- * Returns whether a specific provider is supported.
3495
+ * Get a single external account link
3026
3496
  * @param data The data for the request.
3027
- * @param data.providerName Provider name to check
3497
+ * @param data.id
3028
3498
  * @param data.region Region code for tenant context
3029
- * @returns unknown Provider support status
3499
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
3030
3500
  * @throws ApiError
3031
3501
  */
3032
- public static providerSyncControllerIsProviderSupported(
3033
- data: ProviderSyncControllerIsProviderSupportedData
3034
- ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
3502
+ public static externalAccountLinkControllerFindOne(
3503
+ data: ExternalAccountLinkControllerFindOneData
3504
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
3035
3505
  return __request(OpenAPI, {
3036
3506
  method: 'GET',
3037
- url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3507
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3038
3508
  path: {
3039
- providerName: data.providerName,
3509
+ id: data.id,
3040
3510
  region: data.region
3041
3511
  },
3042
3512
  errors: {
3043
- 401: 'Missing or invalid authentication'
3513
+ 422: 'Link not found or not owned by the user.'
3514
+ }
3515
+ });
3516
+ }
3517
+
3518
+ /**
3519
+ * Soft-delete (disconnect) an external account link
3520
+ * @param data The data for the request.
3521
+ * @param data.id
3522
+ * @param data.region Region code for tenant context
3523
+ * @returns void Link soft-deleted; historical transactions are unaffected.
3524
+ * @throws ApiError
3525
+ */
3526
+ public static externalAccountLinkControllerRemove(
3527
+ data: ExternalAccountLinkControllerRemoveData
3528
+ ): CancelablePromise<ExternalAccountLinkControllerRemoveResponse> {
3529
+ return __request(OpenAPI, {
3530
+ method: 'DELETE',
3531
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3532
+ path: {
3533
+ id: data.id,
3534
+ region: data.region
3044
3535
  }
3045
3536
  });
3046
3537
  }
@@ -3204,359 +3695,180 @@ export class BeanNlpService {
3204
3695
  }
3205
3696
  }
3206
3697
 
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 {
3698
+ export class BeanPlatformsService {
3326
3699
  /**
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
3700
+ * Get all platforms with statistics
3701
+ * @returns unknown List of platforms with binding and account counts
3335
3702
  * @throws ApiError
3336
3703
  */
3337
- public static holdingPnlControllerGetHoldingPnl(
3338
- data: HoldingPnlControllerGetHoldingPnlData
3339
- ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3704
+ public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
3340
3705
  return __request(OpenAPI, {
3341
3706
  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
- }
3707
+ url: '/api/v1/bean/platforms'
3355
3708
  });
3356
3709
  }
3357
- }
3358
3710
 
3359
- export class BeanPricesService {
3360
3711
  /**
3361
- * Create a new price
3362
- * Creates a new price entry for the authenticated user
3712
+ * Create a new platform
3363
3713
  * @param data The data for the request.
3364
- * @param data.region Region code for tenant context
3365
3714
  * @param data.requestBody
3366
- * @returns PriceResponseDto Price created successfully
3715
+ * @returns unknown Platform created successfully
3367
3716
  * @throws ApiError
3368
3717
  */
3369
- public static priceControllerCreate(
3370
- data: PriceControllerCreateData
3371
- ): CancelablePromise<PriceControllerCreateResponse> {
3718
+ public static platformControllerCreate(
3719
+ data: PlatformControllerCreateData
3720
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3372
3721
  return __request(OpenAPI, {
3373
3722
  method: 'POST',
3374
- url: '/api/v1/{region}/bean/prices',
3375
- path: {
3376
- region: data.region
3377
- },
3723
+ url: '/api/v1/bean/platforms',
3378
3724
  body: data.requestBody,
3379
3725
  mediaType: 'application/json',
3380
3726
  errors: {
3381
- 404: 'Currency or quoteCurrency commodity not found',
3382
- 409: 'Price already exists for this currency pair and date'
3727
+ 409: 'Platform already exists'
3383
3728
  }
3384
3729
  });
3385
3730
  }
3386
3731
 
3387
3732
  /**
3388
- * List user prices
3389
- * Returns all price entries for the authenticated user with optional filtering
3733
+ * Get platform list for current user
3390
3734
  * @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
3735
+ * @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").
3736
+ * @returns PlatformListItemDto List of platforms with user binding status
3400
3737
  * @throws ApiError
3401
3738
  */
3402
- public static priceControllerFindAll(
3403
- data: PriceControllerFindAllData
3404
- ): CancelablePromise<PriceControllerFindAllResponse> {
3739
+ public static platformControllerGetPlatformList(
3740
+ data: PlatformControllerGetPlatformListData = {}
3741
+ ): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3405
3742
  return __request(OpenAPI, {
3406
3743
  method: 'GET',
3407
- url: '/api/v1/{region}/bean/prices',
3408
- path: {
3409
- region: data.region
3410
- },
3744
+ url: '/api/v1/bean/platforms/list',
3411
3745
  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
3746
+ region: data.region
3419
3747
  }
3420
3748
  });
3421
3749
  }
3422
3750
 
3423
3751
  /**
3424
- * Get price by ID
3425
- * Returns a single price entry by its ID
3752
+ * Match platforms by name or alias
3426
3753
  * @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
3754
+ * @param data.q Search query — Chinese name, English name, or abbreviation
3755
+ * @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").
3756
+ * @returns PlatformMatchResponseDto Matching platforms with overall match type and truncation flag
3430
3757
  * @throws ApiError
3431
3758
  */
3432
- public static priceControllerFindOne(
3433
- data: PriceControllerFindOneData
3434
- ): CancelablePromise<PriceControllerFindOneResponse> {
3759
+ public static platformControllerMatchPlatforms(
3760
+ data: PlatformControllerMatchPlatformsData
3761
+ ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3435
3762
  return __request(OpenAPI, {
3436
3763
  method: 'GET',
3437
- url: '/api/v1/{region}/bean/prices/{id}',
3438
- path: {
3439
- id: data.id,
3764
+ url: '/api/v1/bean/platforms/match',
3765
+ query: {
3766
+ q: data.q,
3440
3767
  region: data.region
3441
- },
3442
- errors: {
3443
- 404: 'Price not found'
3444
3768
  }
3445
3769
  });
3446
3770
  }
3447
3771
 
3448
3772
  /**
3449
- * Update a price
3450
- * Updates an existing price entry
3773
+ * Update a platform
3451
3774
  * @param data The data for the request.
3452
- * @param data.id Price ID
3453
- * @param data.region Region code for tenant context
3775
+ * @param data.id Platform ID
3454
3776
  * @param data.requestBody
3455
- * @returns PriceResponseDto Price updated successfully
3777
+ * @returns unknown Platform updated successfully
3456
3778
  * @throws ApiError
3457
3779
  */
3458
- public static priceControllerUpdate(
3459
- data: PriceControllerUpdateData
3460
- ): CancelablePromise<PriceControllerUpdateResponse> {
3780
+ public static platformControllerUpdate(
3781
+ data: PlatformControllerUpdateData
3782
+ ): CancelablePromise<PlatformControllerUpdateResponse> {
3461
3783
  return __request(OpenAPI, {
3462
3784
  method: 'PUT',
3463
- url: '/api/v1/{region}/bean/prices/{id}',
3785
+ url: '/api/v1/bean/platforms/{id}',
3464
3786
  path: {
3465
- id: data.id,
3466
- region: data.region
3787
+ id: data.id
3467
3788
  },
3468
3789
  body: data.requestBody,
3469
3790
  mediaType: 'application/json',
3470
3791
  errors: {
3471
- 404: 'Price not found',
3472
- 409: 'Updated price conflicts with existing price'
3792
+ 404: 'Platform not found'
3473
3793
  }
3474
3794
  });
3475
3795
  }
3476
3796
 
3477
3797
  /**
3478
- * Delete a price
3479
- * Deletes a price entry (hard delete)
3798
+ * Delete a platform
3480
3799
  * @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
3800
+ * @param data.id Platform ID
3801
+ * @returns void Platform deleted successfully
3484
3802
  * @throws ApiError
3485
3803
  */
3486
- public static priceControllerDelete(
3487
- data: PriceControllerDeleteData
3488
- ): CancelablePromise<PriceControllerDeleteResponse> {
3804
+ public static platformControllerDelete(
3805
+ data: PlatformControllerDeleteData
3806
+ ): CancelablePromise<PlatformControllerDeleteResponse> {
3489
3807
  return __request(OpenAPI, {
3490
3808
  method: 'DELETE',
3491
- url: '/api/v1/{region}/bean/prices/{id}',
3809
+ url: '/api/v1/bean/platforms/{id}',
3492
3810
  path: {
3493
- id: data.id,
3494
- region: data.region
3811
+ id: data.id
3495
3812
  },
3496
3813
  errors: {
3497
- 404: 'Price not found'
3814
+ 404: 'Platform not found'
3498
3815
  }
3499
3816
  });
3500
3817
  }
3818
+ }
3501
3819
 
3820
+ export class DashboardService {
3502
3821
  /**
3503
- * Bulk create prices
3504
- * Creates multiple price entries at once (skips duplicates)
3822
+ * Get net worth overview
3823
+ * Returns total net worth with breakdown of assets and liabilities
3505
3824
  * @param data The data for the request.
3506
3825
  * @param data.region Region code for tenant context
3507
- * @param data.requestBody
3508
- * @returns PriceResponseDto Prices created successfully
3826
+ * @param data.date Date for balance calculation (ISO 8601 format)
3827
+ * @returns NetWorthResponseDto Net worth retrieved successfully
3509
3828
  * @throws ApiError
3510
3829
  */
3511
- public static priceControllerBulkCreate(
3512
- data: PriceControllerBulkCreateData
3513
- ): CancelablePromise<PriceControllerBulkCreateResponse> {
3830
+ public static dashboardControllerGetNetWorth(
3831
+ data: DashboardControllerGetNetWorthData
3832
+ ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3514
3833
  return __request(OpenAPI, {
3515
- method: 'POST',
3516
- url: '/api/v1/{region}/bean/prices/bulk',
3834
+ method: 'GET',
3835
+ url: '/api/v1/{region}/dashboard/net-worth',
3517
3836
  path: {
3518
3837
  region: data.region
3519
3838
  },
3520
- body: data.requestBody,
3521
- mediaType: 'application/json'
3839
+ query: {
3840
+ date: data.date
3841
+ },
3842
+ errors: {
3843
+ 401: 'User not authenticated'
3844
+ }
3522
3845
  });
3523
3846
  }
3524
- }
3525
3847
 
3526
- export class ReportingService {
3527
3848
  /**
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
- *
3849
+ * Get accounts grouped by platform
3850
+ * Returns accounts with balances grouped by financial platform
3541
3851
  * @param data The data for the request.
3542
3852
  * @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
3853
+ * @param data.groupBy Grouping strategy
3854
+ * @param data.date Date for balance calculation (ISO 8601 format)
3855
+ * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3856
+ * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3546
3857
  * @throws ApiError
3547
3858
  */
3548
- public static reportingControllerGetPortfolioTrends(
3549
- data: ReportingControllerGetPortfolioTrendsData
3550
- ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
3859
+ public static dashboardControllerGetAccounts(
3860
+ data: DashboardControllerGetAccountsData
3861
+ ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3551
3862
  return __request(OpenAPI, {
3552
3863
  method: 'GET',
3553
- url: '/api/v1/{region}/reporting/portfolio/trends',
3864
+ url: '/api/v1/{region}/dashboard/accounts',
3554
3865
  path: {
3555
3866
  region: data.region
3556
3867
  },
3557
3868
  query: {
3558
- period: data.period,
3559
- granularity: data.granularity
3869
+ groupBy: data.groupBy,
3870
+ date: data.date,
3871
+ accountId: data.accountId
3560
3872
  },
3561
3873
  errors: {
3562
3874
  401: 'User not authenticated'
@@ -3565,116 +3877,95 @@ export class ReportingService {
3565
3877
  }
3566
3878
 
3567
3879
  /**
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
- *
3880
+ * Get cash flow summary
3881
+ * Returns income, expenses, and savings for a monthly period
3577
3882
  * @param data The data for the request.
3883
+ * @param data.period Period in YYYY-MM format
3578
3884
  * @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
3885
+ * @returns CashFlowResponseDto Cash flow retrieved successfully
3582
3886
  * @throws ApiError
3583
3887
  */
3584
- public static reportingControllerGetCashFlowTrends(
3585
- data: ReportingControllerGetCashFlowTrendsData
3586
- ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
3888
+ public static dashboardControllerGetCashFlow(
3889
+ data: DashboardControllerGetCashFlowData
3890
+ ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3587
3891
  return __request(OpenAPI, {
3588
3892
  method: 'GET',
3589
- url: '/api/v1/{region}/reporting/cash-flow/trends',
3893
+ url: '/api/v1/{region}/dashboard/cash-flow',
3590
3894
  path: {
3591
3895
  region: data.region
3592
3896
  },
3593
3897
  query: {
3594
- period: data.period,
3595
- granularity: data.granularity
3898
+ period: data.period
3596
3899
  },
3597
3900
  errors: {
3901
+ 400: 'Invalid period format',
3598
3902
  401: 'User not authenticated'
3599
3903
  }
3600
3904
  });
3601
3905
  }
3602
3906
 
3603
3907
  /**
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
- *
3908
+ * Get expenses/income grouped by functional category
3909
+ * 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
3910
  * @param data The data for the request.
3619
3911
  * @param data.region Region code for tenant context
3620
- * @param data.requestBody Optional date (defaults to today)
3621
- * @returns GenerateSnapshotResponse Snapshot generated successfully
3912
+ * @param data.groupBy Grouping strategy
3913
+ * @param data.period Time window (1m = current calendar month)
3914
+ * @param data.flow Account root to aggregate (expense → ^Expenses:, income → ^Income:)
3915
+ * @returns ExpensesByCategoryResponseDto Expenses retrieved successfully
3622
3916
  * @throws ApiError
3623
3917
  */
3624
- public static reportingControllerGenerateSnapshot(
3625
- data: ReportingControllerGenerateSnapshotData
3626
- ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
3918
+ public static dashboardControllerGetExpenses(
3919
+ data: DashboardControllerGetExpensesData
3920
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3627
3921
  return __request(OpenAPI, {
3628
- method: 'POST',
3629
- url: '/api/v1/{region}/reporting/snapshots/generate',
3922
+ method: 'GET',
3923
+ url: '/api/v1/{region}/dashboard/expenses',
3630
3924
  path: {
3631
3925
  region: data.region
3632
3926
  },
3633
- body: data.requestBody,
3634
- mediaType: 'application/json',
3927
+ query: {
3928
+ groupBy: data.groupBy,
3929
+ period: data.period,
3930
+ flow: data.flow
3931
+ },
3635
3932
  errors: {
3636
- 400: 'Invalid date format',
3933
+ 400: 'Invalid groupBy or period',
3637
3934
  401: 'User not authenticated'
3638
3935
  }
3639
3936
  });
3640
3937
  }
3938
+ }
3641
3939
 
3940
+ export class InvestmentService {
3642
3941
  /**
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
- *
3942
+ * Get per-holding unrealized + realized P&L
3943
+ * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3657
3944
  * @param data The data for the request.
3658
3945
  * @param data.region Region code for tenant context
3659
- * @param data.requestBody
3660
- * @returns BackfillSnapshotsResponse Backfill completed successfully
3946
+ * @param data.asOf As-of date (ISO 8601), defaults to today
3947
+ * @param data.accountId Scope to a single account
3948
+ * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3949
+ * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3661
3950
  * @throws ApiError
3662
3951
  */
3663
- public static reportingControllerBackfillSnapshots(
3664
- data: ReportingControllerBackfillSnapshotsData
3665
- ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
3952
+ public static holdingPnlControllerGetHoldingPnl(
3953
+ data: HoldingPnlControllerGetHoldingPnlData
3954
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3666
3955
  return __request(OpenAPI, {
3667
- method: 'POST',
3668
- url: '/api/v1/{region}/reporting/snapshots/backfill',
3956
+ method: 'GET',
3957
+ url: '/api/v1/{region}/investment/holdings/pnl',
3669
3958
  path: {
3670
3959
  region: data.region
3671
3960
  },
3672
- body: data.requestBody,
3673
- mediaType: 'application/json',
3961
+ query: {
3962
+ asOf: data.asOf,
3963
+ accountId: data.accountId,
3964
+ method: data.method
3965
+ },
3674
3966
  errors: {
3675
- 400: 'Invalid date format or range',
3676
- 401: 'User not authenticated',
3677
- 409: 'Backfill already in progress for this user'
3967
+ 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3968
+ 401: 'User not authenticated'
3678
3969
  }
3679
3970
  });
3680
3971
  }
@@ -3703,7 +3994,7 @@ export class AuthService {
3703
3994
  * Anonymous login with access token
3704
3995
  * @param data The data for the request.
3705
3996
  * @param data.requestBody
3706
- * @returns unknown Login successful
3997
+ * @returns AnonymousLoginResponseDto Login successful
3707
3998
  * @throws ApiError
3708
3999
  */
3709
4000
  public static authControllerAccessTokenLogin(
@@ -3890,3 +4181,53 @@ export class InfoService {
3890
4181
  });
3891
4182
  }
3892
4183
  }
4184
+
4185
+ export class MarketDataService {
4186
+ /**
4187
+ * Search market symbols by name or code
4188
+ * Ranked search over the openbb catalog. Empty `q` returns [].
4189
+ * @param data The data for the request.
4190
+ * @param data.q Search term — matched against symbol and instrument name. Empty string returns [].
4191
+ * @param data.limit Maximum number of results (clamped 1..50)
4192
+ * @param data.exchange Filter by exchange code (e.g. US, HK, SS, SZ)
4193
+ * @param data.assetType Filter by OpenBB asset_type (e.g. stock, etf)
4194
+ * @returns SymbolSearchResultDto Ranked search results
4195
+ * @throws ApiError
4196
+ */
4197
+ public static symbolControllerSearch(
4198
+ data: SymbolControllerSearchData
4199
+ ): CancelablePromise<SymbolControllerSearchResponse> {
4200
+ return __request(OpenAPI, {
4201
+ method: 'GET',
4202
+ url: '/api/v1/market/symbols/search',
4203
+ query: {
4204
+ q: data.q,
4205
+ limit: data.limit,
4206
+ exchange: data.exchange,
4207
+ assetType: data.assetType
4208
+ }
4209
+ });
4210
+ }
4211
+
4212
+ /**
4213
+ * Get a market symbol quote
4214
+ * @param data The data for the request.
4215
+ * @param data.symbol
4216
+ * @returns SymbolQuoteDto Symbol quote
4217
+ * @throws ApiError
4218
+ */
4219
+ public static symbolControllerGetQuote(
4220
+ data: SymbolControllerGetQuoteData
4221
+ ): CancelablePromise<SymbolControllerGetQuoteResponse> {
4222
+ return __request(OpenAPI, {
4223
+ method: 'GET',
4224
+ url: '/api/v1/market/symbols/{symbol}/quote',
4225
+ path: {
4226
+ symbol: data.symbol
4227
+ },
4228
+ errors: {
4229
+ 404: 'Symbol not found in the openbb catalog'
4230
+ }
4231
+ });
4232
+ }
4233
+ }