@firela/api-types 0.0.0-canary.3ed455fd → 0.0.0-canary.43fa8a2d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,8 @@ import type {
17
17
  AccountControllerCloseResponse,
18
18
  AccountControllerReopenData,
19
19
  AccountControllerReopenResponse,
20
+ AccountControllerAddOpeningBalanceData,
21
+ AccountControllerAddOpeningBalanceResponse,
20
22
  AccountStandardsControllerGetTemplatesData,
21
23
  AccountStandardsControllerGetTemplatesResponse,
22
24
  AccountStandardsControllerGetTemplateMetadataData,
@@ -97,6 +99,18 @@ import type {
97
99
  CommodityControllerGetOrCreateResponse,
98
100
  CommodityControllerBulkCreateData,
99
101
  CommodityControllerBulkCreateResponse,
102
+ PriceControllerCreateData,
103
+ PriceControllerCreateResponse,
104
+ PriceControllerFindAllData,
105
+ PriceControllerFindAllResponse,
106
+ PriceControllerFindOneData,
107
+ PriceControllerFindOneResponse,
108
+ PriceControllerUpdateData,
109
+ PriceControllerUpdateResponse,
110
+ PriceControllerDeleteData,
111
+ PriceControllerDeleteResponse,
112
+ PriceControllerBulkCreateData,
113
+ PriceControllerBulkCreateResponse,
100
114
  RecurringRuleControllerCreateData,
101
115
  RecurringRuleControllerCreateResponse,
102
116
  RecurringRuleControllerFindAllData,
@@ -129,26 +143,14 @@ import type {
129
143
  ExpectedTransactionControllerEnterNowResponse,
130
144
  ForecastControllerGetForecastData,
131
145
  ForecastControllerGetForecastResponse,
132
- TransactionRuleControllerCreateData,
133
- TransactionRuleControllerCreateResponse,
134
- TransactionRuleControllerListData,
135
- TransactionRuleControllerListResponse,
136
- TransactionRuleControllerValidateData,
137
- TransactionRuleControllerValidateResponse,
138
- TransactionRuleControllerBulkCreateData,
139
- TransactionRuleControllerBulkCreateResponse,
140
- TransactionRuleControllerExportData,
141
- TransactionRuleControllerExportResponse,
142
- TransactionRuleControllerGetStatisticsData,
143
- TransactionRuleControllerGetStatisticsResponse,
144
- TransactionRuleControllerGetDetailData,
145
- TransactionRuleControllerGetDetailResponse,
146
- TransactionRuleControllerUpdateData,
147
- TransactionRuleControllerUpdateResponse,
148
- TransactionRuleControllerDeleteData,
149
- TransactionRuleControllerDeleteResponse,
150
- TransactionRuleControllerTestData,
151
- TransactionRuleControllerTestResponse,
146
+ ReportingControllerGetPortfolioTrendsData,
147
+ ReportingControllerGetPortfolioTrendsResponse,
148
+ ReportingControllerGetCashFlowTrendsData,
149
+ ReportingControllerGetCashFlowTrendsResponse,
150
+ ReportingControllerGenerateSnapshotData,
151
+ ReportingControllerGenerateSnapshotResponse,
152
+ ReportingControllerBackfillSnapshotsData,
153
+ ReportingControllerBackfillSnapshotsResponse,
152
154
  UserControllerDeleteOwnUserData,
153
155
  UserControllerDeleteOwnUserResponse,
154
156
  UserControllerGetUserData,
@@ -171,6 +173,48 @@ import type {
171
173
  PropertyControllerUpdateResponse,
172
174
  PropertyControllerDeleteData,
173
175
  PropertyControllerDeleteResponse,
176
+ TransactionRuleControllerCreateData,
177
+ TransactionRuleControllerCreateResponse,
178
+ TransactionRuleControllerListData,
179
+ TransactionRuleControllerListResponse,
180
+ TransactionRuleControllerValidateData,
181
+ TransactionRuleControllerValidateResponse,
182
+ TransactionRuleControllerBulkCreateData,
183
+ TransactionRuleControllerBulkCreateResponse,
184
+ TransactionRuleControllerExportData,
185
+ TransactionRuleControllerExportResponse,
186
+ TransactionRuleControllerGetStatisticsData,
187
+ TransactionRuleControllerGetStatisticsResponse,
188
+ TransactionRuleControllerGetDetailData,
189
+ TransactionRuleControllerGetDetailResponse,
190
+ TransactionRuleControllerUpdateData,
191
+ TransactionRuleControllerUpdateResponse,
192
+ TransactionRuleControllerDeleteData,
193
+ TransactionRuleControllerDeleteResponse,
194
+ TransactionRuleControllerTestData,
195
+ TransactionRuleControllerTestResponse,
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,
174
218
  ExportControllerExportBeancountResponse,
175
219
  FileImportControllerImportFileData,
176
220
  FileImportControllerImportFileResponse,
@@ -184,22 +228,20 @@ import type {
184
228
  ImporterConfigControllerUpdateConfigResponse,
185
229
  ImporterConfigControllerResetConfigData,
186
230
  ImporterConfigControllerResetConfigResponse,
187
- PlatformControllerFindAllResponse,
188
- PlatformControllerCreateData,
189
- PlatformControllerCreateResponse,
190
- PlatformControllerGetPlatformListResponse,
191
- PlatformControllerMatchPlatformsData,
192
- PlatformControllerMatchPlatformsResponse,
193
- PlatformControllerUpdateData,
194
- PlatformControllerUpdateResponse,
195
- PlatformControllerDeleteData,
196
- PlatformControllerDeleteResponse,
197
231
  ProviderSyncControllerSyncData,
198
232
  ProviderSyncControllerSyncResponse,
199
233
  ProviderSyncControllerGetSupportedProvidersData,
200
234
  ProviderSyncControllerGetSupportedProvidersResponse,
201
235
  ProviderSyncControllerIsProviderSupportedData,
202
236
  ProviderSyncControllerIsProviderSupportedResponse,
237
+ ExternalAccountLinkControllerCreateData,
238
+ ExternalAccountLinkControllerCreateResponse,
239
+ ExternalAccountLinkControllerFindAllData,
240
+ ExternalAccountLinkControllerFindAllResponse,
241
+ ExternalAccountLinkControllerFindOneData,
242
+ ExternalAccountLinkControllerFindOneResponse,
243
+ ExternalAccountLinkControllerRemoveData,
244
+ ExternalAccountLinkControllerRemoveResponse,
203
245
  TelemetryControllerReportTelemetryData,
204
246
  TelemetryControllerReportTelemetryResponse,
205
247
  TelemetryControllerReportCoverageMissData,
@@ -212,32 +254,27 @@ import type {
212
254
  NlpControllerClearSessionResponse,
213
255
  NlpControllerGetSessionData,
214
256
  NlpControllerGetSessionResponse,
257
+ PlatformControllerFindAllResponse,
258
+ PlatformControllerCreateData,
259
+ PlatformControllerCreateResponse,
260
+ PlatformControllerGetPlatformListData,
261
+ PlatformControllerGetPlatformListResponse,
262
+ PlatformControllerMatchPlatformsData,
263
+ PlatformControllerMatchPlatformsResponse,
264
+ PlatformControllerUpdateData,
265
+ PlatformControllerUpdateResponse,
266
+ PlatformControllerDeleteData,
267
+ PlatformControllerDeleteResponse,
215
268
  DashboardControllerGetNetWorthData,
216
269
  DashboardControllerGetNetWorthResponse,
217
270
  DashboardControllerGetAccountsData,
218
271
  DashboardControllerGetAccountsResponse,
219
272
  DashboardControllerGetCashFlowData,
220
273
  DashboardControllerGetCashFlowResponse,
274
+ DashboardControllerGetExpensesData,
275
+ DashboardControllerGetExpensesResponse,
221
276
  HoldingPnlControllerGetHoldingPnlData,
222
277
  HoldingPnlControllerGetHoldingPnlResponse,
223
- PriceControllerCreateData,
224
- PriceControllerCreateResponse,
225
- PriceControllerFindAllData,
226
- PriceControllerFindAllResponse,
227
- PriceControllerFindOneData,
228
- PriceControllerFindOneResponse,
229
- PriceControllerUpdateData,
230
- PriceControllerUpdateResponse,
231
- PriceControllerDeleteData,
232
- PriceControllerDeleteResponse,
233
- PriceControllerBulkCreateData,
234
- PriceControllerBulkCreateResponse,
235
- ReportingControllerGetPortfolioTrendsData,
236
- ReportingControllerGetPortfolioTrendsResponse,
237
- ReportingControllerGenerateSnapshotData,
238
- ReportingControllerGenerateSnapshotResponse,
239
- ReportingControllerBackfillSnapshotsData,
240
- ReportingControllerBackfillSnapshotsResponse,
241
278
  ApiKeysControllerCreateApiKeyResponse,
242
279
  AuthControllerAccessTokenLoginData,
243
280
  AuthControllerAccessTokenLoginResponse,
@@ -252,7 +289,11 @@ import type {
252
289
  HealthControllerResetCircuitBreakerData,
253
290
  HealthControllerResetCircuitBreakerResponse,
254
291
  HealthControllerGetMetricsResponse,
255
- InfoControllerGetInfoResponse
292
+ InfoControllerGetInfoResponse,
293
+ SymbolControllerSearchData,
294
+ SymbolControllerSearchResponse,
295
+ SymbolControllerGetQuoteData,
296
+ SymbolControllerGetQuoteResponse
256
297
  } from './types.gen';
257
298
 
258
299
  export class BeanAccountsService {
@@ -290,7 +331,7 @@ export class BeanAccountsService {
290
331
  * @param data.type Filter by account type
291
332
  * @param data.status Filter by status
292
333
  * @param data.isCustom Filter by custom (user-created) accounts only
293
- * @param data.search Search term for path or i18nKey
334
+ * @param data.search Search term for account path
294
335
  * @param data.limit Maximum number of results
295
336
  * @param data.offset Number of results to skip
296
337
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -371,7 +412,7 @@ export class BeanAccountsService {
371
412
 
372
413
  /**
373
414
  * Delete account
374
- * Deletes an account (only if no transactions)
415
+ * Deletes an account (only if no active transactions; voided/superseded residual postings are cleaned up)
375
416
  * @param data The data for the request.
376
417
  * @param data.id Account UUID
377
418
  * @param data.region Region code for tenant context
@@ -390,7 +431,7 @@ export class BeanAccountsService {
390
431
  },
391
432
  errors: {
392
433
  404: 'Account not found',
393
- 409: 'Account has transactions and cannot be deleted'
434
+ 409: 'Account has active transactions and cannot be deleted'
394
435
  }
395
436
  });
396
437
  }
@@ -452,6 +493,35 @@ export class BeanAccountsService {
452
493
  }
453
494
  });
454
495
  }
496
+
497
+ /**
498
+ * Post an opening-balance transaction
499
+ * Posts a double-entry opening-balance transaction against Equity:Opening-Balances for an existing Assets/Liabilities account. At most one active opening balance per account.
500
+ * @param data The data for the request.
501
+ * @param data.id Account UUID
502
+ * @param data.region Region code for tenant context
503
+ * @param data.requestBody
504
+ * @returns OpeningBalanceResultDto Opening-balance transaction created
505
+ * @throws ApiError
506
+ */
507
+ public static accountControllerAddOpeningBalance(
508
+ data: AccountControllerAddOpeningBalanceData
509
+ ): CancelablePromise<AccountControllerAddOpeningBalanceResponse> {
510
+ return __request(OpenAPI, {
511
+ method: 'POST',
512
+ url: '/api/v1/{region}/bean/accounts/{id}/opening-balance',
513
+ path: {
514
+ id: data.id,
515
+ region: data.region
516
+ },
517
+ body: data.requestBody,
518
+ mediaType: 'application/json',
519
+ errors: {
520
+ 404: 'Account not found',
521
+ 409: 'An opening balance already exists for this account'
522
+ }
523
+ });
524
+ }
455
525
  }
456
526
 
457
527
  export class BeanAccountStandardsService {
@@ -483,7 +553,7 @@ export class BeanAccountStandardsService {
483
553
 
484
554
  /**
485
555
  * Get template metadata for an account path
486
- * Returns extendable status and root type for a template path.
556
+ * Returns root type for a template path.
487
557
  * @param data The data for the request.
488
558
  * @param data.region Region code for tenant context
489
559
  * @param data.path Account path to check
@@ -569,6 +639,7 @@ export class BeanTransactionsService {
569
639
  * @param data.status Filter by transaction status
570
640
  * @param data.search Search in narration and payee fields (max 200 chars)
571
641
  * @param data.accountId Filter by account ID (transactions with postings to this account)
642
+ * @param data.category Filter by ADR-0075 functional category (Group segment); matches any posting to an Expenses/Income account whose derived Group segment equals this value
572
643
  * @returns TransactionListResponseDto Transaction list
573
644
  * @throws ApiError
574
645
  */
@@ -588,7 +659,8 @@ export class BeanTransactionsService {
588
659
  dateTo: data.dateTo,
589
660
  status: data.status,
590
661
  search: data.search,
591
- accountId: data.accountId
662
+ accountId: data.accountId,
663
+ category: data.category
592
664
  },
593
665
  errors: {
594
666
  400: 'Validation failed',
@@ -776,7 +848,7 @@ export class BeanBalancesService {
776
848
  * Query account balance
777
849
  * Calculate account balance at a specific date for a single currency
778
850
  * @param data The data for the request.
779
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
851
+ * @param data.account Account name (e.g., "Assets:Checking")
780
852
  * @param data.region Region code for tenant context
781
853
  * @param data.date Date to calculate balance at (ISO 8601 format)
782
854
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -1497,155 +1569,322 @@ export class BeanCommoditiesService {
1497
1569
  }
1498
1570
  }
1499
1571
 
1500
- export class RecurringRulesService {
1572
+ export class BeanPricesService {
1501
1573
  /**
1502
- * Create a new recurring rule
1503
- * Creates a new recurring transaction rule for the authenticated user
1574
+ * Create a new price
1575
+ * Creates a new price entry for the authenticated user
1504
1576
  * @param data The data for the request.
1505
1577
  * @param data.region Region code for tenant context
1506
1578
  * @param data.requestBody
1507
- * @returns RecurringRuleResponseDto Rule created successfully
1579
+ * @returns PriceResponseDto Price created successfully
1508
1580
  * @throws ApiError
1509
1581
  */
1510
- public static recurringRuleControllerCreate(
1511
- data: RecurringRuleControllerCreateData
1512
- ): CancelablePromise<RecurringRuleControllerCreateResponse> {
1582
+ public static priceControllerCreate(
1583
+ data: PriceControllerCreateData
1584
+ ): CancelablePromise<PriceControllerCreateResponse> {
1513
1585
  return __request(OpenAPI, {
1514
1586
  method: 'POST',
1515
- url: '/api/v1/{region}/bean/recurring-rules',
1587
+ url: '/api/v1/{region}/bean/prices',
1516
1588
  path: {
1517
1589
  region: data.region
1518
1590
  },
1519
1591
  body: data.requestBody,
1520
1592
  mediaType: 'application/json',
1521
1593
  errors: {
1522
- 400: 'Invalid input data (e.g., autoCreate without accounts)',
1523
- 409: 'Rule with same name already exists'
1594
+ 404: 'Currency or quoteCurrency commodity not found',
1595
+ 409: 'Price already exists for this currency pair and date'
1524
1596
  }
1525
1597
  });
1526
1598
  }
1527
1599
 
1528
1600
  /**
1529
- * List recurring rules
1530
- * Returns all recurring rules for the authenticated user with optional filtering
1601
+ * List user prices
1602
+ * Returns all price entries for the authenticated user with optional filtering
1531
1603
  * @param data The data for the request.
1532
1604
  * @param data.region Region code for tenant context
1533
- * @param data.isActive Filter by active status
1534
- * @param data.frequency Filter by frequency (WEEKLY, MONTHLY, etc.)
1535
- * @param data.hasAutoCreate Filter by autoCreate enabled
1536
- * @returns RecurringRuleResponseDto Rules retrieved successfully
1605
+ * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
1606
+ * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
1607
+ * @param data.dateFrom Filter prices from this date (ISO 8601 format)
1608
+ * @param data.dateTo Filter prices to this date (ISO 8601 format)
1609
+ * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
1610
+ * @param data.page Page number for pagination (default: 1)
1611
+ * @param data.limit Number of items per page (default: 20, max: 100)
1612
+ * @returns PriceListResponseDto Prices retrieved successfully
1537
1613
  * @throws ApiError
1538
1614
  */
1539
- public static recurringRuleControllerFindAll(
1540
- data: RecurringRuleControllerFindAllData
1541
- ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
1615
+ public static priceControllerFindAll(
1616
+ data: PriceControllerFindAllData
1617
+ ): CancelablePromise<PriceControllerFindAllResponse> {
1542
1618
  return __request(OpenAPI, {
1543
1619
  method: 'GET',
1544
- url: '/api/v1/{region}/bean/recurring-rules',
1620
+ url: '/api/v1/{region}/bean/prices',
1545
1621
  path: {
1546
1622
  region: data.region
1547
1623
  },
1548
1624
  query: {
1549
- isActive: data.isActive,
1550
- frequency: data.frequency,
1551
- hasAutoCreate: data.hasAutoCreate
1625
+ currency: data.currency,
1626
+ quoteCurrency: data.quoteCurrency,
1627
+ dateFrom: data.dateFrom,
1628
+ dateTo: data.dateTo,
1629
+ search: data.search,
1630
+ page: data.page,
1631
+ limit: data.limit
1552
1632
  }
1553
1633
  });
1554
1634
  }
1555
1635
 
1556
1636
  /**
1557
- * Create recurring rule from transaction
1558
- * Auto-creates a recurring rule using transaction data. User only confirms frequency.
1637
+ * Get price by ID
1638
+ * Returns a single price entry by its ID
1559
1639
  * @param data The data for the request.
1560
- * @param data.transactionId Source transaction ID
1640
+ * @param data.id Price ID
1561
1641
  * @param data.region Region code for tenant context
1562
- * @param data.requestBody
1563
- * @returns RecurringRuleResponseDto Rule created successfully
1642
+ * @returns PriceResponseDto Price retrieved successfully
1564
1643
  * @throws ApiError
1565
1644
  */
1566
- public static recurringRuleControllerCreateFromTransaction(
1567
- data: RecurringRuleControllerCreateFromTransactionData
1568
- ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
1645
+ public static priceControllerFindOne(
1646
+ data: PriceControllerFindOneData
1647
+ ): CancelablePromise<PriceControllerFindOneResponse> {
1569
1648
  return __request(OpenAPI, {
1570
- method: 'POST',
1571
- url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
1649
+ method: 'GET',
1650
+ url: '/api/v1/{region}/bean/prices/{id}',
1572
1651
  path: {
1573
- transactionId: data.transactionId,
1652
+ id: data.id,
1574
1653
  region: data.region
1575
1654
  },
1576
- body: data.requestBody,
1577
- mediaType: 'application/json',
1578
1655
  errors: {
1579
- 404: 'Transaction not found',
1580
- 409: 'Rule with same name already exists or transaction already linked'
1656
+ 404: 'Price not found'
1581
1657
  }
1582
1658
  });
1583
1659
  }
1584
1660
 
1585
1661
  /**
1586
- * Get recurring rule by ID
1587
- * Returns a specific recurring rule with its details
1662
+ * Update a price
1663
+ * Updates an existing price entry
1588
1664
  * @param data The data for the request.
1589
- * @param data.id Rule ID
1665
+ * @param data.id Price ID
1590
1666
  * @param data.region Region code for tenant context
1591
- * @returns RecurringRuleResponseDto Rule retrieved successfully
1667
+ * @param data.requestBody
1668
+ * @returns PriceResponseDto Price updated successfully
1592
1669
  * @throws ApiError
1593
1670
  */
1594
- public static recurringRuleControllerFindOne(
1595
- data: RecurringRuleControllerFindOneData
1596
- ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
1671
+ public static priceControllerUpdate(
1672
+ data: PriceControllerUpdateData
1673
+ ): CancelablePromise<PriceControllerUpdateResponse> {
1597
1674
  return __request(OpenAPI, {
1598
- method: 'GET',
1599
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
1675
+ method: 'PUT',
1676
+ url: '/api/v1/{region}/bean/prices/{id}',
1600
1677
  path: {
1601
1678
  id: data.id,
1602
1679
  region: data.region
1603
1680
  },
1681
+ body: data.requestBody,
1682
+ mediaType: 'application/json',
1604
1683
  errors: {
1605
- 404: 'Rule not found'
1684
+ 404: 'Price not found',
1685
+ 409: 'Updated price conflicts with existing price'
1606
1686
  }
1607
1687
  });
1608
1688
  }
1609
1689
 
1610
1690
  /**
1611
- * Update recurring rule
1612
- * Updates an existing recurring rule
1691
+ * Delete a price
1692
+ * Deletes a price entry (hard delete)
1613
1693
  * @param data The data for the request.
1614
- * @param data.id Rule ID
1694
+ * @param data.id Price ID
1615
1695
  * @param data.region Region code for tenant context
1616
- * @param data.requestBody
1617
- * @returns RecurringRuleResponseDto Rule updated successfully
1696
+ * @returns void Price deleted successfully
1618
1697
  * @throws ApiError
1619
1698
  */
1620
- public static recurringRuleControllerUpdate(
1621
- data: RecurringRuleControllerUpdateData
1622
- ): CancelablePromise<RecurringRuleControllerUpdateResponse> {
1699
+ public static priceControllerDelete(
1700
+ data: PriceControllerDeleteData
1701
+ ): CancelablePromise<PriceControllerDeleteResponse> {
1623
1702
  return __request(OpenAPI, {
1624
- method: 'PATCH',
1625
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
1703
+ method: 'DELETE',
1704
+ url: '/api/v1/{region}/bean/prices/{id}',
1626
1705
  path: {
1627
1706
  id: data.id,
1628
1707
  region: data.region
1629
1708
  },
1630
- body: data.requestBody,
1631
- mediaType: 'application/json',
1632
1709
  errors: {
1633
- 400: 'Invalid input data',
1634
- 404: 'Rule not found'
1710
+ 404: 'Price not found'
1635
1711
  }
1636
1712
  });
1637
1713
  }
1638
1714
 
1639
1715
  /**
1640
- * Delete recurring rule
1641
- * Soft deletes a recurring rule (sets isActive to false)
1716
+ * Bulk create prices
1717
+ * Creates multiple price entries at once (skips duplicates)
1642
1718
  * @param data The data for the request.
1643
- * @param data.id Rule ID
1644
1719
  * @param data.region Region code for tenant context
1645
- * @returns void Rule deleted successfully
1720
+ * @param data.requestBody
1721
+ * @returns PriceResponseDto Prices created successfully
1646
1722
  * @throws ApiError
1647
1723
  */
1648
- public static recurringRuleControllerDelete(
1724
+ public static priceControllerBulkCreate(
1725
+ data: PriceControllerBulkCreateData
1726
+ ): CancelablePromise<PriceControllerBulkCreateResponse> {
1727
+ return __request(OpenAPI, {
1728
+ method: 'POST',
1729
+ url: '/api/v1/{region}/bean/prices/bulk',
1730
+ path: {
1731
+ region: data.region
1732
+ },
1733
+ body: data.requestBody,
1734
+ mediaType: 'application/json'
1735
+ });
1736
+ }
1737
+ }
1738
+
1739
+ export class RecurringRulesService {
1740
+ /**
1741
+ * Create a new recurring rule
1742
+ * Creates a new recurring transaction rule for the authenticated user
1743
+ * @param data The data for the request.
1744
+ * @param data.region Region code for tenant context
1745
+ * @param data.requestBody
1746
+ * @returns RecurringRuleResponseDto Rule created successfully
1747
+ * @throws ApiError
1748
+ */
1749
+ public static recurringRuleControllerCreate(
1750
+ data: RecurringRuleControllerCreateData
1751
+ ): CancelablePromise<RecurringRuleControllerCreateResponse> {
1752
+ return __request(OpenAPI, {
1753
+ method: 'POST',
1754
+ url: '/api/v1/{region}/bean/recurring-rules',
1755
+ path: {
1756
+ region: data.region
1757
+ },
1758
+ body: data.requestBody,
1759
+ mediaType: 'application/json',
1760
+ errors: {
1761
+ 400: 'Invalid input data (e.g., autoCreate without accounts)',
1762
+ 409: 'Rule with same name already exists'
1763
+ }
1764
+ });
1765
+ }
1766
+
1767
+ /**
1768
+ * List recurring rules
1769
+ * Returns all recurring rules for the authenticated user with optional filtering
1770
+ * @param data The data for the request.
1771
+ * @param data.region Region code for tenant context
1772
+ * @param data.isActive Filter by active status
1773
+ * @param data.frequency Filter by frequency (WEEKLY, MONTHLY, etc.)
1774
+ * @param data.hasAutoCreate Filter by autoCreate enabled
1775
+ * @returns RecurringRuleResponseDto Rules retrieved successfully
1776
+ * @throws ApiError
1777
+ */
1778
+ public static recurringRuleControllerFindAll(
1779
+ data: RecurringRuleControllerFindAllData
1780
+ ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
1781
+ return __request(OpenAPI, {
1782
+ method: 'GET',
1783
+ url: '/api/v1/{region}/bean/recurring-rules',
1784
+ path: {
1785
+ region: data.region
1786
+ },
1787
+ query: {
1788
+ isActive: data.isActive,
1789
+ frequency: data.frequency,
1790
+ hasAutoCreate: data.hasAutoCreate
1791
+ }
1792
+ });
1793
+ }
1794
+
1795
+ /**
1796
+ * Create recurring rule from transaction
1797
+ * Auto-creates a recurring rule using transaction data. User only confirms frequency.
1798
+ * @param data The data for the request.
1799
+ * @param data.transactionId Source transaction ID
1800
+ * @param data.region Region code for tenant context
1801
+ * @param data.requestBody
1802
+ * @returns RecurringRuleResponseDto Rule created successfully
1803
+ * @throws ApiError
1804
+ */
1805
+ public static recurringRuleControllerCreateFromTransaction(
1806
+ data: RecurringRuleControllerCreateFromTransactionData
1807
+ ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
1808
+ return __request(OpenAPI, {
1809
+ method: 'POST',
1810
+ url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
1811
+ path: {
1812
+ transactionId: data.transactionId,
1813
+ region: data.region
1814
+ },
1815
+ body: data.requestBody,
1816
+ mediaType: 'application/json',
1817
+ errors: {
1818
+ 404: 'Transaction not found',
1819
+ 409: 'Rule with same name already exists or transaction already linked'
1820
+ }
1821
+ });
1822
+ }
1823
+
1824
+ /**
1825
+ * Get recurring rule by ID
1826
+ * Returns a specific recurring rule with its details
1827
+ * @param data The data for the request.
1828
+ * @param data.id Rule ID
1829
+ * @param data.region Region code for tenant context
1830
+ * @returns RecurringRuleResponseDto Rule retrieved successfully
1831
+ * @throws ApiError
1832
+ */
1833
+ public static recurringRuleControllerFindOne(
1834
+ data: RecurringRuleControllerFindOneData
1835
+ ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
1836
+ return __request(OpenAPI, {
1837
+ method: 'GET',
1838
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
1839
+ path: {
1840
+ id: data.id,
1841
+ region: data.region
1842
+ },
1843
+ errors: {
1844
+ 404: 'Rule not found'
1845
+ }
1846
+ });
1847
+ }
1848
+
1849
+ /**
1850
+ * Update recurring rule
1851
+ * Updates an existing recurring rule
1852
+ * @param data The data for the request.
1853
+ * @param data.id Rule ID
1854
+ * @param data.region Region code for tenant context
1855
+ * @param data.requestBody
1856
+ * @returns RecurringRuleResponseDto Rule updated successfully
1857
+ * @throws ApiError
1858
+ */
1859
+ public static recurringRuleControllerUpdate(
1860
+ data: RecurringRuleControllerUpdateData
1861
+ ): CancelablePromise<RecurringRuleControllerUpdateResponse> {
1862
+ return __request(OpenAPI, {
1863
+ method: 'PATCH',
1864
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
1865
+ path: {
1866
+ id: data.id,
1867
+ region: data.region
1868
+ },
1869
+ body: data.requestBody,
1870
+ mediaType: 'application/json',
1871
+ errors: {
1872
+ 400: 'Invalid input data',
1873
+ 404: 'Rule not found'
1874
+ }
1875
+ });
1876
+ }
1877
+
1878
+ /**
1879
+ * Delete recurring rule
1880
+ * Soft deletes a recurring rule (sets isActive to false)
1881
+ * @param data The data for the request.
1882
+ * @param data.id Rule ID
1883
+ * @param data.region Region code for tenant context
1884
+ * @returns void Rule deleted successfully
1885
+ * @throws ApiError
1886
+ */
1887
+ public static recurringRuleControllerDelete(
1649
1888
  data: RecurringRuleControllerDeleteData
1650
1889
  ): CancelablePromise<RecurringRuleControllerDeleteResponse> {
1651
1890
  return __request(OpenAPI, {
@@ -1927,279 +2166,158 @@ export class RecurringForecastService {
1927
2166
  }
1928
2167
  }
1929
2168
 
1930
- export class BeanTransactionRulesService {
2169
+ export class ReportingService {
1931
2170
  /**
1932
- * Create a new transaction rule (or upsert if upsertByPayee=true)
1933
- * Creates a new rule. If upsertByPayee=true, updates existing rule matching payeeKeywords[0] instead of creating duplicate.
2171
+ * Get portfolio value trends
2172
+ *
2173
+ * Returns time series data of portfolio net worth.
2174
+ *
2175
+ * **Multi-currency Support:**
2176
+ * - `series[].byCurrency` - Currency breakdown for each data point
2177
+ * - `byCurrency` - Separate time series grouped by currency
2178
+ * - `warnings` - Exchange rate warnings if conversion failed
2179
+ *
2180
+ * **Parameters:**
2181
+ * - `period`: Time period (1m, 3m, 6m, 1y)
2182
+ * - `granularity`: Data granularity (day, week, month)
2183
+ *
1934
2184
  * @param data The data for the request.
1935
2185
  * @param data.region Region code for tenant context
1936
- * @param data.requestBody
1937
- * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2186
+ * @param data.period Time period
2187
+ * @param data.granularity Data granularity
2188
+ * @returns PortfolioTrendsResponseDto Trends retrieved successfully
1938
2189
  * @throws ApiError
1939
2190
  */
1940
- public static transactionRuleControllerCreate(
1941
- data: TransactionRuleControllerCreateData
1942
- ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2191
+ public static reportingControllerGetPortfolioTrends(
2192
+ data: ReportingControllerGetPortfolioTrendsData
2193
+ ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
1943
2194
  return __request(OpenAPI, {
1944
- method: 'POST',
1945
- url: '/api/v1/{region}/bean/transaction-rules',
2195
+ method: 'GET',
2196
+ url: '/api/v1/{region}/reporting/portfolio/trends',
1946
2197
  path: {
1947
2198
  region: data.region
1948
2199
  },
1949
- body: data.requestBody,
1950
- mediaType: 'application/json',
2200
+ query: {
2201
+ period: data.period,
2202
+ granularity: data.granularity
2203
+ },
1951
2204
  errors: {
1952
- 400: 'Validation failed',
1953
- 401: 'Unauthorized',
1954
- 409: 'Resource conflict - another process is updating this rule'
2205
+ 401: 'User not authenticated'
1955
2206
  }
1956
2207
  });
1957
2208
  }
1958
2209
 
1959
2210
  /**
1960
- * Get all transaction rules for user
2211
+ * Get cash-flow trends
2212
+ *
2213
+ * Monthly income / expense / netSavings over a fixed N-month window
2214
+ * (current month + N−1 prior). Missing months are zero-filled (flow metric).
2215
+ *
2216
+ * **Parameters:**
2217
+ * - `period`: 1m | 3m | 6m | 1y (default 6m)
2218
+ * - `granularity`: accepted for API symmetry; v1 returns month buckets
2219
+ *
1961
2220
  * @param data The data for the request.
1962
2221
  * @param data.region Region code for tenant context
1963
- * @param data.limit Max results per page (default: 20, max: 100)
1964
- * @param data.offset Pagination offset (default: 0)
1965
- * @param data.enabled Filter by enabled status
1966
- * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
1967
- * @param data.autoApplyEnabled Filter by auto-apply status
1968
- * @returns TransactionRuleListResponseDto List of rules
2222
+ * @param data.period Time period
2223
+ * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
2224
+ * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
1969
2225
  * @throws ApiError
1970
2226
  */
1971
- public static transactionRuleControllerList(
1972
- data: TransactionRuleControllerListData
1973
- ): CancelablePromise<TransactionRuleControllerListResponse> {
2227
+ public static reportingControllerGetCashFlowTrends(
2228
+ data: ReportingControllerGetCashFlowTrendsData
2229
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
1974
2230
  return __request(OpenAPI, {
1975
2231
  method: 'GET',
1976
- url: '/api/v1/{region}/bean/transaction-rules',
2232
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
1977
2233
  path: {
1978
2234
  region: data.region
1979
2235
  },
1980
2236
  query: {
1981
- limit: data.limit,
1982
- offset: data.offset,
1983
- enabled: data.enabled,
1984
- learningSource: data.learningSource,
1985
- autoApplyEnabled: data.autoApplyEnabled
2237
+ period: data.period,
2238
+ granularity: data.granularity
1986
2239
  },
1987
2240
  errors: {
1988
- 401: 'Unauthorized'
2241
+ 401: 'User not authenticated'
1989
2242
  }
1990
2243
  });
1991
2244
  }
1992
2245
 
1993
2246
  /**
1994
- * Validate transaction rule configuration
2247
+ * Generate portfolio snapshot
2248
+ *
2249
+ * Manually generate a portfolio snapshot for a specific date.
2250
+ *
2251
+ * **Multi-currency Support:**
2252
+ * - Fetches balances grouped by currency
2253
+ * - Uses user's baseCurrency setting for conversion
2254
+ * - Stores exchange rates and warnings
2255
+ *
2256
+ * **Use Cases:**
2257
+ * - Testing snapshot generation
2258
+ * - Force regeneration after data correction
2259
+ * - Initial setup for new users
2260
+ *
1995
2261
  * @param data The data for the request.
1996
2262
  * @param data.region Region code for tenant context
1997
- * @param data.requestBody
1998
- * @returns ValidateRuleResponseDto Validation result
2263
+ * @param data.requestBody Optional date (defaults to today)
2264
+ * @returns GenerateSnapshotResponse Snapshot generated successfully
1999
2265
  * @throws ApiError
2000
2266
  */
2001
- public static transactionRuleControllerValidate(
2002
- data: TransactionRuleControllerValidateData
2003
- ): CancelablePromise<TransactionRuleControllerValidateResponse> {
2267
+ public static reportingControllerGenerateSnapshot(
2268
+ data: ReportingControllerGenerateSnapshotData
2269
+ ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
2004
2270
  return __request(OpenAPI, {
2005
2271
  method: 'POST',
2006
- url: '/api/v1/{region}/bean/transaction-rules/validate',
2007
- path: {
2008
- region: data.region
2009
- },
2010
- body: data.requestBody,
2011
- mediaType: 'application/json',
2012
- errors: {
2013
- 400: 'Validation failed',
2014
- 401: 'Unauthorized'
2015
- }
2016
- });
2017
- }
2018
-
2019
- /**
2020
- * Bulk create transaction rules
2021
- * @param data The data for the request.
2022
- * @param data.region Region code for tenant context
2023
- * @param data.requestBody
2024
- * @returns BulkCreateRulesResponseDto Bulk create completed
2025
- * @throws ApiError
2026
- */
2027
- public static transactionRuleControllerBulkCreate(
2028
- data: TransactionRuleControllerBulkCreateData
2029
- ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
2030
- return __request(OpenAPI, {
2031
- method: 'POST',
2032
- url: '/api/v1/{region}/bean/transaction-rules/bulk',
2033
- path: {
2034
- region: data.region
2035
- },
2036
- body: data.requestBody,
2037
- mediaType: 'application/json',
2038
- errors: {
2039
- 400: 'Invalid bulk create data',
2040
- 401: 'Unauthorized'
2041
- }
2042
- });
2043
- }
2044
-
2045
- /**
2046
- * Export transaction rules
2047
- * @param data The data for the request.
2048
- * @param data.format Export format (currently only JSON supported)
2049
- * @param data.region Region code for tenant context
2050
- * @returns ExportRulesResponseDto Exported rules
2051
- * @throws ApiError
2052
- */
2053
- public static transactionRuleControllerExport(
2054
- data: TransactionRuleControllerExportData
2055
- ): CancelablePromise<TransactionRuleControllerExportResponse> {
2056
- return __request(OpenAPI, {
2057
- method: 'GET',
2058
- url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2059
- path: {
2060
- format: data.format,
2061
- region: data.region
2062
- },
2063
- errors: {
2064
- 400: 'Unsupported format',
2065
- 401: 'Unauthorized'
2066
- }
2067
- });
2068
- }
2069
-
2070
- /**
2071
- * Get transaction rule statistics
2072
- * @param data The data for the request.
2073
- * @param data.period Statistics time period
2074
- * @param data.region Region code for tenant context
2075
- * @returns RuleStatisticsResponseDto Rule statistics
2076
- * @throws ApiError
2077
- */
2078
- public static transactionRuleControllerGetStatistics(
2079
- data: TransactionRuleControllerGetStatisticsData
2080
- ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
2081
- return __request(OpenAPI, {
2082
- method: 'GET',
2083
- url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
2084
- path: {
2085
- period: data.period,
2086
- region: data.region
2087
- },
2088
- errors: {
2089
- 401: 'Unauthorized'
2090
- }
2091
- });
2092
- }
2093
-
2094
- /**
2095
- * Get transaction rule detail
2096
- * @param data The data for the request.
2097
- * @param data.ruleId Rule ID
2098
- * @param data.region Region code for tenant context
2099
- * @returns TransactionRuleResponseDto Rule details
2100
- * @throws ApiError
2101
- */
2102
- public static transactionRuleControllerGetDetail(
2103
- data: TransactionRuleControllerGetDetailData
2104
- ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
2105
- return __request(OpenAPI, {
2106
- method: 'GET',
2107
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2108
- path: {
2109
- ruleId: data.ruleId,
2110
- region: data.region
2111
- },
2112
- errors: {
2113
- 401: 'Unauthorized',
2114
- 403: 'Forbidden - not owner of rule',
2115
- 404: 'Rule not found'
2116
- }
2117
- });
2118
- }
2119
-
2120
- /**
2121
- * Update a transaction rule
2122
- * @param data The data for the request.
2123
- * @param data.ruleId Rule ID to update
2124
- * @param data.region Region code for tenant context
2125
- * @param data.requestBody
2126
- * @returns TransactionRuleResponseDto Rule updated successfully
2127
- * @throws ApiError
2128
- */
2129
- public static transactionRuleControllerUpdate(
2130
- data: TransactionRuleControllerUpdateData
2131
- ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2132
- return __request(OpenAPI, {
2133
- method: 'PUT',
2134
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2272
+ url: '/api/v1/{region}/reporting/snapshots/generate',
2135
2273
  path: {
2136
- ruleId: data.ruleId,
2137
2274
  region: data.region
2138
2275
  },
2139
2276
  body: data.requestBody,
2140
2277
  mediaType: 'application/json',
2141
2278
  errors: {
2142
- 400: 'Validation failed',
2143
- 401: 'Unauthorized',
2144
- 403: 'Forbidden - not owner of rule',
2145
- 404: 'Rule not found',
2146
- 409: 'Resource conflict - rule is being modified by another process'
2147
- }
2148
- });
2149
- }
2150
-
2151
- /**
2152
- * Delete a transaction rule
2153
- * @param data The data for the request.
2154
- * @param data.ruleId Rule ID to delete
2155
- * @param data.region Region code for tenant context
2156
- * @returns void Rule deleted successfully
2157
- * @throws ApiError
2158
- */
2159
- public static transactionRuleControllerDelete(
2160
- data: TransactionRuleControllerDeleteData
2161
- ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2162
- return __request(OpenAPI, {
2163
- method: 'DELETE',
2164
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2165
- path: {
2166
- ruleId: data.ruleId,
2167
- region: data.region
2168
- },
2169
- errors: {
2170
- 401: 'Unauthorized',
2171
- 403: 'Forbidden - not owner of rule',
2172
- 404: 'Rule not found',
2173
- 409: 'Resource conflict - rule is being modified by another process'
2279
+ 400: 'Invalid date format',
2280
+ 401: 'User not authenticated'
2174
2281
  }
2175
2282
  });
2176
2283
  }
2177
2284
 
2178
2285
  /**
2179
- * Test rule matching
2286
+ * Backfill portfolio snapshots
2287
+ *
2288
+ * Generate snapshots for a date range (historical data backfill).
2289
+ *
2290
+ * **Multi-currency Support:**
2291
+ * - Each snapshot includes multi-currency data
2292
+ * - Uses exchange rates available at generation time
2293
+ * - Warnings stored for missing exchange rates
2294
+ *
2295
+ * **Best Practices:**
2296
+ * - Use for initial setup after account configuration
2297
+ * - Run during low-traffic periods for large date ranges
2298
+ * - Existing snapshots are skipped (not regenerated)
2299
+ *
2180
2300
  * @param data The data for the request.
2181
- * @param data.ruleId Rule ID to test
2182
2301
  * @param data.region Region code for tenant context
2183
2302
  * @param data.requestBody
2184
- * @returns TestRuleResponseDto Test result
2303
+ * @returns BackfillSnapshotsResponse Backfill completed successfully
2185
2304
  * @throws ApiError
2186
2305
  */
2187
- public static transactionRuleControllerTest(
2188
- data: TransactionRuleControllerTestData
2189
- ): CancelablePromise<TransactionRuleControllerTestResponse> {
2306
+ public static reportingControllerBackfillSnapshots(
2307
+ data: ReportingControllerBackfillSnapshotsData
2308
+ ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
2190
2309
  return __request(OpenAPI, {
2191
2310
  method: 'POST',
2192
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2311
+ url: '/api/v1/{region}/reporting/snapshots/backfill',
2193
2312
  path: {
2194
- ruleId: data.ruleId,
2195
2313
  region: data.region
2196
2314
  },
2197
2315
  body: data.requestBody,
2198
2316
  mediaType: 'application/json',
2199
2317
  errors: {
2200
- 401: 'Unauthorized',
2201
- 403: 'Forbidden - not owner of rule',
2202
- 404: 'Rule not found'
2318
+ 400: 'Invalid date format or range',
2319
+ 401: 'User not authenticated',
2320
+ 409: 'Backfill already in progress for this user'
2203
2321
  }
2204
2322
  });
2205
2323
  }
@@ -2251,7 +2369,7 @@ export class UsersService {
2251
2369
  * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
2252
2370
  * @param data The data for the request.
2253
2371
  * @param data.requestBody
2254
- * @returns unknown User created successfully
2372
+ * @returns SignupResponseDto User created successfully
2255
2373
  * @throws ApiError
2256
2374
  */
2257
2375
  public static userControllerSignupUser(
@@ -2460,294 +2578,765 @@ export class PropertiesService {
2460
2578
  }
2461
2579
  }
2462
2580
 
2463
- export class BeanExportService {
2464
- /**
2465
- * Export Beancount ledger as ZIP
2466
- * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
2467
- * @returns unknown
2468
- * @throws ApiError
2469
- */
2470
- public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
2471
- return __request(OpenAPI, {
2472
- method: 'GET',
2473
- url: '/api/v1/{region}/bean/export/beancount'
2474
- });
2475
- }
2476
- }
2477
-
2478
- export class BeanImportService {
2581
+ export class BeanTransactionRulesService {
2479
2582
  /**
2480
- * Import a bill file
2481
- * Upload and process a bill file (CSV, PDF, OFX, etc.). The system automatically identifies the file type, extracts transactions, validates them, and stores only validated transactions to the database. Maximum file size: 50MB. Only 1 import per user at a time (concurrent imports rejected with 429).
2583
+ * Create a new transaction rule (or upsert if upsertByPayee=true)
2584
+ * Creates a new rule. If upsertByPayee=true, updates existing rule matching payeeKeywords[0] instead of creating duplicate.
2482
2585
  * @param data The data for the request.
2483
2586
  * @param data.region Region code for tenant context
2484
- * @param data.formData Bill file to import
2485
- * @returns ImportResultDto File imported successfully
2587
+ * @param data.requestBody
2588
+ * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2486
2589
  * @throws ApiError
2487
2590
  */
2488
- public static fileImportControllerImportFile(
2489
- data: FileImportControllerImportFileData
2490
- ): CancelablePromise<FileImportControllerImportFileResponse> {
2591
+ public static transactionRuleControllerCreate(
2592
+ data: TransactionRuleControllerCreateData
2593
+ ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2491
2594
  return __request(OpenAPI, {
2492
2595
  method: 'POST',
2493
- url: '/api/v1/{region}/bean/import/file',
2596
+ url: '/api/v1/{region}/bean/transaction-rules',
2494
2597
  path: {
2495
2598
  region: data.region
2496
2599
  },
2497
- formData: data.formData,
2498
- mediaType: 'multipart/form-data',
2600
+ body: data.requestBody,
2601
+ mediaType: 'application/json',
2499
2602
  errors: {
2500
- 400: 'Bad request - file-format-unsupported or file-import-failed',
2501
- 413: 'Payload too large - file exceeds 50MB limit',
2502
- 429: 'Too many requests - user already has import in progress',
2503
- 500: 'Internal server error - DATABASE_ERROR'
2603
+ 400: 'Validation failed',
2604
+ 401: 'Unauthorized',
2605
+ 409: 'Resource conflict - another process is updating this rule'
2504
2606
  }
2505
2607
  });
2506
2608
  }
2507
2609
 
2508
2610
  /**
2509
- * Identify file type
2510
- * Upload a file to check if it can be processed by any registered importer. Does not perform actual import - useful for pre-validation. Uses user-specific importer configuration.
2611
+ * Get all transaction rules for user
2511
2612
  * @param data The data for the request.
2512
2613
  * @param data.region Region code for tenant context
2513
- * @param data.formData File to identify
2514
- * @returns IdentifyResultDto File identification result
2614
+ * @param data.limit Max results per page (default: 20, max: 100)
2615
+ * @param data.offset Pagination offset (default: 0)
2616
+ * @param data.enabled Filter by enabled status
2617
+ * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
2618
+ * @param data.autoApplyEnabled Filter by auto-apply status
2619
+ * @returns TransactionRuleListResponseDto List of rules
2515
2620
  * @throws ApiError
2516
2621
  */
2517
- public static fileImportControllerIdentifyFile(
2518
- data: FileImportControllerIdentifyFileData
2519
- ): CancelablePromise<FileImportControllerIdentifyFileResponse> {
2622
+ public static transactionRuleControllerList(
2623
+ data: TransactionRuleControllerListData
2624
+ ): CancelablePromise<TransactionRuleControllerListResponse> {
2625
+ return __request(OpenAPI, {
2626
+ method: 'GET',
2627
+ url: '/api/v1/{region}/bean/transaction-rules',
2628
+ path: {
2629
+ region: data.region
2630
+ },
2631
+ query: {
2632
+ limit: data.limit,
2633
+ offset: data.offset,
2634
+ enabled: data.enabled,
2635
+ learningSource: data.learningSource,
2636
+ autoApplyEnabled: data.autoApplyEnabled
2637
+ },
2638
+ errors: {
2639
+ 401: 'Unauthorized'
2640
+ }
2641
+ });
2642
+ }
2643
+
2644
+ /**
2645
+ * Validate transaction rule configuration
2646
+ * @param data The data for the request.
2647
+ * @param data.region Region code for tenant context
2648
+ * @param data.requestBody
2649
+ * @returns ValidateRuleResponseDto Validation result
2650
+ * @throws ApiError
2651
+ */
2652
+ public static transactionRuleControllerValidate(
2653
+ data: TransactionRuleControllerValidateData
2654
+ ): CancelablePromise<TransactionRuleControllerValidateResponse> {
2520
2655
  return __request(OpenAPI, {
2521
2656
  method: 'POST',
2522
- url: '/api/v1/{region}/bean/import/identify',
2657
+ url: '/api/v1/{region}/bean/transaction-rules/validate',
2523
2658
  path: {
2524
2659
  region: data.region
2525
2660
  },
2526
- formData: data.formData,
2527
- mediaType: 'multipart/form-data',
2661
+ body: data.requestBody,
2662
+ mediaType: 'application/json',
2528
2663
  errors: {
2529
- 400: 'Bad request - No file uploaded'
2664
+ 400: 'Validation failed',
2665
+ 401: 'Unauthorized'
2530
2666
  }
2531
2667
  });
2532
2668
  }
2533
2669
 
2534
2670
  /**
2535
- * Import a Beancount file in community format
2536
- * Upload a .beancount file to import. The system parses community-format paths, converts to internal format using category metadata, auto-creates accounts, and imports transactions with deduplication. Maximum file size: 50MB. Only 1 import per user at a time.
2671
+ * Bulk create transaction rules
2537
2672
  * @param data The data for the request.
2538
2673
  * @param data.region Region code for tenant context
2539
- * @param data.formData Beancount file to import
2540
- * @returns unknown Beancount file imported successfully
2674
+ * @param data.requestBody
2675
+ * @returns BulkCreateRulesResponseDto Bulk create completed
2541
2676
  * @throws ApiError
2542
2677
  */
2543
- public static fileImportControllerImportBeancount(
2544
- data: FileImportControllerImportBeancountData
2545
- ): CancelablePromise<FileImportControllerImportBeancountResponse> {
2678
+ public static transactionRuleControllerBulkCreate(
2679
+ data: TransactionRuleControllerBulkCreateData
2680
+ ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
2546
2681
  return __request(OpenAPI, {
2547
2682
  method: 'POST',
2548
- url: '/api/v1/{region}/bean/import/beancount',
2683
+ url: '/api/v1/{region}/bean/transaction-rules/bulk',
2549
2684
  path: {
2550
2685
  region: data.region
2551
2686
  },
2552
- formData: data.formData,
2553
- mediaType: 'multipart/form-data',
2687
+ body: data.requestBody,
2688
+ mediaType: 'application/json',
2554
2689
  errors: {
2555
- 400: 'Bad request - invalid file or no file uploaded'
2690
+ 400: 'Invalid bulk create data',
2691
+ 401: 'Unauthorized'
2556
2692
  }
2557
2693
  });
2558
2694
  }
2559
2695
 
2560
2696
  /**
2561
- * Get importer configuration
2562
- * Returns the current configuration for the specified importer. Creates default configuration if none exists.
2697
+ * Export transaction rules
2563
2698
  * @param data The data for the request.
2564
- * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
2699
+ * @param data.format Export format (currently only JSON supported)
2565
2700
  * @param data.region Region code for tenant context
2566
- * @returns ImporterConfigDto Configuration retrieved successfully
2701
+ * @returns ExportRulesResponseDto Exported rules
2567
2702
  * @throws ApiError
2568
2703
  */
2569
- public static importerConfigControllerGetConfig(
2570
- data: ImporterConfigControllerGetConfigData
2571
- ): CancelablePromise<ImporterConfigControllerGetConfigResponse> {
2704
+ public static transactionRuleControllerExport(
2705
+ data: TransactionRuleControllerExportData
2706
+ ): CancelablePromise<TransactionRuleControllerExportResponse> {
2572
2707
  return __request(OpenAPI, {
2573
2708
  method: 'GET',
2574
- url: '/api/v1/{region}/bean/import/config/{importerId}',
2709
+ url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2575
2710
  path: {
2576
- importerId: data.importerId,
2711
+ format: data.format,
2577
2712
  region: data.region
2578
2713
  },
2579
2714
  errors: {
2580
- 400: 'Invalid input - Unsupported importer',
2581
- 401: 'Unauthorized - Authentication required'
2715
+ 400: 'Unsupported format',
2716
+ 401: 'Unauthorized'
2582
2717
  }
2583
2718
  });
2584
2719
  }
2585
2720
 
2586
2721
  /**
2587
- * Update importer configuration
2588
- * Updates the configuration for the specified importer. Partial updates are supported.
2722
+ * Get transaction rule statistics
2589
2723
  * @param data The data for the request.
2590
- * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
2724
+ * @param data.period Statistics time period
2591
2725
  * @param data.region Region code for tenant context
2592
- * @param data.requestBody Partial configuration update. Only provided fields will be updated.
2593
- * @returns ImporterConfigDto Configuration updated successfully
2726
+ * @returns RuleStatisticsResponseDto Rule statistics
2594
2727
  * @throws ApiError
2595
2728
  */
2596
- public static importerConfigControllerUpdateConfig(
2597
- data: ImporterConfigControllerUpdateConfigData
2598
- ): CancelablePromise<ImporterConfigControllerUpdateConfigResponse> {
2729
+ public static transactionRuleControllerGetStatistics(
2730
+ data: TransactionRuleControllerGetStatisticsData
2731
+ ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
2732
+ return __request(OpenAPI, {
2733
+ method: 'GET',
2734
+ url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
2735
+ path: {
2736
+ period: data.period,
2737
+ region: data.region
2738
+ },
2739
+ errors: {
2740
+ 401: 'Unauthorized'
2741
+ }
2742
+ });
2743
+ }
2744
+
2745
+ /**
2746
+ * Get transaction rule detail
2747
+ * @param data The data for the request.
2748
+ * @param data.ruleId Rule ID
2749
+ * @param data.region Region code for tenant context
2750
+ * @returns TransactionRuleResponseDto Rule details
2751
+ * @throws ApiError
2752
+ */
2753
+ public static transactionRuleControllerGetDetail(
2754
+ data: TransactionRuleControllerGetDetailData
2755
+ ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
2756
+ return __request(OpenAPI, {
2757
+ method: 'GET',
2758
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2759
+ path: {
2760
+ ruleId: data.ruleId,
2761
+ region: data.region
2762
+ },
2763
+ errors: {
2764
+ 401: 'Unauthorized',
2765
+ 403: 'Forbidden - not owner of rule',
2766
+ 404: 'Rule not found'
2767
+ }
2768
+ });
2769
+ }
2770
+
2771
+ /**
2772
+ * Update a transaction rule
2773
+ * @param data The data for the request.
2774
+ * @param data.ruleId Rule ID to update
2775
+ * @param data.region Region code for tenant context
2776
+ * @param data.requestBody
2777
+ * @returns TransactionRuleResponseDto Rule updated successfully
2778
+ * @throws ApiError
2779
+ */
2780
+ public static transactionRuleControllerUpdate(
2781
+ data: TransactionRuleControllerUpdateData
2782
+ ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2599
2783
  return __request(OpenAPI, {
2600
2784
  method: 'PUT',
2601
- url: '/api/v1/{region}/bean/import/config/{importerId}',
2785
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2602
2786
  path: {
2603
- importerId: data.importerId,
2787
+ ruleId: data.ruleId,
2604
2788
  region: data.region
2605
2789
  },
2606
2790
  body: data.requestBody,
2607
2791
  mediaType: 'application/json',
2608
2792
  errors: {
2609
- 400: 'Invalid input - Validation failed',
2610
- 404: 'Configuration not found'
2793
+ 400: 'Validation failed',
2794
+ 401: 'Unauthorized',
2795
+ 403: 'Forbidden - not owner of rule',
2796
+ 404: 'Rule not found',
2797
+ 409: 'Resource conflict - rule is being modified by another process'
2611
2798
  }
2612
2799
  });
2613
2800
  }
2614
2801
 
2615
2802
  /**
2616
- * Reset configuration to default
2617
- * Resets the configuration for the specified importer to default values. This operation overwrites all existing configuration.
2803
+ * Delete a transaction rule
2618
2804
  * @param data The data for the request.
2619
- * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
2805
+ * @param data.ruleId Rule ID to delete
2620
2806
  * @param data.region Region code for tenant context
2621
- * @returns ImporterConfigDto Configuration reset successfully
2807
+ * @returns void Rule deleted successfully
2622
2808
  * @throws ApiError
2623
2809
  */
2624
- public static importerConfigControllerResetConfig(
2625
- data: ImporterConfigControllerResetConfigData
2626
- ): CancelablePromise<ImporterConfigControllerResetConfigResponse> {
2810
+ public static transactionRuleControllerDelete(
2811
+ data: TransactionRuleControllerDeleteData
2812
+ ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2627
2813
  return __request(OpenAPI, {
2628
- method: 'POST',
2629
- url: '/api/v1/{region}/bean/import/config/{importerId}/reset',
2814
+ method: 'DELETE',
2815
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2630
2816
  path: {
2631
- importerId: data.importerId,
2817
+ ruleId: data.ruleId,
2632
2818
  region: data.region
2633
2819
  },
2634
2820
  errors: {
2635
- 400: 'Invalid input - Unsupported importer'
2821
+ 401: 'Unauthorized',
2822
+ 403: 'Forbidden - not owner of rule',
2823
+ 404: 'Rule not found',
2824
+ 409: 'Resource conflict - rule is being modified by another process'
2636
2825
  }
2637
2826
  });
2638
2827
  }
2639
- }
2640
2828
 
2641
- export class BeanPlatformsService {
2642
2829
  /**
2643
- * Get all platforms with statistics
2644
- * @returns unknown List of platforms with binding and account counts
2830
+ * Test rule matching
2831
+ * @param data The data for the request.
2832
+ * @param data.ruleId Rule ID to test
2833
+ * @param data.region Region code for tenant context
2834
+ * @param data.requestBody
2835
+ * @returns TestRuleResponseDto Test result
2645
2836
  * @throws ApiError
2646
2837
  */
2647
- public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
2838
+ public static transactionRuleControllerTest(
2839
+ data: TransactionRuleControllerTestData
2840
+ ): CancelablePromise<TransactionRuleControllerTestResponse> {
2648
2841
  return __request(OpenAPI, {
2649
- method: 'GET',
2650
- url: '/api/v1/bean/platforms'
2842
+ method: 'POST',
2843
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2844
+ path: {
2845
+ ruleId: data.ruleId,
2846
+ region: data.region
2847
+ },
2848
+ body: data.requestBody,
2849
+ mediaType: 'application/json',
2850
+ errors: {
2851
+ 401: 'Unauthorized',
2852
+ 403: 'Forbidden - not owner of rule',
2853
+ 404: 'Rule not found'
2854
+ }
2651
2855
  });
2652
2856
  }
2857
+ }
2653
2858
 
2859
+ export class LifeEventsService {
2654
2860
  /**
2655
- * Create a new platform
2861
+ * Create a new life event
2862
+ * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
2656
2863
  * @param data The data for the request.
2864
+ * @param data.region Region code for tenant context (decorative for life events)
2657
2865
  * @param data.requestBody
2658
- * @returns unknown Platform created successfully
2866
+ * @returns EventResponseDto Life event created successfully
2659
2867
  * @throws ApiError
2660
2868
  */
2661
- public static platformControllerCreate(
2662
- data: PlatformControllerCreateData
2663
- ): CancelablePromise<PlatformControllerCreateResponse> {
2869
+ public static eventControllerCreate(
2870
+ data: EventControllerCreateData
2871
+ ): CancelablePromise<EventControllerCreateResponse> {
2664
2872
  return __request(OpenAPI, {
2665
2873
  method: 'POST',
2666
- url: '/api/v1/bean/platforms',
2874
+ url: '/api/v1/{region}/bean/events',
2875
+ path: {
2876
+ region: data.region
2877
+ },
2667
2878
  body: data.requestBody,
2668
2879
  mediaType: 'application/json',
2669
2880
  errors: {
2670
- 409: 'Platform already exists'
2881
+ 409: 'Life event already exists for this (userId, type, date) combination'
2671
2882
  }
2672
2883
  });
2673
2884
  }
2674
2885
 
2675
2886
  /**
2676
- * Get platform list for current user
2677
- * @returns unknown List of platforms with user binding status
2887
+ * List user life events
2888
+ * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2889
+ * @param data The data for the request.
2890
+ * @param data.region Region code for tenant context (decorative for life events)
2891
+ * @param data.type Filter by life event type (exact match)
2892
+ * @param data.q Search term for description (case-insensitive partial match)
2893
+ * @param data.from Filter life events from this date (ISO 8601 format)
2894
+ * @param data.to Filter life events to this date (ISO 8601 format)
2895
+ * @param data.page Page number for pagination (default: 1)
2896
+ * @param data.limit Number of items per page (default: 20, max: 100)
2897
+ * @returns EventListResponseDto Life events retrieved successfully
2678
2898
  * @throws ApiError
2679
2899
  */
2680
- public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
2900
+ public static eventControllerFindAll(
2901
+ data: EventControllerFindAllData
2902
+ ): CancelablePromise<EventControllerFindAllResponse> {
2681
2903
  return __request(OpenAPI, {
2682
2904
  method: 'GET',
2683
- url: '/api/v1/bean/platforms/list'
2905
+ url: '/api/v1/{region}/bean/events',
2906
+ path: {
2907
+ region: data.region
2908
+ },
2909
+ query: {
2910
+ type: data.type,
2911
+ q: data.q,
2912
+ from: data.from,
2913
+ to: data.to,
2914
+ page: data.page,
2915
+ limit: data.limit
2916
+ }
2684
2917
  });
2685
2918
  }
2686
2919
 
2687
2920
  /**
2688
- * Match platforms by name or alias
2921
+ * Get life event by ID
2922
+ * Returns a single life event by its ID. Returns ETag header.
2689
2923
  * @param data The data for the request.
2690
- * @param data.q Search query — Chinese name, English name, or abbreviation
2691
- * @param data.region Region code for category override lookup
2692
- * @returns unknown List of matching platforms with suggested segment names
2924
+ * @param data.id Life event ID
2925
+ * @param data.region Region code for tenant context (decorative for life events)
2926
+ * @returns EventResponseDto Life event retrieved successfully
2693
2927
  * @throws ApiError
2694
2928
  */
2695
- public static platformControllerMatchPlatforms(
2696
- data: PlatformControllerMatchPlatformsData
2697
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
2929
+ public static eventControllerFindOne(
2930
+ data: EventControllerFindOneData
2931
+ ): CancelablePromise<EventControllerFindOneResponse> {
2698
2932
  return __request(OpenAPI, {
2699
2933
  method: 'GET',
2700
- url: '/api/v1/bean/platforms/match',
2701
- query: {
2702
- q: data.q,
2934
+ url: '/api/v1/{region}/bean/events/{id}',
2935
+ path: {
2936
+ id: data.id,
2703
2937
  region: data.region
2938
+ },
2939
+ errors: {
2940
+ 404: 'Life event not found'
2704
2941
  }
2705
2942
  });
2706
2943
  }
2707
2944
 
2708
2945
  /**
2709
- * Update a platform
2946
+ * Update a life event
2947
+ * Updates an existing life event. If If-Match header is provided, performs optimistic concurrency check; mismatched updatedAt returns 412.
2710
2948
  * @param data The data for the request.
2711
- * @param data.id Platform ID
2949
+ * @param data.id Life event ID
2950
+ * @param data.region Region code for tenant context (decorative for life events)
2712
2951
  * @param data.requestBody
2713
- * @returns unknown Platform updated successfully
2952
+ * @returns EventResponseDto Life event updated successfully
2714
2953
  * @throws ApiError
2715
2954
  */
2716
- public static platformControllerUpdate(
2717
- data: PlatformControllerUpdateData
2718
- ): CancelablePromise<PlatformControllerUpdateResponse> {
2955
+ public static eventControllerUpdate(
2956
+ data: EventControllerUpdateData
2957
+ ): CancelablePromise<EventControllerUpdateResponse> {
2958
+ return __request(OpenAPI, {
2959
+ method: 'PUT',
2960
+ url: '/api/v1/{region}/bean/events/{id}',
2961
+ path: {
2962
+ id: data.id,
2963
+ region: data.region
2964
+ },
2965
+ body: data.requestBody,
2966
+ mediaType: 'application/json',
2967
+ errors: {
2968
+ 400: 'If-Match header is not a valid ISO 8601 date',
2969
+ 404: 'Life event not found',
2970
+ 409: 'Updated event conflicts with an existing (userId, type, date) combination',
2971
+ 412: 'If-Match precondition failed (updatedAt mismatch)'
2972
+ }
2973
+ });
2974
+ }
2975
+
2976
+ /**
2977
+ * Delete a life event
2978
+ * Deletes a life event entry (hard delete). Returns 204.
2979
+ * @param data The data for the request.
2980
+ * @param data.id Life event ID
2981
+ * @param data.region Region code for tenant context (decorative for life events)
2982
+ * @returns void Life event deleted successfully
2983
+ * @throws ApiError
2984
+ */
2985
+ public static eventControllerDelete(
2986
+ data: EventControllerDeleteData
2987
+ ): CancelablePromise<EventControllerDeleteResponse> {
2988
+ return __request(OpenAPI, {
2989
+ method: 'DELETE',
2990
+ url: '/api/v1/{region}/bean/events/{id}',
2991
+ path: {
2992
+ id: data.id,
2993
+ region: data.region
2994
+ },
2995
+ errors: {
2996
+ 404: 'Life event not found'
2997
+ }
2998
+ });
2999
+ }
3000
+
3001
+ /**
3002
+ * Slice time-series by a life event (Phase 79)
3003
+ * Returns aggregated time-series for postings matching accountPattern within the half-open date range of the given life event.
3004
+ * @param data The data for the request.
3005
+ * @param data.id Life event ID
3006
+ * @param data.accountPattern
3007
+ * @param data.granularity
3008
+ * @param data.region Region code for tenant context (decorative for life events)
3009
+ * @returns unknown Time-series sliced by the life event range
3010
+ * @throws ApiError
3011
+ */
3012
+ public static eventControllerGetSlice(
3013
+ data: EventControllerGetSliceData
3014
+ ): CancelablePromise<EventControllerGetSliceResponse> {
3015
+ return __request(OpenAPI, {
3016
+ method: 'GET',
3017
+ url: '/api/v1/{region}/bean/events/{id}/slice',
3018
+ path: {
3019
+ id: data.id,
3020
+ region: data.region
3021
+ },
3022
+ query: {
3023
+ accountPattern: data.accountPattern,
3024
+ granularity: data.granularity
3025
+ },
3026
+ errors: {
3027
+ 400: 'accountPattern query param is empty',
3028
+ 404: 'Life event not found'
3029
+ }
3030
+ });
3031
+ }
3032
+ }
3033
+
3034
+ export class OnboardingService {
3035
+ /**
3036
+ * Bootstrap core accounts + register asset accounts with opening balances (ADR-0113)
3037
+ * @param data The data for the request.
3038
+ * @param data.region Region code for tenant context
3039
+ * @param data.requestBody
3040
+ * @returns unknown Onboarding bootstrap result.
3041
+ * @throws ApiError
3042
+ */
3043
+ public static onboardingControllerBootstrap(
3044
+ data: OnboardingControllerBootstrapData
3045
+ ): CancelablePromise<OnboardingControllerBootstrapResponse> {
3046
+ return __request(OpenAPI, {
3047
+ method: 'POST',
3048
+ url: '/api/v1/{region}/bean/onboarding',
3049
+ path: {
3050
+ region: data.region
3051
+ },
3052
+ body: data.requestBody,
3053
+ mediaType: 'application/json',
3054
+ errors: {
3055
+ 422: 'Invalid region/account path/duplicate paths.'
3056
+ }
3057
+ });
3058
+ }
3059
+ }
3060
+
3061
+ export class BalanceReconciliationService {
3062
+ /**
3063
+ * Preview reconciliation (book vs actual)
3064
+ * Computes book balance, diff, Beancount-inferred tolerance, and suggested action without persisting.
3065
+ * @param data The data for the request.
3066
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3067
+ * @param data.requestBody
3068
+ * @returns ReconciliationComputeResultDto Reconciliation preview
3069
+ * @throws ApiError
3070
+ */
3071
+ public static reconciliationControllerCompute(
3072
+ data: ReconciliationControllerComputeData
3073
+ ): CancelablePromise<ReconciliationControllerComputeResponse> {
3074
+ return __request(OpenAPI, {
3075
+ method: 'POST',
3076
+ url: '/api/v1/{region}/bean/reconciliations',
3077
+ path: {
3078
+ region: data.region
3079
+ },
3080
+ body: data.requestBody,
3081
+ mediaType: 'application/json',
3082
+ errors: {
3083
+ 404: 'Account not found'
3084
+ }
3085
+ });
3086
+ }
3087
+
3088
+ /**
3089
+ * Record a balance assertion
3090
+ * Persists the reconciliation as a BeanBalance assertion (amount = actual, diffAmount = book − actual). Re-reconciling the same day/currency upserts.
3091
+ * @param data The data for the request.
3092
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3093
+ * @param data.requestBody
3094
+ * @returns ReconciliationRecordDto Balance assertion recorded
3095
+ * @throws ApiError
3096
+ */
3097
+ public static reconciliationControllerAssert(
3098
+ data: ReconciliationControllerAssertData
3099
+ ): CancelablePromise<ReconciliationControllerAssertResponse> {
3100
+ return __request(OpenAPI, {
3101
+ method: 'POST',
3102
+ url: '/api/v1/{region}/bean/reconciliations/assert',
3103
+ path: {
3104
+ region: data.region
3105
+ },
3106
+ body: data.requestBody,
3107
+ mediaType: 'application/json',
3108
+ errors: {
3109
+ 404: 'Account not found'
3110
+ }
3111
+ });
3112
+ }
3113
+
3114
+ /**
3115
+ * Generate a pad adjusting entry
3116
+ * When book is outside tolerance, synthesizes a Beancount pad transaction (flag P) booking the diff from source_account and persists it. Source defaults to Equity:Opening-Balances.
3117
+ * @param data The data for the request.
3118
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3119
+ * @param data.requestBody
3120
+ * @returns PadResultDto Pad adjusting entry generated
3121
+ * @throws ApiError
3122
+ */
3123
+ public static reconciliationControllerPad(
3124
+ data: ReconciliationControllerPadData
3125
+ ): CancelablePromise<ReconciliationControllerPadResponse> {
3126
+ return __request(OpenAPI, {
3127
+ method: 'POST',
3128
+ url: '/api/v1/{region}/bean/reconciliations/pad',
3129
+ path: {
3130
+ region: data.region
3131
+ },
3132
+ body: data.requestBody,
3133
+ mediaType: 'application/json',
3134
+ errors: {
3135
+ 400: 'Book already within tolerance — no pad needed',
3136
+ 404: 'Account not found'
3137
+ }
3138
+ });
3139
+ }
3140
+
3141
+ /**
3142
+ * List reconciliation history for an account
3143
+ * Returns recorded balance assertions (most recent first). The latest drives the account-detail "Last <date>" badge.
3144
+ * @param data The data for the request.
3145
+ * @param data.accountId BeanAccount id
3146
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3147
+ * @returns ReconciliationRecordDto Reconciliation history
3148
+ * @throws ApiError
3149
+ */
3150
+ public static reconciliationControllerHistory(
3151
+ data: ReconciliationControllerHistoryData
3152
+ ): CancelablePromise<ReconciliationControllerHistoryResponse> {
3153
+ return __request(OpenAPI, {
3154
+ method: 'GET',
3155
+ url: '/api/v1/{region}/bean/accounts/{accountId}/reconciliations',
3156
+ path: {
3157
+ accountId: data.accountId,
3158
+ region: data.region
3159
+ },
3160
+ errors: {
3161
+ 404: 'Account not found'
3162
+ }
3163
+ });
3164
+ }
3165
+ }
3166
+
3167
+ export class BeanExportService {
3168
+ /**
3169
+ * Export Beancount ledger as ZIP
3170
+ * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
3171
+ * @returns unknown
3172
+ * @throws ApiError
3173
+ */
3174
+ public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
3175
+ return __request(OpenAPI, {
3176
+ method: 'GET',
3177
+ url: '/api/v1/{region}/bean/export/beancount'
3178
+ });
3179
+ }
3180
+ }
3181
+
3182
+ export class BeanImportService {
3183
+ /**
3184
+ * Import a bill file
3185
+ * Upload and process a bill file (CSV, PDF, OFX, etc.). The system automatically identifies the file type, extracts transactions, validates them, and stores only validated transactions to the database. Maximum file size: 50MB. Only 1 import per user at a time (concurrent imports rejected with 429).
3186
+ * @param data The data for the request.
3187
+ * @param data.region Region code for tenant context
3188
+ * @param data.formData Bill file to import
3189
+ * @returns ImportResultDto File imported successfully
3190
+ * @throws ApiError
3191
+ */
3192
+ public static fileImportControllerImportFile(
3193
+ data: FileImportControllerImportFileData
3194
+ ): CancelablePromise<FileImportControllerImportFileResponse> {
3195
+ return __request(OpenAPI, {
3196
+ method: 'POST',
3197
+ url: '/api/v1/{region}/bean/import/file',
3198
+ path: {
3199
+ region: data.region
3200
+ },
3201
+ formData: data.formData,
3202
+ mediaType: 'multipart/form-data',
3203
+ errors: {
3204
+ 400: 'Bad request - file-format-unsupported or file-import-failed',
3205
+ 413: 'Payload too large - file exceeds 50MB limit',
3206
+ 429: 'Too many requests - user already has import in progress',
3207
+ 500: 'Internal server error - DATABASE_ERROR'
3208
+ }
3209
+ });
3210
+ }
3211
+
3212
+ /**
3213
+ * Identify file type
3214
+ * Upload a file to check if it can be processed by any registered importer. Does not perform actual import - useful for pre-validation. Uses user-specific importer configuration.
3215
+ * @param data The data for the request.
3216
+ * @param data.region Region code for tenant context
3217
+ * @param data.formData File to identify
3218
+ * @returns IdentifyResultDto File identification result
3219
+ * @throws ApiError
3220
+ */
3221
+ public static fileImportControllerIdentifyFile(
3222
+ data: FileImportControllerIdentifyFileData
3223
+ ): CancelablePromise<FileImportControllerIdentifyFileResponse> {
3224
+ return __request(OpenAPI, {
3225
+ method: 'POST',
3226
+ url: '/api/v1/{region}/bean/import/identify',
3227
+ path: {
3228
+ region: data.region
3229
+ },
3230
+ formData: data.formData,
3231
+ mediaType: 'multipart/form-data',
3232
+ errors: {
3233
+ 400: 'Bad request - No file uploaded'
3234
+ }
3235
+ });
3236
+ }
3237
+
3238
+ /**
3239
+ * Import a Beancount file in community format
3240
+ * Upload a .beancount file to import. The system parses community-format paths, converts to internal format using category metadata, auto-creates accounts, and imports transactions with deduplication. Maximum file size: 50MB. Only 1 import per user at a time.
3241
+ * @param data The data for the request.
3242
+ * @param data.region Region code for tenant context
3243
+ * @param data.formData Beancount file to import
3244
+ * @returns unknown Beancount file imported successfully
3245
+ * @throws ApiError
3246
+ */
3247
+ public static fileImportControllerImportBeancount(
3248
+ data: FileImportControllerImportBeancountData
3249
+ ): CancelablePromise<FileImportControllerImportBeancountResponse> {
3250
+ return __request(OpenAPI, {
3251
+ method: 'POST',
3252
+ url: '/api/v1/{region}/bean/import/beancount',
3253
+ path: {
3254
+ region: data.region
3255
+ },
3256
+ formData: data.formData,
3257
+ mediaType: 'multipart/form-data',
3258
+ errors: {
3259
+ 400: 'Bad request - invalid file or no file uploaded'
3260
+ }
3261
+ });
3262
+ }
3263
+
3264
+ /**
3265
+ * Get importer configuration
3266
+ * Returns the current configuration for the specified importer. Creates default configuration if none exists.
3267
+ * @param data The data for the request.
3268
+ * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
3269
+ * @param data.region Region code for tenant context
3270
+ * @returns ImporterConfigDto Configuration retrieved successfully
3271
+ * @throws ApiError
3272
+ */
3273
+ public static importerConfigControllerGetConfig(
3274
+ data: ImporterConfigControllerGetConfigData
3275
+ ): CancelablePromise<ImporterConfigControllerGetConfigResponse> {
3276
+ return __request(OpenAPI, {
3277
+ method: 'GET',
3278
+ url: '/api/v1/{region}/bean/import/config/{importerId}',
3279
+ path: {
3280
+ importerId: data.importerId,
3281
+ region: data.region
3282
+ },
3283
+ errors: {
3284
+ 400: 'Invalid input - Unsupported importer',
3285
+ 401: 'Unauthorized - Authentication required'
3286
+ }
3287
+ });
3288
+ }
3289
+
3290
+ /**
3291
+ * Update importer configuration
3292
+ * Updates the configuration for the specified importer. Partial updates are supported.
3293
+ * @param data The data for the request.
3294
+ * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
3295
+ * @param data.region Region code for tenant context
3296
+ * @param data.requestBody Partial configuration update. Only provided fields will be updated.
3297
+ * @returns ImporterConfigDto Configuration updated successfully
3298
+ * @throws ApiError
3299
+ */
3300
+ public static importerConfigControllerUpdateConfig(
3301
+ data: ImporterConfigControllerUpdateConfigData
3302
+ ): CancelablePromise<ImporterConfigControllerUpdateConfigResponse> {
2719
3303
  return __request(OpenAPI, {
2720
3304
  method: 'PUT',
2721
- url: '/api/v1/bean/platforms/{id}',
3305
+ url: '/api/v1/{region}/bean/import/config/{importerId}',
2722
3306
  path: {
2723
- id: data.id
3307
+ importerId: data.importerId,
3308
+ region: data.region
2724
3309
  },
2725
3310
  body: data.requestBody,
2726
3311
  mediaType: 'application/json',
2727
3312
  errors: {
2728
- 404: 'Platform not found'
3313
+ 400: 'Invalid input - Validation failed',
3314
+ 404: 'Configuration not found'
2729
3315
  }
2730
3316
  });
2731
3317
  }
2732
3318
 
2733
3319
  /**
2734
- * Delete a platform
3320
+ * Reset configuration to default
3321
+ * Resets the configuration for the specified importer to default values. This operation overwrites all existing configuration.
2735
3322
  * @param data The data for the request.
2736
- * @param data.id Platform ID
2737
- * @returns void Platform deleted successfully
3323
+ * @param data.importerId Importer identifier. Supported importers: alipay, alipay-web, wechat, boc, boc-credit, ccb, cmb, cmbc, cmbc-credit, icbc, icbc-credit, hsbc-hk-credit, hsbc-hk-debit
3324
+ * @param data.region Region code for tenant context
3325
+ * @returns ImporterConfigDto Configuration reset successfully
2738
3326
  * @throws ApiError
2739
3327
  */
2740
- public static platformControllerDelete(
2741
- data: PlatformControllerDeleteData
2742
- ): CancelablePromise<PlatformControllerDeleteResponse> {
3328
+ public static importerConfigControllerResetConfig(
3329
+ data: ImporterConfigControllerResetConfigData
3330
+ ): CancelablePromise<ImporterConfigControllerResetConfigResponse> {
2743
3331
  return __request(OpenAPI, {
2744
- method: 'DELETE',
2745
- url: '/api/v1/bean/platforms/{id}',
3332
+ method: 'POST',
3333
+ url: '/api/v1/{region}/bean/import/config/{importerId}/reset',
2746
3334
  path: {
2747
- id: data.id
3335
+ importerId: data.importerId,
3336
+ region: data.region
2748
3337
  },
2749
3338
  errors: {
2750
- 404: 'Platform not found'
3339
+ 400: 'Invalid input - Unsupported importer'
2751
3340
  }
2752
3341
  });
2753
3342
  }
@@ -2853,6 +3442,101 @@ export class ProviderSyncService {
2853
3442
  }
2854
3443
  }
2855
3444
 
3445
+ export class ExternalAccountLinksService {
3446
+ /**
3447
+ * Create an external account → BeanAccount mapping (ADR-0113)
3448
+ * @param data The data for the request.
3449
+ * @param data.region Region code for tenant context
3450
+ * @param data.requestBody
3451
+ * @returns ExternalAccountLinkResponseDto Link created.
3452
+ * @throws ApiError
3453
+ */
3454
+ public static externalAccountLinkControllerCreate(
3455
+ data: ExternalAccountLinkControllerCreateData
3456
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
3457
+ return __request(OpenAPI, {
3458
+ method: 'POST',
3459
+ url: '/api/v1/{region}/bean/external-account-links',
3460
+ path: {
3461
+ region: data.region
3462
+ },
3463
+ body: data.requestBody,
3464
+ mediaType: 'application/json',
3465
+ errors: {
3466
+ 422: 'beanAccountId not owned, or an active link already exists.'
3467
+ }
3468
+ });
3469
+ }
3470
+
3471
+ /**
3472
+ * List the user's active external account links
3473
+ * @param data The data for the request.
3474
+ * @param data.provider
3475
+ * @param data.region Region code for tenant context
3476
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
3477
+ * @throws ApiError
3478
+ */
3479
+ public static externalAccountLinkControllerFindAll(
3480
+ data: ExternalAccountLinkControllerFindAllData
3481
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
3482
+ return __request(OpenAPI, {
3483
+ method: 'GET',
3484
+ url: '/api/v1/{region}/bean/external-account-links',
3485
+ path: {
3486
+ region: data.region
3487
+ },
3488
+ query: {
3489
+ provider: data.provider
3490
+ }
3491
+ });
3492
+ }
3493
+
3494
+ /**
3495
+ * Get a single external account link
3496
+ * @param data The data for the request.
3497
+ * @param data.id
3498
+ * @param data.region Region code for tenant context
3499
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
3500
+ * @throws ApiError
3501
+ */
3502
+ public static externalAccountLinkControllerFindOne(
3503
+ data: ExternalAccountLinkControllerFindOneData
3504
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
3505
+ return __request(OpenAPI, {
3506
+ method: 'GET',
3507
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3508
+ path: {
3509
+ id: data.id,
3510
+ region: data.region
3511
+ },
3512
+ errors: {
3513
+ 422: 'Link not found or not owned by the user.'
3514
+ }
3515
+ });
3516
+ }
3517
+
3518
+ /**
3519
+ * Soft-delete (disconnect) an external account link
3520
+ * @param data The data for the request.
3521
+ * @param data.id
3522
+ * @param data.region Region code for tenant context
3523
+ * @returns void Link soft-deleted; historical transactions are unaffected.
3524
+ * @throws ApiError
3525
+ */
3526
+ public static externalAccountLinkControllerRemove(
3527
+ data: ExternalAccountLinkControllerRemoveData
3528
+ ): CancelablePromise<ExternalAccountLinkControllerRemoveResponse> {
3529
+ return __request(OpenAPI, {
3530
+ method: 'DELETE',
3531
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3532
+ path: {
3533
+ id: data.id,
3534
+ region: data.region
3535
+ }
3536
+ });
3537
+ }
3538
+ }
3539
+
2856
3540
  export class ImportTelemetryService {
2857
3541
  /**
2858
3542
  * Receive anonymous parser failure telemetry
@@ -3011,411 +3695,277 @@ export class BeanNlpService {
3011
3695
  }
3012
3696
  }
3013
3697
 
3014
- export class DashboardService {
3015
- /**
3016
- * Get net worth overview
3017
- * Returns total net worth with breakdown of assets and liabilities
3018
- * @param data The data for the request.
3019
- * @param data.region Region code for tenant context
3020
- * @param data.date Date for balance calculation (ISO 8601 format)
3021
- * @returns NetWorthResponseDto Net worth retrieved successfully
3022
- * @throws ApiError
3023
- */
3024
- public static dashboardControllerGetNetWorth(
3025
- data: DashboardControllerGetNetWorthData
3026
- ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3027
- return __request(OpenAPI, {
3028
- method: 'GET',
3029
- url: '/api/v1/{region}/dashboard/net-worth',
3030
- path: {
3031
- region: data.region
3032
- },
3033
- query: {
3034
- date: data.date
3035
- },
3036
- errors: {
3037
- 401: 'User not authenticated'
3038
- }
3039
- });
3040
- }
3041
-
3698
+ export class BeanPlatformsService {
3042
3699
  /**
3043
- * Get accounts grouped by platform
3044
- * Returns accounts with balances grouped by financial platform
3045
- * @param data The data for the request.
3046
- * @param data.region Region code for tenant context
3047
- * @param data.groupBy Grouping strategy
3048
- * @param data.date Date for balance calculation (ISO 8601 format)
3049
- * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3050
- * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3700
+ * Get all platforms with statistics
3701
+ * @returns unknown List of platforms with binding and account counts
3051
3702
  * @throws ApiError
3052
3703
  */
3053
- public static dashboardControllerGetAccounts(
3054
- data: DashboardControllerGetAccountsData
3055
- ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3704
+ public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
3056
3705
  return __request(OpenAPI, {
3057
3706
  method: 'GET',
3058
- url: '/api/v1/{region}/dashboard/accounts',
3059
- path: {
3060
- region: data.region
3061
- },
3062
- query: {
3063
- groupBy: data.groupBy,
3064
- date: data.date,
3065
- accountId: data.accountId
3066
- },
3067
- errors: {
3068
- 401: 'User not authenticated'
3069
- }
3707
+ url: '/api/v1/bean/platforms'
3070
3708
  });
3071
3709
  }
3072
3710
 
3073
3711
  /**
3074
- * Get cash flow summary
3075
- * Returns income, expenses, and savings for a monthly period
3712
+ * Create a new platform
3076
3713
  * @param data The data for the request.
3077
- * @param data.period Period in YYYY-MM format
3078
- * @param data.region Region code for tenant context
3079
- * @returns CashFlowResponseDto Cash flow retrieved successfully
3714
+ * @param data.requestBody
3715
+ * @returns unknown Platform created successfully
3080
3716
  * @throws ApiError
3081
3717
  */
3082
- public static dashboardControllerGetCashFlow(
3083
- data: DashboardControllerGetCashFlowData
3084
- ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3718
+ public static platformControllerCreate(
3719
+ data: PlatformControllerCreateData
3720
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3085
3721
  return __request(OpenAPI, {
3086
- method: 'GET',
3087
- url: '/api/v1/{region}/dashboard/cash-flow',
3088
- path: {
3089
- region: data.region
3090
- },
3091
- query: {
3092
- period: data.period
3093
- },
3722
+ method: 'POST',
3723
+ url: '/api/v1/bean/platforms',
3724
+ body: data.requestBody,
3725
+ mediaType: 'application/json',
3094
3726
  errors: {
3095
- 400: 'Invalid period format',
3096
- 401: 'User not authenticated'
3727
+ 409: 'Platform already exists'
3097
3728
  }
3098
3729
  });
3099
3730
  }
3100
- }
3101
3731
 
3102
- export class InvestmentService {
3103
3732
  /**
3104
- * Get per-holding unrealized + realized P&L
3105
- * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3733
+ * Get platform list for current user
3106
3734
  * @param data The data for the request.
3107
- * @param data.region Region code for tenant context
3108
- * @param data.asOf As-of date (ISO 8601), defaults to today
3109
- * @param data.accountId Scope to a single account
3110
- * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3111
- * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3735
+ * @param data.region Region code (ISO 3166-1 alpha-2) that biases within-type-bucket ordering (local-region platforms first). Case-insensitive — stored/compared UPPERCASE ("cn" == "CN").
3736
+ * @returns PlatformListItemDto List of platforms with user binding status
3112
3737
  * @throws ApiError
3113
3738
  */
3114
- public static holdingPnlControllerGetHoldingPnl(
3115
- data: HoldingPnlControllerGetHoldingPnlData
3116
- ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3739
+ public static platformControllerGetPlatformList(
3740
+ data: PlatformControllerGetPlatformListData = {}
3741
+ ): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3117
3742
  return __request(OpenAPI, {
3118
3743
  method: 'GET',
3119
- url: '/api/v1/{region}/investment/holdings/pnl',
3120
- path: {
3121
- region: data.region
3122
- },
3744
+ url: '/api/v1/bean/platforms/list',
3123
3745
  query: {
3124
- asOf: data.asOf,
3125
- accountId: data.accountId,
3126
- method: data.method
3127
- },
3128
- errors: {
3129
- 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3130
- 401: 'User not authenticated'
3131
- }
3132
- });
3133
- }
3134
- }
3135
-
3136
- export class BeanPricesService {
3137
- /**
3138
- * Create a new price
3139
- * Creates a new price entry for the authenticated user
3140
- * @param data The data for the request.
3141
- * @param data.region Region code for tenant context
3142
- * @param data.requestBody
3143
- * @returns PriceResponseDto Price created successfully
3144
- * @throws ApiError
3145
- */
3146
- public static priceControllerCreate(
3147
- data: PriceControllerCreateData
3148
- ): CancelablePromise<PriceControllerCreateResponse> {
3149
- return __request(OpenAPI, {
3150
- method: 'POST',
3151
- url: '/api/v1/{region}/bean/prices',
3152
- path: {
3153
3746
  region: data.region
3154
- },
3155
- body: data.requestBody,
3156
- mediaType: 'application/json',
3157
- errors: {
3158
- 404: 'Currency or quoteCurrency commodity not found',
3159
- 409: 'Price already exists for this currency pair and date'
3160
3747
  }
3161
3748
  });
3162
3749
  }
3163
3750
 
3164
3751
  /**
3165
- * List user prices
3166
- * Returns all price entries for the authenticated user with optional filtering
3752
+ * Match platforms by name or alias
3167
3753
  * @param data The data for the request.
3168
- * @param data.region Region code for tenant context
3169
- * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
3170
- * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
3171
- * @param data.dateFrom Filter prices from this date (ISO 8601 format)
3172
- * @param data.dateTo Filter prices to this date (ISO 8601 format)
3173
- * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
3174
- * @param data.page Page number for pagination (default: 1)
3175
- * @param data.limit Number of items per page (default: 20, max: 100)
3176
- * @returns PriceListResponseDto Prices retrieved successfully
3754
+ * @param data.q Search query Chinese name, English name, or abbreviation
3755
+ * @param data.region Region code (ISO 3166-1 alpha-2) that biases within-tier ordering (local-region platforms first); also the intended categoryOverrides key. Case-insensitive stored/compared UPPERCASE ("cn" == "CN").
3756
+ * @returns PlatformMatchResponseDto Matching platforms with overall match type and truncation flag
3177
3757
  * @throws ApiError
3178
3758
  */
3179
- public static priceControllerFindAll(
3180
- data: PriceControllerFindAllData
3181
- ): CancelablePromise<PriceControllerFindAllResponse> {
3759
+ public static platformControllerMatchPlatforms(
3760
+ data: PlatformControllerMatchPlatformsData
3761
+ ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3182
3762
  return __request(OpenAPI, {
3183
3763
  method: 'GET',
3184
- url: '/api/v1/{region}/bean/prices',
3185
- path: {
3186
- region: data.region
3187
- },
3764
+ url: '/api/v1/bean/platforms/match',
3188
3765
  query: {
3189
- currency: data.currency,
3190
- quoteCurrency: data.quoteCurrency,
3191
- dateFrom: data.dateFrom,
3192
- dateTo: data.dateTo,
3193
- search: data.search,
3194
- page: data.page,
3195
- limit: data.limit
3766
+ q: data.q,
3767
+ region: data.region
3196
3768
  }
3197
3769
  });
3198
3770
  }
3199
3771
 
3200
3772
  /**
3201
- * Get price by ID
3202
- * Returns a single price entry by its ID
3773
+ * Update a platform
3203
3774
  * @param data The data for the request.
3204
- * @param data.id Price ID
3205
- * @param data.region Region code for tenant context
3206
- * @returns PriceResponseDto Price retrieved successfully
3775
+ * @param data.id Platform ID
3776
+ * @param data.requestBody
3777
+ * @returns unknown Platform updated successfully
3207
3778
  * @throws ApiError
3208
3779
  */
3209
- public static priceControllerFindOne(
3210
- data: PriceControllerFindOneData
3211
- ): CancelablePromise<PriceControllerFindOneResponse> {
3780
+ public static platformControllerUpdate(
3781
+ data: PlatformControllerUpdateData
3782
+ ): CancelablePromise<PlatformControllerUpdateResponse> {
3212
3783
  return __request(OpenAPI, {
3213
- method: 'GET',
3214
- url: '/api/v1/{region}/bean/prices/{id}',
3784
+ method: 'PUT',
3785
+ url: '/api/v1/bean/platforms/{id}',
3215
3786
  path: {
3216
- id: data.id,
3217
- region: data.region
3787
+ id: data.id
3218
3788
  },
3789
+ body: data.requestBody,
3790
+ mediaType: 'application/json',
3219
3791
  errors: {
3220
- 404: 'Price not found'
3792
+ 404: 'Platform not found'
3221
3793
  }
3222
3794
  });
3223
3795
  }
3224
3796
 
3225
3797
  /**
3226
- * Update a price
3227
- * Updates an existing price entry
3798
+ * Delete a platform
3228
3799
  * @param data The data for the request.
3229
- * @param data.id Price ID
3230
- * @param data.region Region code for tenant context
3231
- * @param data.requestBody
3232
- * @returns PriceResponseDto Price updated successfully
3800
+ * @param data.id Platform ID
3801
+ * @returns void Platform deleted successfully
3233
3802
  * @throws ApiError
3234
3803
  */
3235
- public static priceControllerUpdate(
3236
- data: PriceControllerUpdateData
3237
- ): CancelablePromise<PriceControllerUpdateResponse> {
3804
+ public static platformControllerDelete(
3805
+ data: PlatformControllerDeleteData
3806
+ ): CancelablePromise<PlatformControllerDeleteResponse> {
3238
3807
  return __request(OpenAPI, {
3239
- method: 'PUT',
3240
- url: '/api/v1/{region}/bean/prices/{id}',
3808
+ method: 'DELETE',
3809
+ url: '/api/v1/bean/platforms/{id}',
3241
3810
  path: {
3242
- id: data.id,
3243
- region: data.region
3811
+ id: data.id
3244
3812
  },
3245
- body: data.requestBody,
3246
- mediaType: 'application/json',
3247
3813
  errors: {
3248
- 404: 'Price not found',
3249
- 409: 'Updated price conflicts with existing price'
3814
+ 404: 'Platform not found'
3250
3815
  }
3251
3816
  });
3252
3817
  }
3818
+ }
3253
3819
 
3820
+ export class DashboardService {
3254
3821
  /**
3255
- * Delete a price
3256
- * Deletes a price entry (hard delete)
3822
+ * Get net worth overview
3823
+ * Returns total net worth with breakdown of assets and liabilities
3257
3824
  * @param data The data for the request.
3258
- * @param data.id Price ID
3259
3825
  * @param data.region Region code for tenant context
3260
- * @returns void Price deleted successfully
3826
+ * @param data.date Date for balance calculation (ISO 8601 format)
3827
+ * @returns NetWorthResponseDto Net worth retrieved successfully
3261
3828
  * @throws ApiError
3262
3829
  */
3263
- public static priceControllerDelete(
3264
- data: PriceControllerDeleteData
3265
- ): CancelablePromise<PriceControllerDeleteResponse> {
3830
+ public static dashboardControllerGetNetWorth(
3831
+ data: DashboardControllerGetNetWorthData
3832
+ ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3266
3833
  return __request(OpenAPI, {
3267
- method: 'DELETE',
3268
- url: '/api/v1/{region}/bean/prices/{id}',
3834
+ method: 'GET',
3835
+ url: '/api/v1/{region}/dashboard/net-worth',
3269
3836
  path: {
3270
- id: data.id,
3271
3837
  region: data.region
3272
3838
  },
3839
+ query: {
3840
+ date: data.date
3841
+ },
3273
3842
  errors: {
3274
- 404: 'Price not found'
3843
+ 401: 'User not authenticated'
3275
3844
  }
3276
3845
  });
3277
3846
  }
3278
3847
 
3279
3848
  /**
3280
- * Bulk create prices
3281
- * Creates multiple price entries at once (skips duplicates)
3849
+ * Get accounts grouped by platform
3850
+ * Returns accounts with balances grouped by financial platform
3282
3851
  * @param data The data for the request.
3283
3852
  * @param data.region Region code for tenant context
3284
- * @param data.requestBody
3285
- * @returns PriceResponseDto Prices created successfully
3853
+ * @param data.groupBy Grouping strategy
3854
+ * @param data.date Date for balance calculation (ISO 8601 format)
3855
+ * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3856
+ * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3286
3857
  * @throws ApiError
3287
3858
  */
3288
- public static priceControllerBulkCreate(
3289
- data: PriceControllerBulkCreateData
3290
- ): CancelablePromise<PriceControllerBulkCreateResponse> {
3859
+ public static dashboardControllerGetAccounts(
3860
+ data: DashboardControllerGetAccountsData
3861
+ ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3291
3862
  return __request(OpenAPI, {
3292
- method: 'POST',
3293
- url: '/api/v1/{region}/bean/prices/bulk',
3863
+ method: 'GET',
3864
+ url: '/api/v1/{region}/dashboard/accounts',
3294
3865
  path: {
3295
3866
  region: data.region
3296
3867
  },
3297
- body: data.requestBody,
3298
- mediaType: 'application/json'
3868
+ query: {
3869
+ groupBy: data.groupBy,
3870
+ date: data.date,
3871
+ accountId: data.accountId
3872
+ },
3873
+ errors: {
3874
+ 401: 'User not authenticated'
3875
+ }
3299
3876
  });
3300
3877
  }
3301
- }
3302
3878
 
3303
- export class ReportingService {
3304
3879
  /**
3305
- * Get portfolio value trends
3306
- *
3307
- * Returns time series data of portfolio net worth.
3308
- *
3309
- * **Multi-currency Support:**
3310
- * - `series[].byCurrency` - Currency breakdown for each data point
3311
- * - `byCurrency` - Separate time series grouped by currency
3312
- * - `warnings` - Exchange rate warnings if conversion failed
3313
- *
3314
- * **Parameters:**
3315
- * - `period`: Time period (1m, 3m, 6m, 1y)
3316
- * - `granularity`: Data granularity (day, week, month)
3317
- *
3880
+ * Get cash flow summary
3881
+ * Returns income, expenses, and savings for a monthly period
3318
3882
  * @param data The data for the request.
3883
+ * @param data.period Period in YYYY-MM format
3319
3884
  * @param data.region Region code for tenant context
3320
- * @param data.period Time period
3321
- * @param data.granularity Data granularity
3322
- * @returns PortfolioTrendsResponseDto Trends retrieved successfully
3885
+ * @returns CashFlowResponseDto Cash flow retrieved successfully
3323
3886
  * @throws ApiError
3324
3887
  */
3325
- public static reportingControllerGetPortfolioTrends(
3326
- data: ReportingControllerGetPortfolioTrendsData
3327
- ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
3888
+ public static dashboardControllerGetCashFlow(
3889
+ data: DashboardControllerGetCashFlowData
3890
+ ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3328
3891
  return __request(OpenAPI, {
3329
3892
  method: 'GET',
3330
- url: '/api/v1/{region}/reporting/portfolio/trends',
3893
+ url: '/api/v1/{region}/dashboard/cash-flow',
3331
3894
  path: {
3332
3895
  region: data.region
3333
3896
  },
3334
3897
  query: {
3335
- period: data.period,
3336
- granularity: data.granularity
3898
+ period: data.period
3337
3899
  },
3338
3900
  errors: {
3901
+ 400: 'Invalid period format',
3339
3902
  401: 'User not authenticated'
3340
3903
  }
3341
3904
  });
3342
3905
  }
3343
3906
 
3344
3907
  /**
3345
- * Generate portfolio snapshot
3346
- *
3347
- * Manually generate a portfolio snapshot for a specific date.
3348
- *
3349
- * **Multi-currency Support:**
3350
- * - Fetches balances grouped by currency
3351
- * - Uses user's baseCurrency setting for conversion
3352
- * - Stores exchange rates and warnings
3353
- *
3354
- * **Use Cases:**
3355
- * - Testing snapshot generation
3356
- * - Force regeneration after data correction
3357
- * - Initial setup for new users
3358
- *
3908
+ * Get expenses/income grouped by functional category
3909
+ * Returns amounts pre-aggregated by functional category (account-path Group segment) with server-side multi-currency conversion. flow=expense (default) aggregates ^Expenses: accounts; flow=income aggregates ^Income: accounts (issue #518)
3359
3910
  * @param data The data for the request.
3360
3911
  * @param data.region Region code for tenant context
3361
- * @param data.requestBody Optional date (defaults to today)
3362
- * @returns GenerateSnapshotResponse Snapshot generated successfully
3912
+ * @param data.groupBy Grouping strategy
3913
+ * @param data.period Time window (1m = current calendar month)
3914
+ * @param data.flow Account root to aggregate (expense → ^Expenses:, income → ^Income:)
3915
+ * @returns ExpensesByCategoryResponseDto Expenses retrieved successfully
3363
3916
  * @throws ApiError
3364
3917
  */
3365
- public static reportingControllerGenerateSnapshot(
3366
- data: ReportingControllerGenerateSnapshotData
3367
- ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
3918
+ public static dashboardControllerGetExpenses(
3919
+ data: DashboardControllerGetExpensesData
3920
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3368
3921
  return __request(OpenAPI, {
3369
- method: 'POST',
3370
- url: '/api/v1/{region}/reporting/snapshots/generate',
3922
+ method: 'GET',
3923
+ url: '/api/v1/{region}/dashboard/expenses',
3371
3924
  path: {
3372
3925
  region: data.region
3373
3926
  },
3374
- body: data.requestBody,
3375
- mediaType: 'application/json',
3927
+ query: {
3928
+ groupBy: data.groupBy,
3929
+ period: data.period,
3930
+ flow: data.flow
3931
+ },
3376
3932
  errors: {
3377
- 400: 'Invalid date format',
3933
+ 400: 'Invalid groupBy or period',
3378
3934
  401: 'User not authenticated'
3379
3935
  }
3380
3936
  });
3381
3937
  }
3938
+ }
3382
3939
 
3940
+ export class InvestmentService {
3383
3941
  /**
3384
- * Backfill portfolio snapshots
3385
- *
3386
- * Generate snapshots for a date range (historical data backfill).
3387
- *
3388
- * **Multi-currency Support:**
3389
- * - Each snapshot includes multi-currency data
3390
- * - Uses exchange rates available at generation time
3391
- * - Warnings stored for missing exchange rates
3392
- *
3393
- * **Best Practices:**
3394
- * - Use for initial setup after account configuration
3395
- * - Run during low-traffic periods for large date ranges
3396
- * - Existing snapshots are skipped (not regenerated)
3397
- *
3942
+ * Get per-holding unrealized + realized P&L
3943
+ * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3398
3944
  * @param data The data for the request.
3399
3945
  * @param data.region Region code for tenant context
3400
- * @param data.requestBody
3401
- * @returns BackfillSnapshotsResponse Backfill completed successfully
3946
+ * @param data.asOf As-of date (ISO 8601), defaults to today
3947
+ * @param data.accountId Scope to a single account
3948
+ * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3949
+ * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3402
3950
  * @throws ApiError
3403
3951
  */
3404
- public static reportingControllerBackfillSnapshots(
3405
- data: ReportingControllerBackfillSnapshotsData
3406
- ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
3952
+ public static holdingPnlControllerGetHoldingPnl(
3953
+ data: HoldingPnlControllerGetHoldingPnlData
3954
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3407
3955
  return __request(OpenAPI, {
3408
- method: 'POST',
3409
- url: '/api/v1/{region}/reporting/snapshots/backfill',
3956
+ method: 'GET',
3957
+ url: '/api/v1/{region}/investment/holdings/pnl',
3410
3958
  path: {
3411
3959
  region: data.region
3412
3960
  },
3413
- body: data.requestBody,
3414
- mediaType: 'application/json',
3961
+ query: {
3962
+ asOf: data.asOf,
3963
+ accountId: data.accountId,
3964
+ method: data.method
3965
+ },
3415
3966
  errors: {
3416
- 400: 'Invalid date format or range',
3417
- 401: 'User not authenticated',
3418
- 409: 'Backfill already in progress for this user'
3967
+ 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3968
+ 401: 'User not authenticated'
3419
3969
  }
3420
3970
  });
3421
3971
  }
@@ -3444,7 +3994,7 @@ export class AuthService {
3444
3994
  * Anonymous login with access token
3445
3995
  * @param data The data for the request.
3446
3996
  * @param data.requestBody
3447
- * @returns unknown Login successful
3997
+ * @returns AnonymousLoginResponseDto Login successful
3448
3998
  * @throws ApiError
3449
3999
  */
3450
4000
  public static authControllerAccessTokenLogin(
@@ -3631,3 +4181,53 @@ export class InfoService {
3631
4181
  });
3632
4182
  }
3633
4183
  }
4184
+
4185
+ export class MarketDataService {
4186
+ /**
4187
+ * Search market symbols by name or code
4188
+ * Ranked search over the openbb catalog. Empty `q` returns [].
4189
+ * @param data The data for the request.
4190
+ * @param data.q Search term — matched against symbol and instrument name. Empty string returns [].
4191
+ * @param data.limit Maximum number of results (clamped 1..50)
4192
+ * @param data.exchange Filter by exchange code (e.g. US, HK, SS, SZ)
4193
+ * @param data.assetType Filter by OpenBB asset_type (e.g. stock, etf)
4194
+ * @returns SymbolSearchResultDto Ranked search results
4195
+ * @throws ApiError
4196
+ */
4197
+ public static symbolControllerSearch(
4198
+ data: SymbolControllerSearchData
4199
+ ): CancelablePromise<SymbolControllerSearchResponse> {
4200
+ return __request(OpenAPI, {
4201
+ method: 'GET',
4202
+ url: '/api/v1/market/symbols/search',
4203
+ query: {
4204
+ q: data.q,
4205
+ limit: data.limit,
4206
+ exchange: data.exchange,
4207
+ assetType: data.assetType
4208
+ }
4209
+ });
4210
+ }
4211
+
4212
+ /**
4213
+ * Get a market symbol quote
4214
+ * @param data The data for the request.
4215
+ * @param data.symbol
4216
+ * @returns SymbolQuoteDto Symbol quote
4217
+ * @throws ApiError
4218
+ */
4219
+ public static symbolControllerGetQuote(
4220
+ data: SymbolControllerGetQuoteData
4221
+ ): CancelablePromise<SymbolControllerGetQuoteResponse> {
4222
+ return __request(OpenAPI, {
4223
+ method: 'GET',
4224
+ url: '/api/v1/market/symbols/{symbol}/quote',
4225
+ path: {
4226
+ symbol: data.symbol
4227
+ },
4228
+ errors: {
4229
+ 404: 'Symbol not found in the openbb catalog'
4230
+ }
4231
+ });
4232
+ }
4233
+ }