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

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