@firela/api-types 0.0.0-canary.32edff08 → 0.0.0-canary.3550df41

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,
@@ -29,6 +31,8 @@ import type {
29
31
  TransactionControllerListResponse,
30
32
  TransactionControllerCreateBatchData,
31
33
  TransactionControllerCreateBatchResponse,
34
+ TransactionControllerCorrectData,
35
+ TransactionControllerCorrectResponse,
32
36
  TransactionControllerSuggestTagsData,
33
37
  TransactionControllerSuggestTagsResponse,
34
38
  TransactionControllerGetDetailData,
@@ -95,6 +99,18 @@ import type {
95
99
  CommodityControllerGetOrCreateResponse,
96
100
  CommodityControllerBulkCreateData,
97
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,
98
114
  RecurringRuleControllerCreateData,
99
115
  RecurringRuleControllerCreateResponse,
100
116
  RecurringRuleControllerFindAllData,
@@ -127,26 +143,14 @@ import type {
127
143
  ExpectedTransactionControllerEnterNowResponse,
128
144
  ForecastControllerGetForecastData,
129
145
  ForecastControllerGetForecastResponse,
130
- TransactionRuleControllerCreateData,
131
- TransactionRuleControllerCreateResponse,
132
- TransactionRuleControllerListData,
133
- TransactionRuleControllerListResponse,
134
- TransactionRuleControllerValidateData,
135
- TransactionRuleControllerValidateResponse,
136
- TransactionRuleControllerBulkCreateData,
137
- TransactionRuleControllerBulkCreateResponse,
138
- TransactionRuleControllerExportData,
139
- TransactionRuleControllerExportResponse,
140
- TransactionRuleControllerGetStatisticsData,
141
- TransactionRuleControllerGetStatisticsResponse,
142
- TransactionRuleControllerGetDetailData,
143
- TransactionRuleControllerGetDetailResponse,
144
- TransactionRuleControllerUpdateData,
145
- TransactionRuleControllerUpdateResponse,
146
- TransactionRuleControllerDeleteData,
147
- TransactionRuleControllerDeleteResponse,
148
- TransactionRuleControllerTestData,
149
- TransactionRuleControllerTestResponse,
146
+ ReportingControllerGetPortfolioTrendsData,
147
+ ReportingControllerGetPortfolioTrendsResponse,
148
+ ReportingControllerGetCashFlowTrendsData,
149
+ ReportingControllerGetCashFlowTrendsResponse,
150
+ ReportingControllerGenerateSnapshotData,
151
+ ReportingControllerGenerateSnapshotResponse,
152
+ ReportingControllerBackfillSnapshotsData,
153
+ ReportingControllerBackfillSnapshotsResponse,
150
154
  UserControllerDeleteOwnUserData,
151
155
  UserControllerDeleteOwnUserResponse,
152
156
  UserControllerGetUserData,
@@ -169,6 +173,48 @@ import type {
169
173
  PropertyControllerUpdateResponse,
170
174
  PropertyControllerDeleteData,
171
175
  PropertyControllerDeleteResponse,
176
+ TransactionRuleControllerCreateData,
177
+ TransactionRuleControllerCreateResponse,
178
+ TransactionRuleControllerListData,
179
+ TransactionRuleControllerListResponse,
180
+ TransactionRuleControllerValidateData,
181
+ TransactionRuleControllerValidateResponse,
182
+ TransactionRuleControllerBulkCreateData,
183
+ TransactionRuleControllerBulkCreateResponse,
184
+ TransactionRuleControllerExportData,
185
+ TransactionRuleControllerExportResponse,
186
+ TransactionRuleControllerGetStatisticsData,
187
+ TransactionRuleControllerGetStatisticsResponse,
188
+ TransactionRuleControllerGetDetailData,
189
+ TransactionRuleControllerGetDetailResponse,
190
+ TransactionRuleControllerUpdateData,
191
+ TransactionRuleControllerUpdateResponse,
192
+ TransactionRuleControllerDeleteData,
193
+ TransactionRuleControllerDeleteResponse,
194
+ TransactionRuleControllerTestData,
195
+ TransactionRuleControllerTestResponse,
196
+ EventControllerCreateData,
197
+ EventControllerCreateResponse,
198
+ EventControllerFindAllData,
199
+ EventControllerFindAllResponse,
200
+ EventControllerFindOneData,
201
+ EventControllerFindOneResponse,
202
+ EventControllerUpdateData,
203
+ EventControllerUpdateResponse,
204
+ EventControllerDeleteData,
205
+ EventControllerDeleteResponse,
206
+ EventControllerGetSliceData,
207
+ EventControllerGetSliceResponse,
208
+ OnboardingControllerBootstrapData,
209
+ OnboardingControllerBootstrapResponse,
210
+ ReconciliationControllerComputeData,
211
+ ReconciliationControllerComputeResponse,
212
+ ReconciliationControllerAssertData,
213
+ ReconciliationControllerAssertResponse,
214
+ ReconciliationControllerPadData,
215
+ ReconciliationControllerPadResponse,
216
+ ReconciliationControllerHistoryData,
217
+ ReconciliationControllerHistoryResponse,
172
218
  ExportControllerExportBeancountResponse,
173
219
  FileImportControllerImportFileData,
174
220
  FileImportControllerImportFileResponse,
@@ -182,42 +228,52 @@ import type {
182
228
  ImporterConfigControllerUpdateConfigResponse,
183
229
  ImporterConfigControllerResetConfigData,
184
230
  ImporterConfigControllerResetConfigResponse,
185
- PlatformControllerFindAllResponse,
186
- PlatformControllerCreateData,
187
- PlatformControllerCreateResponse,
188
- PlatformControllerGetPlatformListResponse,
189
- PlatformControllerMatchPlatformsData,
190
- PlatformControllerMatchPlatformsResponse,
191
- PlatformControllerUpdateData,
192
- PlatformControllerUpdateResponse,
193
- PlatformControllerDeleteData,
194
- PlatformControllerDeleteResponse,
195
231
  ProviderSyncControllerSyncData,
196
232
  ProviderSyncControllerSyncResponse,
197
233
  ProviderSyncControllerGetSupportedProvidersData,
198
234
  ProviderSyncControllerGetSupportedProvidersResponse,
199
235
  ProviderSyncControllerIsProviderSupportedData,
200
236
  ProviderSyncControllerIsProviderSupportedResponse,
237
+ ExternalAccountLinkControllerCreateData,
238
+ ExternalAccountLinkControllerCreateResponse,
239
+ ExternalAccountLinkControllerFindAllData,
240
+ ExternalAccountLinkControllerFindAllResponse,
241
+ ExternalAccountLinkControllerFindOneData,
242
+ ExternalAccountLinkControllerFindOneResponse,
243
+ ExternalAccountLinkControllerRemoveData,
244
+ ExternalAccountLinkControllerRemoveResponse,
201
245
  TelemetryControllerReportTelemetryData,
202
246
  TelemetryControllerReportTelemetryResponse,
247
+ TelemetryControllerReportCoverageMissData,
248
+ TelemetryControllerReportCoverageMissResponse,
249
+ TelemetryControllerGetCoverageMetricsData,
250
+ TelemetryControllerGetCoverageMetricsResponse,
203
251
  NlpControllerProcessNaturalLanguageData,
204
252
  NlpControllerProcessNaturalLanguageResponse,
205
253
  NlpControllerClearSessionData,
206
254
  NlpControllerClearSessionResponse,
207
255
  NlpControllerGetSessionData,
208
256
  NlpControllerGetSessionResponse,
257
+ PlatformControllerFindAllResponse,
258
+ PlatformControllerCreateData,
259
+ PlatformControllerCreateResponse,
260
+ PlatformControllerGetPlatformListResponse,
261
+ PlatformControllerMatchPlatformsData,
262
+ PlatformControllerMatchPlatformsResponse,
263
+ PlatformControllerUpdateData,
264
+ PlatformControllerUpdateResponse,
265
+ PlatformControllerDeleteData,
266
+ PlatformControllerDeleteResponse,
209
267
  DashboardControllerGetNetWorthData,
210
268
  DashboardControllerGetNetWorthResponse,
211
269
  DashboardControllerGetAccountsData,
212
270
  DashboardControllerGetAccountsResponse,
213
271
  DashboardControllerGetCashFlowData,
214
272
  DashboardControllerGetCashFlowResponse,
215
- ReportingControllerGetPortfolioTrendsData,
216
- ReportingControllerGetPortfolioTrendsResponse,
217
- ReportingControllerGenerateSnapshotData,
218
- ReportingControllerGenerateSnapshotResponse,
219
- ReportingControllerBackfillSnapshotsData,
220
- ReportingControllerBackfillSnapshotsResponse,
273
+ DashboardControllerGetExpensesData,
274
+ DashboardControllerGetExpensesResponse,
275
+ HoldingPnlControllerGetHoldingPnlData,
276
+ HoldingPnlControllerGetHoldingPnlResponse,
221
277
  ApiKeysControllerCreateApiKeyResponse,
222
278
  AuthControllerAccessTokenLoginData,
223
279
  AuthControllerAccessTokenLoginResponse,
@@ -232,7 +288,11 @@ import type {
232
288
  HealthControllerResetCircuitBreakerData,
233
289
  HealthControllerResetCircuitBreakerResponse,
234
290
  HealthControllerGetMetricsResponse,
235
- InfoControllerGetInfoResponse
291
+ InfoControllerGetInfoResponse,
292
+ SymbolControllerSearchData,
293
+ SymbolControllerSearchResponse,
294
+ SymbolControllerGetQuoteData,
295
+ SymbolControllerGetQuoteResponse
236
296
  } from './types.gen';
237
297
 
238
298
  export class BeanAccountsService {
@@ -270,7 +330,7 @@ export class BeanAccountsService {
270
330
  * @param data.type Filter by account type
271
331
  * @param data.status Filter by status
272
332
  * @param data.isCustom Filter by custom (user-created) accounts only
273
- * @param data.search Search term for path or i18nKey
333
+ * @param data.search Search term for account path
274
334
  * @param data.limit Maximum number of results
275
335
  * @param data.offset Number of results to skip
276
336
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -351,7 +411,7 @@ export class BeanAccountsService {
351
411
 
352
412
  /**
353
413
  * Delete account
354
- * Deletes an account (only if no transactions)
414
+ * Deletes an account (only if no active transactions; voided/superseded residual postings are cleaned up)
355
415
  * @param data The data for the request.
356
416
  * @param data.id Account UUID
357
417
  * @param data.region Region code for tenant context
@@ -370,7 +430,7 @@ export class BeanAccountsService {
370
430
  },
371
431
  errors: {
372
432
  404: 'Account not found',
373
- 409: 'Account has transactions and cannot be deleted'
433
+ 409: 'Account has active transactions and cannot be deleted'
374
434
  }
375
435
  });
376
436
  }
@@ -432,6 +492,35 @@ export class BeanAccountsService {
432
492
  }
433
493
  });
434
494
  }
495
+
496
+ /**
497
+ * Post an opening-balance transaction
498
+ * 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.
499
+ * @param data The data for the request.
500
+ * @param data.id Account UUID
501
+ * @param data.region Region code for tenant context
502
+ * @param data.requestBody
503
+ * @returns OpeningBalanceResultDto Opening-balance transaction created
504
+ * @throws ApiError
505
+ */
506
+ public static accountControllerAddOpeningBalance(
507
+ data: AccountControllerAddOpeningBalanceData
508
+ ): CancelablePromise<AccountControllerAddOpeningBalanceResponse> {
509
+ return __request(OpenAPI, {
510
+ method: 'POST',
511
+ url: '/api/v1/{region}/bean/accounts/{id}/opening-balance',
512
+ path: {
513
+ id: data.id,
514
+ region: data.region
515
+ },
516
+ body: data.requestBody,
517
+ mediaType: 'application/json',
518
+ errors: {
519
+ 404: 'Account not found',
520
+ 409: 'An opening balance already exists for this account'
521
+ }
522
+ });
523
+ }
435
524
  }
436
525
 
437
526
  export class BeanAccountStandardsService {
@@ -463,7 +552,7 @@ export class BeanAccountStandardsService {
463
552
 
464
553
  /**
465
554
  * Get template metadata for an account path
466
- * Returns extendable status and root type for a template path.
555
+ * Returns root type for a template path.
467
556
  * @param data The data for the request.
468
557
  * @param data.region Region code for tenant context
469
558
  * @param data.path Account path to check
@@ -549,6 +638,7 @@ export class BeanTransactionsService {
549
638
  * @param data.status Filter by transaction status
550
639
  * @param data.search Search in narration and payee fields (max 200 chars)
551
640
  * @param data.accountId Filter by account ID (transactions with postings to this account)
641
+ * @param data.category Filter by ADR-0075 functional category (Group segment); matches any posting to an Expenses/Income account whose derived Group segment equals this value
552
642
  * @returns TransactionListResponseDto Transaction list
553
643
  * @throws ApiError
554
644
  */
@@ -568,7 +658,8 @@ export class BeanTransactionsService {
568
658
  dateTo: data.dateTo,
569
659
  status: data.status,
570
660
  search: data.search,
571
- accountId: data.accountId
661
+ accountId: data.accountId,
662
+ category: data.category
572
663
  },
573
664
  errors: {
574
665
  400: 'Validation failed',
@@ -605,6 +696,36 @@ export class BeanTransactionsService {
605
696
  });
606
697
  }
607
698
 
699
+ /**
700
+ * Correct (supersede) a transaction
701
+ * Atomically voids the original (SUPERSEDED) and creates a replacement through the full validation pipeline.
702
+ * @param data The data for the request.
703
+ * @param data.id Original transaction ID to correct
704
+ * @param data.region Region code for tenant context
705
+ * @param data.requestBody
706
+ * @returns TransactionDetailDto Corrected transaction created
707
+ * @throws ApiError
708
+ */
709
+ public static transactionControllerCorrect(
710
+ data: TransactionControllerCorrectData
711
+ ): CancelablePromise<TransactionControllerCorrectResponse> {
712
+ return __request(OpenAPI, {
713
+ method: 'POST',
714
+ url: '/api/v1/{region}/bean/transactions/{id}/correct',
715
+ path: {
716
+ id: data.id,
717
+ region: data.region
718
+ },
719
+ body: data.requestBody,
720
+ mediaType: 'application/json',
721
+ errors: {
722
+ 404: 'Original transaction not found',
723
+ 409: 'Original no longer ACTIVE (concurrent modification)',
724
+ 422: 'Pipeline validation failed (does not balance, invalid accounts)'
725
+ }
726
+ });
727
+ }
728
+
608
729
  /**
609
730
  * Suggest transaction tags
610
731
  * Returns distinct tags from the user ACTIVE transactions, sorted by usage, for autocomplete. Optional q performs a case-insensitive prefix match.
@@ -726,7 +847,7 @@ export class BeanBalancesService {
726
847
  * Query account balance
727
848
  * Calculate account balance at a specific date for a single currency
728
849
  * @param data The data for the request.
729
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
850
+ * @param data.account Account name (e.g., "Assets:Checking")
730
851
  * @param data.region Region code for tenant context
731
852
  * @param data.date Date to calculate balance at (ISO 8601 format)
732
853
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -1447,6 +1568,173 @@ export class BeanCommoditiesService {
1447
1568
  }
1448
1569
  }
1449
1570
 
1571
+ export class BeanPricesService {
1572
+ /**
1573
+ * Create a new price
1574
+ * Creates a new price entry for the authenticated user
1575
+ * @param data The data for the request.
1576
+ * @param data.region Region code for tenant context
1577
+ * @param data.requestBody
1578
+ * @returns PriceResponseDto Price created successfully
1579
+ * @throws ApiError
1580
+ */
1581
+ public static priceControllerCreate(
1582
+ data: PriceControllerCreateData
1583
+ ): CancelablePromise<PriceControllerCreateResponse> {
1584
+ return __request(OpenAPI, {
1585
+ method: 'POST',
1586
+ url: '/api/v1/{region}/bean/prices',
1587
+ path: {
1588
+ region: data.region
1589
+ },
1590
+ body: data.requestBody,
1591
+ mediaType: 'application/json',
1592
+ errors: {
1593
+ 404: 'Currency or quoteCurrency commodity not found',
1594
+ 409: 'Price already exists for this currency pair and date'
1595
+ }
1596
+ });
1597
+ }
1598
+
1599
+ /**
1600
+ * List user prices
1601
+ * Returns all price entries for the authenticated user with optional filtering
1602
+ * @param data The data for the request.
1603
+ * @param data.region Region code for tenant context
1604
+ * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
1605
+ * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
1606
+ * @param data.dateFrom Filter prices from this date (ISO 8601 format)
1607
+ * @param data.dateTo Filter prices to this date (ISO 8601 format)
1608
+ * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
1609
+ * @param data.page Page number for pagination (default: 1)
1610
+ * @param data.limit Number of items per page (default: 20, max: 100)
1611
+ * @returns PriceListResponseDto Prices retrieved successfully
1612
+ * @throws ApiError
1613
+ */
1614
+ public static priceControllerFindAll(
1615
+ data: PriceControllerFindAllData
1616
+ ): CancelablePromise<PriceControllerFindAllResponse> {
1617
+ return __request(OpenAPI, {
1618
+ method: 'GET',
1619
+ url: '/api/v1/{region}/bean/prices',
1620
+ path: {
1621
+ region: data.region
1622
+ },
1623
+ query: {
1624
+ currency: data.currency,
1625
+ quoteCurrency: data.quoteCurrency,
1626
+ dateFrom: data.dateFrom,
1627
+ dateTo: data.dateTo,
1628
+ search: data.search,
1629
+ page: data.page,
1630
+ limit: data.limit
1631
+ }
1632
+ });
1633
+ }
1634
+
1635
+ /**
1636
+ * Get price by ID
1637
+ * Returns a single price entry by its ID
1638
+ * @param data The data for the request.
1639
+ * @param data.id Price ID
1640
+ * @param data.region Region code for tenant context
1641
+ * @returns PriceResponseDto Price retrieved successfully
1642
+ * @throws ApiError
1643
+ */
1644
+ public static priceControllerFindOne(
1645
+ data: PriceControllerFindOneData
1646
+ ): CancelablePromise<PriceControllerFindOneResponse> {
1647
+ return __request(OpenAPI, {
1648
+ method: 'GET',
1649
+ url: '/api/v1/{region}/bean/prices/{id}',
1650
+ path: {
1651
+ id: data.id,
1652
+ region: data.region
1653
+ },
1654
+ errors: {
1655
+ 404: 'Price not found'
1656
+ }
1657
+ });
1658
+ }
1659
+
1660
+ /**
1661
+ * Update a price
1662
+ * Updates an existing price entry
1663
+ * @param data The data for the request.
1664
+ * @param data.id Price ID
1665
+ * @param data.region Region code for tenant context
1666
+ * @param data.requestBody
1667
+ * @returns PriceResponseDto Price updated successfully
1668
+ * @throws ApiError
1669
+ */
1670
+ public static priceControllerUpdate(
1671
+ data: PriceControllerUpdateData
1672
+ ): CancelablePromise<PriceControllerUpdateResponse> {
1673
+ return __request(OpenAPI, {
1674
+ method: 'PUT',
1675
+ url: '/api/v1/{region}/bean/prices/{id}',
1676
+ path: {
1677
+ id: data.id,
1678
+ region: data.region
1679
+ },
1680
+ body: data.requestBody,
1681
+ mediaType: 'application/json',
1682
+ errors: {
1683
+ 404: 'Price not found',
1684
+ 409: 'Updated price conflicts with existing price'
1685
+ }
1686
+ });
1687
+ }
1688
+
1689
+ /**
1690
+ * Delete a price
1691
+ * Deletes a price entry (hard delete)
1692
+ * @param data The data for the request.
1693
+ * @param data.id Price ID
1694
+ * @param data.region Region code for tenant context
1695
+ * @returns void Price deleted successfully
1696
+ * @throws ApiError
1697
+ */
1698
+ public static priceControllerDelete(
1699
+ data: PriceControllerDeleteData
1700
+ ): CancelablePromise<PriceControllerDeleteResponse> {
1701
+ return __request(OpenAPI, {
1702
+ method: 'DELETE',
1703
+ url: '/api/v1/{region}/bean/prices/{id}',
1704
+ path: {
1705
+ id: data.id,
1706
+ region: data.region
1707
+ },
1708
+ errors: {
1709
+ 404: 'Price not found'
1710
+ }
1711
+ });
1712
+ }
1713
+
1714
+ /**
1715
+ * Bulk create prices
1716
+ * Creates multiple price entries at once (skips duplicates)
1717
+ * @param data The data for the request.
1718
+ * @param data.region Region code for tenant context
1719
+ * @param data.requestBody
1720
+ * @returns PriceResponseDto Prices created successfully
1721
+ * @throws ApiError
1722
+ */
1723
+ public static priceControllerBulkCreate(
1724
+ data: PriceControllerBulkCreateData
1725
+ ): CancelablePromise<PriceControllerBulkCreateResponse> {
1726
+ return __request(OpenAPI, {
1727
+ method: 'POST',
1728
+ url: '/api/v1/{region}/bean/prices/bulk',
1729
+ path: {
1730
+ region: data.region
1731
+ },
1732
+ body: data.requestBody,
1733
+ mediaType: 'application/json'
1734
+ });
1735
+ }
1736
+ }
1737
+
1450
1738
  export class RecurringRulesService {
1451
1739
  /**
1452
1740
  * Create a new recurring rule
@@ -1877,279 +2165,158 @@ export class RecurringForecastService {
1877
2165
  }
1878
2166
  }
1879
2167
 
1880
- export class BeanTransactionRulesService {
2168
+ export class ReportingService {
1881
2169
  /**
1882
- * Create a new transaction rule (or upsert if upsertByPayee=true)
1883
- * Creates a new rule. If upsertByPayee=true, updates existing rule matching payeeKeywords[0] instead of creating duplicate.
2170
+ * Get portfolio value trends
2171
+ *
2172
+ * Returns time series data of portfolio net worth.
2173
+ *
2174
+ * **Multi-currency Support:**
2175
+ * - `series[].byCurrency` - Currency breakdown for each data point
2176
+ * - `byCurrency` - Separate time series grouped by currency
2177
+ * - `warnings` - Exchange rate warnings if conversion failed
2178
+ *
2179
+ * **Parameters:**
2180
+ * - `period`: Time period (1m, 3m, 6m, 1y)
2181
+ * - `granularity`: Data granularity (day, week, month)
2182
+ *
1884
2183
  * @param data The data for the request.
1885
2184
  * @param data.region Region code for tenant context
1886
- * @param data.requestBody
1887
- * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2185
+ * @param data.period Time period
2186
+ * @param data.granularity Data granularity
2187
+ * @returns PortfolioTrendsResponseDto Trends retrieved successfully
1888
2188
  * @throws ApiError
1889
2189
  */
1890
- public static transactionRuleControllerCreate(
1891
- data: TransactionRuleControllerCreateData
1892
- ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2190
+ public static reportingControllerGetPortfolioTrends(
2191
+ data: ReportingControllerGetPortfolioTrendsData
2192
+ ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
1893
2193
  return __request(OpenAPI, {
1894
- method: 'POST',
1895
- url: '/api/v1/{region}/bean/transaction-rules',
1896
- path: {
1897
- region: data.region
1898
- },
1899
- body: data.requestBody,
1900
- mediaType: 'application/json',
1901
- errors: {
1902
- 400: 'Validation failed',
1903
- 401: 'Unauthorized',
1904
- 409: 'Resource conflict - another process is updating this rule'
1905
- }
1906
- });
1907
- }
1908
-
1909
- /**
1910
- * Get all transaction rules for user
1911
- * @param data The data for the request.
1912
- * @param data.region Region code for tenant context
1913
- * @param data.limit Max results per page (default: 20, max: 100)
1914
- * @param data.offset Pagination offset (default: 0)
1915
- * @param data.enabled Filter by enabled status
1916
- * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
1917
- * @param data.autoApplyEnabled Filter by auto-apply status
1918
- * @returns TransactionRuleListResponseDto List of rules
1919
- * @throws ApiError
1920
- */
1921
- public static transactionRuleControllerList(
1922
- data: TransactionRuleControllerListData
1923
- ): CancelablePromise<TransactionRuleControllerListResponse> {
1924
- return __request(OpenAPI, {
1925
- method: 'GET',
1926
- url: '/api/v1/{region}/bean/transaction-rules',
2194
+ method: 'GET',
2195
+ url: '/api/v1/{region}/reporting/portfolio/trends',
1927
2196
  path: {
1928
2197
  region: data.region
1929
2198
  },
1930
2199
  query: {
1931
- limit: data.limit,
1932
- offset: data.offset,
1933
- enabled: data.enabled,
1934
- learningSource: data.learningSource,
1935
- autoApplyEnabled: data.autoApplyEnabled
1936
- },
1937
- errors: {
1938
- 401: 'Unauthorized'
1939
- }
1940
- });
1941
- }
1942
-
1943
- /**
1944
- * Validate transaction rule configuration
1945
- * @param data The data for the request.
1946
- * @param data.region Region code for tenant context
1947
- * @param data.requestBody
1948
- * @returns ValidateRuleResponseDto Validation result
1949
- * @throws ApiError
1950
- */
1951
- public static transactionRuleControllerValidate(
1952
- data: TransactionRuleControllerValidateData
1953
- ): CancelablePromise<TransactionRuleControllerValidateResponse> {
1954
- return __request(OpenAPI, {
1955
- method: 'POST',
1956
- url: '/api/v1/{region}/bean/transaction-rules/validate',
1957
- path: {
1958
- region: data.region
1959
- },
1960
- body: data.requestBody,
1961
- mediaType: 'application/json',
1962
- errors: {
1963
- 400: 'Validation failed',
1964
- 401: 'Unauthorized'
1965
- }
1966
- });
1967
- }
1968
-
1969
- /**
1970
- * Bulk create transaction rules
1971
- * @param data The data for the request.
1972
- * @param data.region Region code for tenant context
1973
- * @param data.requestBody
1974
- * @returns BulkCreateRulesResponseDto Bulk create completed
1975
- * @throws ApiError
1976
- */
1977
- public static transactionRuleControllerBulkCreate(
1978
- data: TransactionRuleControllerBulkCreateData
1979
- ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
1980
- return __request(OpenAPI, {
1981
- method: 'POST',
1982
- url: '/api/v1/{region}/bean/transaction-rules/bulk',
1983
- path: {
1984
- region: data.region
2200
+ period: data.period,
2201
+ granularity: data.granularity
1985
2202
  },
1986
- body: data.requestBody,
1987
- mediaType: 'application/json',
1988
2203
  errors: {
1989
- 400: 'Invalid bulk create data',
1990
- 401: 'Unauthorized'
2204
+ 401: 'User not authenticated'
1991
2205
  }
1992
2206
  });
1993
2207
  }
1994
2208
 
1995
2209
  /**
1996
- * Export transaction rules
2210
+ * Get cash-flow trends
2211
+ *
2212
+ * Monthly income / expense / netSavings over a fixed N-month window
2213
+ * (current month + N−1 prior). Missing months are zero-filled (flow metric).
2214
+ *
2215
+ * **Parameters:**
2216
+ * - `period`: 1m | 3m | 6m | 1y (default 6m)
2217
+ * - `granularity`: accepted for API symmetry; v1 returns month buckets
2218
+ *
1997
2219
  * @param data The data for the request.
1998
- * @param data.format Export format (currently only JSON supported)
1999
2220
  * @param data.region Region code for tenant context
2000
- * @returns ExportRulesResponseDto Exported rules
2221
+ * @param data.period Time period
2222
+ * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
2223
+ * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
2001
2224
  * @throws ApiError
2002
2225
  */
2003
- public static transactionRuleControllerExport(
2004
- data: TransactionRuleControllerExportData
2005
- ): CancelablePromise<TransactionRuleControllerExportResponse> {
2226
+ public static reportingControllerGetCashFlowTrends(
2227
+ data: ReportingControllerGetCashFlowTrendsData
2228
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
2006
2229
  return __request(OpenAPI, {
2007
2230
  method: 'GET',
2008
- url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2231
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
2009
2232
  path: {
2010
- format: data.format,
2011
2233
  region: data.region
2012
2234
  },
2013
- errors: {
2014
- 400: 'Unsupported format',
2015
- 401: 'Unauthorized'
2016
- }
2017
- });
2018
- }
2019
-
2020
- /**
2021
- * Get transaction rule statistics
2022
- * @param data The data for the request.
2023
- * @param data.period Statistics time period
2024
- * @param data.region Region code for tenant context
2025
- * @returns RuleStatisticsResponseDto Rule statistics
2026
- * @throws ApiError
2027
- */
2028
- public static transactionRuleControllerGetStatistics(
2029
- data: TransactionRuleControllerGetStatisticsData
2030
- ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
2031
- return __request(OpenAPI, {
2032
- method: 'GET',
2033
- url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
2034
- path: {
2235
+ query: {
2035
2236
  period: data.period,
2036
- region: data.region
2037
- },
2038
- errors: {
2039
- 401: 'Unauthorized'
2040
- }
2041
- });
2042
- }
2043
-
2044
- /**
2045
- * Get transaction rule detail
2046
- * @param data The data for the request.
2047
- * @param data.ruleId Rule ID
2048
- * @param data.region Region code for tenant context
2049
- * @returns TransactionRuleResponseDto Rule details
2050
- * @throws ApiError
2051
- */
2052
- public static transactionRuleControllerGetDetail(
2053
- data: TransactionRuleControllerGetDetailData
2054
- ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
2055
- return __request(OpenAPI, {
2056
- method: 'GET',
2057
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2058
- path: {
2059
- ruleId: data.ruleId,
2060
- region: data.region
2237
+ granularity: data.granularity
2061
2238
  },
2062
2239
  errors: {
2063
- 401: 'Unauthorized',
2064
- 403: 'Forbidden - not owner of rule',
2065
- 404: 'Rule not found'
2240
+ 401: 'User not authenticated'
2066
2241
  }
2067
2242
  });
2068
2243
  }
2069
2244
 
2070
2245
  /**
2071
- * Update a transaction rule
2246
+ * Generate portfolio snapshot
2247
+ *
2248
+ * Manually generate a portfolio snapshot for a specific date.
2249
+ *
2250
+ * **Multi-currency Support:**
2251
+ * - Fetches balances grouped by currency
2252
+ * - Uses user's baseCurrency setting for conversion
2253
+ * - Stores exchange rates and warnings
2254
+ *
2255
+ * **Use Cases:**
2256
+ * - Testing snapshot generation
2257
+ * - Force regeneration after data correction
2258
+ * - Initial setup for new users
2259
+ *
2072
2260
  * @param data The data for the request.
2073
- * @param data.ruleId Rule ID to update
2074
2261
  * @param data.region Region code for tenant context
2075
- * @param data.requestBody
2076
- * @returns TransactionRuleResponseDto Rule updated successfully
2262
+ * @param data.requestBody Optional date (defaults to today)
2263
+ * @returns GenerateSnapshotResponse Snapshot generated successfully
2077
2264
  * @throws ApiError
2078
2265
  */
2079
- public static transactionRuleControllerUpdate(
2080
- data: TransactionRuleControllerUpdateData
2081
- ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2266
+ public static reportingControllerGenerateSnapshot(
2267
+ data: ReportingControllerGenerateSnapshotData
2268
+ ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
2082
2269
  return __request(OpenAPI, {
2083
- method: 'PUT',
2084
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2270
+ method: 'POST',
2271
+ url: '/api/v1/{region}/reporting/snapshots/generate',
2085
2272
  path: {
2086
- ruleId: data.ruleId,
2087
2273
  region: data.region
2088
2274
  },
2089
2275
  body: data.requestBody,
2090
2276
  mediaType: 'application/json',
2091
2277
  errors: {
2092
- 400: 'Validation failed',
2093
- 401: 'Unauthorized',
2094
- 403: 'Forbidden - not owner of rule',
2095
- 404: 'Rule not found',
2096
- 409: 'Resource conflict - rule is being modified by another process'
2097
- }
2098
- });
2099
- }
2100
-
2101
- /**
2102
- * Delete a transaction rule
2103
- * @param data The data for the request.
2104
- * @param data.ruleId Rule ID to delete
2105
- * @param data.region Region code for tenant context
2106
- * @returns void Rule deleted successfully
2107
- * @throws ApiError
2108
- */
2109
- public static transactionRuleControllerDelete(
2110
- data: TransactionRuleControllerDeleteData
2111
- ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2112
- return __request(OpenAPI, {
2113
- method: 'DELETE',
2114
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2115
- path: {
2116
- ruleId: data.ruleId,
2117
- region: data.region
2118
- },
2119
- errors: {
2120
- 401: 'Unauthorized',
2121
- 403: 'Forbidden - not owner of rule',
2122
- 404: 'Rule not found',
2123
- 409: 'Resource conflict - rule is being modified by another process'
2278
+ 400: 'Invalid date format',
2279
+ 401: 'User not authenticated'
2124
2280
  }
2125
2281
  });
2126
2282
  }
2127
2283
 
2128
2284
  /**
2129
- * Test rule matching
2285
+ * Backfill portfolio snapshots
2286
+ *
2287
+ * Generate snapshots for a date range (historical data backfill).
2288
+ *
2289
+ * **Multi-currency Support:**
2290
+ * - Each snapshot includes multi-currency data
2291
+ * - Uses exchange rates available at generation time
2292
+ * - Warnings stored for missing exchange rates
2293
+ *
2294
+ * **Best Practices:**
2295
+ * - Use for initial setup after account configuration
2296
+ * - Run during low-traffic periods for large date ranges
2297
+ * - Existing snapshots are skipped (not regenerated)
2298
+ *
2130
2299
  * @param data The data for the request.
2131
- * @param data.ruleId Rule ID to test
2132
2300
  * @param data.region Region code for tenant context
2133
2301
  * @param data.requestBody
2134
- * @returns TestRuleResponseDto Test result
2302
+ * @returns BackfillSnapshotsResponse Backfill completed successfully
2135
2303
  * @throws ApiError
2136
2304
  */
2137
- public static transactionRuleControllerTest(
2138
- data: TransactionRuleControllerTestData
2139
- ): CancelablePromise<TransactionRuleControllerTestResponse> {
2305
+ public static reportingControllerBackfillSnapshots(
2306
+ data: ReportingControllerBackfillSnapshotsData
2307
+ ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
2140
2308
  return __request(OpenAPI, {
2141
2309
  method: 'POST',
2142
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2310
+ url: '/api/v1/{region}/reporting/snapshots/backfill',
2143
2311
  path: {
2144
- ruleId: data.ruleId,
2145
2312
  region: data.region
2146
2313
  },
2147
2314
  body: data.requestBody,
2148
2315
  mediaType: 'application/json',
2149
2316
  errors: {
2150
- 401: 'Unauthorized',
2151
- 403: 'Forbidden - not owner of rule',
2152
- 404: 'Rule not found'
2317
+ 400: 'Invalid date format or range',
2318
+ 401: 'User not authenticated',
2319
+ 409: 'Backfill already in progress for this user'
2153
2320
  }
2154
2321
  });
2155
2322
  }
@@ -2201,7 +2368,7 @@ export class UsersService {
2201
2368
  * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
2202
2369
  * @param data The data for the request.
2203
2370
  * @param data.requestBody
2204
- * @returns unknown User created successfully
2371
+ * @returns SignupResponseDto User created successfully
2205
2372
  * @throws ApiError
2206
2373
  */
2207
2374
  public static userControllerSignupUser(
@@ -2410,11 +2577,597 @@ export class PropertiesService {
2410
2577
  }
2411
2578
  }
2412
2579
 
2413
- export class BeanExportService {
2580
+ export class BeanTransactionRulesService {
2414
2581
  /**
2415
- * Export Beancount ledger as ZIP
2416
- * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
2417
- * @returns unknown
2582
+ * Create a new transaction rule (or upsert if upsertByPayee=true)
2583
+ * Creates a new rule. If upsertByPayee=true, updates existing rule matching payeeKeywords[0] instead of creating duplicate.
2584
+ * @param data The data for the request.
2585
+ * @param data.region Region code for tenant context
2586
+ * @param data.requestBody
2587
+ * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2588
+ * @throws ApiError
2589
+ */
2590
+ public static transactionRuleControllerCreate(
2591
+ data: TransactionRuleControllerCreateData
2592
+ ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2593
+ return __request(OpenAPI, {
2594
+ method: 'POST',
2595
+ url: '/api/v1/{region}/bean/transaction-rules',
2596
+ path: {
2597
+ region: data.region
2598
+ },
2599
+ body: data.requestBody,
2600
+ mediaType: 'application/json',
2601
+ errors: {
2602
+ 400: 'Validation failed',
2603
+ 401: 'Unauthorized',
2604
+ 409: 'Resource conflict - another process is updating this rule'
2605
+ }
2606
+ });
2607
+ }
2608
+
2609
+ /**
2610
+ * Get all transaction rules for user
2611
+ * @param data The data for the request.
2612
+ * @param data.region Region code for tenant context
2613
+ * @param data.limit Max results per page (default: 20, max: 100)
2614
+ * @param data.offset Pagination offset (default: 0)
2615
+ * @param data.enabled Filter by enabled status
2616
+ * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
2617
+ * @param data.autoApplyEnabled Filter by auto-apply status
2618
+ * @returns TransactionRuleListResponseDto List of rules
2619
+ * @throws ApiError
2620
+ */
2621
+ public static transactionRuleControllerList(
2622
+ data: TransactionRuleControllerListData
2623
+ ): CancelablePromise<TransactionRuleControllerListResponse> {
2624
+ return __request(OpenAPI, {
2625
+ method: 'GET',
2626
+ url: '/api/v1/{region}/bean/transaction-rules',
2627
+ path: {
2628
+ region: data.region
2629
+ },
2630
+ query: {
2631
+ limit: data.limit,
2632
+ offset: data.offset,
2633
+ enabled: data.enabled,
2634
+ learningSource: data.learningSource,
2635
+ autoApplyEnabled: data.autoApplyEnabled
2636
+ },
2637
+ errors: {
2638
+ 401: 'Unauthorized'
2639
+ }
2640
+ });
2641
+ }
2642
+
2643
+ /**
2644
+ * Validate transaction rule configuration
2645
+ * @param data The data for the request.
2646
+ * @param data.region Region code for tenant context
2647
+ * @param data.requestBody
2648
+ * @returns ValidateRuleResponseDto Validation result
2649
+ * @throws ApiError
2650
+ */
2651
+ public static transactionRuleControllerValidate(
2652
+ data: TransactionRuleControllerValidateData
2653
+ ): CancelablePromise<TransactionRuleControllerValidateResponse> {
2654
+ return __request(OpenAPI, {
2655
+ method: 'POST',
2656
+ url: '/api/v1/{region}/bean/transaction-rules/validate',
2657
+ path: {
2658
+ region: data.region
2659
+ },
2660
+ body: data.requestBody,
2661
+ mediaType: 'application/json',
2662
+ errors: {
2663
+ 400: 'Validation failed',
2664
+ 401: 'Unauthorized'
2665
+ }
2666
+ });
2667
+ }
2668
+
2669
+ /**
2670
+ * Bulk create transaction rules
2671
+ * @param data The data for the request.
2672
+ * @param data.region Region code for tenant context
2673
+ * @param data.requestBody
2674
+ * @returns BulkCreateRulesResponseDto Bulk create completed
2675
+ * @throws ApiError
2676
+ */
2677
+ public static transactionRuleControllerBulkCreate(
2678
+ data: TransactionRuleControllerBulkCreateData
2679
+ ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
2680
+ return __request(OpenAPI, {
2681
+ method: 'POST',
2682
+ url: '/api/v1/{region}/bean/transaction-rules/bulk',
2683
+ path: {
2684
+ region: data.region
2685
+ },
2686
+ body: data.requestBody,
2687
+ mediaType: 'application/json',
2688
+ errors: {
2689
+ 400: 'Invalid bulk create data',
2690
+ 401: 'Unauthorized'
2691
+ }
2692
+ });
2693
+ }
2694
+
2695
+ /**
2696
+ * Export transaction rules
2697
+ * @param data The data for the request.
2698
+ * @param data.format Export format (currently only JSON supported)
2699
+ * @param data.region Region code for tenant context
2700
+ * @returns ExportRulesResponseDto Exported rules
2701
+ * @throws ApiError
2702
+ */
2703
+ public static transactionRuleControllerExport(
2704
+ data: TransactionRuleControllerExportData
2705
+ ): CancelablePromise<TransactionRuleControllerExportResponse> {
2706
+ return __request(OpenAPI, {
2707
+ method: 'GET',
2708
+ url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2709
+ path: {
2710
+ format: data.format,
2711
+ region: data.region
2712
+ },
2713
+ errors: {
2714
+ 400: 'Unsupported format',
2715
+ 401: 'Unauthorized'
2716
+ }
2717
+ });
2718
+ }
2719
+
2720
+ /**
2721
+ * Get transaction rule statistics
2722
+ * @param data The data for the request.
2723
+ * @param data.period Statistics time period
2724
+ * @param data.region Region code for tenant context
2725
+ * @returns RuleStatisticsResponseDto Rule statistics
2726
+ * @throws ApiError
2727
+ */
2728
+ public static transactionRuleControllerGetStatistics(
2729
+ data: TransactionRuleControllerGetStatisticsData
2730
+ ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
2731
+ return __request(OpenAPI, {
2732
+ method: 'GET',
2733
+ url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
2734
+ path: {
2735
+ period: data.period,
2736
+ region: data.region
2737
+ },
2738
+ errors: {
2739
+ 401: 'Unauthorized'
2740
+ }
2741
+ });
2742
+ }
2743
+
2744
+ /**
2745
+ * Get transaction rule detail
2746
+ * @param data The data for the request.
2747
+ * @param data.ruleId Rule ID
2748
+ * @param data.region Region code for tenant context
2749
+ * @returns TransactionRuleResponseDto Rule details
2750
+ * @throws ApiError
2751
+ */
2752
+ public static transactionRuleControllerGetDetail(
2753
+ data: TransactionRuleControllerGetDetailData
2754
+ ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
2755
+ return __request(OpenAPI, {
2756
+ method: 'GET',
2757
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2758
+ path: {
2759
+ ruleId: data.ruleId,
2760
+ region: data.region
2761
+ },
2762
+ errors: {
2763
+ 401: 'Unauthorized',
2764
+ 403: 'Forbidden - not owner of rule',
2765
+ 404: 'Rule not found'
2766
+ }
2767
+ });
2768
+ }
2769
+
2770
+ /**
2771
+ * Update a transaction rule
2772
+ * @param data The data for the request.
2773
+ * @param data.ruleId Rule ID to update
2774
+ * @param data.region Region code for tenant context
2775
+ * @param data.requestBody
2776
+ * @returns TransactionRuleResponseDto Rule updated successfully
2777
+ * @throws ApiError
2778
+ */
2779
+ public static transactionRuleControllerUpdate(
2780
+ data: TransactionRuleControllerUpdateData
2781
+ ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2782
+ return __request(OpenAPI, {
2783
+ method: 'PUT',
2784
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2785
+ path: {
2786
+ ruleId: data.ruleId,
2787
+ region: data.region
2788
+ },
2789
+ body: data.requestBody,
2790
+ mediaType: 'application/json',
2791
+ errors: {
2792
+ 400: 'Validation failed',
2793
+ 401: 'Unauthorized',
2794
+ 403: 'Forbidden - not owner of rule',
2795
+ 404: 'Rule not found',
2796
+ 409: 'Resource conflict - rule is being modified by another process'
2797
+ }
2798
+ });
2799
+ }
2800
+
2801
+ /**
2802
+ * Delete a transaction rule
2803
+ * @param data The data for the request.
2804
+ * @param data.ruleId Rule ID to delete
2805
+ * @param data.region Region code for tenant context
2806
+ * @returns void Rule deleted successfully
2807
+ * @throws ApiError
2808
+ */
2809
+ public static transactionRuleControllerDelete(
2810
+ data: TransactionRuleControllerDeleteData
2811
+ ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2812
+ return __request(OpenAPI, {
2813
+ method: 'DELETE',
2814
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2815
+ path: {
2816
+ ruleId: data.ruleId,
2817
+ region: data.region
2818
+ },
2819
+ errors: {
2820
+ 401: 'Unauthorized',
2821
+ 403: 'Forbidden - not owner of rule',
2822
+ 404: 'Rule not found',
2823
+ 409: 'Resource conflict - rule is being modified by another process'
2824
+ }
2825
+ });
2826
+ }
2827
+
2828
+ /**
2829
+ * Test rule matching
2830
+ * @param data The data for the request.
2831
+ * @param data.ruleId Rule ID to test
2832
+ * @param data.region Region code for tenant context
2833
+ * @param data.requestBody
2834
+ * @returns TestRuleResponseDto Test result
2835
+ * @throws ApiError
2836
+ */
2837
+ public static transactionRuleControllerTest(
2838
+ data: TransactionRuleControllerTestData
2839
+ ): CancelablePromise<TransactionRuleControllerTestResponse> {
2840
+ return __request(OpenAPI, {
2841
+ method: 'POST',
2842
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2843
+ path: {
2844
+ ruleId: data.ruleId,
2845
+ region: data.region
2846
+ },
2847
+ body: data.requestBody,
2848
+ mediaType: 'application/json',
2849
+ errors: {
2850
+ 401: 'Unauthorized',
2851
+ 403: 'Forbidden - not owner of rule',
2852
+ 404: 'Rule not found'
2853
+ }
2854
+ });
2855
+ }
2856
+ }
2857
+
2858
+ export class LifeEventsService {
2859
+ /**
2860
+ * Create a new life event
2861
+ * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
2862
+ * @param data The data for the request.
2863
+ * @param data.region Region code for tenant context (decorative for life events)
2864
+ * @param data.requestBody
2865
+ * @returns EventResponseDto Life event created successfully
2866
+ * @throws ApiError
2867
+ */
2868
+ public static eventControllerCreate(
2869
+ data: EventControllerCreateData
2870
+ ): CancelablePromise<EventControllerCreateResponse> {
2871
+ return __request(OpenAPI, {
2872
+ method: 'POST',
2873
+ url: '/api/v1/{region}/bean/events',
2874
+ path: {
2875
+ region: data.region
2876
+ },
2877
+ body: data.requestBody,
2878
+ mediaType: 'application/json',
2879
+ errors: {
2880
+ 409: 'Life event already exists for this (userId, type, date) combination'
2881
+ }
2882
+ });
2883
+ }
2884
+
2885
+ /**
2886
+ * List user life events
2887
+ * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2888
+ * @param data The data for the request.
2889
+ * @param data.region Region code for tenant context (decorative for life events)
2890
+ * @param data.type Filter by life event type (exact match)
2891
+ * @param data.q Search term for description (case-insensitive partial match)
2892
+ * @param data.from Filter life events from this date (ISO 8601 format)
2893
+ * @param data.to Filter life events to this date (ISO 8601 format)
2894
+ * @param data.page Page number for pagination (default: 1)
2895
+ * @param data.limit Number of items per page (default: 20, max: 100)
2896
+ * @returns EventListResponseDto Life events retrieved successfully
2897
+ * @throws ApiError
2898
+ */
2899
+ public static eventControllerFindAll(
2900
+ data: EventControllerFindAllData
2901
+ ): CancelablePromise<EventControllerFindAllResponse> {
2902
+ return __request(OpenAPI, {
2903
+ method: 'GET',
2904
+ url: '/api/v1/{region}/bean/events',
2905
+ path: {
2906
+ region: data.region
2907
+ },
2908
+ query: {
2909
+ type: data.type,
2910
+ q: data.q,
2911
+ from: data.from,
2912
+ to: data.to,
2913
+ page: data.page,
2914
+ limit: data.limit
2915
+ }
2916
+ });
2917
+ }
2918
+
2919
+ /**
2920
+ * Get life event by ID
2921
+ * Returns a single life event by its ID. Returns ETag header.
2922
+ * @param data The data for the request.
2923
+ * @param data.id Life event ID
2924
+ * @param data.region Region code for tenant context (decorative for life events)
2925
+ * @returns EventResponseDto Life event retrieved successfully
2926
+ * @throws ApiError
2927
+ */
2928
+ public static eventControllerFindOne(
2929
+ data: EventControllerFindOneData
2930
+ ): CancelablePromise<EventControllerFindOneResponse> {
2931
+ return __request(OpenAPI, {
2932
+ method: 'GET',
2933
+ url: '/api/v1/{region}/bean/events/{id}',
2934
+ path: {
2935
+ id: data.id,
2936
+ region: data.region
2937
+ },
2938
+ errors: {
2939
+ 404: 'Life event not found'
2940
+ }
2941
+ });
2942
+ }
2943
+
2944
+ /**
2945
+ * Update a life event
2946
+ * Updates an existing life event. If If-Match header is provided, performs optimistic concurrency check; mismatched updatedAt returns 412.
2947
+ * @param data The data for the request.
2948
+ * @param data.id Life event ID
2949
+ * @param data.region Region code for tenant context (decorative for life events)
2950
+ * @param data.requestBody
2951
+ * @returns EventResponseDto Life event updated successfully
2952
+ * @throws ApiError
2953
+ */
2954
+ public static eventControllerUpdate(
2955
+ data: EventControllerUpdateData
2956
+ ): CancelablePromise<EventControllerUpdateResponse> {
2957
+ return __request(OpenAPI, {
2958
+ method: 'PUT',
2959
+ url: '/api/v1/{region}/bean/events/{id}',
2960
+ path: {
2961
+ id: data.id,
2962
+ region: data.region
2963
+ },
2964
+ body: data.requestBody,
2965
+ mediaType: 'application/json',
2966
+ errors: {
2967
+ 400: 'If-Match header is not a valid ISO 8601 date',
2968
+ 404: 'Life event not found',
2969
+ 409: 'Updated event conflicts with an existing (userId, type, date) combination',
2970
+ 412: 'If-Match precondition failed (updatedAt mismatch)'
2971
+ }
2972
+ });
2973
+ }
2974
+
2975
+ /**
2976
+ * Delete a life event
2977
+ * Deletes a life event entry (hard delete). Returns 204.
2978
+ * @param data The data for the request.
2979
+ * @param data.id Life event ID
2980
+ * @param data.region Region code for tenant context (decorative for life events)
2981
+ * @returns void Life event deleted successfully
2982
+ * @throws ApiError
2983
+ */
2984
+ public static eventControllerDelete(
2985
+ data: EventControllerDeleteData
2986
+ ): CancelablePromise<EventControllerDeleteResponse> {
2987
+ return __request(OpenAPI, {
2988
+ method: 'DELETE',
2989
+ url: '/api/v1/{region}/bean/events/{id}',
2990
+ path: {
2991
+ id: data.id,
2992
+ region: data.region
2993
+ },
2994
+ errors: {
2995
+ 404: 'Life event not found'
2996
+ }
2997
+ });
2998
+ }
2999
+
3000
+ /**
3001
+ * Slice time-series by a life event (Phase 79)
3002
+ * Returns aggregated time-series for postings matching accountPattern within the half-open date range of the given life event.
3003
+ * @param data The data for the request.
3004
+ * @param data.id Life event ID
3005
+ * @param data.accountPattern
3006
+ * @param data.granularity
3007
+ * @param data.region Region code for tenant context (decorative for life events)
3008
+ * @returns unknown Time-series sliced by the life event range
3009
+ * @throws ApiError
3010
+ */
3011
+ public static eventControllerGetSlice(
3012
+ data: EventControllerGetSliceData
3013
+ ): CancelablePromise<EventControllerGetSliceResponse> {
3014
+ return __request(OpenAPI, {
3015
+ method: 'GET',
3016
+ url: '/api/v1/{region}/bean/events/{id}/slice',
3017
+ path: {
3018
+ id: data.id,
3019
+ region: data.region
3020
+ },
3021
+ query: {
3022
+ accountPattern: data.accountPattern,
3023
+ granularity: data.granularity
3024
+ },
3025
+ errors: {
3026
+ 400: 'accountPattern query param is empty',
3027
+ 404: 'Life event not found'
3028
+ }
3029
+ });
3030
+ }
3031
+ }
3032
+
3033
+ export class OnboardingService {
3034
+ /**
3035
+ * Bootstrap core accounts + register asset accounts with opening balances (ADR-0113)
3036
+ * @param data The data for the request.
3037
+ * @param data.region Region code for tenant context
3038
+ * @param data.requestBody
3039
+ * @returns unknown Onboarding bootstrap result.
3040
+ * @throws ApiError
3041
+ */
3042
+ public static onboardingControllerBootstrap(
3043
+ data: OnboardingControllerBootstrapData
3044
+ ): CancelablePromise<OnboardingControllerBootstrapResponse> {
3045
+ return __request(OpenAPI, {
3046
+ method: 'POST',
3047
+ url: '/api/v1/{region}/bean/onboarding',
3048
+ path: {
3049
+ region: data.region
3050
+ },
3051
+ body: data.requestBody,
3052
+ mediaType: 'application/json',
3053
+ errors: {
3054
+ 422: 'Invalid region/account path/duplicate paths.'
3055
+ }
3056
+ });
3057
+ }
3058
+ }
3059
+
3060
+ export class BalanceReconciliationService {
3061
+ /**
3062
+ * Preview reconciliation (book vs actual)
3063
+ * Computes book balance, diff, Beancount-inferred tolerance, and suggested action without persisting.
3064
+ * @param data The data for the request.
3065
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3066
+ * @param data.requestBody
3067
+ * @returns ReconciliationComputeResultDto Reconciliation preview
3068
+ * @throws ApiError
3069
+ */
3070
+ public static reconciliationControllerCompute(
3071
+ data: ReconciliationControllerComputeData
3072
+ ): CancelablePromise<ReconciliationControllerComputeResponse> {
3073
+ return __request(OpenAPI, {
3074
+ method: 'POST',
3075
+ url: '/api/v1/{region}/bean/reconciliations',
3076
+ path: {
3077
+ region: data.region
3078
+ },
3079
+ body: data.requestBody,
3080
+ mediaType: 'application/json',
3081
+ errors: {
3082
+ 404: 'Account not found'
3083
+ }
3084
+ });
3085
+ }
3086
+
3087
+ /**
3088
+ * Record a balance assertion
3089
+ * Persists the reconciliation as a BeanBalance assertion (amount = actual, diffAmount = book − actual). Re-reconciling the same day/currency upserts.
3090
+ * @param data The data for the request.
3091
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3092
+ * @param data.requestBody
3093
+ * @returns ReconciliationRecordDto Balance assertion recorded
3094
+ * @throws ApiError
3095
+ */
3096
+ public static reconciliationControllerAssert(
3097
+ data: ReconciliationControllerAssertData
3098
+ ): CancelablePromise<ReconciliationControllerAssertResponse> {
3099
+ return __request(OpenAPI, {
3100
+ method: 'POST',
3101
+ url: '/api/v1/{region}/bean/reconciliations/assert',
3102
+ path: {
3103
+ region: data.region
3104
+ },
3105
+ body: data.requestBody,
3106
+ mediaType: 'application/json',
3107
+ errors: {
3108
+ 404: 'Account not found'
3109
+ }
3110
+ });
3111
+ }
3112
+
3113
+ /**
3114
+ * Generate a pad adjusting entry
3115
+ * 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.
3116
+ * @param data The data for the request.
3117
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3118
+ * @param data.requestBody
3119
+ * @returns PadResultDto Pad adjusting entry generated
3120
+ * @throws ApiError
3121
+ */
3122
+ public static reconciliationControllerPad(
3123
+ data: ReconciliationControllerPadData
3124
+ ): CancelablePromise<ReconciliationControllerPadResponse> {
3125
+ return __request(OpenAPI, {
3126
+ method: 'POST',
3127
+ url: '/api/v1/{region}/bean/reconciliations/pad',
3128
+ path: {
3129
+ region: data.region
3130
+ },
3131
+ body: data.requestBody,
3132
+ mediaType: 'application/json',
3133
+ errors: {
3134
+ 400: 'Book already within tolerance — no pad needed',
3135
+ 404: 'Account not found'
3136
+ }
3137
+ });
3138
+ }
3139
+
3140
+ /**
3141
+ * List reconciliation history for an account
3142
+ * Returns recorded balance assertions (most recent first). The latest drives the account-detail "Last <date>" badge.
3143
+ * @param data The data for the request.
3144
+ * @param data.accountId BeanAccount id
3145
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3146
+ * @returns ReconciliationRecordDto Reconciliation history
3147
+ * @throws ApiError
3148
+ */
3149
+ public static reconciliationControllerHistory(
3150
+ data: ReconciliationControllerHistoryData
3151
+ ): CancelablePromise<ReconciliationControllerHistoryResponse> {
3152
+ return __request(OpenAPI, {
3153
+ method: 'GET',
3154
+ url: '/api/v1/{region}/bean/accounts/{accountId}/reconciliations',
3155
+ path: {
3156
+ accountId: data.accountId,
3157
+ region: data.region
3158
+ },
3159
+ errors: {
3160
+ 404: 'Account not found'
3161
+ }
3162
+ });
3163
+ }
3164
+ }
3165
+
3166
+ export class BeanExportService {
3167
+ /**
3168
+ * Export Beancount ledger as ZIP
3169
+ * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
3170
+ * @returns unknown
2418
3171
  * @throws ApiError
2419
3172
  */
2420
3173
  public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
@@ -2588,243 +3341,271 @@ export class BeanImportService {
2588
3341
  }
2589
3342
  }
2590
3343
 
2591
- export class BeanPlatformsService {
2592
- /**
2593
- * Get all platforms with statistics
2594
- * @returns unknown List of platforms with binding and account counts
2595
- * @throws ApiError
2596
- */
2597
- public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
2598
- return __request(OpenAPI, {
2599
- method: 'GET',
2600
- url: '/api/v1/bean/platforms'
2601
- });
2602
- }
2603
-
3344
+ export class ProviderSyncService {
2604
3345
  /**
2605
- * Create a new platform
3346
+ * Sync transactions from financial data provider
3347
+ *
3348
+ * Accepts raw transactions from external financial data providers, transforms them to Beancount format, and processes them through the ingestion pipeline.
3349
+ *
3350
+ * **Supported Providers:**
3351
+ * - **plaid**: Plaid API (US, Canada, Europe)
3352
+ * - **teller**: Teller API (US)
3353
+ * - **truelayer**: TrueLayer Open Banking (UK, Europe)
3354
+ * - **gocardless**: GoCardless Bank Account Data (Europe)
3355
+ * - **simplefin**: SimpleFIN (Self-hosted)
3356
+ * - **yodlee**: Yodlee (Global)
3357
+ * - **beancount-direct**: Beancount format transactions
3358
+ * - **parsed-bill**: Client-side parsed bill transactions
3359
+ *
3360
+ * **Processing Flow:**
3361
+ * 1. Transform raw data via provider adapter
3362
+ * 2. Validate transaction format
3363
+ * 3. Deduplicate using originalId
3364
+ * 4. Classify using rule engine
3365
+ * 5. Route low-confidence to Review Center
3366
+ * 6. Persist validated transactions
3367
+ *
2606
3368
  * @param data The data for the request.
3369
+ * @param data.providerName Provider name
3370
+ * @param data.region Region code for tenant context
2607
3371
  * @param data.requestBody
2608
- * @returns unknown Platform created successfully
3372
+ * @returns ProviderSyncResponseDto Sync completed successfully
2609
3373
  * @throws ApiError
2610
3374
  */
2611
- public static platformControllerCreate(
2612
- data: PlatformControllerCreateData
2613
- ): CancelablePromise<PlatformControllerCreateResponse> {
3375
+ public static providerSyncControllerSync(
3376
+ data: ProviderSyncControllerSyncData
3377
+ ): CancelablePromise<ProviderSyncControllerSyncResponse> {
2614
3378
  return __request(OpenAPI, {
2615
3379
  method: 'POST',
2616
- url: '/api/v1/bean/platforms',
3380
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3381
+ path: {
3382
+ providerName: data.providerName,
3383
+ region: data.region
3384
+ },
2617
3385
  body: data.requestBody,
2618
3386
  mediaType: 'application/json',
2619
3387
  errors: {
2620
- 409: 'Platform already exists'
3388
+ 400: 'Invalid request data',
3389
+ 401: 'Missing or invalid authentication',
3390
+ 404: 'Provider not supported'
2621
3391
  }
2622
3392
  });
2623
3393
  }
2624
3394
 
2625
3395
  /**
2626
- * Get platform list for current user
2627
- * @returns unknown List of platforms with user binding status
3396
+ * Get supported providers
3397
+ * Returns a list of all providers supported by the sync endpoint.
3398
+ * @param data The data for the request.
3399
+ * @param data.region Region code for tenant context
3400
+ * @returns SupportedProvidersResponseDto List of supported providers
2628
3401
  * @throws ApiError
2629
3402
  */
2630
- public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3403
+ public static providerSyncControllerGetSupportedProviders(
3404
+ data: ProviderSyncControllerGetSupportedProvidersData
3405
+ ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
2631
3406
  return __request(OpenAPI, {
2632
3407
  method: 'GET',
2633
- url: '/api/v1/bean/platforms/list'
3408
+ url: '/api/v1/{region}/bean/import/provider/supported',
3409
+ path: {
3410
+ region: data.region
3411
+ },
3412
+ errors: {
3413
+ 401: 'Missing or invalid authentication'
3414
+ }
2634
3415
  });
2635
3416
  }
2636
3417
 
2637
3418
  /**
2638
- * Match platforms by name or alias
3419
+ * Check if provider is supported
3420
+ * Returns whether a specific provider is supported.
2639
3421
  * @param data The data for the request.
2640
- * @param data.q Search query — Chinese name, English name, or abbreviation
2641
- * @param data.region Region code for category override lookup
2642
- * @returns unknown List of matching platforms with suggested segment names
3422
+ * @param data.providerName Provider name to check
3423
+ * @param data.region Region code for tenant context
3424
+ * @returns unknown Provider support status
2643
3425
  * @throws ApiError
2644
3426
  */
2645
- public static platformControllerMatchPlatforms(
2646
- data: PlatformControllerMatchPlatformsData
2647
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3427
+ public static providerSyncControllerIsProviderSupported(
3428
+ data: ProviderSyncControllerIsProviderSupportedData
3429
+ ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
2648
3430
  return __request(OpenAPI, {
2649
3431
  method: 'GET',
2650
- url: '/api/v1/bean/platforms/match',
2651
- query: {
2652
- q: data.q,
3432
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3433
+ path: {
3434
+ providerName: data.providerName,
2653
3435
  region: data.region
3436
+ },
3437
+ errors: {
3438
+ 401: 'Missing or invalid authentication'
2654
3439
  }
2655
3440
  });
2656
3441
  }
3442
+ }
2657
3443
 
3444
+ export class ExternalAccountLinksService {
2658
3445
  /**
2659
- * Update a platform
3446
+ * Create an external account → BeanAccount mapping (ADR-0113)
2660
3447
  * @param data The data for the request.
2661
- * @param data.id Platform ID
3448
+ * @param data.region Region code for tenant context
2662
3449
  * @param data.requestBody
2663
- * @returns unknown Platform updated successfully
3450
+ * @returns ExternalAccountLinkResponseDto Link created.
2664
3451
  * @throws ApiError
2665
3452
  */
2666
- public static platformControllerUpdate(
2667
- data: PlatformControllerUpdateData
2668
- ): CancelablePromise<PlatformControllerUpdateResponse> {
3453
+ public static externalAccountLinkControllerCreate(
3454
+ data: ExternalAccountLinkControllerCreateData
3455
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
2669
3456
  return __request(OpenAPI, {
2670
- method: 'PUT',
2671
- url: '/api/v1/bean/platforms/{id}',
3457
+ method: 'POST',
3458
+ url: '/api/v1/{region}/bean/external-account-links',
2672
3459
  path: {
2673
- id: data.id
3460
+ region: data.region
2674
3461
  },
2675
3462
  body: data.requestBody,
2676
3463
  mediaType: 'application/json',
2677
3464
  errors: {
2678
- 404: 'Platform not found'
3465
+ 422: 'beanAccountId not owned, or an active link already exists.'
2679
3466
  }
2680
3467
  });
2681
3468
  }
2682
3469
 
2683
3470
  /**
2684
- * Delete a platform
3471
+ * List the user's active external account links
2685
3472
  * @param data The data for the request.
2686
- * @param data.id Platform ID
2687
- * @returns void Platform deleted successfully
3473
+ * @param data.provider
3474
+ * @param data.region Region code for tenant context
3475
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
2688
3476
  * @throws ApiError
2689
3477
  */
2690
- public static platformControllerDelete(
2691
- data: PlatformControllerDeleteData
2692
- ): CancelablePromise<PlatformControllerDeleteResponse> {
3478
+ public static externalAccountLinkControllerFindAll(
3479
+ data: ExternalAccountLinkControllerFindAllData
3480
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
2693
3481
  return __request(OpenAPI, {
2694
- method: 'DELETE',
2695
- url: '/api/v1/bean/platforms/{id}',
3482
+ method: 'GET',
3483
+ url: '/api/v1/{region}/bean/external-account-links',
2696
3484
  path: {
2697
- id: data.id
3485
+ region: data.region
2698
3486
  },
2699
- errors: {
2700
- 404: 'Platform not found'
3487
+ query: {
3488
+ provider: data.provider
2701
3489
  }
2702
3490
  });
2703
3491
  }
2704
- }
2705
3492
 
2706
- export class ProviderSyncService {
2707
3493
  /**
2708
- * Sync transactions from financial data provider
2709
- *
2710
- * Accepts raw transactions from external financial data providers, transforms them to Beancount format, and processes them through the ingestion pipeline.
2711
- *
2712
- * **Supported Providers:**
2713
- * - **plaid**: Plaid API (US, Canada, Europe)
2714
- * - **teller**: Teller API (US)
2715
- * - **truelayer**: TrueLayer Open Banking (UK, Europe)
2716
- * - **gocardless**: GoCardless Bank Account Data (Europe)
2717
- * - **simplefin**: SimpleFIN (Self-hosted)
2718
- * - **yodlee**: Yodlee (Global)
2719
- * - **beancount-direct**: Beancount format transactions
2720
- * - **parsed-bill**: Client-side parsed bill transactions
2721
- *
2722
- * **Processing Flow:**
2723
- * 1. Transform raw data via provider adapter
2724
- * 2. Validate transaction format
2725
- * 3. Deduplicate using originalId
2726
- * 4. Classify using rule engine
2727
- * 5. Route low-confidence to Review Center
2728
- * 6. Persist validated transactions
2729
- *
3494
+ * Get a single external account link
2730
3495
  * @param data The data for the request.
2731
- * @param data.providerName Provider name
2732
- * @param data.region Region code
2733
- * @param data.requestBody
2734
- * @returns ProviderSyncResponseDto Sync completed successfully
3496
+ * @param data.id
3497
+ * @param data.region Region code for tenant context
3498
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
2735
3499
  * @throws ApiError
2736
3500
  */
2737
- public static providerSyncControllerSync(
2738
- data: ProviderSyncControllerSyncData
2739
- ): CancelablePromise<ProviderSyncControllerSyncResponse> {
3501
+ public static externalAccountLinkControllerFindOne(
3502
+ data: ExternalAccountLinkControllerFindOneData
3503
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
2740
3504
  return __request(OpenAPI, {
2741
- method: 'POST',
2742
- url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3505
+ method: 'GET',
3506
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
2743
3507
  path: {
2744
- providerName: data.providerName,
3508
+ id: data.id,
2745
3509
  region: data.region
2746
3510
  },
2747
- body: data.requestBody,
2748
- mediaType: 'application/json',
2749
3511
  errors: {
2750
- 400: 'Invalid request data',
2751
- 401: 'Missing or invalid authentication',
2752
- 404: 'Provider not supported'
3512
+ 422: 'Link not found or not owned by the user.'
2753
3513
  }
2754
3514
  });
2755
3515
  }
2756
3516
 
2757
3517
  /**
2758
- * Get supported providers
2759
- * Returns a list of all providers supported by the sync endpoint.
3518
+ * Soft-delete (disconnect) an external account link
2760
3519
  * @param data The data for the request.
3520
+ * @param data.id
2761
3521
  * @param data.region Region code for tenant context
2762
- * @returns SupportedProvidersResponseDto List of supported providers
3522
+ * @returns void Link soft-deleted; historical transactions are unaffected.
2763
3523
  * @throws ApiError
2764
3524
  */
2765
- public static providerSyncControllerGetSupportedProviders(
2766
- data: ProviderSyncControllerGetSupportedProvidersData
2767
- ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
3525
+ public static externalAccountLinkControllerRemove(
3526
+ data: ExternalAccountLinkControllerRemoveData
3527
+ ): CancelablePromise<ExternalAccountLinkControllerRemoveResponse> {
2768
3528
  return __request(OpenAPI, {
2769
- method: 'GET',
2770
- url: '/api/v1/{region}/bean/import/provider/supported',
3529
+ method: 'DELETE',
3530
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3531
+ path: {
3532
+ id: data.id,
3533
+ region: data.region
3534
+ }
3535
+ });
3536
+ }
3537
+ }
3538
+
3539
+ export class ImportTelemetryService {
3540
+ /**
3541
+ * Receive anonymous parser failure telemetry
3542
+ * @param data The data for the request.
3543
+ * @param data.region Region code for tenant context
3544
+ * @param data.requestBody
3545
+ * @returns unknown Telemetry report received
3546
+ * @throws ApiError
3547
+ */
3548
+ public static telemetryControllerReportTelemetry(
3549
+ data: TelemetryControllerReportTelemetryData
3550
+ ): CancelablePromise<TelemetryControllerReportTelemetryResponse> {
3551
+ return __request(OpenAPI, {
3552
+ method: 'POST',
3553
+ url: '/api/v1/{region}/bean/import/parser-telemetry',
2771
3554
  path: {
2772
3555
  region: data.region
2773
3556
  },
3557
+ body: data.requestBody,
3558
+ mediaType: 'application/json',
2774
3559
  errors: {
2775
- 401: 'Missing or invalid authentication'
3560
+ 401: 'Unauthorized'
2776
3561
  }
2777
3562
  });
2778
3563
  }
2779
3564
 
2780
3565
  /**
2781
- * Check if provider is supported
2782
- * Returns whether a specific provider is supported.
3566
+ * Receive anonymous zero-hit coverage miss report
2783
3567
  * @param data The data for the request.
2784
- * @param data.providerName Provider name to check
2785
3568
  * @param data.region Region code for tenant context
2786
- * @returns unknown Provider support status
3569
+ * @param data.requestBody
3570
+ * @returns unknown Coverage miss report received
2787
3571
  * @throws ApiError
2788
3572
  */
2789
- public static providerSyncControllerIsProviderSupported(
2790
- data: ProviderSyncControllerIsProviderSupportedData
2791
- ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
3573
+ public static telemetryControllerReportCoverageMiss(
3574
+ data: TelemetryControllerReportCoverageMissData
3575
+ ): CancelablePromise<TelemetryControllerReportCoverageMissResponse> {
2792
3576
  return __request(OpenAPI, {
2793
- method: 'GET',
2794
- url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3577
+ method: 'POST',
3578
+ url: '/api/v1/{region}/bean/import/parser-coverage-miss',
2795
3579
  path: {
2796
- providerName: data.providerName,
2797
3580
  region: data.region
2798
3581
  },
3582
+ body: data.requestBody,
3583
+ mediaType: 'application/json',
2799
3584
  errors: {
2800
- 401: 'Missing or invalid authentication'
3585
+ 401: 'Unauthorized'
2801
3586
  }
2802
3587
  });
2803
3588
  }
2804
- }
2805
3589
 
2806
- export class ImportTelemetryService {
2807
3590
  /**
2808
- * Receive anonymous parser failure telemetry
3591
+ * Coverage metrics (uncovered format aggregation)
2809
3592
  * @param data The data for the request.
2810
3593
  * @param data.region Region code for tenant context
2811
- * @param data.requestBody
2812
- * @returns unknown Telemetry report received
3594
+ * @param data.topN Top-N uncovered formats (default 10)
3595
+ * @returns unknown Coverage metrics
2813
3596
  * @throws ApiError
2814
3597
  */
2815
- public static telemetryControllerReportTelemetry(
2816
- data: TelemetryControllerReportTelemetryData
2817
- ): CancelablePromise<TelemetryControllerReportTelemetryResponse> {
3598
+ public static telemetryControllerGetCoverageMetrics(
3599
+ data: TelemetryControllerGetCoverageMetricsData
3600
+ ): CancelablePromise<TelemetryControllerGetCoverageMetricsResponse> {
2818
3601
  return __request(OpenAPI, {
2819
- method: 'POST',
2820
- url: '/api/v1/{region}/bean/import/parser-telemetry',
3602
+ method: 'GET',
3603
+ url: '/api/v1/{region}/bean/import/parser-coverage-metrics',
2821
3604
  path: {
2822
3605
  region: data.region
2823
3606
  },
2824
- body: data.requestBody,
2825
- mediaType: 'application/json',
2826
- errors: {
2827
- 401: 'Unauthorized'
3607
+ query: {
3608
+ topN: data.topN
2828
3609
  }
2829
3610
  });
2830
3611
  }
@@ -2913,6 +3694,121 @@ export class BeanNlpService {
2913
3694
  }
2914
3695
  }
2915
3696
 
3697
+ export class BeanPlatformsService {
3698
+ /**
3699
+ * Get all platforms with statistics
3700
+ * @returns unknown List of platforms with binding and account counts
3701
+ * @throws ApiError
3702
+ */
3703
+ public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
3704
+ return __request(OpenAPI, {
3705
+ method: 'GET',
3706
+ url: '/api/v1/bean/platforms'
3707
+ });
3708
+ }
3709
+
3710
+ /**
3711
+ * Create a new platform
3712
+ * @param data The data for the request.
3713
+ * @param data.requestBody
3714
+ * @returns unknown Platform created successfully
3715
+ * @throws ApiError
3716
+ */
3717
+ public static platformControllerCreate(
3718
+ data: PlatformControllerCreateData
3719
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3720
+ return __request(OpenAPI, {
3721
+ method: 'POST',
3722
+ url: '/api/v1/bean/platforms',
3723
+ body: data.requestBody,
3724
+ mediaType: 'application/json',
3725
+ errors: {
3726
+ 409: 'Platform already exists'
3727
+ }
3728
+ });
3729
+ }
3730
+
3731
+ /**
3732
+ * Get platform list for current user
3733
+ * @returns PlatformListItemDto List of platforms with user binding status
3734
+ * @throws ApiError
3735
+ */
3736
+ public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3737
+ return __request(OpenAPI, {
3738
+ method: 'GET',
3739
+ url: '/api/v1/bean/platforms/list'
3740
+ });
3741
+ }
3742
+
3743
+ /**
3744
+ * Match platforms by name or alias
3745
+ * @param data The data for the request.
3746
+ * @param data.q Search query — Chinese name, English name, or abbreviation
3747
+ * @param data.region Region code for category override lookup
3748
+ * @returns PlatformMatchResponseDto Matching platforms with overall match type and truncation flag
3749
+ * @throws ApiError
3750
+ */
3751
+ public static platformControllerMatchPlatforms(
3752
+ data: PlatformControllerMatchPlatformsData
3753
+ ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3754
+ return __request(OpenAPI, {
3755
+ method: 'GET',
3756
+ url: '/api/v1/bean/platforms/match',
3757
+ query: {
3758
+ q: data.q,
3759
+ region: data.region
3760
+ }
3761
+ });
3762
+ }
3763
+
3764
+ /**
3765
+ * Update a platform
3766
+ * @param data The data for the request.
3767
+ * @param data.id Platform ID
3768
+ * @param data.requestBody
3769
+ * @returns unknown Platform updated successfully
3770
+ * @throws ApiError
3771
+ */
3772
+ public static platformControllerUpdate(
3773
+ data: PlatformControllerUpdateData
3774
+ ): CancelablePromise<PlatformControllerUpdateResponse> {
3775
+ return __request(OpenAPI, {
3776
+ method: 'PUT',
3777
+ url: '/api/v1/bean/platforms/{id}',
3778
+ path: {
3779
+ id: data.id
3780
+ },
3781
+ body: data.requestBody,
3782
+ mediaType: 'application/json',
3783
+ errors: {
3784
+ 404: 'Platform not found'
3785
+ }
3786
+ });
3787
+ }
3788
+
3789
+ /**
3790
+ * Delete a platform
3791
+ * @param data The data for the request.
3792
+ * @param data.id Platform ID
3793
+ * @returns void Platform deleted successfully
3794
+ * @throws ApiError
3795
+ */
3796
+ public static platformControllerDelete(
3797
+ data: PlatformControllerDeleteData
3798
+ ): CancelablePromise<PlatformControllerDeleteResponse> {
3799
+ return __request(OpenAPI, {
3800
+ method: 'DELETE',
3801
+ url: '/api/v1/bean/platforms/{id}',
3802
+ path: {
3803
+ id: data.id
3804
+ },
3805
+ errors: {
3806
+ 404: 'Platform not found'
3807
+ }
3808
+ });
3809
+ }
3810
+ }
3811
+
2916
3812
  export class DashboardService {
2917
3813
  /**
2918
3814
  * Get net worth overview
@@ -2948,6 +3844,7 @@ export class DashboardService {
2948
3844
  * @param data.region Region code for tenant context
2949
3845
  * @param data.groupBy Grouping strategy
2950
3846
  * @param data.date Date for balance calculation (ISO 8601 format)
3847
+ * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
2951
3848
  * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
2952
3849
  * @throws ApiError
2953
3850
  */
@@ -2962,7 +3859,8 @@ export class DashboardService {
2962
3859
  },
2963
3860
  query: {
2964
3861
  groupBy: data.groupBy,
2965
- date: data.date
3862
+ date: data.date,
3863
+ accountId: data.accountId
2966
3864
  },
2967
3865
  errors: {
2968
3866
  401: 'User not authenticated'
@@ -2997,124 +3895,69 @@ export class DashboardService {
2997
3895
  }
2998
3896
  });
2999
3897
  }
3000
- }
3001
3898
 
3002
- export class ReportingService {
3003
3899
  /**
3004
- * Get portfolio value trends
3005
- *
3006
- * Returns time series data of portfolio net worth.
3007
- *
3008
- * **Multi-currency Support:**
3009
- * - `series[].byCurrency` - Currency breakdown for each data point
3010
- * - `byCurrency` - Separate time series grouped by currency
3011
- * - `warnings` - Exchange rate warnings if conversion failed
3012
- *
3013
- * **Parameters:**
3014
- * - `period`: Time period (1m, 3m, 6m, 1y)
3015
- * - `granularity`: Data granularity (day, week, month)
3016
- *
3900
+ * Get expenses/income grouped by functional category
3901
+ * 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)
3017
3902
  * @param data The data for the request.
3018
3903
  * @param data.region Region code for tenant context
3019
- * @param data.period Time period
3020
- * @param data.granularity Data granularity
3021
- * @returns PortfolioTrendsResponseDto Trends retrieved successfully
3904
+ * @param data.groupBy Grouping strategy
3905
+ * @param data.period Time window (1m = current calendar month)
3906
+ * @param data.flow Account root to aggregate (expense → ^Expenses:, income → ^Income:)
3907
+ * @returns ExpensesByCategoryResponseDto Expenses retrieved successfully
3022
3908
  * @throws ApiError
3023
3909
  */
3024
- public static reportingControllerGetPortfolioTrends(
3025
- data: ReportingControllerGetPortfolioTrendsData
3026
- ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
3910
+ public static dashboardControllerGetExpenses(
3911
+ data: DashboardControllerGetExpensesData
3912
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3027
3913
  return __request(OpenAPI, {
3028
3914
  method: 'GET',
3029
- url: '/api/v1/{region}/reporting/portfolio/trends',
3915
+ url: '/api/v1/{region}/dashboard/expenses',
3030
3916
  path: {
3031
3917
  region: data.region
3032
3918
  },
3033
3919
  query: {
3920
+ groupBy: data.groupBy,
3034
3921
  period: data.period,
3035
- granularity: data.granularity
3922
+ flow: data.flow
3036
3923
  },
3037
3924
  errors: {
3925
+ 400: 'Invalid groupBy or period',
3038
3926
  401: 'User not authenticated'
3039
3927
  }
3040
3928
  });
3041
3929
  }
3930
+ }
3042
3931
 
3932
+ export class InvestmentService {
3043
3933
  /**
3044
- * Generate portfolio snapshot
3045
- *
3046
- * Manually generate a portfolio snapshot for a specific date.
3047
- *
3048
- * **Multi-currency Support:**
3049
- * - Fetches balances grouped by currency
3050
- * - Uses user's baseCurrency setting for conversion
3051
- * - Stores exchange rates and warnings
3052
- *
3053
- * **Use Cases:**
3054
- * - Testing snapshot generation
3055
- * - Force regeneration after data correction
3056
- * - Initial setup for new users
3057
- *
3934
+ * Get per-holding unrealized + realized P&L
3935
+ * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3058
3936
  * @param data The data for the request.
3059
3937
  * @param data.region Region code for tenant context
3060
- * @param data.requestBody Optional date (defaults to today)
3061
- * @returns GenerateSnapshotResponse Snapshot generated successfully
3938
+ * @param data.asOf As-of date (ISO 8601), defaults to today
3939
+ * @param data.accountId Scope to a single account
3940
+ * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3941
+ * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3062
3942
  * @throws ApiError
3063
3943
  */
3064
- public static reportingControllerGenerateSnapshot(
3065
- data: ReportingControllerGenerateSnapshotData
3066
- ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
3944
+ public static holdingPnlControllerGetHoldingPnl(
3945
+ data: HoldingPnlControllerGetHoldingPnlData
3946
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3067
3947
  return __request(OpenAPI, {
3068
- method: 'POST',
3069
- url: '/api/v1/{region}/reporting/snapshots/generate',
3948
+ method: 'GET',
3949
+ url: '/api/v1/{region}/investment/holdings/pnl',
3070
3950
  path: {
3071
3951
  region: data.region
3072
3952
  },
3073
- body: data.requestBody,
3074
- mediaType: 'application/json',
3075
- errors: {
3076
- 400: 'Invalid date format',
3077
- 401: 'User not authenticated'
3078
- }
3079
- });
3080
- }
3081
-
3082
- /**
3083
- * Backfill portfolio snapshots
3084
- *
3085
- * Generate snapshots for a date range (historical data backfill).
3086
- *
3087
- * **Multi-currency Support:**
3088
- * - Each snapshot includes multi-currency data
3089
- * - Uses exchange rates available at generation time
3090
- * - Warnings stored for missing exchange rates
3091
- *
3092
- * **Best Practices:**
3093
- * - Use for initial setup after account configuration
3094
- * - Run during low-traffic periods for large date ranges
3095
- * - Existing snapshots are skipped (not regenerated)
3096
- *
3097
- * @param data The data for the request.
3098
- * @param data.region Region code for tenant context
3099
- * @param data.requestBody
3100
- * @returns BackfillSnapshotsResponse Backfill completed successfully
3101
- * @throws ApiError
3102
- */
3103
- public static reportingControllerBackfillSnapshots(
3104
- data: ReportingControllerBackfillSnapshotsData
3105
- ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
3106
- return __request(OpenAPI, {
3107
- method: 'POST',
3108
- url: '/api/v1/{region}/reporting/snapshots/backfill',
3109
- path: {
3110
- region: data.region
3953
+ query: {
3954
+ asOf: data.asOf,
3955
+ accountId: data.accountId,
3956
+ method: data.method
3111
3957
  },
3112
- body: data.requestBody,
3113
- mediaType: 'application/json',
3114
3958
  errors: {
3115
- 400: 'Invalid date format or range',
3116
- 401: 'User not authenticated',
3117
- 409: 'Backfill already in progress for this user'
3959
+ 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3960
+ 401: 'User not authenticated'
3118
3961
  }
3119
3962
  });
3120
3963
  }
@@ -3143,7 +3986,7 @@ export class AuthService {
3143
3986
  * Anonymous login with access token
3144
3987
  * @param data The data for the request.
3145
3988
  * @param data.requestBody
3146
- * @returns unknown Login successful
3989
+ * @returns AnonymousLoginResponseDto Login successful
3147
3990
  * @throws ApiError
3148
3991
  */
3149
3992
  public static authControllerAccessTokenLogin(
@@ -3330,3 +4173,53 @@ export class InfoService {
3330
4173
  });
3331
4174
  }
3332
4175
  }
4176
+
4177
+ export class MarketDataService {
4178
+ /**
4179
+ * Search market symbols by name or code
4180
+ * Ranked search over the openbb catalog. Empty `q` returns [].
4181
+ * @param data The data for the request.
4182
+ * @param data.q Search term — matched against symbol and instrument name. Empty string returns [].
4183
+ * @param data.limit Maximum number of results (clamped 1..50)
4184
+ * @param data.exchange Filter by exchange code (e.g. US, HK, SS, SZ)
4185
+ * @param data.assetType Filter by OpenBB asset_type (e.g. stock, etf)
4186
+ * @returns SymbolSearchResultDto Ranked search results
4187
+ * @throws ApiError
4188
+ */
4189
+ public static symbolControllerSearch(
4190
+ data: SymbolControllerSearchData
4191
+ ): CancelablePromise<SymbolControllerSearchResponse> {
4192
+ return __request(OpenAPI, {
4193
+ method: 'GET',
4194
+ url: '/api/v1/market/symbols/search',
4195
+ query: {
4196
+ q: data.q,
4197
+ limit: data.limit,
4198
+ exchange: data.exchange,
4199
+ assetType: data.assetType
4200
+ }
4201
+ });
4202
+ }
4203
+
4204
+ /**
4205
+ * Get a market symbol quote
4206
+ * @param data The data for the request.
4207
+ * @param data.symbol
4208
+ * @returns SymbolQuoteDto Symbol quote
4209
+ * @throws ApiError
4210
+ */
4211
+ public static symbolControllerGetQuote(
4212
+ data: SymbolControllerGetQuoteData
4213
+ ): CancelablePromise<SymbolControllerGetQuoteResponse> {
4214
+ return __request(OpenAPI, {
4215
+ method: 'GET',
4216
+ url: '/api/v1/market/symbols/{symbol}/quote',
4217
+ path: {
4218
+ symbol: data.symbol
4219
+ },
4220
+ errors: {
4221
+ 404: 'Symbol not found in the openbb catalog'
4222
+ }
4223
+ });
4224
+ }
4225
+ }