@firela/api-types 0.0.0-canary.da5984a1 → 0.0.0-canary.da8dfd93

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,50 @@ 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
+ CategoryCatalogControllerListData,
197
+ CategoryCatalogControllerListResponse,
198
+ EventControllerCreateData,
199
+ EventControllerCreateResponse,
200
+ EventControllerFindAllData,
201
+ EventControllerFindAllResponse,
202
+ EventControllerFindOneData,
203
+ EventControllerFindOneResponse,
204
+ EventControllerUpdateData,
205
+ EventControllerUpdateResponse,
206
+ EventControllerDeleteData,
207
+ EventControllerDeleteResponse,
208
+ EventControllerGetSliceData,
209
+ EventControllerGetSliceResponse,
210
+ OnboardingControllerBootstrapData,
211
+ OnboardingControllerBootstrapResponse,
212
+ ReconciliationControllerComputeData,
213
+ ReconciliationControllerComputeResponse,
214
+ ReconciliationControllerAssertData,
215
+ ReconciliationControllerAssertResponse,
216
+ ReconciliationControllerPadData,
217
+ ReconciliationControllerPadResponse,
218
+ ReconciliationControllerHistoryData,
219
+ ReconciliationControllerHistoryResponse,
172
220
  ExportControllerExportBeancountResponse,
173
221
  FileImportControllerImportFileData,
174
222
  FileImportControllerImportFileResponse,
@@ -182,42 +230,53 @@ import type {
182
230
  ImporterConfigControllerUpdateConfigResponse,
183
231
  ImporterConfigControllerResetConfigData,
184
232
  ImporterConfigControllerResetConfigResponse,
185
- PlatformControllerFindAllResponse,
186
- PlatformControllerCreateData,
187
- PlatformControllerCreateResponse,
188
- PlatformControllerGetPlatformListResponse,
189
- PlatformControllerMatchPlatformsData,
190
- PlatformControllerMatchPlatformsResponse,
191
- PlatformControllerUpdateData,
192
- PlatformControllerUpdateResponse,
193
- PlatformControllerDeleteData,
194
- PlatformControllerDeleteResponse,
195
233
  ProviderSyncControllerSyncData,
196
234
  ProviderSyncControllerSyncResponse,
197
235
  ProviderSyncControllerGetSupportedProvidersData,
198
236
  ProviderSyncControllerGetSupportedProvidersResponse,
199
237
  ProviderSyncControllerIsProviderSupportedData,
200
238
  ProviderSyncControllerIsProviderSupportedResponse,
239
+ ExternalAccountLinkControllerCreateData,
240
+ ExternalAccountLinkControllerCreateResponse,
241
+ ExternalAccountLinkControllerFindAllData,
242
+ ExternalAccountLinkControllerFindAllResponse,
243
+ ExternalAccountLinkControllerFindOneData,
244
+ ExternalAccountLinkControllerFindOneResponse,
245
+ ExternalAccountLinkControllerRemoveData,
246
+ ExternalAccountLinkControllerRemoveResponse,
201
247
  TelemetryControllerReportTelemetryData,
202
248
  TelemetryControllerReportTelemetryResponse,
249
+ TelemetryControllerReportCoverageMissData,
250
+ TelemetryControllerReportCoverageMissResponse,
251
+ TelemetryControllerGetCoverageMetricsData,
252
+ TelemetryControllerGetCoverageMetricsResponse,
203
253
  NlpControllerProcessNaturalLanguageData,
204
254
  NlpControllerProcessNaturalLanguageResponse,
205
255
  NlpControllerClearSessionData,
206
256
  NlpControllerClearSessionResponse,
207
257
  NlpControllerGetSessionData,
208
258
  NlpControllerGetSessionResponse,
259
+ PlatformControllerFindAllResponse,
260
+ PlatformControllerCreateData,
261
+ PlatformControllerCreateResponse,
262
+ PlatformControllerGetPlatformListData,
263
+ PlatformControllerGetPlatformListResponse,
264
+ PlatformControllerMatchPlatformsData,
265
+ PlatformControllerMatchPlatformsResponse,
266
+ PlatformControllerUpdateData,
267
+ PlatformControllerUpdateResponse,
268
+ PlatformControllerDeleteData,
269
+ PlatformControllerDeleteResponse,
209
270
  DashboardControllerGetNetWorthData,
210
271
  DashboardControllerGetNetWorthResponse,
211
272
  DashboardControllerGetAccountsData,
212
273
  DashboardControllerGetAccountsResponse,
213
274
  DashboardControllerGetCashFlowData,
214
275
  DashboardControllerGetCashFlowResponse,
215
- ReportingControllerGetPortfolioTrendsData,
216
- ReportingControllerGetPortfolioTrendsResponse,
217
- ReportingControllerGenerateSnapshotData,
218
- ReportingControllerGenerateSnapshotResponse,
219
- ReportingControllerBackfillSnapshotsData,
220
- ReportingControllerBackfillSnapshotsResponse,
276
+ DashboardControllerGetExpensesData,
277
+ DashboardControllerGetExpensesResponse,
278
+ HoldingPnlControllerGetHoldingPnlData,
279
+ HoldingPnlControllerGetHoldingPnlResponse,
221
280
  ApiKeysControllerCreateApiKeyResponse,
222
281
  AuthControllerAccessTokenLoginData,
223
282
  AuthControllerAccessTokenLoginResponse,
@@ -232,7 +291,11 @@ import type {
232
291
  HealthControllerResetCircuitBreakerData,
233
292
  HealthControllerResetCircuitBreakerResponse,
234
293
  HealthControllerGetMetricsResponse,
235
- InfoControllerGetInfoResponse
294
+ InfoControllerGetInfoResponse,
295
+ SymbolControllerSearchData,
296
+ SymbolControllerSearchResponse,
297
+ SymbolControllerGetQuoteData,
298
+ SymbolControllerGetQuoteResponse
236
299
  } from './types.gen';
237
300
 
238
301
  export class BeanAccountsService {
@@ -270,7 +333,7 @@ export class BeanAccountsService {
270
333
  * @param data.type Filter by account type
271
334
  * @param data.status Filter by status
272
335
  * @param data.isCustom Filter by custom (user-created) accounts only
273
- * @param data.search Search term for path or i18nKey
336
+ * @param data.search Search term for account path
274
337
  * @param data.limit Maximum number of results
275
338
  * @param data.offset Number of results to skip
276
339
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -351,7 +414,7 @@ export class BeanAccountsService {
351
414
 
352
415
  /**
353
416
  * Delete account
354
- * Deletes an account (only if no transactions)
417
+ * Deletes an account (only if no active transactions; voided/superseded residual postings are cleaned up)
355
418
  * @param data The data for the request.
356
419
  * @param data.id Account UUID
357
420
  * @param data.region Region code for tenant context
@@ -370,7 +433,7 @@ export class BeanAccountsService {
370
433
  },
371
434
  errors: {
372
435
  404: 'Account not found',
373
- 409: 'Account has transactions and cannot be deleted'
436
+ 409: 'Account has active transactions and cannot be deleted'
374
437
  }
375
438
  });
376
439
  }
@@ -432,6 +495,35 @@ export class BeanAccountsService {
432
495
  }
433
496
  });
434
497
  }
498
+
499
+ /**
500
+ * Post an opening-balance transaction
501
+ * Posts a double-entry opening-balance transaction against Equity:Opening-Balances for an existing Assets/Liabilities account. At most one active opening balance per account.
502
+ * @param data The data for the request.
503
+ * @param data.id Account UUID
504
+ * @param data.region Region code for tenant context
505
+ * @param data.requestBody
506
+ * @returns OpeningBalanceResultDto Opening-balance transaction created
507
+ * @throws ApiError
508
+ */
509
+ public static accountControllerAddOpeningBalance(
510
+ data: AccountControllerAddOpeningBalanceData
511
+ ): CancelablePromise<AccountControllerAddOpeningBalanceResponse> {
512
+ return __request(OpenAPI, {
513
+ method: 'POST',
514
+ url: '/api/v1/{region}/bean/accounts/{id}/opening-balance',
515
+ path: {
516
+ id: data.id,
517
+ region: data.region
518
+ },
519
+ body: data.requestBody,
520
+ mediaType: 'application/json',
521
+ errors: {
522
+ 404: 'Account not found',
523
+ 409: 'An opening balance already exists for this account'
524
+ }
525
+ });
526
+ }
435
527
  }
436
528
 
437
529
  export class BeanAccountStandardsService {
@@ -463,7 +555,7 @@ export class BeanAccountStandardsService {
463
555
 
464
556
  /**
465
557
  * Get template metadata for an account path
466
- * Returns extendable status and root type for a template path.
558
+ * Returns root type for a template path.
467
559
  * @param data The data for the request.
468
560
  * @param data.region Region code for tenant context
469
561
  * @param data.path Account path to check
@@ -549,6 +641,7 @@ export class BeanTransactionsService {
549
641
  * @param data.status Filter by transaction status
550
642
  * @param data.search Search in narration and payee fields (max 200 chars)
551
643
  * @param data.accountId Filter by account ID (transactions with postings to this account)
644
+ * @param data.category Filter by ADR-0075 functional category (Group segment); matches any posting to an Expenses/Income account whose derived Group segment equals this value
552
645
  * @returns TransactionListResponseDto Transaction list
553
646
  * @throws ApiError
554
647
  */
@@ -568,7 +661,8 @@ export class BeanTransactionsService {
568
661
  dateTo: data.dateTo,
569
662
  status: data.status,
570
663
  search: data.search,
571
- accountId: data.accountId
664
+ accountId: data.accountId,
665
+ category: data.category
572
666
  },
573
667
  errors: {
574
668
  400: 'Validation failed',
@@ -605,6 +699,36 @@ export class BeanTransactionsService {
605
699
  });
606
700
  }
607
701
 
702
+ /**
703
+ * Correct (supersede) a transaction
704
+ * Atomically voids the original (SUPERSEDED) and creates a replacement through the full validation pipeline.
705
+ * @param data The data for the request.
706
+ * @param data.id Original transaction ID to correct
707
+ * @param data.region Region code for tenant context
708
+ * @param data.requestBody
709
+ * @returns TransactionDetailDto Corrected transaction created
710
+ * @throws ApiError
711
+ */
712
+ public static transactionControllerCorrect(
713
+ data: TransactionControllerCorrectData
714
+ ): CancelablePromise<TransactionControllerCorrectResponse> {
715
+ return __request(OpenAPI, {
716
+ method: 'POST',
717
+ url: '/api/v1/{region}/bean/transactions/{id}/correct',
718
+ path: {
719
+ id: data.id,
720
+ region: data.region
721
+ },
722
+ body: data.requestBody,
723
+ mediaType: 'application/json',
724
+ errors: {
725
+ 404: 'Original transaction not found',
726
+ 409: 'Original no longer ACTIVE (concurrent modification)',
727
+ 422: 'Pipeline validation failed (does not balance, invalid accounts)'
728
+ }
729
+ });
730
+ }
731
+
608
732
  /**
609
733
  * Suggest transaction tags
610
734
  * Returns distinct tags from the user ACTIVE transactions, sorted by usage, for autocomplete. Optional q performs a case-insensitive prefix match.
@@ -726,7 +850,7 @@ export class BeanBalancesService {
726
850
  * Query account balance
727
851
  * Calculate account balance at a specific date for a single currency
728
852
  * @param data The data for the request.
729
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
853
+ * @param data.account Account name (e.g., "Assets:Checking")
730
854
  * @param data.region Region code for tenant context
731
855
  * @param data.date Date to calculate balance at (ISO 8601 format)
732
856
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -1447,6 +1571,173 @@ export class BeanCommoditiesService {
1447
1571
  }
1448
1572
  }
1449
1573
 
1574
+ export class BeanPricesService {
1575
+ /**
1576
+ * Create a new price
1577
+ * Creates a new price entry for the authenticated user
1578
+ * @param data The data for the request.
1579
+ * @param data.region Region code for tenant context
1580
+ * @param data.requestBody
1581
+ * @returns PriceResponseDto Price created successfully
1582
+ * @throws ApiError
1583
+ */
1584
+ public static priceControllerCreate(
1585
+ data: PriceControllerCreateData
1586
+ ): CancelablePromise<PriceControllerCreateResponse> {
1587
+ return __request(OpenAPI, {
1588
+ method: 'POST',
1589
+ url: '/api/v1/{region}/bean/prices',
1590
+ path: {
1591
+ region: data.region
1592
+ },
1593
+ body: data.requestBody,
1594
+ mediaType: 'application/json',
1595
+ errors: {
1596
+ 404: 'Currency or quoteCurrency commodity not found',
1597
+ 409: 'Price already exists for this currency pair and date'
1598
+ }
1599
+ });
1600
+ }
1601
+
1602
+ /**
1603
+ * List user prices
1604
+ * Returns all price entries for the authenticated user with optional filtering
1605
+ * @param data The data for the request.
1606
+ * @param data.region Region code for tenant context
1607
+ * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
1608
+ * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
1609
+ * @param data.dateFrom Filter prices from this date (ISO 8601 format)
1610
+ * @param data.dateTo Filter prices to this date (ISO 8601 format)
1611
+ * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
1612
+ * @param data.page Page number for pagination (default: 1)
1613
+ * @param data.limit Number of items per page (default: 20, max: 100)
1614
+ * @returns PriceListResponseDto Prices retrieved successfully
1615
+ * @throws ApiError
1616
+ */
1617
+ public static priceControllerFindAll(
1618
+ data: PriceControllerFindAllData
1619
+ ): CancelablePromise<PriceControllerFindAllResponse> {
1620
+ return __request(OpenAPI, {
1621
+ method: 'GET',
1622
+ url: '/api/v1/{region}/bean/prices',
1623
+ path: {
1624
+ region: data.region
1625
+ },
1626
+ query: {
1627
+ currency: data.currency,
1628
+ quoteCurrency: data.quoteCurrency,
1629
+ dateFrom: data.dateFrom,
1630
+ dateTo: data.dateTo,
1631
+ search: data.search,
1632
+ page: data.page,
1633
+ limit: data.limit
1634
+ }
1635
+ });
1636
+ }
1637
+
1638
+ /**
1639
+ * Get price by ID
1640
+ * Returns a single price entry by its ID
1641
+ * @param data The data for the request.
1642
+ * @param data.id Price ID
1643
+ * @param data.region Region code for tenant context
1644
+ * @returns PriceResponseDto Price retrieved successfully
1645
+ * @throws ApiError
1646
+ */
1647
+ public static priceControllerFindOne(
1648
+ data: PriceControllerFindOneData
1649
+ ): CancelablePromise<PriceControllerFindOneResponse> {
1650
+ return __request(OpenAPI, {
1651
+ method: 'GET',
1652
+ url: '/api/v1/{region}/bean/prices/{id}',
1653
+ path: {
1654
+ id: data.id,
1655
+ region: data.region
1656
+ },
1657
+ errors: {
1658
+ 404: 'Price not found'
1659
+ }
1660
+ });
1661
+ }
1662
+
1663
+ /**
1664
+ * Update a price
1665
+ * Updates an existing price entry
1666
+ * @param data The data for the request.
1667
+ * @param data.id Price ID
1668
+ * @param data.region Region code for tenant context
1669
+ * @param data.requestBody
1670
+ * @returns PriceResponseDto Price updated successfully
1671
+ * @throws ApiError
1672
+ */
1673
+ public static priceControllerUpdate(
1674
+ data: PriceControllerUpdateData
1675
+ ): CancelablePromise<PriceControllerUpdateResponse> {
1676
+ return __request(OpenAPI, {
1677
+ method: 'PUT',
1678
+ url: '/api/v1/{region}/bean/prices/{id}',
1679
+ path: {
1680
+ id: data.id,
1681
+ region: data.region
1682
+ },
1683
+ body: data.requestBody,
1684
+ mediaType: 'application/json',
1685
+ errors: {
1686
+ 404: 'Price not found',
1687
+ 409: 'Updated price conflicts with existing price'
1688
+ }
1689
+ });
1690
+ }
1691
+
1692
+ /**
1693
+ * Delete a price
1694
+ * Deletes a price entry (hard delete)
1695
+ * @param data The data for the request.
1696
+ * @param data.id Price ID
1697
+ * @param data.region Region code for tenant context
1698
+ * @returns void Price deleted successfully
1699
+ * @throws ApiError
1700
+ */
1701
+ public static priceControllerDelete(
1702
+ data: PriceControllerDeleteData
1703
+ ): CancelablePromise<PriceControllerDeleteResponse> {
1704
+ return __request(OpenAPI, {
1705
+ method: 'DELETE',
1706
+ url: '/api/v1/{region}/bean/prices/{id}',
1707
+ path: {
1708
+ id: data.id,
1709
+ region: data.region
1710
+ },
1711
+ errors: {
1712
+ 404: 'Price not found'
1713
+ }
1714
+ });
1715
+ }
1716
+
1717
+ /**
1718
+ * Bulk create prices
1719
+ * Creates multiple price entries at once (skips duplicates)
1720
+ * @param data The data for the request.
1721
+ * @param data.region Region code for tenant context
1722
+ * @param data.requestBody
1723
+ * @returns PriceResponseDto Prices created successfully
1724
+ * @throws ApiError
1725
+ */
1726
+ public static priceControllerBulkCreate(
1727
+ data: PriceControllerBulkCreateData
1728
+ ): CancelablePromise<PriceControllerBulkCreateResponse> {
1729
+ return __request(OpenAPI, {
1730
+ method: 'POST',
1731
+ url: '/api/v1/{region}/bean/prices/bulk',
1732
+ path: {
1733
+ region: data.region
1734
+ },
1735
+ body: data.requestBody,
1736
+ mediaType: 'application/json'
1737
+ });
1738
+ }
1739
+ }
1740
+
1450
1741
  export class RecurringRulesService {
1451
1742
  /**
1452
1743
  * Create a new recurring rule
@@ -1877,279 +2168,158 @@ export class RecurringForecastService {
1877
2168
  }
1878
2169
  }
1879
2170
 
1880
- export class BeanTransactionRulesService {
2171
+ export class ReportingService {
1881
2172
  /**
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.
2173
+ * Get portfolio value trends
2174
+ *
2175
+ * Returns time series data of portfolio net worth.
2176
+ *
2177
+ * **Multi-currency Support:**
2178
+ * - `series[].byCurrency` - Currency breakdown for each data point
2179
+ * - `byCurrency` - Separate time series grouped by currency
2180
+ * - `warnings` - Exchange rate warnings if conversion failed
2181
+ *
2182
+ * **Parameters:**
2183
+ * - `period`: Time period (1m, 3m, 6m, 1y)
2184
+ * - `granularity`: Data granularity (day, week, month)
2185
+ *
1884
2186
  * @param data The data for the request.
1885
2187
  * @param data.region Region code for tenant context
1886
- * @param data.requestBody
1887
- * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2188
+ * @param data.period Time period
2189
+ * @param data.granularity Data granularity
2190
+ * @returns PortfolioTrendsResponseDto Trends retrieved successfully
1888
2191
  * @throws ApiError
1889
2192
  */
1890
- public static transactionRuleControllerCreate(
1891
- data: TransactionRuleControllerCreateData
1892
- ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2193
+ public static reportingControllerGetPortfolioTrends(
2194
+ data: ReportingControllerGetPortfolioTrendsData
2195
+ ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
1893
2196
  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',
2197
+ method: 'GET',
2198
+ url: '/api/v1/{region}/reporting/portfolio/trends',
1927
2199
  path: {
1928
2200
  region: data.region
1929
2201
  },
1930
2202
  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
2203
+ period: data.period,
2204
+ granularity: data.granularity
1985
2205
  },
1986
- body: data.requestBody,
1987
- mediaType: 'application/json',
1988
2206
  errors: {
1989
- 400: 'Invalid bulk create data',
1990
- 401: 'Unauthorized'
2207
+ 401: 'User not authenticated'
1991
2208
  }
1992
2209
  });
1993
2210
  }
1994
2211
 
1995
2212
  /**
1996
- * Export transaction rules
2213
+ * Get cash-flow trends
2214
+ *
2215
+ * Monthly income / expense / netSavings over a fixed N-month window
2216
+ * (current month + N−1 prior). Missing months are zero-filled (flow metric).
2217
+ *
2218
+ * **Parameters:**
2219
+ * - `period`: 1m | 3m | 6m | 1y (default 6m)
2220
+ * - `granularity`: accepted for API symmetry; v1 returns month buckets
2221
+ *
1997
2222
  * @param data The data for the request.
1998
- * @param data.format Export format (currently only JSON supported)
1999
2223
  * @param data.region Region code for tenant context
2000
- * @returns ExportRulesResponseDto Exported rules
2224
+ * @param data.period Time period
2225
+ * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
2226
+ * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
2001
2227
  * @throws ApiError
2002
2228
  */
2003
- public static transactionRuleControllerExport(
2004
- data: TransactionRuleControllerExportData
2005
- ): CancelablePromise<TransactionRuleControllerExportResponse> {
2229
+ public static reportingControllerGetCashFlowTrends(
2230
+ data: ReportingControllerGetCashFlowTrendsData
2231
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
2006
2232
  return __request(OpenAPI, {
2007
2233
  method: 'GET',
2008
- url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2234
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
2009
2235
  path: {
2010
- format: data.format,
2011
2236
  region: data.region
2012
2237
  },
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: {
2238
+ query: {
2035
2239
  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
2240
+ granularity: data.granularity
2061
2241
  },
2062
2242
  errors: {
2063
- 401: 'Unauthorized',
2064
- 403: 'Forbidden - not owner of rule',
2065
- 404: 'Rule not found'
2243
+ 401: 'User not authenticated'
2066
2244
  }
2067
2245
  });
2068
2246
  }
2069
2247
 
2070
2248
  /**
2071
- * Update a transaction rule
2249
+ * Generate portfolio snapshot
2250
+ *
2251
+ * Manually generate a portfolio snapshot for a specific date.
2252
+ *
2253
+ * **Multi-currency Support:**
2254
+ * - Fetches balances grouped by currency
2255
+ * - Uses user's baseCurrency setting for conversion
2256
+ * - Stores exchange rates and warnings
2257
+ *
2258
+ * **Use Cases:**
2259
+ * - Testing snapshot generation
2260
+ * - Force regeneration after data correction
2261
+ * - Initial setup for new users
2262
+ *
2072
2263
  * @param data The data for the request.
2073
- * @param data.ruleId Rule ID to update
2074
2264
  * @param data.region Region code for tenant context
2075
- * @param data.requestBody
2076
- * @returns TransactionRuleResponseDto Rule updated successfully
2265
+ * @param data.requestBody Optional date (defaults to today)
2266
+ * @returns GenerateSnapshotResponse Snapshot generated successfully
2077
2267
  * @throws ApiError
2078
2268
  */
2079
- public static transactionRuleControllerUpdate(
2080
- data: TransactionRuleControllerUpdateData
2081
- ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2269
+ public static reportingControllerGenerateSnapshot(
2270
+ data: ReportingControllerGenerateSnapshotData
2271
+ ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
2082
2272
  return __request(OpenAPI, {
2083
- method: 'PUT',
2084
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2273
+ method: 'POST',
2274
+ url: '/api/v1/{region}/reporting/snapshots/generate',
2085
2275
  path: {
2086
- ruleId: data.ruleId,
2087
2276
  region: data.region
2088
2277
  },
2089
2278
  body: data.requestBody,
2090
2279
  mediaType: 'application/json',
2091
2280
  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'
2281
+ 400: 'Invalid date format',
2282
+ 401: 'User not authenticated'
2124
2283
  }
2125
2284
  });
2126
2285
  }
2127
2286
 
2128
2287
  /**
2129
- * Test rule matching
2288
+ * Backfill portfolio snapshots
2289
+ *
2290
+ * Generate snapshots for a date range (historical data backfill).
2291
+ *
2292
+ * **Multi-currency Support:**
2293
+ * - Each snapshot includes multi-currency data
2294
+ * - Uses exchange rates available at generation time
2295
+ * - Warnings stored for missing exchange rates
2296
+ *
2297
+ * **Best Practices:**
2298
+ * - Use for initial setup after account configuration
2299
+ * - Run during low-traffic periods for large date ranges
2300
+ * - Existing snapshots are skipped (not regenerated)
2301
+ *
2130
2302
  * @param data The data for the request.
2131
- * @param data.ruleId Rule ID to test
2132
2303
  * @param data.region Region code for tenant context
2133
2304
  * @param data.requestBody
2134
- * @returns TestRuleResponseDto Test result
2305
+ * @returns BackfillSnapshotsResponse Backfill completed successfully
2135
2306
  * @throws ApiError
2136
2307
  */
2137
- public static transactionRuleControllerTest(
2138
- data: TransactionRuleControllerTestData
2139
- ): CancelablePromise<TransactionRuleControllerTestResponse> {
2308
+ public static reportingControllerBackfillSnapshots(
2309
+ data: ReportingControllerBackfillSnapshotsData
2310
+ ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
2140
2311
  return __request(OpenAPI, {
2141
2312
  method: 'POST',
2142
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2313
+ url: '/api/v1/{region}/reporting/snapshots/backfill',
2143
2314
  path: {
2144
- ruleId: data.ruleId,
2145
2315
  region: data.region
2146
2316
  },
2147
2317
  body: data.requestBody,
2148
2318
  mediaType: 'application/json',
2149
2319
  errors: {
2150
- 401: 'Unauthorized',
2151
- 403: 'Forbidden - not owner of rule',
2152
- 404: 'Rule not found'
2320
+ 400: 'Invalid date format or range',
2321
+ 401: 'User not authenticated',
2322
+ 409: 'Backfill already in progress for this user'
2153
2323
  }
2154
2324
  });
2155
2325
  }
@@ -2181,7 +2351,7 @@ export class UsersService {
2181
2351
  * Get current authenticated user
2182
2352
  * @param data The data for the request.
2183
2353
  * @param data.acceptLanguage
2184
- * @returns unknown User retrieved successfully
2354
+ * @returns UserResponseDto User retrieved successfully
2185
2355
  * @throws ApiError
2186
2356
  */
2187
2357
  public static userControllerGetUser(
@@ -2201,7 +2371,7 @@ export class UsersService {
2201
2371
  * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
2202
2372
  * @param data The data for the request.
2203
2373
  * @param data.requestBody
2204
- * @returns unknown User created successfully
2374
+ * @returns SignupResponseDto User created successfully
2205
2375
  * @throws ApiError
2206
2376
  */
2207
2377
  public static userControllerSignupUser(
@@ -2410,11 +2580,625 @@ export class PropertiesService {
2410
2580
  }
2411
2581
  }
2412
2582
 
2413
- export class BeanExportService {
2583
+ export class BeanTransactionRulesService {
2414
2584
  /**
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
2585
+ * Create a new transaction rule (or upsert if upsertByPayee=true)
2586
+ * Creates a new rule. If upsertByPayee=true, updates existing rule matching payeeKeywords[0] instead of creating duplicate.
2587
+ * @param data The data for the request.
2588
+ * @param data.region Region code for tenant context
2589
+ * @param data.requestBody
2590
+ * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2591
+ * @throws ApiError
2592
+ */
2593
+ public static transactionRuleControllerCreate(
2594
+ data: TransactionRuleControllerCreateData
2595
+ ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2596
+ return __request(OpenAPI, {
2597
+ method: 'POST',
2598
+ url: '/api/v1/{region}/bean/transaction-rules',
2599
+ path: {
2600
+ region: data.region
2601
+ },
2602
+ body: data.requestBody,
2603
+ mediaType: 'application/json',
2604
+ errors: {
2605
+ 400: 'Validation failed',
2606
+ 401: 'Unauthorized',
2607
+ 409: 'Resource conflict - another process is updating this rule'
2608
+ }
2609
+ });
2610
+ }
2611
+
2612
+ /**
2613
+ * Get all transaction rules for user
2614
+ * @param data The data for the request.
2615
+ * @param data.region Region code for tenant context
2616
+ * @param data.limit Max results per page (default: 20, max: 100)
2617
+ * @param data.offset Pagination offset (default: 0)
2618
+ * @param data.enabled Filter by enabled status
2619
+ * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
2620
+ * @param data.autoApplyEnabled Filter by auto-apply status
2621
+ * @returns TransactionRuleListResponseDto List of rules
2622
+ * @throws ApiError
2623
+ */
2624
+ public static transactionRuleControllerList(
2625
+ data: TransactionRuleControllerListData
2626
+ ): CancelablePromise<TransactionRuleControllerListResponse> {
2627
+ return __request(OpenAPI, {
2628
+ method: 'GET',
2629
+ url: '/api/v1/{region}/bean/transaction-rules',
2630
+ path: {
2631
+ region: data.region
2632
+ },
2633
+ query: {
2634
+ limit: data.limit,
2635
+ offset: data.offset,
2636
+ enabled: data.enabled,
2637
+ learningSource: data.learningSource,
2638
+ autoApplyEnabled: data.autoApplyEnabled
2639
+ },
2640
+ errors: {
2641
+ 401: 'Unauthorized'
2642
+ }
2643
+ });
2644
+ }
2645
+
2646
+ /**
2647
+ * Validate transaction rule configuration
2648
+ * @param data The data for the request.
2649
+ * @param data.region Region code for tenant context
2650
+ * @param data.requestBody
2651
+ * @returns ValidateRuleResponseDto Validation result
2652
+ * @throws ApiError
2653
+ */
2654
+ public static transactionRuleControllerValidate(
2655
+ data: TransactionRuleControllerValidateData
2656
+ ): CancelablePromise<TransactionRuleControllerValidateResponse> {
2657
+ return __request(OpenAPI, {
2658
+ method: 'POST',
2659
+ url: '/api/v1/{region}/bean/transaction-rules/validate',
2660
+ path: {
2661
+ region: data.region
2662
+ },
2663
+ body: data.requestBody,
2664
+ mediaType: 'application/json',
2665
+ errors: {
2666
+ 400: 'Validation failed',
2667
+ 401: 'Unauthorized'
2668
+ }
2669
+ });
2670
+ }
2671
+
2672
+ /**
2673
+ * Bulk create transaction rules
2674
+ * @param data The data for the request.
2675
+ * @param data.region Region code for tenant context
2676
+ * @param data.requestBody
2677
+ * @returns BulkCreateRulesResponseDto Bulk create completed
2678
+ * @throws ApiError
2679
+ */
2680
+ public static transactionRuleControllerBulkCreate(
2681
+ data: TransactionRuleControllerBulkCreateData
2682
+ ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
2683
+ return __request(OpenAPI, {
2684
+ method: 'POST',
2685
+ url: '/api/v1/{region}/bean/transaction-rules/bulk',
2686
+ path: {
2687
+ region: data.region
2688
+ },
2689
+ body: data.requestBody,
2690
+ mediaType: 'application/json',
2691
+ errors: {
2692
+ 400: 'Invalid bulk create data',
2693
+ 401: 'Unauthorized'
2694
+ }
2695
+ });
2696
+ }
2697
+
2698
+ /**
2699
+ * Export transaction rules
2700
+ * @param data The data for the request.
2701
+ * @param data.format Export format (currently only JSON supported)
2702
+ * @param data.region Region code for tenant context
2703
+ * @returns ExportRulesResponseDto Exported rules
2704
+ * @throws ApiError
2705
+ */
2706
+ public static transactionRuleControllerExport(
2707
+ data: TransactionRuleControllerExportData
2708
+ ): CancelablePromise<TransactionRuleControllerExportResponse> {
2709
+ return __request(OpenAPI, {
2710
+ method: 'GET',
2711
+ url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2712
+ path: {
2713
+ format: data.format,
2714
+ region: data.region
2715
+ },
2716
+ errors: {
2717
+ 400: 'Unsupported format',
2718
+ 401: 'Unauthorized'
2719
+ }
2720
+ });
2721
+ }
2722
+
2723
+ /**
2724
+ * Get transaction rule statistics
2725
+ * @param data The data for the request.
2726
+ * @param data.period Statistics time period
2727
+ * @param data.region Region code for tenant context
2728
+ * @returns RuleStatisticsResponseDto Rule statistics
2729
+ * @throws ApiError
2730
+ */
2731
+ public static transactionRuleControllerGetStatistics(
2732
+ data: TransactionRuleControllerGetStatisticsData
2733
+ ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
2734
+ return __request(OpenAPI, {
2735
+ method: 'GET',
2736
+ url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
2737
+ path: {
2738
+ period: data.period,
2739
+ region: data.region
2740
+ },
2741
+ errors: {
2742
+ 401: 'Unauthorized'
2743
+ }
2744
+ });
2745
+ }
2746
+
2747
+ /**
2748
+ * Get transaction rule detail
2749
+ * @param data The data for the request.
2750
+ * @param data.ruleId Rule ID
2751
+ * @param data.region Region code for tenant context
2752
+ * @returns TransactionRuleResponseDto Rule details
2753
+ * @throws ApiError
2754
+ */
2755
+ public static transactionRuleControllerGetDetail(
2756
+ data: TransactionRuleControllerGetDetailData
2757
+ ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
2758
+ return __request(OpenAPI, {
2759
+ method: 'GET',
2760
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2761
+ path: {
2762
+ ruleId: data.ruleId,
2763
+ region: data.region
2764
+ },
2765
+ errors: {
2766
+ 401: 'Unauthorized',
2767
+ 403: 'Forbidden - not owner of rule',
2768
+ 404: 'Rule not found'
2769
+ }
2770
+ });
2771
+ }
2772
+
2773
+ /**
2774
+ * Update a transaction rule
2775
+ * @param data The data for the request.
2776
+ * @param data.ruleId Rule ID to update
2777
+ * @param data.region Region code for tenant context
2778
+ * @param data.requestBody
2779
+ * @returns TransactionRuleResponseDto Rule updated successfully
2780
+ * @throws ApiError
2781
+ */
2782
+ public static transactionRuleControllerUpdate(
2783
+ data: TransactionRuleControllerUpdateData
2784
+ ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2785
+ return __request(OpenAPI, {
2786
+ method: 'PUT',
2787
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2788
+ path: {
2789
+ ruleId: data.ruleId,
2790
+ region: data.region
2791
+ },
2792
+ body: data.requestBody,
2793
+ mediaType: 'application/json',
2794
+ errors: {
2795
+ 400: 'Validation failed',
2796
+ 401: 'Unauthorized',
2797
+ 403: 'Forbidden - not owner of rule',
2798
+ 404: 'Rule not found',
2799
+ 409: 'Resource conflict - rule is being modified by another process'
2800
+ }
2801
+ });
2802
+ }
2803
+
2804
+ /**
2805
+ * Delete a transaction rule
2806
+ * @param data The data for the request.
2807
+ * @param data.ruleId Rule ID to delete
2808
+ * @param data.region Region code for tenant context
2809
+ * @returns void Rule deleted successfully
2810
+ * @throws ApiError
2811
+ */
2812
+ public static transactionRuleControllerDelete(
2813
+ data: TransactionRuleControllerDeleteData
2814
+ ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2815
+ return __request(OpenAPI, {
2816
+ method: 'DELETE',
2817
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2818
+ path: {
2819
+ ruleId: data.ruleId,
2820
+ region: data.region
2821
+ },
2822
+ errors: {
2823
+ 401: 'Unauthorized',
2824
+ 403: 'Forbidden - not owner of rule',
2825
+ 404: 'Rule not found',
2826
+ 409: 'Resource conflict - rule is being modified by another process'
2827
+ }
2828
+ });
2829
+ }
2830
+
2831
+ /**
2832
+ * Test rule matching
2833
+ * @param data The data for the request.
2834
+ * @param data.ruleId Rule ID to test
2835
+ * @param data.region Region code for tenant context
2836
+ * @param data.requestBody
2837
+ * @returns TestRuleResponseDto Test result
2838
+ * @throws ApiError
2839
+ */
2840
+ public static transactionRuleControllerTest(
2841
+ data: TransactionRuleControllerTestData
2842
+ ): CancelablePromise<TransactionRuleControllerTestResponse> {
2843
+ return __request(OpenAPI, {
2844
+ method: 'POST',
2845
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2846
+ path: {
2847
+ ruleId: data.ruleId,
2848
+ region: data.region
2849
+ },
2850
+ body: data.requestBody,
2851
+ mediaType: 'application/json',
2852
+ errors: {
2853
+ 401: 'Unauthorized',
2854
+ 403: 'Forbidden - not owner of rule',
2855
+ 404: 'Rule not found'
2856
+ }
2857
+ });
2858
+ }
2859
+ }
2860
+
2861
+ export class BeanCategoryCatalogService {
2862
+ /**
2863
+ * List category catalog for a region
2864
+ * Returns the region-scoped category slugs (expense/income/investment/banking/transfer/payment) for the NLP result picker. CN-exclusive payment instruments (huabei/baitiao) appear only under /cn.
2865
+ * @param data The data for the request.
2866
+ * @param data.region Region code for tenant context
2867
+ * @param data.scenario Filter by scenario
2868
+ * @param data.routeBearing Filter by routeBearing (entity-router route() consumes it)
2869
+ * @returns CategoryCatalogListResponseDto Category catalog retrieved successfully
2870
+ * @throws ApiError
2871
+ */
2872
+ public static categoryCatalogControllerList(
2873
+ data: CategoryCatalogControllerListData
2874
+ ): CancelablePromise<CategoryCatalogControllerListResponse> {
2875
+ return __request(OpenAPI, {
2876
+ method: 'GET',
2877
+ url: '/api/v1/{region}/bean/categories',
2878
+ path: {
2879
+ region: data.region
2880
+ },
2881
+ query: {
2882
+ scenario: data.scenario,
2883
+ routeBearing: data.routeBearing
2884
+ }
2885
+ });
2886
+ }
2887
+ }
2888
+
2889
+ export class LifeEventsService {
2890
+ /**
2891
+ * Create a new life event
2892
+ * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
2893
+ * @param data The data for the request.
2894
+ * @param data.region Region code for tenant context (decorative for life events)
2895
+ * @param data.requestBody
2896
+ * @returns EventResponseDto Life event created successfully
2897
+ * @throws ApiError
2898
+ */
2899
+ public static eventControllerCreate(
2900
+ data: EventControllerCreateData
2901
+ ): CancelablePromise<EventControllerCreateResponse> {
2902
+ return __request(OpenAPI, {
2903
+ method: 'POST',
2904
+ url: '/api/v1/{region}/bean/events',
2905
+ path: {
2906
+ region: data.region
2907
+ },
2908
+ body: data.requestBody,
2909
+ mediaType: 'application/json',
2910
+ errors: {
2911
+ 409: 'Life event already exists for this (userId, type, date) combination'
2912
+ }
2913
+ });
2914
+ }
2915
+
2916
+ /**
2917
+ * List user life events
2918
+ * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2919
+ * @param data The data for the request.
2920
+ * @param data.region Region code for tenant context (decorative for life events)
2921
+ * @param data.type Filter by life event type (exact match)
2922
+ * @param data.q Search term for description (case-insensitive partial match)
2923
+ * @param data.from Filter life events from this date (ISO 8601 format)
2924
+ * @param data.to Filter life events to this date (ISO 8601 format)
2925
+ * @param data.page Page number for pagination (default: 1)
2926
+ * @param data.limit Number of items per page (default: 20, max: 100)
2927
+ * @returns EventListResponseDto Life events retrieved successfully
2928
+ * @throws ApiError
2929
+ */
2930
+ public static eventControllerFindAll(
2931
+ data: EventControllerFindAllData
2932
+ ): CancelablePromise<EventControllerFindAllResponse> {
2933
+ return __request(OpenAPI, {
2934
+ method: 'GET',
2935
+ url: '/api/v1/{region}/bean/events',
2936
+ path: {
2937
+ region: data.region
2938
+ },
2939
+ query: {
2940
+ type: data.type,
2941
+ q: data.q,
2942
+ from: data.from,
2943
+ to: data.to,
2944
+ page: data.page,
2945
+ limit: data.limit
2946
+ }
2947
+ });
2948
+ }
2949
+
2950
+ /**
2951
+ * Get life event by ID
2952
+ * Returns a single life event by its ID. Returns ETag header.
2953
+ * @param data The data for the request.
2954
+ * @param data.id Life event ID
2955
+ * @param data.region Region code for tenant context (decorative for life events)
2956
+ * @returns EventResponseDto Life event retrieved successfully
2957
+ * @throws ApiError
2958
+ */
2959
+ public static eventControllerFindOne(
2960
+ data: EventControllerFindOneData
2961
+ ): CancelablePromise<EventControllerFindOneResponse> {
2962
+ return __request(OpenAPI, {
2963
+ method: 'GET',
2964
+ url: '/api/v1/{region}/bean/events/{id}',
2965
+ path: {
2966
+ id: data.id,
2967
+ region: data.region
2968
+ },
2969
+ errors: {
2970
+ 404: 'Life event not found'
2971
+ }
2972
+ });
2973
+ }
2974
+
2975
+ /**
2976
+ * Update a life event
2977
+ * Updates an existing life event. If If-Match header is provided, performs optimistic concurrency check; mismatched updatedAt returns 412.
2978
+ * @param data The data for the request.
2979
+ * @param data.id Life event ID
2980
+ * @param data.region Region code for tenant context (decorative for life events)
2981
+ * @param data.requestBody
2982
+ * @returns EventResponseDto Life event updated successfully
2983
+ * @throws ApiError
2984
+ */
2985
+ public static eventControllerUpdate(
2986
+ data: EventControllerUpdateData
2987
+ ): CancelablePromise<EventControllerUpdateResponse> {
2988
+ return __request(OpenAPI, {
2989
+ method: 'PUT',
2990
+ url: '/api/v1/{region}/bean/events/{id}',
2991
+ path: {
2992
+ id: data.id,
2993
+ region: data.region
2994
+ },
2995
+ body: data.requestBody,
2996
+ mediaType: 'application/json',
2997
+ errors: {
2998
+ 400: 'If-Match header is not a valid ISO 8601 date',
2999
+ 404: 'Life event not found',
3000
+ 409: 'Updated event conflicts with an existing (userId, type, date) combination',
3001
+ 412: 'If-Match precondition failed (updatedAt mismatch)'
3002
+ }
3003
+ });
3004
+ }
3005
+
3006
+ /**
3007
+ * Delete a life event
3008
+ * Deletes a life event entry (hard delete). Returns 204.
3009
+ * @param data The data for the request.
3010
+ * @param data.id Life event ID
3011
+ * @param data.region Region code for tenant context (decorative for life events)
3012
+ * @returns void Life event deleted successfully
3013
+ * @throws ApiError
3014
+ */
3015
+ public static eventControllerDelete(
3016
+ data: EventControllerDeleteData
3017
+ ): CancelablePromise<EventControllerDeleteResponse> {
3018
+ return __request(OpenAPI, {
3019
+ method: 'DELETE',
3020
+ url: '/api/v1/{region}/bean/events/{id}',
3021
+ path: {
3022
+ id: data.id,
3023
+ region: data.region
3024
+ },
3025
+ errors: {
3026
+ 404: 'Life event not found'
3027
+ }
3028
+ });
3029
+ }
3030
+
3031
+ /**
3032
+ * Slice time-series by a life event (Phase 79)
3033
+ * Returns aggregated time-series for postings matching accountPattern within the half-open date range of the given life event.
3034
+ * @param data The data for the request.
3035
+ * @param data.id Life event ID
3036
+ * @param data.accountPattern
3037
+ * @param data.granularity
3038
+ * @param data.region Region code for tenant context (decorative for life events)
3039
+ * @returns unknown Time-series sliced by the life event range
3040
+ * @throws ApiError
3041
+ */
3042
+ public static eventControllerGetSlice(
3043
+ data: EventControllerGetSliceData
3044
+ ): CancelablePromise<EventControllerGetSliceResponse> {
3045
+ return __request(OpenAPI, {
3046
+ method: 'GET',
3047
+ url: '/api/v1/{region}/bean/events/{id}/slice',
3048
+ path: {
3049
+ id: data.id,
3050
+ region: data.region
3051
+ },
3052
+ query: {
3053
+ accountPattern: data.accountPattern,
3054
+ granularity: data.granularity
3055
+ },
3056
+ errors: {
3057
+ 400: 'accountPattern query param is empty',
3058
+ 404: 'Life event not found'
3059
+ }
3060
+ });
3061
+ }
3062
+ }
3063
+
3064
+ export class OnboardingService {
3065
+ /**
3066
+ * Bootstrap core accounts + register asset accounts with opening balances (ADR-0113)
3067
+ * @param data The data for the request.
3068
+ * @param data.region Region code for tenant context
3069
+ * @param data.requestBody
3070
+ * @returns unknown Onboarding bootstrap result.
3071
+ * @throws ApiError
3072
+ */
3073
+ public static onboardingControllerBootstrap(
3074
+ data: OnboardingControllerBootstrapData
3075
+ ): CancelablePromise<OnboardingControllerBootstrapResponse> {
3076
+ return __request(OpenAPI, {
3077
+ method: 'POST',
3078
+ url: '/api/v1/{region}/bean/onboarding',
3079
+ path: {
3080
+ region: data.region
3081
+ },
3082
+ body: data.requestBody,
3083
+ mediaType: 'application/json',
3084
+ errors: {
3085
+ 422: 'Invalid region/account path/duplicate paths.'
3086
+ }
3087
+ });
3088
+ }
3089
+ }
3090
+
3091
+ export class BalanceReconciliationService {
3092
+ /**
3093
+ * Preview reconciliation (book vs actual)
3094
+ * Computes book balance, diff, Beancount-inferred tolerance, and suggested action without persisting.
3095
+ * @param data The data for the request.
3096
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3097
+ * @param data.requestBody
3098
+ * @returns ReconciliationComputeResultDto Reconciliation preview
3099
+ * @throws ApiError
3100
+ */
3101
+ public static reconciliationControllerCompute(
3102
+ data: ReconciliationControllerComputeData
3103
+ ): CancelablePromise<ReconciliationControllerComputeResponse> {
3104
+ return __request(OpenAPI, {
3105
+ method: 'POST',
3106
+ url: '/api/v1/{region}/bean/reconciliations',
3107
+ path: {
3108
+ region: data.region
3109
+ },
3110
+ body: data.requestBody,
3111
+ mediaType: 'application/json',
3112
+ errors: {
3113
+ 404: 'Account not found'
3114
+ }
3115
+ });
3116
+ }
3117
+
3118
+ /**
3119
+ * Record a balance assertion
3120
+ * Persists the reconciliation as a BeanBalance assertion (amount = actual, diffAmount = book − actual). Re-reconciling the same day/currency upserts.
3121
+ * @param data The data for the request.
3122
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3123
+ * @param data.requestBody
3124
+ * @returns ReconciliationRecordDto Balance assertion recorded
3125
+ * @throws ApiError
3126
+ */
3127
+ public static reconciliationControllerAssert(
3128
+ data: ReconciliationControllerAssertData
3129
+ ): CancelablePromise<ReconciliationControllerAssertResponse> {
3130
+ return __request(OpenAPI, {
3131
+ method: 'POST',
3132
+ url: '/api/v1/{region}/bean/reconciliations/assert',
3133
+ path: {
3134
+ region: data.region
3135
+ },
3136
+ body: data.requestBody,
3137
+ mediaType: 'application/json',
3138
+ errors: {
3139
+ 404: 'Account not found'
3140
+ }
3141
+ });
3142
+ }
3143
+
3144
+ /**
3145
+ * Generate a pad adjusting entry
3146
+ * When book is outside tolerance, synthesizes a Beancount pad transaction (flag P) booking the diff from source_account and persists it. Source defaults to Equity:Opening-Balances.
3147
+ * @param data The data for the request.
3148
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3149
+ * @param data.requestBody
3150
+ * @returns PadResultDto Pad adjusting entry generated
3151
+ * @throws ApiError
3152
+ */
3153
+ public static reconciliationControllerPad(
3154
+ data: ReconciliationControllerPadData
3155
+ ): CancelablePromise<ReconciliationControllerPadResponse> {
3156
+ return __request(OpenAPI, {
3157
+ method: 'POST',
3158
+ url: '/api/v1/{region}/bean/reconciliations/pad',
3159
+ path: {
3160
+ region: data.region
3161
+ },
3162
+ body: data.requestBody,
3163
+ mediaType: 'application/json',
3164
+ errors: {
3165
+ 400: 'Book already within tolerance — no pad needed',
3166
+ 404: 'Account not found'
3167
+ }
3168
+ });
3169
+ }
3170
+
3171
+ /**
3172
+ * List reconciliation history for an account
3173
+ * Returns recorded balance assertions (most recent first). The latest drives the account-detail "Last <date>" badge.
3174
+ * @param data The data for the request.
3175
+ * @param data.accountId BeanAccount id
3176
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3177
+ * @returns ReconciliationRecordDto Reconciliation history
3178
+ * @throws ApiError
3179
+ */
3180
+ public static reconciliationControllerHistory(
3181
+ data: ReconciliationControllerHistoryData
3182
+ ): CancelablePromise<ReconciliationControllerHistoryResponse> {
3183
+ return __request(OpenAPI, {
3184
+ method: 'GET',
3185
+ url: '/api/v1/{region}/bean/accounts/{accountId}/reconciliations',
3186
+ path: {
3187
+ accountId: data.accountId,
3188
+ region: data.region
3189
+ },
3190
+ errors: {
3191
+ 404: 'Account not found'
3192
+ }
3193
+ });
3194
+ }
3195
+ }
3196
+
3197
+ export class BeanExportService {
3198
+ /**
3199
+ * Export Beancount ledger as ZIP
3200
+ * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
3201
+ * @returns unknown
2418
3202
  * @throws ApiError
2419
3203
  */
2420
3204
  public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
@@ -2588,243 +3372,271 @@ export class BeanImportService {
2588
3372
  }
2589
3373
  }
2590
3374
 
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
-
3375
+ export class ProviderSyncService {
2604
3376
  /**
2605
- * Create a new platform
3377
+ * Sync transactions from financial data provider
3378
+ *
3379
+ * Accepts raw transactions from external financial data providers, transforms them to Beancount format, and processes them through the ingestion pipeline.
3380
+ *
3381
+ * **Supported Providers:**
3382
+ * - **plaid**: Plaid API (US, Canada, Europe)
3383
+ * - **teller**: Teller API (US)
3384
+ * - **truelayer**: TrueLayer Open Banking (UK, Europe)
3385
+ * - **gocardless**: GoCardless Bank Account Data (Europe)
3386
+ * - **simplefin**: SimpleFIN (Self-hosted)
3387
+ * - **yodlee**: Yodlee (Global)
3388
+ * - **beancount-direct**: Beancount format transactions
3389
+ * - **parsed-bill**: Client-side parsed bill transactions
3390
+ *
3391
+ * **Processing Flow:**
3392
+ * 1. Transform raw data via provider adapter
3393
+ * 2. Validate transaction format
3394
+ * 3. Deduplicate using originalId
3395
+ * 4. Classify using rule engine
3396
+ * 5. Route low-confidence to Review Center
3397
+ * 6. Persist validated transactions
3398
+ *
2606
3399
  * @param data The data for the request.
3400
+ * @param data.providerName Provider name
3401
+ * @param data.region Region code for tenant context
2607
3402
  * @param data.requestBody
2608
- * @returns unknown Platform created successfully
3403
+ * @returns ProviderSyncResponseDto Sync completed successfully
2609
3404
  * @throws ApiError
2610
3405
  */
2611
- public static platformControllerCreate(
2612
- data: PlatformControllerCreateData
2613
- ): CancelablePromise<PlatformControllerCreateResponse> {
3406
+ public static providerSyncControllerSync(
3407
+ data: ProviderSyncControllerSyncData
3408
+ ): CancelablePromise<ProviderSyncControllerSyncResponse> {
2614
3409
  return __request(OpenAPI, {
2615
3410
  method: 'POST',
2616
- url: '/api/v1/bean/platforms',
3411
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3412
+ path: {
3413
+ providerName: data.providerName,
3414
+ region: data.region
3415
+ },
2617
3416
  body: data.requestBody,
2618
3417
  mediaType: 'application/json',
2619
3418
  errors: {
2620
- 409: 'Platform already exists'
3419
+ 400: 'Invalid request data',
3420
+ 401: 'Missing or invalid authentication',
3421
+ 404: 'Provider not supported'
2621
3422
  }
2622
3423
  });
2623
3424
  }
2624
3425
 
2625
3426
  /**
2626
- * Get platform list for current user
2627
- * @returns unknown List of platforms with user binding status
3427
+ * Get supported providers
3428
+ * Returns a list of all providers supported by the sync endpoint.
3429
+ * @param data The data for the request.
3430
+ * @param data.region Region code for tenant context
3431
+ * @returns SupportedProvidersResponseDto List of supported providers
2628
3432
  * @throws ApiError
2629
3433
  */
2630
- public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3434
+ public static providerSyncControllerGetSupportedProviders(
3435
+ data: ProviderSyncControllerGetSupportedProvidersData
3436
+ ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
2631
3437
  return __request(OpenAPI, {
2632
3438
  method: 'GET',
2633
- url: '/api/v1/bean/platforms/list'
3439
+ url: '/api/v1/{region}/bean/import/provider/supported',
3440
+ path: {
3441
+ region: data.region
3442
+ },
3443
+ errors: {
3444
+ 401: 'Missing or invalid authentication'
3445
+ }
2634
3446
  });
2635
3447
  }
2636
3448
 
2637
3449
  /**
2638
- * Match platforms by name or alias
3450
+ * Check if provider is supported
3451
+ * Returns whether a specific provider is supported.
2639
3452
  * @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
3453
+ * @param data.providerName Provider name to check
3454
+ * @param data.region Region code for tenant context
3455
+ * @returns unknown Provider support status
2643
3456
  * @throws ApiError
2644
3457
  */
2645
- public static platformControllerMatchPlatforms(
2646
- data: PlatformControllerMatchPlatformsData
2647
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3458
+ public static providerSyncControllerIsProviderSupported(
3459
+ data: ProviderSyncControllerIsProviderSupportedData
3460
+ ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
2648
3461
  return __request(OpenAPI, {
2649
3462
  method: 'GET',
2650
- url: '/api/v1/bean/platforms/match',
2651
- query: {
2652
- q: data.q,
3463
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3464
+ path: {
3465
+ providerName: data.providerName,
2653
3466
  region: data.region
3467
+ },
3468
+ errors: {
3469
+ 401: 'Missing or invalid authentication'
2654
3470
  }
2655
3471
  });
2656
3472
  }
3473
+ }
2657
3474
 
3475
+ export class ExternalAccountLinksService {
2658
3476
  /**
2659
- * Update a platform
3477
+ * Create an external account → BeanAccount mapping (ADR-0113)
2660
3478
  * @param data The data for the request.
2661
- * @param data.id Platform ID
3479
+ * @param data.region Region code for tenant context
2662
3480
  * @param data.requestBody
2663
- * @returns unknown Platform updated successfully
3481
+ * @returns ExternalAccountLinkResponseDto Link created.
2664
3482
  * @throws ApiError
2665
3483
  */
2666
- public static platformControllerUpdate(
2667
- data: PlatformControllerUpdateData
2668
- ): CancelablePromise<PlatformControllerUpdateResponse> {
3484
+ public static externalAccountLinkControllerCreate(
3485
+ data: ExternalAccountLinkControllerCreateData
3486
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
2669
3487
  return __request(OpenAPI, {
2670
- method: 'PUT',
2671
- url: '/api/v1/bean/platforms/{id}',
3488
+ method: 'POST',
3489
+ url: '/api/v1/{region}/bean/external-account-links',
2672
3490
  path: {
2673
- id: data.id
3491
+ region: data.region
2674
3492
  },
2675
3493
  body: data.requestBody,
2676
3494
  mediaType: 'application/json',
2677
3495
  errors: {
2678
- 404: 'Platform not found'
3496
+ 422: 'beanAccountId not owned, or an active link already exists.'
2679
3497
  }
2680
3498
  });
2681
3499
  }
2682
3500
 
2683
3501
  /**
2684
- * Delete a platform
3502
+ * List the user's active external account links
2685
3503
  * @param data The data for the request.
2686
- * @param data.id Platform ID
2687
- * @returns void Platform deleted successfully
3504
+ * @param data.provider
3505
+ * @param data.region Region code for tenant context
3506
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
2688
3507
  * @throws ApiError
2689
3508
  */
2690
- public static platformControllerDelete(
2691
- data: PlatformControllerDeleteData
2692
- ): CancelablePromise<PlatformControllerDeleteResponse> {
3509
+ public static externalAccountLinkControllerFindAll(
3510
+ data: ExternalAccountLinkControllerFindAllData
3511
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
2693
3512
  return __request(OpenAPI, {
2694
- method: 'DELETE',
2695
- url: '/api/v1/bean/platforms/{id}',
3513
+ method: 'GET',
3514
+ url: '/api/v1/{region}/bean/external-account-links',
2696
3515
  path: {
2697
- id: data.id
3516
+ region: data.region
2698
3517
  },
2699
- errors: {
2700
- 404: 'Platform not found'
3518
+ query: {
3519
+ provider: data.provider
2701
3520
  }
2702
3521
  });
2703
3522
  }
2704
- }
2705
3523
 
2706
- export class ProviderSyncService {
2707
3524
  /**
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
- *
3525
+ * Get a single external account link
2730
3526
  * @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
3527
+ * @param data.id
3528
+ * @param data.region Region code for tenant context
3529
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
2735
3530
  * @throws ApiError
2736
3531
  */
2737
- public static providerSyncControllerSync(
2738
- data: ProviderSyncControllerSyncData
2739
- ): CancelablePromise<ProviderSyncControllerSyncResponse> {
3532
+ public static externalAccountLinkControllerFindOne(
3533
+ data: ExternalAccountLinkControllerFindOneData
3534
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
2740
3535
  return __request(OpenAPI, {
2741
- method: 'POST',
2742
- url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3536
+ method: 'GET',
3537
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
2743
3538
  path: {
2744
- providerName: data.providerName,
3539
+ id: data.id,
2745
3540
  region: data.region
2746
3541
  },
2747
- body: data.requestBody,
2748
- mediaType: 'application/json',
2749
3542
  errors: {
2750
- 400: 'Invalid request data',
2751
- 401: 'Missing or invalid authentication',
2752
- 404: 'Provider not supported'
3543
+ 422: 'Link not found or not owned by the user.'
2753
3544
  }
2754
3545
  });
2755
3546
  }
2756
3547
 
2757
3548
  /**
2758
- * Get supported providers
2759
- * Returns a list of all providers supported by the sync endpoint.
3549
+ * Soft-delete (disconnect) an external account link
2760
3550
  * @param data The data for the request.
3551
+ * @param data.id
2761
3552
  * @param data.region Region code for tenant context
2762
- * @returns SupportedProvidersResponseDto List of supported providers
3553
+ * @returns void Link soft-deleted; historical transactions are unaffected.
2763
3554
  * @throws ApiError
2764
3555
  */
2765
- public static providerSyncControllerGetSupportedProviders(
2766
- data: ProviderSyncControllerGetSupportedProvidersData
2767
- ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
3556
+ public static externalAccountLinkControllerRemove(
3557
+ data: ExternalAccountLinkControllerRemoveData
3558
+ ): CancelablePromise<ExternalAccountLinkControllerRemoveResponse> {
2768
3559
  return __request(OpenAPI, {
2769
- method: 'GET',
2770
- url: '/api/v1/{region}/bean/import/provider/supported',
3560
+ method: 'DELETE',
3561
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3562
+ path: {
3563
+ id: data.id,
3564
+ region: data.region
3565
+ }
3566
+ });
3567
+ }
3568
+ }
3569
+
3570
+ export class ImportTelemetryService {
3571
+ /**
3572
+ * Receive anonymous parser failure telemetry
3573
+ * @param data The data for the request.
3574
+ * @param data.region Region code for tenant context
3575
+ * @param data.requestBody
3576
+ * @returns unknown Telemetry report received
3577
+ * @throws ApiError
3578
+ */
3579
+ public static telemetryControllerReportTelemetry(
3580
+ data: TelemetryControllerReportTelemetryData
3581
+ ): CancelablePromise<TelemetryControllerReportTelemetryResponse> {
3582
+ return __request(OpenAPI, {
3583
+ method: 'POST',
3584
+ url: '/api/v1/{region}/bean/import/parser-telemetry',
2771
3585
  path: {
2772
3586
  region: data.region
2773
3587
  },
3588
+ body: data.requestBody,
3589
+ mediaType: 'application/json',
2774
3590
  errors: {
2775
- 401: 'Missing or invalid authentication'
3591
+ 401: 'Unauthorized'
2776
3592
  }
2777
3593
  });
2778
3594
  }
2779
3595
 
2780
3596
  /**
2781
- * Check if provider is supported
2782
- * Returns whether a specific provider is supported.
3597
+ * Receive anonymous zero-hit coverage miss report
2783
3598
  * @param data The data for the request.
2784
- * @param data.providerName Provider name to check
2785
3599
  * @param data.region Region code for tenant context
2786
- * @returns unknown Provider support status
3600
+ * @param data.requestBody
3601
+ * @returns unknown Coverage miss report received
2787
3602
  * @throws ApiError
2788
3603
  */
2789
- public static providerSyncControllerIsProviderSupported(
2790
- data: ProviderSyncControllerIsProviderSupportedData
2791
- ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
3604
+ public static telemetryControllerReportCoverageMiss(
3605
+ data: TelemetryControllerReportCoverageMissData
3606
+ ): CancelablePromise<TelemetryControllerReportCoverageMissResponse> {
2792
3607
  return __request(OpenAPI, {
2793
- method: 'GET',
2794
- url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3608
+ method: 'POST',
3609
+ url: '/api/v1/{region}/bean/import/parser-coverage-miss',
2795
3610
  path: {
2796
- providerName: data.providerName,
2797
3611
  region: data.region
2798
3612
  },
3613
+ body: data.requestBody,
3614
+ mediaType: 'application/json',
2799
3615
  errors: {
2800
- 401: 'Missing or invalid authentication'
3616
+ 401: 'Unauthorized'
2801
3617
  }
2802
3618
  });
2803
3619
  }
2804
- }
2805
3620
 
2806
- export class ImportTelemetryService {
2807
3621
  /**
2808
- * Receive anonymous parser failure telemetry
3622
+ * Coverage metrics (uncovered format aggregation)
2809
3623
  * @param data The data for the request.
2810
3624
  * @param data.region Region code for tenant context
2811
- * @param data.requestBody
2812
- * @returns unknown Telemetry report received
3625
+ * @param data.topN Top-N uncovered formats (default 10)
3626
+ * @returns unknown Coverage metrics
2813
3627
  * @throws ApiError
2814
3628
  */
2815
- public static telemetryControllerReportTelemetry(
2816
- data: TelemetryControllerReportTelemetryData
2817
- ): CancelablePromise<TelemetryControllerReportTelemetryResponse> {
3629
+ public static telemetryControllerGetCoverageMetrics(
3630
+ data: TelemetryControllerGetCoverageMetricsData
3631
+ ): CancelablePromise<TelemetryControllerGetCoverageMetricsResponse> {
2818
3632
  return __request(OpenAPI, {
2819
- method: 'POST',
2820
- url: '/api/v1/{region}/bean/import/parser-telemetry',
3633
+ method: 'GET',
3634
+ url: '/api/v1/{region}/bean/import/parser-coverage-metrics',
2821
3635
  path: {
2822
3636
  region: data.region
2823
3637
  },
2824
- body: data.requestBody,
2825
- mediaType: 'application/json',
2826
- errors: {
2827
- 401: 'Unauthorized'
3638
+ query: {
3639
+ topN: data.topN
2828
3640
  }
2829
3641
  });
2830
3642
  }
@@ -2913,6 +3725,128 @@ export class BeanNlpService {
2913
3725
  }
2914
3726
  }
2915
3727
 
3728
+ export class BeanPlatformsService {
3729
+ /**
3730
+ * Get all platforms with statistics
3731
+ * @returns unknown List of platforms with binding and account counts
3732
+ * @throws ApiError
3733
+ */
3734
+ public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
3735
+ return __request(OpenAPI, {
3736
+ method: 'GET',
3737
+ url: '/api/v1/bean/platforms'
3738
+ });
3739
+ }
3740
+
3741
+ /**
3742
+ * Create a new platform
3743
+ * @param data The data for the request.
3744
+ * @param data.requestBody
3745
+ * @returns unknown Platform created successfully
3746
+ * @throws ApiError
3747
+ */
3748
+ public static platformControllerCreate(
3749
+ data: PlatformControllerCreateData
3750
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3751
+ return __request(OpenAPI, {
3752
+ method: 'POST',
3753
+ url: '/api/v1/bean/platforms',
3754
+ body: data.requestBody,
3755
+ mediaType: 'application/json',
3756
+ errors: {
3757
+ 409: 'Platform already exists'
3758
+ }
3759
+ });
3760
+ }
3761
+
3762
+ /**
3763
+ * Get platform list for current user
3764
+ * @param data The data for the request.
3765
+ * @param data.region Region code (ISO 3166-1 alpha-2) that biases within-type-bucket ordering (local-region platforms first). Case-insensitive — stored/compared UPPERCASE ("cn" == "CN").
3766
+ * @returns PlatformListItemDto List of platforms with user binding status
3767
+ * @throws ApiError
3768
+ */
3769
+ public static platformControllerGetPlatformList(
3770
+ data: PlatformControllerGetPlatformListData = {}
3771
+ ): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3772
+ return __request(OpenAPI, {
3773
+ method: 'GET',
3774
+ url: '/api/v1/bean/platforms/list',
3775
+ query: {
3776
+ region: data.region
3777
+ }
3778
+ });
3779
+ }
3780
+
3781
+ /**
3782
+ * Match platforms by name or alias
3783
+ * @param data The data for the request.
3784
+ * @param data.q Search query — Chinese name, English name, or abbreviation
3785
+ * @param data.region Region code (ISO 3166-1 alpha-2) that biases within-tier ordering (local-region platforms first); also the intended categoryOverrides key. Case-insensitive — stored/compared UPPERCASE ("cn" == "CN").
3786
+ * @returns PlatformMatchResponseDto Matching platforms with overall match type and truncation flag
3787
+ * @throws ApiError
3788
+ */
3789
+ public static platformControllerMatchPlatforms(
3790
+ data: PlatformControllerMatchPlatformsData
3791
+ ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3792
+ return __request(OpenAPI, {
3793
+ method: 'GET',
3794
+ url: '/api/v1/bean/platforms/match',
3795
+ query: {
3796
+ q: data.q,
3797
+ region: data.region
3798
+ }
3799
+ });
3800
+ }
3801
+
3802
+ /**
3803
+ * Update a platform
3804
+ * @param data The data for the request.
3805
+ * @param data.id Platform ID
3806
+ * @param data.requestBody
3807
+ * @returns unknown Platform updated successfully
3808
+ * @throws ApiError
3809
+ */
3810
+ public static platformControllerUpdate(
3811
+ data: PlatformControllerUpdateData
3812
+ ): CancelablePromise<PlatformControllerUpdateResponse> {
3813
+ return __request(OpenAPI, {
3814
+ method: 'PUT',
3815
+ url: '/api/v1/bean/platforms/{id}',
3816
+ path: {
3817
+ id: data.id
3818
+ },
3819
+ body: data.requestBody,
3820
+ mediaType: 'application/json',
3821
+ errors: {
3822
+ 404: 'Platform not found'
3823
+ }
3824
+ });
3825
+ }
3826
+
3827
+ /**
3828
+ * Delete a platform
3829
+ * @param data The data for the request.
3830
+ * @param data.id Platform ID
3831
+ * @returns void Platform deleted successfully
3832
+ * @throws ApiError
3833
+ */
3834
+ public static platformControllerDelete(
3835
+ data: PlatformControllerDeleteData
3836
+ ): CancelablePromise<PlatformControllerDeleteResponse> {
3837
+ return __request(OpenAPI, {
3838
+ method: 'DELETE',
3839
+ url: '/api/v1/bean/platforms/{id}',
3840
+ path: {
3841
+ id: data.id
3842
+ },
3843
+ errors: {
3844
+ 404: 'Platform not found'
3845
+ }
3846
+ });
3847
+ }
3848
+ }
3849
+
2916
3850
  export class DashboardService {
2917
3851
  /**
2918
3852
  * Get net worth overview
@@ -2948,6 +3882,7 @@ export class DashboardService {
2948
3882
  * @param data.region Region code for tenant context
2949
3883
  * @param data.groupBy Grouping strategy
2950
3884
  * @param data.date Date for balance calculation (ISO 8601 format)
3885
+ * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
2951
3886
  * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
2952
3887
  * @throws ApiError
2953
3888
  */
@@ -2962,7 +3897,8 @@ export class DashboardService {
2962
3897
  },
2963
3898
  query: {
2964
3899
  groupBy: data.groupBy,
2965
- date: data.date
3900
+ date: data.date,
3901
+ accountId: data.accountId
2966
3902
  },
2967
3903
  errors: {
2968
3904
  401: 'User not authenticated'
@@ -2997,124 +3933,69 @@ export class DashboardService {
2997
3933
  }
2998
3934
  });
2999
3935
  }
3000
- }
3001
3936
 
3002
- export class ReportingService {
3003
3937
  /**
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
- *
3938
+ * Get expenses/income grouped by functional category
3939
+ * Returns amounts pre-aggregated by functional category (account-path Group segment) with server-side multi-currency conversion. flow=expense (default) aggregates ^Expenses: accounts; flow=income aggregates ^Income: accounts (issue #518)
3017
3940
  * @param data The data for the request.
3018
3941
  * @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
3942
+ * @param data.groupBy Grouping strategy
3943
+ * @param data.period Time window (1m = current calendar month)
3944
+ * @param data.flow Account root to aggregate (expense → ^Expenses:, income → ^Income:)
3945
+ * @returns ExpensesByCategoryResponseDto Expenses retrieved successfully
3022
3946
  * @throws ApiError
3023
3947
  */
3024
- public static reportingControllerGetPortfolioTrends(
3025
- data: ReportingControllerGetPortfolioTrendsData
3026
- ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
3948
+ public static dashboardControllerGetExpenses(
3949
+ data: DashboardControllerGetExpensesData
3950
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3027
3951
  return __request(OpenAPI, {
3028
3952
  method: 'GET',
3029
- url: '/api/v1/{region}/reporting/portfolio/trends',
3953
+ url: '/api/v1/{region}/dashboard/expenses',
3030
3954
  path: {
3031
3955
  region: data.region
3032
3956
  },
3033
3957
  query: {
3958
+ groupBy: data.groupBy,
3034
3959
  period: data.period,
3035
- granularity: data.granularity
3960
+ flow: data.flow
3036
3961
  },
3037
3962
  errors: {
3963
+ 400: 'Invalid groupBy or period',
3038
3964
  401: 'User not authenticated'
3039
3965
  }
3040
3966
  });
3041
3967
  }
3968
+ }
3042
3969
 
3970
+ export class InvestmentService {
3043
3971
  /**
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
- *
3972
+ * Get per-holding unrealized + realized P&L
3973
+ * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3058
3974
  * @param data The data for the request.
3059
3975
  * @param data.region Region code for tenant context
3060
- * @param data.requestBody Optional date (defaults to today)
3061
- * @returns GenerateSnapshotResponse Snapshot generated successfully
3976
+ * @param data.asOf As-of date (ISO 8601), defaults to today
3977
+ * @param data.accountId Scope to a single account
3978
+ * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3979
+ * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3062
3980
  * @throws ApiError
3063
3981
  */
3064
- public static reportingControllerGenerateSnapshot(
3065
- data: ReportingControllerGenerateSnapshotData
3066
- ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
3982
+ public static holdingPnlControllerGetHoldingPnl(
3983
+ data: HoldingPnlControllerGetHoldingPnlData
3984
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3067
3985
  return __request(OpenAPI, {
3068
- method: 'POST',
3069
- url: '/api/v1/{region}/reporting/snapshots/generate',
3986
+ method: 'GET',
3987
+ url: '/api/v1/{region}/investment/holdings/pnl',
3070
3988
  path: {
3071
3989
  region: data.region
3072
3990
  },
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
3991
+ query: {
3992
+ asOf: data.asOf,
3993
+ accountId: data.accountId,
3994
+ method: data.method
3111
3995
  },
3112
- body: data.requestBody,
3113
- mediaType: 'application/json',
3114
3996
  errors: {
3115
- 400: 'Invalid date format or range',
3116
- 401: 'User not authenticated',
3117
- 409: 'Backfill already in progress for this user'
3997
+ 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3998
+ 401: 'User not authenticated'
3118
3999
  }
3119
4000
  });
3120
4001
  }
@@ -3143,7 +4024,7 @@ export class AuthService {
3143
4024
  * Anonymous login with access token
3144
4025
  * @param data The data for the request.
3145
4026
  * @param data.requestBody
3146
- * @returns unknown Login successful
4027
+ * @returns AnonymousLoginResponseDto Login successful
3147
4028
  * @throws ApiError
3148
4029
  */
3149
4030
  public static authControllerAccessTokenLogin(
@@ -3330,3 +4211,53 @@ export class InfoService {
3330
4211
  });
3331
4212
  }
3332
4213
  }
4214
+
4215
+ export class MarketDataService {
4216
+ /**
4217
+ * Search market symbols by name or code
4218
+ * Ranked search over the openbb catalog. Empty `q` returns [].
4219
+ * @param data The data for the request.
4220
+ * @param data.q Search term — matched against symbol and instrument name. Empty string returns [].
4221
+ * @param data.limit Maximum number of results (clamped 1..50)
4222
+ * @param data.exchange Filter by exchange code (e.g. US, HK, SS, SZ)
4223
+ * @param data.assetType Filter by OpenBB asset_type (e.g. stock, etf)
4224
+ * @returns SymbolSearchResultDto Ranked search results
4225
+ * @throws ApiError
4226
+ */
4227
+ public static symbolControllerSearch(
4228
+ data: SymbolControllerSearchData
4229
+ ): CancelablePromise<SymbolControllerSearchResponse> {
4230
+ return __request(OpenAPI, {
4231
+ method: 'GET',
4232
+ url: '/api/v1/market/symbols/search',
4233
+ query: {
4234
+ q: data.q,
4235
+ limit: data.limit,
4236
+ exchange: data.exchange,
4237
+ assetType: data.assetType
4238
+ }
4239
+ });
4240
+ }
4241
+
4242
+ /**
4243
+ * Get a market symbol quote
4244
+ * @param data The data for the request.
4245
+ * @param data.symbol
4246
+ * @returns SymbolQuoteDto Symbol quote
4247
+ * @throws ApiError
4248
+ */
4249
+ public static symbolControllerGetQuote(
4250
+ data: SymbolControllerGetQuoteData
4251
+ ): CancelablePromise<SymbolControllerGetQuoteResponse> {
4252
+ return __request(OpenAPI, {
4253
+ method: 'GET',
4254
+ url: '/api/v1/market/symbols/{symbol}/quote',
4255
+ path: {
4256
+ symbol: data.symbol
4257
+ },
4258
+ errors: {
4259
+ 404: 'Symbol not found in the openbb catalog'
4260
+ }
4261
+ });
4262
+ }
4263
+ }