@firela/api-types 0.0.0-canary.52154bb3 → 0.0.0-canary.54e42bbc

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