@firela/api-types 0.0.0-canary.32edff08 → 0.0.0-canary.356601c3

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,53 @@ 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
+ PlatformControllerGetPlatformListData,
261
+ PlatformControllerGetPlatformListResponse,
262
+ PlatformControllerMatchPlatformsData,
263
+ PlatformControllerMatchPlatformsResponse,
264
+ PlatformControllerUpdateData,
265
+ PlatformControllerUpdateResponse,
266
+ PlatformControllerDeleteData,
267
+ PlatformControllerDeleteResponse,
209
268
  DashboardControllerGetNetWorthData,
210
269
  DashboardControllerGetNetWorthResponse,
211
270
  DashboardControllerGetAccountsData,
212
271
  DashboardControllerGetAccountsResponse,
213
272
  DashboardControllerGetCashFlowData,
214
273
  DashboardControllerGetCashFlowResponse,
215
- ReportingControllerGetPortfolioTrendsData,
216
- ReportingControllerGetPortfolioTrendsResponse,
217
- ReportingControllerGenerateSnapshotData,
218
- ReportingControllerGenerateSnapshotResponse,
219
- ReportingControllerBackfillSnapshotsData,
220
- ReportingControllerBackfillSnapshotsResponse,
274
+ DashboardControllerGetExpensesData,
275
+ DashboardControllerGetExpensesResponse,
276
+ HoldingPnlControllerGetHoldingPnlData,
277
+ HoldingPnlControllerGetHoldingPnlResponse,
221
278
  ApiKeysControllerCreateApiKeyResponse,
222
279
  AuthControllerAccessTokenLoginData,
223
280
  AuthControllerAccessTokenLoginResponse,
@@ -232,7 +289,11 @@ import type {
232
289
  HealthControllerResetCircuitBreakerData,
233
290
  HealthControllerResetCircuitBreakerResponse,
234
291
  HealthControllerGetMetricsResponse,
235
- InfoControllerGetInfoResponse
292
+ InfoControllerGetInfoResponse,
293
+ SymbolControllerSearchData,
294
+ SymbolControllerSearchResponse,
295
+ SymbolControllerGetQuoteData,
296
+ SymbolControllerGetQuoteResponse
236
297
  } from './types.gen';
237
298
 
238
299
  export class BeanAccountsService {
@@ -270,7 +331,7 @@ export class BeanAccountsService {
270
331
  * @param data.type Filter by account type
271
332
  * @param data.status Filter by status
272
333
  * @param data.isCustom Filter by custom (user-created) accounts only
273
- * @param data.search Search term for path or i18nKey
334
+ * @param data.search Search term for account path
274
335
  * @param data.limit Maximum number of results
275
336
  * @param data.offset Number of results to skip
276
337
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -351,7 +412,7 @@ export class BeanAccountsService {
351
412
 
352
413
  /**
353
414
  * Delete account
354
- * Deletes an account (only if no transactions)
415
+ * Deletes an account (only if no active transactions; voided/superseded residual postings are cleaned up)
355
416
  * @param data The data for the request.
356
417
  * @param data.id Account UUID
357
418
  * @param data.region Region code for tenant context
@@ -370,7 +431,7 @@ export class BeanAccountsService {
370
431
  },
371
432
  errors: {
372
433
  404: 'Account not found',
373
- 409: 'Account has transactions and cannot be deleted'
434
+ 409: 'Account has active transactions and cannot be deleted'
374
435
  }
375
436
  });
376
437
  }
@@ -432,6 +493,35 @@ export class BeanAccountsService {
432
493
  }
433
494
  });
434
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
+ }
435
525
  }
436
526
 
437
527
  export class BeanAccountStandardsService {
@@ -463,7 +553,7 @@ export class BeanAccountStandardsService {
463
553
 
464
554
  /**
465
555
  * Get template metadata for an account path
466
- * Returns extendable status and root type for a template path.
556
+ * Returns root type for a template path.
467
557
  * @param data The data for the request.
468
558
  * @param data.region Region code for tenant context
469
559
  * @param data.path Account path to check
@@ -549,6 +639,7 @@ export class BeanTransactionsService {
549
639
  * @param data.status Filter by transaction status
550
640
  * @param data.search Search in narration and payee fields (max 200 chars)
551
641
  * @param data.accountId Filter by account ID (transactions with postings to this account)
642
+ * @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
643
  * @returns TransactionListResponseDto Transaction list
553
644
  * @throws ApiError
554
645
  */
@@ -568,7 +659,8 @@ export class BeanTransactionsService {
568
659
  dateTo: data.dateTo,
569
660
  status: data.status,
570
661
  search: data.search,
571
- accountId: data.accountId
662
+ accountId: data.accountId,
663
+ category: data.category
572
664
  },
573
665
  errors: {
574
666
  400: 'Validation failed',
@@ -605,6 +697,36 @@ export class BeanTransactionsService {
605
697
  });
606
698
  }
607
699
 
700
+ /**
701
+ * Correct (supersede) a transaction
702
+ * Atomically voids the original (SUPERSEDED) and creates a replacement through the full validation pipeline.
703
+ * @param data The data for the request.
704
+ * @param data.id Original transaction ID to correct
705
+ * @param data.region Region code for tenant context
706
+ * @param data.requestBody
707
+ * @returns TransactionDetailDto Corrected transaction created
708
+ * @throws ApiError
709
+ */
710
+ public static transactionControllerCorrect(
711
+ data: TransactionControllerCorrectData
712
+ ): CancelablePromise<TransactionControllerCorrectResponse> {
713
+ return __request(OpenAPI, {
714
+ method: 'POST',
715
+ url: '/api/v1/{region}/bean/transactions/{id}/correct',
716
+ path: {
717
+ id: data.id,
718
+ region: data.region
719
+ },
720
+ body: data.requestBody,
721
+ mediaType: 'application/json',
722
+ errors: {
723
+ 404: 'Original transaction not found',
724
+ 409: 'Original no longer ACTIVE (concurrent modification)',
725
+ 422: 'Pipeline validation failed (does not balance, invalid accounts)'
726
+ }
727
+ });
728
+ }
729
+
608
730
  /**
609
731
  * Suggest transaction tags
610
732
  * Returns distinct tags from the user ACTIVE transactions, sorted by usage, for autocomplete. Optional q performs a case-insensitive prefix match.
@@ -726,7 +848,7 @@ export class BeanBalancesService {
726
848
  * Query account balance
727
849
  * Calculate account balance at a specific date for a single currency
728
850
  * @param data The data for the request.
729
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
851
+ * @param data.account Account name (e.g., "Assets:Checking")
730
852
  * @param data.region Region code for tenant context
731
853
  * @param data.date Date to calculate balance at (ISO 8601 format)
732
854
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -1447,6 +1569,173 @@ export class BeanCommoditiesService {
1447
1569
  }
1448
1570
  }
1449
1571
 
1572
+ export class BeanPricesService {
1573
+ /**
1574
+ * Create a new price
1575
+ * Creates a new price entry for the authenticated user
1576
+ * @param data The data for the request.
1577
+ * @param data.region Region code for tenant context
1578
+ * @param data.requestBody
1579
+ * @returns PriceResponseDto Price created successfully
1580
+ * @throws ApiError
1581
+ */
1582
+ public static priceControllerCreate(
1583
+ data: PriceControllerCreateData
1584
+ ): CancelablePromise<PriceControllerCreateResponse> {
1585
+ return __request(OpenAPI, {
1586
+ method: 'POST',
1587
+ url: '/api/v1/{region}/bean/prices',
1588
+ path: {
1589
+ region: data.region
1590
+ },
1591
+ body: data.requestBody,
1592
+ mediaType: 'application/json',
1593
+ errors: {
1594
+ 404: 'Currency or quoteCurrency commodity not found',
1595
+ 409: 'Price already exists for this currency pair and date'
1596
+ }
1597
+ });
1598
+ }
1599
+
1600
+ /**
1601
+ * List user prices
1602
+ * Returns all price entries for the authenticated user with optional filtering
1603
+ * @param data The data for the request.
1604
+ * @param data.region Region code for tenant context
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
1613
+ * @throws ApiError
1614
+ */
1615
+ public static priceControllerFindAll(
1616
+ data: PriceControllerFindAllData
1617
+ ): CancelablePromise<PriceControllerFindAllResponse> {
1618
+ return __request(OpenAPI, {
1619
+ method: 'GET',
1620
+ url: '/api/v1/{region}/bean/prices',
1621
+ path: {
1622
+ region: data.region
1623
+ },
1624
+ query: {
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
1632
+ }
1633
+ });
1634
+ }
1635
+
1636
+ /**
1637
+ * Get price by ID
1638
+ * Returns a single price entry by its ID
1639
+ * @param data The data for the request.
1640
+ * @param data.id Price ID
1641
+ * @param data.region Region code for tenant context
1642
+ * @returns PriceResponseDto Price retrieved successfully
1643
+ * @throws ApiError
1644
+ */
1645
+ public static priceControllerFindOne(
1646
+ data: PriceControllerFindOneData
1647
+ ): CancelablePromise<PriceControllerFindOneResponse> {
1648
+ return __request(OpenAPI, {
1649
+ method: 'GET',
1650
+ url: '/api/v1/{region}/bean/prices/{id}',
1651
+ path: {
1652
+ id: data.id,
1653
+ region: data.region
1654
+ },
1655
+ errors: {
1656
+ 404: 'Price not found'
1657
+ }
1658
+ });
1659
+ }
1660
+
1661
+ /**
1662
+ * Update a price
1663
+ * Updates an existing price entry
1664
+ * @param data The data for the request.
1665
+ * @param data.id Price ID
1666
+ * @param data.region Region code for tenant context
1667
+ * @param data.requestBody
1668
+ * @returns PriceResponseDto Price updated successfully
1669
+ * @throws ApiError
1670
+ */
1671
+ public static priceControllerUpdate(
1672
+ data: PriceControllerUpdateData
1673
+ ): CancelablePromise<PriceControllerUpdateResponse> {
1674
+ return __request(OpenAPI, {
1675
+ method: 'PUT',
1676
+ url: '/api/v1/{region}/bean/prices/{id}',
1677
+ path: {
1678
+ id: data.id,
1679
+ region: data.region
1680
+ },
1681
+ body: data.requestBody,
1682
+ mediaType: 'application/json',
1683
+ errors: {
1684
+ 404: 'Price not found',
1685
+ 409: 'Updated price conflicts with existing price'
1686
+ }
1687
+ });
1688
+ }
1689
+
1690
+ /**
1691
+ * Delete a price
1692
+ * Deletes a price entry (hard delete)
1693
+ * @param data The data for the request.
1694
+ * @param data.id Price ID
1695
+ * @param data.region Region code for tenant context
1696
+ * @returns void Price deleted successfully
1697
+ * @throws ApiError
1698
+ */
1699
+ public static priceControllerDelete(
1700
+ data: PriceControllerDeleteData
1701
+ ): CancelablePromise<PriceControllerDeleteResponse> {
1702
+ return __request(OpenAPI, {
1703
+ method: 'DELETE',
1704
+ url: '/api/v1/{region}/bean/prices/{id}',
1705
+ path: {
1706
+ id: data.id,
1707
+ region: data.region
1708
+ },
1709
+ errors: {
1710
+ 404: 'Price not found'
1711
+ }
1712
+ });
1713
+ }
1714
+
1715
+ /**
1716
+ * Bulk create prices
1717
+ * Creates multiple price entries at once (skips duplicates)
1718
+ * @param data The data for the request.
1719
+ * @param data.region Region code for tenant context
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
+
1450
1739
  export class RecurringRulesService {
1451
1740
  /**
1452
1741
  * Create a new recurring rule
@@ -1877,279 +2166,158 @@ export class RecurringForecastService {
1877
2166
  }
1878
2167
  }
1879
2168
 
1880
- export class BeanTransactionRulesService {
2169
+ export class ReportingService {
1881
2170
  /**
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.
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
+ *
1884
2184
  * @param data The data for the request.
1885
2185
  * @param data.region Region code for tenant context
1886
- * @param data.requestBody
1887
- * @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
1888
2189
  * @throws ApiError
1889
2190
  */
1890
- public static transactionRuleControllerCreate(
1891
- data: TransactionRuleControllerCreateData
1892
- ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2191
+ public static reportingControllerGetPortfolioTrends(
2192
+ data: ReportingControllerGetPortfolioTrendsData
2193
+ ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
1893
2194
  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',
2195
+ method: 'GET',
2196
+ url: '/api/v1/{region}/reporting/portfolio/trends',
1927
2197
  path: {
1928
2198
  region: data.region
1929
2199
  },
1930
2200
  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
2201
+ period: data.period,
2202
+ granularity: data.granularity
1985
2203
  },
1986
- body: data.requestBody,
1987
- mediaType: 'application/json',
1988
2204
  errors: {
1989
- 400: 'Invalid bulk create data',
1990
- 401: 'Unauthorized'
2205
+ 401: 'User not authenticated'
1991
2206
  }
1992
2207
  });
1993
2208
  }
1994
2209
 
1995
2210
  /**
1996
- * Export transaction rules
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
+ *
1997
2220
  * @param data The data for the request.
1998
- * @param data.format Export format (currently only JSON supported)
1999
2221
  * @param data.region Region code for tenant context
2000
- * @returns ExportRulesResponseDto Exported 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
2001
2225
  * @throws ApiError
2002
2226
  */
2003
- public static transactionRuleControllerExport(
2004
- data: TransactionRuleControllerExportData
2005
- ): CancelablePromise<TransactionRuleControllerExportResponse> {
2227
+ public static reportingControllerGetCashFlowTrends(
2228
+ data: ReportingControllerGetCashFlowTrendsData
2229
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
2006
2230
  return __request(OpenAPI, {
2007
2231
  method: 'GET',
2008
- url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2232
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
2009
2233
  path: {
2010
- format: data.format,
2011
2234
  region: data.region
2012
2235
  },
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: {
2236
+ query: {
2035
2237
  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
2238
+ granularity: data.granularity
2061
2239
  },
2062
2240
  errors: {
2063
- 401: 'Unauthorized',
2064
- 403: 'Forbidden - not owner of rule',
2065
- 404: 'Rule not found'
2241
+ 401: 'User not authenticated'
2066
2242
  }
2067
2243
  });
2068
2244
  }
2069
2245
 
2070
2246
  /**
2071
- * Update a transaction rule
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
+ *
2072
2261
  * @param data The data for the request.
2073
- * @param data.ruleId Rule ID to update
2074
2262
  * @param data.region Region code for tenant context
2075
- * @param data.requestBody
2076
- * @returns TransactionRuleResponseDto Rule updated successfully
2263
+ * @param data.requestBody Optional date (defaults to today)
2264
+ * @returns GenerateSnapshotResponse Snapshot generated successfully
2077
2265
  * @throws ApiError
2078
2266
  */
2079
- public static transactionRuleControllerUpdate(
2080
- data: TransactionRuleControllerUpdateData
2081
- ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2267
+ public static reportingControllerGenerateSnapshot(
2268
+ data: ReportingControllerGenerateSnapshotData
2269
+ ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
2082
2270
  return __request(OpenAPI, {
2083
- method: 'PUT',
2084
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2271
+ method: 'POST',
2272
+ url: '/api/v1/{region}/reporting/snapshots/generate',
2085
2273
  path: {
2086
- ruleId: data.ruleId,
2087
2274
  region: data.region
2088
2275
  },
2089
2276
  body: data.requestBody,
2090
2277
  mediaType: 'application/json',
2091
2278
  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'
2279
+ 400: 'Invalid date format',
2280
+ 401: 'User not authenticated'
2124
2281
  }
2125
2282
  });
2126
2283
  }
2127
2284
 
2128
2285
  /**
2129
- * 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
+ *
2130
2300
  * @param data The data for the request.
2131
- * @param data.ruleId Rule ID to test
2132
2301
  * @param data.region Region code for tenant context
2133
2302
  * @param data.requestBody
2134
- * @returns TestRuleResponseDto Test result
2303
+ * @returns BackfillSnapshotsResponse Backfill completed successfully
2135
2304
  * @throws ApiError
2136
2305
  */
2137
- public static transactionRuleControllerTest(
2138
- data: TransactionRuleControllerTestData
2139
- ): CancelablePromise<TransactionRuleControllerTestResponse> {
2306
+ public static reportingControllerBackfillSnapshots(
2307
+ data: ReportingControllerBackfillSnapshotsData
2308
+ ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
2140
2309
  return __request(OpenAPI, {
2141
2310
  method: 'POST',
2142
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2311
+ url: '/api/v1/{region}/reporting/snapshots/backfill',
2143
2312
  path: {
2144
- ruleId: data.ruleId,
2145
2313
  region: data.region
2146
2314
  },
2147
2315
  body: data.requestBody,
2148
2316
  mediaType: 'application/json',
2149
2317
  errors: {
2150
- 401: 'Unauthorized',
2151
- 403: 'Forbidden - not owner of rule',
2152
- 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'
2153
2321
  }
2154
2322
  });
2155
2323
  }
@@ -2201,7 +2369,7 @@ export class UsersService {
2201
2369
  * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
2202
2370
  * @param data The data for the request.
2203
2371
  * @param data.requestBody
2204
- * @returns unknown User created successfully
2372
+ * @returns SignupResponseDto User created successfully
2205
2373
  * @throws ApiError
2206
2374
  */
2207
2375
  public static userControllerSignupUser(
@@ -2410,11 +2578,597 @@ export class PropertiesService {
2410
2578
  }
2411
2579
  }
2412
2580
 
2413
- export class BeanExportService {
2581
+ export class BeanTransactionRulesService {
2414
2582
  /**
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
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.
2585
+ * @param data The data for the request.
2586
+ * @param data.region Region code for tenant context
2587
+ * @param data.requestBody
2588
+ * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2589
+ * @throws ApiError
2590
+ */
2591
+ public static transactionRuleControllerCreate(
2592
+ data: TransactionRuleControllerCreateData
2593
+ ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2594
+ return __request(OpenAPI, {
2595
+ method: 'POST',
2596
+ url: '/api/v1/{region}/bean/transaction-rules',
2597
+ path: {
2598
+ region: data.region
2599
+ },
2600
+ body: data.requestBody,
2601
+ mediaType: 'application/json',
2602
+ errors: {
2603
+ 400: 'Validation failed',
2604
+ 401: 'Unauthorized',
2605
+ 409: 'Resource conflict - another process is updating this rule'
2606
+ }
2607
+ });
2608
+ }
2609
+
2610
+ /**
2611
+ * Get all transaction rules for user
2612
+ * @param data The data for the request.
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
2620
+ * @throws ApiError
2621
+ */
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',
2905
+ url: '/api/v1/{region}/bean/events',
2906
+ path: {
2907
+ region: data.region
2908
+ },
2909
+ query: {
2910
+ type: data.type,
2911
+ q: data.q,
2912
+ from: data.from,
2913
+ to: data.to,
2914
+ page: data.page,
2915
+ limit: data.limit
2916
+ }
2917
+ });
2918
+ }
2919
+
2920
+ /**
2921
+ * Get life event by ID
2922
+ * Returns a single life event by its ID. Returns ETag header.
2923
+ * @param data The data for the request.
2924
+ * @param data.id Life event ID
2925
+ * @param data.region Region code for tenant context (decorative for life events)
2926
+ * @returns EventResponseDto Life event retrieved successfully
2927
+ * @throws ApiError
2928
+ */
2929
+ public static eventControllerFindOne(
2930
+ data: EventControllerFindOneData
2931
+ ): CancelablePromise<EventControllerFindOneResponse> {
2932
+ return __request(OpenAPI, {
2933
+ method: 'GET',
2934
+ url: '/api/v1/{region}/bean/events/{id}',
2935
+ path: {
2936
+ id: data.id,
2937
+ region: data.region
2938
+ },
2939
+ errors: {
2940
+ 404: 'Life event not found'
2941
+ }
2942
+ });
2943
+ }
2944
+
2945
+ /**
2946
+ * Update a life event
2947
+ * Updates an existing life event. If If-Match header is provided, performs optimistic concurrency check; mismatched updatedAt returns 412.
2948
+ * @param data The data for the request.
2949
+ * @param data.id Life event ID
2950
+ * @param data.region Region code for tenant context (decorative for life events)
2951
+ * @param data.requestBody
2952
+ * @returns EventResponseDto Life event updated successfully
2953
+ * @throws ApiError
2954
+ */
2955
+ public static eventControllerUpdate(
2956
+ data: EventControllerUpdateData
2957
+ ): CancelablePromise<EventControllerUpdateResponse> {
2958
+ return __request(OpenAPI, {
2959
+ method: 'PUT',
2960
+ url: '/api/v1/{region}/bean/events/{id}',
2961
+ path: {
2962
+ id: data.id,
2963
+ region: data.region
2964
+ },
2965
+ body: data.requestBody,
2966
+ mediaType: 'application/json',
2967
+ errors: {
2968
+ 400: 'If-Match header is not a valid ISO 8601 date',
2969
+ 404: 'Life event not found',
2970
+ 409: 'Updated event conflicts with an existing (userId, type, date) combination',
2971
+ 412: 'If-Match precondition failed (updatedAt mismatch)'
2972
+ }
2973
+ });
2974
+ }
2975
+
2976
+ /**
2977
+ * Delete a life event
2978
+ * Deletes a life event entry (hard delete). Returns 204.
2979
+ * @param data The data for the request.
2980
+ * @param data.id Life event ID
2981
+ * @param data.region Region code for tenant context (decorative for life events)
2982
+ * @returns void Life event deleted successfully
2983
+ * @throws ApiError
2984
+ */
2985
+ public static eventControllerDelete(
2986
+ data: EventControllerDeleteData
2987
+ ): CancelablePromise<EventControllerDeleteResponse> {
2988
+ return __request(OpenAPI, {
2989
+ method: 'DELETE',
2990
+ url: '/api/v1/{region}/bean/events/{id}',
2991
+ path: {
2992
+ id: data.id,
2993
+ region: data.region
2994
+ },
2995
+ errors: {
2996
+ 404: 'Life event not found'
2997
+ }
2998
+ });
2999
+ }
3000
+
3001
+ /**
3002
+ * Slice time-series by a life event (Phase 79)
3003
+ * Returns aggregated time-series for postings matching accountPattern within the half-open date range of the given life event.
3004
+ * @param data The data for the request.
3005
+ * @param data.id Life event ID
3006
+ * @param data.accountPattern
3007
+ * @param data.granularity
3008
+ * @param data.region Region code for tenant context (decorative for life events)
3009
+ * @returns unknown Time-series sliced by the life event range
3010
+ * @throws ApiError
3011
+ */
3012
+ public static eventControllerGetSlice(
3013
+ data: EventControllerGetSliceData
3014
+ ): CancelablePromise<EventControllerGetSliceResponse> {
3015
+ return __request(OpenAPI, {
3016
+ method: 'GET',
3017
+ url: '/api/v1/{region}/bean/events/{id}/slice',
3018
+ path: {
3019
+ id: data.id,
3020
+ region: data.region
3021
+ },
3022
+ query: {
3023
+ accountPattern: data.accountPattern,
3024
+ granularity: data.granularity
3025
+ },
3026
+ errors: {
3027
+ 400: 'accountPattern query param is empty',
3028
+ 404: 'Life event not found'
3029
+ }
3030
+ });
3031
+ }
3032
+ }
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
+
3167
+ export class BeanExportService {
3168
+ /**
3169
+ * Export Beancount ledger as ZIP
3170
+ * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
3171
+ * @returns unknown
2418
3172
  * @throws ApiError
2419
3173
  */
2420
3174
  public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
@@ -2588,243 +3342,271 @@ export class BeanImportService {
2588
3342
  }
2589
3343
  }
2590
3344
 
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
-
3345
+ export class ProviderSyncService {
2604
3346
  /**
2605
- * 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
+ *
2606
3369
  * @param data The data for the request.
3370
+ * @param data.providerName Provider name
3371
+ * @param data.region Region code for tenant context
2607
3372
  * @param data.requestBody
2608
- * @returns unknown Platform created successfully
3373
+ * @returns ProviderSyncResponseDto Sync completed successfully
2609
3374
  * @throws ApiError
2610
3375
  */
2611
- public static platformControllerCreate(
2612
- data: PlatformControllerCreateData
2613
- ): CancelablePromise<PlatformControllerCreateResponse> {
3376
+ public static providerSyncControllerSync(
3377
+ data: ProviderSyncControllerSyncData
3378
+ ): CancelablePromise<ProviderSyncControllerSyncResponse> {
2614
3379
  return __request(OpenAPI, {
2615
3380
  method: 'POST',
2616
- 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
+ },
2617
3386
  body: data.requestBody,
2618
3387
  mediaType: 'application/json',
2619
3388
  errors: {
2620
- 409: 'Platform already exists'
3389
+ 400: 'Invalid request data',
3390
+ 401: 'Missing or invalid authentication',
3391
+ 404: 'Provider not supported'
2621
3392
  }
2622
3393
  });
2623
3394
  }
2624
3395
 
2625
3396
  /**
2626
- * Get platform list for current user
2627
- * @returns unknown List of platforms with user binding status
3397
+ * Get supported providers
3398
+ * Returns a list of all providers supported by the sync endpoint.
3399
+ * @param data The data for the request.
3400
+ * @param data.region Region code for tenant context
3401
+ * @returns SupportedProvidersResponseDto List of supported providers
2628
3402
  * @throws ApiError
2629
3403
  */
2630
- public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3404
+ public static providerSyncControllerGetSupportedProviders(
3405
+ data: ProviderSyncControllerGetSupportedProvidersData
3406
+ ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
2631
3407
  return __request(OpenAPI, {
2632
3408
  method: 'GET',
2633
- url: '/api/v1/bean/platforms/list'
3409
+ url: '/api/v1/{region}/bean/import/provider/supported',
3410
+ path: {
3411
+ region: data.region
3412
+ },
3413
+ errors: {
3414
+ 401: 'Missing or invalid authentication'
3415
+ }
2634
3416
  });
2635
3417
  }
2636
3418
 
2637
3419
  /**
2638
- * Match platforms by name or alias
3420
+ * Check if provider is supported
3421
+ * Returns whether a specific provider is supported.
2639
3422
  * @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
3423
+ * @param data.providerName Provider name to check
3424
+ * @param data.region Region code for tenant context
3425
+ * @returns unknown Provider support status
2643
3426
  * @throws ApiError
2644
3427
  */
2645
- public static platformControllerMatchPlatforms(
2646
- data: PlatformControllerMatchPlatformsData
2647
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3428
+ public static providerSyncControllerIsProviderSupported(
3429
+ data: ProviderSyncControllerIsProviderSupportedData
3430
+ ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
2648
3431
  return __request(OpenAPI, {
2649
3432
  method: 'GET',
2650
- url: '/api/v1/bean/platforms/match',
2651
- query: {
2652
- q: data.q,
3433
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3434
+ path: {
3435
+ providerName: data.providerName,
2653
3436
  region: data.region
3437
+ },
3438
+ errors: {
3439
+ 401: 'Missing or invalid authentication'
2654
3440
  }
2655
3441
  });
2656
3442
  }
3443
+ }
2657
3444
 
3445
+ export class ExternalAccountLinksService {
2658
3446
  /**
2659
- * Update a platform
3447
+ * Create an external account → BeanAccount mapping (ADR-0113)
2660
3448
  * @param data The data for the request.
2661
- * @param data.id Platform ID
3449
+ * @param data.region Region code for tenant context
2662
3450
  * @param data.requestBody
2663
- * @returns unknown Platform updated successfully
3451
+ * @returns ExternalAccountLinkResponseDto Link created.
2664
3452
  * @throws ApiError
2665
3453
  */
2666
- public static platformControllerUpdate(
2667
- data: PlatformControllerUpdateData
2668
- ): CancelablePromise<PlatformControllerUpdateResponse> {
3454
+ public static externalAccountLinkControllerCreate(
3455
+ data: ExternalAccountLinkControllerCreateData
3456
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
2669
3457
  return __request(OpenAPI, {
2670
- method: 'PUT',
2671
- url: '/api/v1/bean/platforms/{id}',
3458
+ method: 'POST',
3459
+ url: '/api/v1/{region}/bean/external-account-links',
2672
3460
  path: {
2673
- id: data.id
3461
+ region: data.region
2674
3462
  },
2675
3463
  body: data.requestBody,
2676
3464
  mediaType: 'application/json',
2677
3465
  errors: {
2678
- 404: 'Platform not found'
3466
+ 422: 'beanAccountId not owned, or an active link already exists.'
2679
3467
  }
2680
3468
  });
2681
3469
  }
2682
3470
 
2683
3471
  /**
2684
- * Delete a platform
3472
+ * List the user's active external account links
2685
3473
  * @param data The data for the request.
2686
- * @param data.id Platform ID
2687
- * @returns void Platform deleted successfully
3474
+ * @param data.provider
3475
+ * @param data.region Region code for tenant context
3476
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
2688
3477
  * @throws ApiError
2689
3478
  */
2690
- public static platformControllerDelete(
2691
- data: PlatformControllerDeleteData
2692
- ): CancelablePromise<PlatformControllerDeleteResponse> {
3479
+ public static externalAccountLinkControllerFindAll(
3480
+ data: ExternalAccountLinkControllerFindAllData
3481
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
2693
3482
  return __request(OpenAPI, {
2694
- method: 'DELETE',
2695
- url: '/api/v1/bean/platforms/{id}',
3483
+ method: 'GET',
3484
+ url: '/api/v1/{region}/bean/external-account-links',
2696
3485
  path: {
2697
- id: data.id
3486
+ region: data.region
2698
3487
  },
2699
- errors: {
2700
- 404: 'Platform not found'
3488
+ query: {
3489
+ provider: data.provider
2701
3490
  }
2702
3491
  });
2703
3492
  }
2704
- }
2705
3493
 
2706
- export class ProviderSyncService {
2707
3494
  /**
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
- *
3495
+ * Get a single external account link
2730
3496
  * @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
3497
+ * @param data.id
3498
+ * @param data.region Region code for tenant context
3499
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
2735
3500
  * @throws ApiError
2736
3501
  */
2737
- public static providerSyncControllerSync(
2738
- data: ProviderSyncControllerSyncData
2739
- ): CancelablePromise<ProviderSyncControllerSyncResponse> {
3502
+ public static externalAccountLinkControllerFindOne(
3503
+ data: ExternalAccountLinkControllerFindOneData
3504
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
2740
3505
  return __request(OpenAPI, {
2741
- method: 'POST',
2742
- url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3506
+ method: 'GET',
3507
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
2743
3508
  path: {
2744
- providerName: data.providerName,
3509
+ id: data.id,
2745
3510
  region: data.region
2746
3511
  },
2747
- body: data.requestBody,
2748
- mediaType: 'application/json',
2749
3512
  errors: {
2750
- 400: 'Invalid request data',
2751
- 401: 'Missing or invalid authentication',
2752
- 404: 'Provider not supported'
3513
+ 422: 'Link not found or not owned by the user.'
2753
3514
  }
2754
3515
  });
2755
3516
  }
2756
3517
 
2757
3518
  /**
2758
- * Get supported providers
2759
- * Returns a list of all providers supported by the sync endpoint.
3519
+ * Soft-delete (disconnect) an external account link
2760
3520
  * @param data The data for the request.
3521
+ * @param data.id
2761
3522
  * @param data.region Region code for tenant context
2762
- * @returns SupportedProvidersResponseDto List of supported providers
3523
+ * @returns void Link soft-deleted; historical transactions are unaffected.
2763
3524
  * @throws ApiError
2764
3525
  */
2765
- public static providerSyncControllerGetSupportedProviders(
2766
- data: ProviderSyncControllerGetSupportedProvidersData
2767
- ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
3526
+ public static externalAccountLinkControllerRemove(
3527
+ data: ExternalAccountLinkControllerRemoveData
3528
+ ): CancelablePromise<ExternalAccountLinkControllerRemoveResponse> {
2768
3529
  return __request(OpenAPI, {
2769
- method: 'GET',
2770
- url: '/api/v1/{region}/bean/import/provider/supported',
3530
+ method: 'DELETE',
3531
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3532
+ path: {
3533
+ id: data.id,
3534
+ region: data.region
3535
+ }
3536
+ });
3537
+ }
3538
+ }
3539
+
3540
+ export class ImportTelemetryService {
3541
+ /**
3542
+ * Receive anonymous parser failure telemetry
3543
+ * @param data The data for the request.
3544
+ * @param data.region Region code for tenant context
3545
+ * @param data.requestBody
3546
+ * @returns unknown Telemetry report received
3547
+ * @throws ApiError
3548
+ */
3549
+ public static telemetryControllerReportTelemetry(
3550
+ data: TelemetryControllerReportTelemetryData
3551
+ ): CancelablePromise<TelemetryControllerReportTelemetryResponse> {
3552
+ return __request(OpenAPI, {
3553
+ method: 'POST',
3554
+ url: '/api/v1/{region}/bean/import/parser-telemetry',
2771
3555
  path: {
2772
3556
  region: data.region
2773
3557
  },
3558
+ body: data.requestBody,
3559
+ mediaType: 'application/json',
2774
3560
  errors: {
2775
- 401: 'Missing or invalid authentication'
3561
+ 401: 'Unauthorized'
2776
3562
  }
2777
3563
  });
2778
3564
  }
2779
3565
 
2780
3566
  /**
2781
- * Check if provider is supported
2782
- * Returns whether a specific provider is supported.
3567
+ * Receive anonymous zero-hit coverage miss report
2783
3568
  * @param data The data for the request.
2784
- * @param data.providerName Provider name to check
2785
3569
  * @param data.region Region code for tenant context
2786
- * @returns unknown Provider support status
3570
+ * @param data.requestBody
3571
+ * @returns unknown Coverage miss report received
2787
3572
  * @throws ApiError
2788
3573
  */
2789
- public static providerSyncControllerIsProviderSupported(
2790
- data: ProviderSyncControllerIsProviderSupportedData
2791
- ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
3574
+ public static telemetryControllerReportCoverageMiss(
3575
+ data: TelemetryControllerReportCoverageMissData
3576
+ ): CancelablePromise<TelemetryControllerReportCoverageMissResponse> {
2792
3577
  return __request(OpenAPI, {
2793
- method: 'GET',
2794
- url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3578
+ method: 'POST',
3579
+ url: '/api/v1/{region}/bean/import/parser-coverage-miss',
2795
3580
  path: {
2796
- providerName: data.providerName,
2797
3581
  region: data.region
2798
3582
  },
3583
+ body: data.requestBody,
3584
+ mediaType: 'application/json',
2799
3585
  errors: {
2800
- 401: 'Missing or invalid authentication'
3586
+ 401: 'Unauthorized'
2801
3587
  }
2802
3588
  });
2803
3589
  }
2804
- }
2805
3590
 
2806
- export class ImportTelemetryService {
2807
3591
  /**
2808
- * Receive anonymous parser failure telemetry
3592
+ * Coverage metrics (uncovered format aggregation)
2809
3593
  * @param data The data for the request.
2810
3594
  * @param data.region Region code for tenant context
2811
- * @param data.requestBody
2812
- * @returns unknown Telemetry report received
3595
+ * @param data.topN Top-N uncovered formats (default 10)
3596
+ * @returns unknown Coverage metrics
2813
3597
  * @throws ApiError
2814
3598
  */
2815
- public static telemetryControllerReportTelemetry(
2816
- data: TelemetryControllerReportTelemetryData
2817
- ): CancelablePromise<TelemetryControllerReportTelemetryResponse> {
3599
+ public static telemetryControllerGetCoverageMetrics(
3600
+ data: TelemetryControllerGetCoverageMetricsData
3601
+ ): CancelablePromise<TelemetryControllerGetCoverageMetricsResponse> {
2818
3602
  return __request(OpenAPI, {
2819
- method: 'POST',
2820
- url: '/api/v1/{region}/bean/import/parser-telemetry',
3603
+ method: 'GET',
3604
+ url: '/api/v1/{region}/bean/import/parser-coverage-metrics',
2821
3605
  path: {
2822
3606
  region: data.region
2823
3607
  },
2824
- body: data.requestBody,
2825
- mediaType: 'application/json',
2826
- errors: {
2827
- 401: 'Unauthorized'
3608
+ query: {
3609
+ topN: data.topN
2828
3610
  }
2829
3611
  });
2830
3612
  }
@@ -2913,6 +3695,128 @@ export class BeanNlpService {
2913
3695
  }
2914
3696
  }
2915
3697
 
3698
+ export class BeanPlatformsService {
3699
+ /**
3700
+ * Get all platforms with statistics
3701
+ * @returns unknown List of platforms with binding and account counts
3702
+ * @throws ApiError
3703
+ */
3704
+ public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
3705
+ return __request(OpenAPI, {
3706
+ method: 'GET',
3707
+ url: '/api/v1/bean/platforms'
3708
+ });
3709
+ }
3710
+
3711
+ /**
3712
+ * Create a new platform
3713
+ * @param data The data for the request.
3714
+ * @param data.requestBody
3715
+ * @returns unknown Platform created successfully
3716
+ * @throws ApiError
3717
+ */
3718
+ public static platformControllerCreate(
3719
+ data: PlatformControllerCreateData
3720
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3721
+ return __request(OpenAPI, {
3722
+ method: 'POST',
3723
+ url: '/api/v1/bean/platforms',
3724
+ body: data.requestBody,
3725
+ mediaType: 'application/json',
3726
+ errors: {
3727
+ 409: 'Platform already exists'
3728
+ }
3729
+ });
3730
+ }
3731
+
3732
+ /**
3733
+ * Get platform list for current user
3734
+ * @param data The data for the request.
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
3737
+ * @throws ApiError
3738
+ */
3739
+ public static platformControllerGetPlatformList(
3740
+ data: PlatformControllerGetPlatformListData = {}
3741
+ ): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3742
+ return __request(OpenAPI, {
3743
+ method: 'GET',
3744
+ url: '/api/v1/bean/platforms/list',
3745
+ query: {
3746
+ region: data.region
3747
+ }
3748
+ });
3749
+ }
3750
+
3751
+ /**
3752
+ * Match platforms by name or alias
3753
+ * @param data The data for the request.
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
3757
+ * @throws ApiError
3758
+ */
3759
+ public static platformControllerMatchPlatforms(
3760
+ data: PlatformControllerMatchPlatformsData
3761
+ ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3762
+ return __request(OpenAPI, {
3763
+ method: 'GET',
3764
+ url: '/api/v1/bean/platforms/match',
3765
+ query: {
3766
+ q: data.q,
3767
+ region: data.region
3768
+ }
3769
+ });
3770
+ }
3771
+
3772
+ /**
3773
+ * Update a platform
3774
+ * @param data The data for the request.
3775
+ * @param data.id Platform ID
3776
+ * @param data.requestBody
3777
+ * @returns unknown Platform updated successfully
3778
+ * @throws ApiError
3779
+ */
3780
+ public static platformControllerUpdate(
3781
+ data: PlatformControllerUpdateData
3782
+ ): CancelablePromise<PlatformControllerUpdateResponse> {
3783
+ return __request(OpenAPI, {
3784
+ method: 'PUT',
3785
+ url: '/api/v1/bean/platforms/{id}',
3786
+ path: {
3787
+ id: data.id
3788
+ },
3789
+ body: data.requestBody,
3790
+ mediaType: 'application/json',
3791
+ errors: {
3792
+ 404: 'Platform not found'
3793
+ }
3794
+ });
3795
+ }
3796
+
3797
+ /**
3798
+ * Delete a platform
3799
+ * @param data The data for the request.
3800
+ * @param data.id Platform ID
3801
+ * @returns void Platform deleted successfully
3802
+ * @throws ApiError
3803
+ */
3804
+ public static platformControllerDelete(
3805
+ data: PlatformControllerDeleteData
3806
+ ): CancelablePromise<PlatformControllerDeleteResponse> {
3807
+ return __request(OpenAPI, {
3808
+ method: 'DELETE',
3809
+ url: '/api/v1/bean/platforms/{id}',
3810
+ path: {
3811
+ id: data.id
3812
+ },
3813
+ errors: {
3814
+ 404: 'Platform not found'
3815
+ }
3816
+ });
3817
+ }
3818
+ }
3819
+
2916
3820
  export class DashboardService {
2917
3821
  /**
2918
3822
  * Get net worth overview
@@ -2948,6 +3852,7 @@ export class DashboardService {
2948
3852
  * @param data.region Region code for tenant context
2949
3853
  * @param data.groupBy Grouping strategy
2950
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)
2951
3856
  * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
2952
3857
  * @throws ApiError
2953
3858
  */
@@ -2962,7 +3867,8 @@ export class DashboardService {
2962
3867
  },
2963
3868
  query: {
2964
3869
  groupBy: data.groupBy,
2965
- date: data.date
3870
+ date: data.date,
3871
+ accountId: data.accountId
2966
3872
  },
2967
3873
  errors: {
2968
3874
  401: 'User not authenticated'
@@ -2997,124 +3903,69 @@ export class DashboardService {
2997
3903
  }
2998
3904
  });
2999
3905
  }
3000
- }
3001
3906
 
3002
- export class ReportingService {
3003
3907
  /**
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
- *
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)
3017
3910
  * @param data The data for the request.
3018
3911
  * @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
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
3022
3916
  * @throws ApiError
3023
3917
  */
3024
- public static reportingControllerGetPortfolioTrends(
3025
- data: ReportingControllerGetPortfolioTrendsData
3026
- ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
3918
+ public static dashboardControllerGetExpenses(
3919
+ data: DashboardControllerGetExpensesData
3920
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3027
3921
  return __request(OpenAPI, {
3028
3922
  method: 'GET',
3029
- url: '/api/v1/{region}/reporting/portfolio/trends',
3923
+ url: '/api/v1/{region}/dashboard/expenses',
3030
3924
  path: {
3031
3925
  region: data.region
3032
3926
  },
3033
3927
  query: {
3928
+ groupBy: data.groupBy,
3034
3929
  period: data.period,
3035
- granularity: data.granularity
3930
+ flow: data.flow
3036
3931
  },
3037
3932
  errors: {
3933
+ 400: 'Invalid groupBy or period',
3038
3934
  401: 'User not authenticated'
3039
3935
  }
3040
3936
  });
3041
3937
  }
3938
+ }
3042
3939
 
3940
+ export class InvestmentService {
3043
3941
  /**
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
- *
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).
3058
3944
  * @param data The data for the request.
3059
3945
  * @param data.region Region code for tenant context
3060
- * @param data.requestBody Optional date (defaults to today)
3061
- * @returns GenerateSnapshotResponse Snapshot generated 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
3062
3950
  * @throws ApiError
3063
3951
  */
3064
- public static reportingControllerGenerateSnapshot(
3065
- data: ReportingControllerGenerateSnapshotData
3066
- ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
3952
+ public static holdingPnlControllerGetHoldingPnl(
3953
+ data: HoldingPnlControllerGetHoldingPnlData
3954
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3067
3955
  return __request(OpenAPI, {
3068
- method: 'POST',
3069
- url: '/api/v1/{region}/reporting/snapshots/generate',
3956
+ method: 'GET',
3957
+ url: '/api/v1/{region}/investment/holdings/pnl',
3070
3958
  path: {
3071
3959
  region: data.region
3072
3960
  },
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
3961
+ query: {
3962
+ asOf: data.asOf,
3963
+ accountId: data.accountId,
3964
+ method: data.method
3111
3965
  },
3112
- body: data.requestBody,
3113
- mediaType: 'application/json',
3114
3966
  errors: {
3115
- 400: 'Invalid date format or range',
3116
- 401: 'User not authenticated',
3117
- 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'
3118
3969
  }
3119
3970
  });
3120
3971
  }
@@ -3143,7 +3994,7 @@ export class AuthService {
3143
3994
  * Anonymous login with access token
3144
3995
  * @param data The data for the request.
3145
3996
  * @param data.requestBody
3146
- * @returns unknown Login successful
3997
+ * @returns AnonymousLoginResponseDto Login successful
3147
3998
  * @throws ApiError
3148
3999
  */
3149
4000
  public static authControllerAccessTokenLogin(
@@ -3330,3 +4181,53 @@ export class InfoService {
3330
4181
  });
3331
4182
  }
3332
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
+ }