@firela/api-types 0.0.0-canary.09a8ff4c → 0.0.0-canary.0f069763

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,
@@ -183,6 +197,16 @@ import type {
183
197
  EventControllerDeleteResponse,
184
198
  EventControllerGetSliceData,
185
199
  EventControllerGetSliceResponse,
200
+ OnboardingControllerBootstrapData,
201
+ OnboardingControllerBootstrapResponse,
202
+ ReconciliationControllerComputeData,
203
+ ReconciliationControllerComputeResponse,
204
+ ReconciliationControllerAssertData,
205
+ ReconciliationControllerAssertResponse,
206
+ ReconciliationControllerPadData,
207
+ ReconciliationControllerPadResponse,
208
+ ReconciliationControllerHistoryData,
209
+ ReconciliationControllerHistoryResponse,
186
210
  ExportControllerExportBeancountResponse,
187
211
  FileImportControllerImportFileData,
188
212
  FileImportControllerImportFileResponse,
@@ -196,22 +220,20 @@ import type {
196
220
  ImporterConfigControllerUpdateConfigResponse,
197
221
  ImporterConfigControllerResetConfigData,
198
222
  ImporterConfigControllerResetConfigResponse,
199
- PlatformControllerFindAllResponse,
200
- PlatformControllerCreateData,
201
- PlatformControllerCreateResponse,
202
- PlatformControllerGetPlatformListResponse,
203
- PlatformControllerMatchPlatformsData,
204
- PlatformControllerMatchPlatformsResponse,
205
- PlatformControllerUpdateData,
206
- PlatformControllerUpdateResponse,
207
- PlatformControllerDeleteData,
208
- PlatformControllerDeleteResponse,
209
223
  ProviderSyncControllerSyncData,
210
224
  ProviderSyncControllerSyncResponse,
211
225
  ProviderSyncControllerGetSupportedProvidersData,
212
226
  ProviderSyncControllerGetSupportedProvidersResponse,
213
227
  ProviderSyncControllerIsProviderSupportedData,
214
228
  ProviderSyncControllerIsProviderSupportedResponse,
229
+ ExternalAccountLinkControllerCreateData,
230
+ ExternalAccountLinkControllerCreateResponse,
231
+ ExternalAccountLinkControllerFindAllData,
232
+ ExternalAccountLinkControllerFindAllResponse,
233
+ ExternalAccountLinkControllerFindOneData,
234
+ ExternalAccountLinkControllerFindOneResponse,
235
+ ExternalAccountLinkControllerRemoveData,
236
+ ExternalAccountLinkControllerRemoveResponse,
215
237
  TelemetryControllerReportTelemetryData,
216
238
  TelemetryControllerReportTelemetryResponse,
217
239
  TelemetryControllerReportCoverageMissData,
@@ -224,26 +246,26 @@ import type {
224
246
  NlpControllerClearSessionResponse,
225
247
  NlpControllerGetSessionData,
226
248
  NlpControllerGetSessionResponse,
249
+ PlatformControllerFindAllResponse,
250
+ PlatformControllerCreateData,
251
+ PlatformControllerCreateResponse,
252
+ PlatformControllerGetPlatformListResponse,
253
+ PlatformControllerMatchPlatformsData,
254
+ PlatformControllerMatchPlatformsResponse,
255
+ PlatformControllerUpdateData,
256
+ PlatformControllerUpdateResponse,
257
+ PlatformControllerDeleteData,
258
+ PlatformControllerDeleteResponse,
227
259
  DashboardControllerGetNetWorthData,
228
260
  DashboardControllerGetNetWorthResponse,
229
261
  DashboardControllerGetAccountsData,
230
262
  DashboardControllerGetAccountsResponse,
231
263
  DashboardControllerGetCashFlowData,
232
264
  DashboardControllerGetCashFlowResponse,
265
+ DashboardControllerGetExpensesData,
266
+ DashboardControllerGetExpensesResponse,
233
267
  HoldingPnlControllerGetHoldingPnlData,
234
268
  HoldingPnlControllerGetHoldingPnlResponse,
235
- PriceControllerCreateData,
236
- PriceControllerCreateResponse,
237
- PriceControllerFindAllData,
238
- PriceControllerFindAllResponse,
239
- PriceControllerFindOneData,
240
- PriceControllerFindOneResponse,
241
- PriceControllerUpdateData,
242
- PriceControllerUpdateResponse,
243
- PriceControllerDeleteData,
244
- PriceControllerDeleteResponse,
245
- PriceControllerBulkCreateData,
246
- PriceControllerBulkCreateResponse,
247
269
  ReportingControllerGetPortfolioTrendsData,
248
270
  ReportingControllerGetPortfolioTrendsResponse,
249
271
  ReportingControllerGetCashFlowTrendsData,
@@ -304,7 +326,7 @@ export class BeanAccountsService {
304
326
  * @param data.type Filter by account type
305
327
  * @param data.status Filter by status
306
328
  * @param data.isCustom Filter by custom (user-created) accounts only
307
- * @param data.search Search term for path or i18nKey
329
+ * @param data.search Search term for account path
308
330
  * @param data.limit Maximum number of results
309
331
  * @param data.offset Number of results to skip
310
332
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -466,6 +488,35 @@ export class BeanAccountsService {
466
488
  }
467
489
  });
468
490
  }
491
+
492
+ /**
493
+ * Post an opening-balance transaction
494
+ * Posts a double-entry opening-balance transaction against Equity:Opening-Balances for an existing Assets/Liabilities account. At most one active opening balance per account.
495
+ * @param data The data for the request.
496
+ * @param data.id Account UUID
497
+ * @param data.region Region code for tenant context
498
+ * @param data.requestBody
499
+ * @returns OpeningBalanceResultDto Opening-balance transaction created
500
+ * @throws ApiError
501
+ */
502
+ public static accountControllerAddOpeningBalance(
503
+ data: AccountControllerAddOpeningBalanceData
504
+ ): CancelablePromise<AccountControllerAddOpeningBalanceResponse> {
505
+ return __request(OpenAPI, {
506
+ method: 'POST',
507
+ url: '/api/v1/{region}/bean/accounts/{id}/opening-balance',
508
+ path: {
509
+ id: data.id,
510
+ region: data.region
511
+ },
512
+ body: data.requestBody,
513
+ mediaType: 'application/json',
514
+ errors: {
515
+ 404: 'Account not found',
516
+ 409: 'An opening balance already exists for this account'
517
+ }
518
+ });
519
+ }
469
520
  }
470
521
 
471
522
  export class BeanAccountStandardsService {
@@ -497,7 +548,7 @@ export class BeanAccountStandardsService {
497
548
 
498
549
  /**
499
550
  * Get template metadata for an account path
500
- * Returns extendable status and root type for a template path.
551
+ * Returns root type for a template path.
501
552
  * @param data The data for the request.
502
553
  * @param data.region Region code for tenant context
503
554
  * @param data.path Account path to check
@@ -583,6 +634,7 @@ export class BeanTransactionsService {
583
634
  * @param data.status Filter by transaction status
584
635
  * @param data.search Search in narration and payee fields (max 200 chars)
585
636
  * @param data.accountId Filter by account ID (transactions with postings to this account)
637
+ * @param data.category Filter by ADR-0075 functional category (Group segment); matches any posting to an Expenses/Income account whose derived Group segment equals this value
586
638
  * @returns TransactionListResponseDto Transaction list
587
639
  * @throws ApiError
588
640
  */
@@ -602,7 +654,8 @@ export class BeanTransactionsService {
602
654
  dateTo: data.dateTo,
603
655
  status: data.status,
604
656
  search: data.search,
605
- accountId: data.accountId
657
+ accountId: data.accountId,
658
+ category: data.category
606
659
  },
607
660
  errors: {
608
661
  400: 'Validation failed',
@@ -790,7 +843,7 @@ export class BeanBalancesService {
790
843
  * Query account balance
791
844
  * Calculate account balance at a specific date for a single currency
792
845
  * @param data The data for the request.
793
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
846
+ * @param data.account Account name (e.g., "Assets:Checking")
794
847
  * @param data.region Region code for tenant context
795
848
  * @param data.date Date to calculate balance at (ISO 8601 format)
796
849
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -1511,6 +1564,173 @@ export class BeanCommoditiesService {
1511
1564
  }
1512
1565
  }
1513
1566
 
1567
+ export class BeanPricesService {
1568
+ /**
1569
+ * Create a new price
1570
+ * Creates a new price entry for the authenticated user
1571
+ * @param data The data for the request.
1572
+ * @param data.region Region code for tenant context
1573
+ * @param data.requestBody
1574
+ * @returns PriceResponseDto Price created successfully
1575
+ * @throws ApiError
1576
+ */
1577
+ public static priceControllerCreate(
1578
+ data: PriceControllerCreateData
1579
+ ): CancelablePromise<PriceControllerCreateResponse> {
1580
+ return __request(OpenAPI, {
1581
+ method: 'POST',
1582
+ url: '/api/v1/{region}/bean/prices',
1583
+ path: {
1584
+ region: data.region
1585
+ },
1586
+ body: data.requestBody,
1587
+ mediaType: 'application/json',
1588
+ errors: {
1589
+ 404: 'Currency or quoteCurrency commodity not found',
1590
+ 409: 'Price already exists for this currency pair and date'
1591
+ }
1592
+ });
1593
+ }
1594
+
1595
+ /**
1596
+ * List user prices
1597
+ * Returns all price entries for the authenticated user with optional filtering
1598
+ * @param data The data for the request.
1599
+ * @param data.region Region code for tenant context
1600
+ * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
1601
+ * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
1602
+ * @param data.dateFrom Filter prices from this date (ISO 8601 format)
1603
+ * @param data.dateTo Filter prices to this date (ISO 8601 format)
1604
+ * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
1605
+ * @param data.page Page number for pagination (default: 1)
1606
+ * @param data.limit Number of items per page (default: 20, max: 100)
1607
+ * @returns PriceListResponseDto Prices retrieved successfully
1608
+ * @throws ApiError
1609
+ */
1610
+ public static priceControllerFindAll(
1611
+ data: PriceControllerFindAllData
1612
+ ): CancelablePromise<PriceControllerFindAllResponse> {
1613
+ return __request(OpenAPI, {
1614
+ method: 'GET',
1615
+ url: '/api/v1/{region}/bean/prices',
1616
+ path: {
1617
+ region: data.region
1618
+ },
1619
+ query: {
1620
+ currency: data.currency,
1621
+ quoteCurrency: data.quoteCurrency,
1622
+ dateFrom: data.dateFrom,
1623
+ dateTo: data.dateTo,
1624
+ search: data.search,
1625
+ page: data.page,
1626
+ limit: data.limit
1627
+ }
1628
+ });
1629
+ }
1630
+
1631
+ /**
1632
+ * Get price by ID
1633
+ * Returns a single price entry by its ID
1634
+ * @param data The data for the request.
1635
+ * @param data.id Price ID
1636
+ * @param data.region Region code for tenant context
1637
+ * @returns PriceResponseDto Price retrieved successfully
1638
+ * @throws ApiError
1639
+ */
1640
+ public static priceControllerFindOne(
1641
+ data: PriceControllerFindOneData
1642
+ ): CancelablePromise<PriceControllerFindOneResponse> {
1643
+ return __request(OpenAPI, {
1644
+ method: 'GET',
1645
+ url: '/api/v1/{region}/bean/prices/{id}',
1646
+ path: {
1647
+ id: data.id,
1648
+ region: data.region
1649
+ },
1650
+ errors: {
1651
+ 404: 'Price not found'
1652
+ }
1653
+ });
1654
+ }
1655
+
1656
+ /**
1657
+ * Update a price
1658
+ * Updates an existing price entry
1659
+ * @param data The data for the request.
1660
+ * @param data.id Price ID
1661
+ * @param data.region Region code for tenant context
1662
+ * @param data.requestBody
1663
+ * @returns PriceResponseDto Price updated successfully
1664
+ * @throws ApiError
1665
+ */
1666
+ public static priceControllerUpdate(
1667
+ data: PriceControllerUpdateData
1668
+ ): CancelablePromise<PriceControllerUpdateResponse> {
1669
+ return __request(OpenAPI, {
1670
+ method: 'PUT',
1671
+ url: '/api/v1/{region}/bean/prices/{id}',
1672
+ path: {
1673
+ id: data.id,
1674
+ region: data.region
1675
+ },
1676
+ body: data.requestBody,
1677
+ mediaType: 'application/json',
1678
+ errors: {
1679
+ 404: 'Price not found',
1680
+ 409: 'Updated price conflicts with existing price'
1681
+ }
1682
+ });
1683
+ }
1684
+
1685
+ /**
1686
+ * Delete a price
1687
+ * Deletes a price entry (hard delete)
1688
+ * @param data The data for the request.
1689
+ * @param data.id Price ID
1690
+ * @param data.region Region code for tenant context
1691
+ * @returns void Price deleted successfully
1692
+ * @throws ApiError
1693
+ */
1694
+ public static priceControllerDelete(
1695
+ data: PriceControllerDeleteData
1696
+ ): CancelablePromise<PriceControllerDeleteResponse> {
1697
+ return __request(OpenAPI, {
1698
+ method: 'DELETE',
1699
+ url: '/api/v1/{region}/bean/prices/{id}',
1700
+ path: {
1701
+ id: data.id,
1702
+ region: data.region
1703
+ },
1704
+ errors: {
1705
+ 404: 'Price not found'
1706
+ }
1707
+ });
1708
+ }
1709
+
1710
+ /**
1711
+ * Bulk create prices
1712
+ * Creates multiple price entries at once (skips duplicates)
1713
+ * @param data The data for the request.
1714
+ * @param data.region Region code for tenant context
1715
+ * @param data.requestBody
1716
+ * @returns PriceResponseDto Prices created successfully
1717
+ * @throws ApiError
1718
+ */
1719
+ public static priceControllerBulkCreate(
1720
+ data: PriceControllerBulkCreateData
1721
+ ): CancelablePromise<PriceControllerBulkCreateResponse> {
1722
+ return __request(OpenAPI, {
1723
+ method: 'POST',
1724
+ url: '/api/v1/{region}/bean/prices/bulk',
1725
+ path: {
1726
+ region: data.region
1727
+ },
1728
+ body: data.requestBody,
1729
+ mediaType: 'application/json'
1730
+ });
1731
+ }
1732
+ }
1733
+
1514
1734
  export class RecurringRulesService {
1515
1735
  /**
1516
1736
  * Create a new recurring rule
@@ -2649,27 +2869,160 @@ export class LifeEventsService {
2649
2869
  }
2650
2870
  }
2651
2871
 
2652
- export class BeanExportService {
2872
+ export class OnboardingService {
2653
2873
  /**
2654
- * Export Beancount ledger as ZIP
2655
- * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
2656
- * @returns unknown
2874
+ * Bootstrap core accounts + register asset accounts with opening balances (ADR-0113)
2875
+ * @param data The data for the request.
2876
+ * @param data.region Region code for tenant context
2877
+ * @param data.requestBody
2878
+ * @returns unknown Onboarding bootstrap result.
2657
2879
  * @throws ApiError
2658
2880
  */
2659
- public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
2881
+ public static onboardingControllerBootstrap(
2882
+ data: OnboardingControllerBootstrapData
2883
+ ): CancelablePromise<OnboardingControllerBootstrapResponse> {
2660
2884
  return __request(OpenAPI, {
2661
- method: 'GET',
2662
- url: '/api/v1/{region}/bean/export/beancount'
2885
+ method: 'POST',
2886
+ url: '/api/v1/{region}/bean/onboarding',
2887
+ path: {
2888
+ region: data.region
2889
+ },
2890
+ body: data.requestBody,
2891
+ mediaType: 'application/json',
2892
+ errors: {
2893
+ 422: 'Invalid region/account path/duplicate paths.'
2894
+ }
2663
2895
  });
2664
2896
  }
2665
2897
  }
2666
2898
 
2667
- export class BeanImportService {
2899
+ export class BalanceReconciliationService {
2668
2900
  /**
2669
- * Import a bill file
2670
- * 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).
2901
+ * Preview reconciliation (book vs actual)
2902
+ * Computes book balance, diff, Beancount-inferred tolerance, and suggested action without persisting.
2671
2903
  * @param data The data for the request.
2672
- * @param data.region Region code for tenant context
2904
+ * @param data.region Region code for tenant context (decorative for reconciliation)
2905
+ * @param data.requestBody
2906
+ * @returns ReconciliationComputeResultDto Reconciliation preview
2907
+ * @throws ApiError
2908
+ */
2909
+ public static reconciliationControllerCompute(
2910
+ data: ReconciliationControllerComputeData
2911
+ ): CancelablePromise<ReconciliationControllerComputeResponse> {
2912
+ return __request(OpenAPI, {
2913
+ method: 'POST',
2914
+ url: '/api/v1/{region}/bean/reconciliations',
2915
+ path: {
2916
+ region: data.region
2917
+ },
2918
+ body: data.requestBody,
2919
+ mediaType: 'application/json',
2920
+ errors: {
2921
+ 404: 'Account not found'
2922
+ }
2923
+ });
2924
+ }
2925
+
2926
+ /**
2927
+ * Record a balance assertion
2928
+ * Persists the reconciliation as a BeanBalance assertion (amount = actual, diffAmount = book − actual). Re-reconciling the same day/currency upserts.
2929
+ * @param data The data for the request.
2930
+ * @param data.region Region code for tenant context (decorative for reconciliation)
2931
+ * @param data.requestBody
2932
+ * @returns ReconciliationRecordDto Balance assertion recorded
2933
+ * @throws ApiError
2934
+ */
2935
+ public static reconciliationControllerAssert(
2936
+ data: ReconciliationControllerAssertData
2937
+ ): CancelablePromise<ReconciliationControllerAssertResponse> {
2938
+ return __request(OpenAPI, {
2939
+ method: 'POST',
2940
+ url: '/api/v1/{region}/bean/reconciliations/assert',
2941
+ path: {
2942
+ region: data.region
2943
+ },
2944
+ body: data.requestBody,
2945
+ mediaType: 'application/json',
2946
+ errors: {
2947
+ 404: 'Account not found'
2948
+ }
2949
+ });
2950
+ }
2951
+
2952
+ /**
2953
+ * Generate a pad adjusting entry
2954
+ * 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.
2955
+ * @param data The data for the request.
2956
+ * @param data.region Region code for tenant context (decorative for reconciliation)
2957
+ * @param data.requestBody
2958
+ * @returns PadResultDto Pad adjusting entry generated
2959
+ * @throws ApiError
2960
+ */
2961
+ public static reconciliationControllerPad(
2962
+ data: ReconciliationControllerPadData
2963
+ ): CancelablePromise<ReconciliationControllerPadResponse> {
2964
+ return __request(OpenAPI, {
2965
+ method: 'POST',
2966
+ url: '/api/v1/{region}/bean/reconciliations/pad',
2967
+ path: {
2968
+ region: data.region
2969
+ },
2970
+ body: data.requestBody,
2971
+ mediaType: 'application/json',
2972
+ errors: {
2973
+ 400: 'Book already within tolerance — no pad needed',
2974
+ 404: 'Account not found'
2975
+ }
2976
+ });
2977
+ }
2978
+
2979
+ /**
2980
+ * List reconciliation history for an account
2981
+ * Returns recorded balance assertions (most recent first). The latest drives the account-detail "Last <date>" badge.
2982
+ * @param data The data for the request.
2983
+ * @param data.accountId BeanAccount id
2984
+ * @param data.region Region code for tenant context (decorative for reconciliation)
2985
+ * @returns ReconciliationRecordDto Reconciliation history
2986
+ * @throws ApiError
2987
+ */
2988
+ public static reconciliationControllerHistory(
2989
+ data: ReconciliationControllerHistoryData
2990
+ ): CancelablePromise<ReconciliationControllerHistoryResponse> {
2991
+ return __request(OpenAPI, {
2992
+ method: 'GET',
2993
+ url: '/api/v1/{region}/bean/accounts/{accountId}/reconciliations',
2994
+ path: {
2995
+ accountId: data.accountId,
2996
+ region: data.region
2997
+ },
2998
+ errors: {
2999
+ 404: 'Account not found'
3000
+ }
3001
+ });
3002
+ }
3003
+ }
3004
+
3005
+ export class BeanExportService {
3006
+ /**
3007
+ * Export Beancount ledger as ZIP
3008
+ * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
3009
+ * @returns unknown
3010
+ * @throws ApiError
3011
+ */
3012
+ public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
3013
+ return __request(OpenAPI, {
3014
+ method: 'GET',
3015
+ url: '/api/v1/{region}/bean/export/beancount'
3016
+ });
3017
+ }
3018
+ }
3019
+
3020
+ export class BeanImportService {
3021
+ /**
3022
+ * Import a bill file
3023
+ * 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).
3024
+ * @param data The data for the request.
3025
+ * @param data.region Region code for tenant context
2673
3026
  * @param data.formData Bill file to import
2674
3027
  * @returns ImportResultDto File imported successfully
2675
3028
  * @throws ApiError
@@ -2827,121 +3180,6 @@ export class BeanImportService {
2827
3180
  }
2828
3181
  }
2829
3182
 
2830
- export class BeanPlatformsService {
2831
- /**
2832
- * Get all platforms with statistics
2833
- * @returns unknown List of platforms with binding and account counts
2834
- * @throws ApiError
2835
- */
2836
- public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
2837
- return __request(OpenAPI, {
2838
- method: 'GET',
2839
- url: '/api/v1/bean/platforms'
2840
- });
2841
- }
2842
-
2843
- /**
2844
- * Create a new platform
2845
- * @param data The data for the request.
2846
- * @param data.requestBody
2847
- * @returns unknown Platform created successfully
2848
- * @throws ApiError
2849
- */
2850
- public static platformControllerCreate(
2851
- data: PlatformControllerCreateData
2852
- ): CancelablePromise<PlatformControllerCreateResponse> {
2853
- return __request(OpenAPI, {
2854
- method: 'POST',
2855
- url: '/api/v1/bean/platforms',
2856
- body: data.requestBody,
2857
- mediaType: 'application/json',
2858
- errors: {
2859
- 409: 'Platform already exists'
2860
- }
2861
- });
2862
- }
2863
-
2864
- /**
2865
- * Get platform list for current user
2866
- * @returns unknown List of platforms with user binding status
2867
- * @throws ApiError
2868
- */
2869
- public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
2870
- return __request(OpenAPI, {
2871
- method: 'GET',
2872
- url: '/api/v1/bean/platforms/list'
2873
- });
2874
- }
2875
-
2876
- /**
2877
- * Match platforms by name or alias
2878
- * @param data The data for the request.
2879
- * @param data.q Search query — Chinese name, English name, or abbreviation
2880
- * @param data.region Region code for category override lookup
2881
- * @returns unknown List of matching platforms with suggested segment names
2882
- * @throws ApiError
2883
- */
2884
- public static platformControllerMatchPlatforms(
2885
- data: PlatformControllerMatchPlatformsData
2886
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
2887
- return __request(OpenAPI, {
2888
- method: 'GET',
2889
- url: '/api/v1/bean/platforms/match',
2890
- query: {
2891
- q: data.q,
2892
- region: data.region
2893
- }
2894
- });
2895
- }
2896
-
2897
- /**
2898
- * Update a platform
2899
- * @param data The data for the request.
2900
- * @param data.id Platform ID
2901
- * @param data.requestBody
2902
- * @returns unknown Platform updated successfully
2903
- * @throws ApiError
2904
- */
2905
- public static platformControllerUpdate(
2906
- data: PlatformControllerUpdateData
2907
- ): CancelablePromise<PlatformControllerUpdateResponse> {
2908
- return __request(OpenAPI, {
2909
- method: 'PUT',
2910
- url: '/api/v1/bean/platforms/{id}',
2911
- path: {
2912
- id: data.id
2913
- },
2914
- body: data.requestBody,
2915
- mediaType: 'application/json',
2916
- errors: {
2917
- 404: 'Platform not found'
2918
- }
2919
- });
2920
- }
2921
-
2922
- /**
2923
- * Delete a platform
2924
- * @param data The data for the request.
2925
- * @param data.id Platform ID
2926
- * @returns void Platform deleted successfully
2927
- * @throws ApiError
2928
- */
2929
- public static platformControllerDelete(
2930
- data: PlatformControllerDeleteData
2931
- ): CancelablePromise<PlatformControllerDeleteResponse> {
2932
- return __request(OpenAPI, {
2933
- method: 'DELETE',
2934
- url: '/api/v1/bean/platforms/{id}',
2935
- path: {
2936
- id: data.id
2937
- },
2938
- errors: {
2939
- 404: 'Platform not found'
2940
- }
2941
- });
2942
- }
2943
- }
2944
-
2945
3183
  export class ProviderSyncService {
2946
3184
  /**
2947
3185
  * Sync transactions from financial data provider
@@ -3042,130 +3280,121 @@ export class ProviderSyncService {
3042
3280
  }
3043
3281
  }
3044
3282
 
3045
- export class ImportTelemetryService {
3283
+ export class ExternalAccountLinksService {
3046
3284
  /**
3047
- * Receive anonymous parser failure telemetry
3285
+ * Create an external account → BeanAccount mapping (ADR-0113)
3048
3286
  * @param data The data for the request.
3049
3287
  * @param data.region Region code for tenant context
3050
3288
  * @param data.requestBody
3051
- * @returns unknown Telemetry report received
3289
+ * @returns ExternalAccountLinkResponseDto Link created.
3052
3290
  * @throws ApiError
3053
3291
  */
3054
- public static telemetryControllerReportTelemetry(
3055
- data: TelemetryControllerReportTelemetryData
3056
- ): CancelablePromise<TelemetryControllerReportTelemetryResponse> {
3292
+ public static externalAccountLinkControllerCreate(
3293
+ data: ExternalAccountLinkControllerCreateData
3294
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
3057
3295
  return __request(OpenAPI, {
3058
3296
  method: 'POST',
3059
- url: '/api/v1/{region}/bean/import/parser-telemetry',
3297
+ url: '/api/v1/{region}/bean/external-account-links',
3060
3298
  path: {
3061
3299
  region: data.region
3062
3300
  },
3063
3301
  body: data.requestBody,
3064
3302
  mediaType: 'application/json',
3065
3303
  errors: {
3066
- 401: 'Unauthorized'
3304
+ 422: 'beanAccountId not owned, or an active link already exists.'
3067
3305
  }
3068
3306
  });
3069
3307
  }
3070
3308
 
3071
3309
  /**
3072
- * Receive anonymous zero-hit coverage miss report
3310
+ * List the user's active external account links
3073
3311
  * @param data The data for the request.
3312
+ * @param data.provider
3074
3313
  * @param data.region Region code for tenant context
3075
- * @param data.requestBody
3076
- * @returns unknown Coverage miss report received
3314
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
3077
3315
  * @throws ApiError
3078
3316
  */
3079
- public static telemetryControllerReportCoverageMiss(
3080
- data: TelemetryControllerReportCoverageMissData
3081
- ): CancelablePromise<TelemetryControllerReportCoverageMissResponse> {
3317
+ public static externalAccountLinkControllerFindAll(
3318
+ data: ExternalAccountLinkControllerFindAllData
3319
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
3082
3320
  return __request(OpenAPI, {
3083
- method: 'POST',
3084
- url: '/api/v1/{region}/bean/import/parser-coverage-miss',
3321
+ method: 'GET',
3322
+ url: '/api/v1/{region}/bean/external-account-links',
3085
3323
  path: {
3086
3324
  region: data.region
3087
3325
  },
3088
- body: data.requestBody,
3089
- mediaType: 'application/json',
3090
- errors: {
3091
- 401: 'Unauthorized'
3326
+ query: {
3327
+ provider: data.provider
3092
3328
  }
3093
3329
  });
3094
3330
  }
3095
3331
 
3096
3332
  /**
3097
- * Coverage metrics (uncovered format aggregation)
3333
+ * Get a single external account link
3098
3334
  * @param data The data for the request.
3335
+ * @param data.id
3099
3336
  * @param data.region Region code for tenant context
3100
- * @param data.topN Top-N uncovered formats (default 10)
3101
- * @returns unknown Coverage metrics
3337
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
3102
3338
  * @throws ApiError
3103
3339
  */
3104
- public static telemetryControllerGetCoverageMetrics(
3105
- data: TelemetryControllerGetCoverageMetricsData
3106
- ): CancelablePromise<TelemetryControllerGetCoverageMetricsResponse> {
3340
+ public static externalAccountLinkControllerFindOne(
3341
+ data: ExternalAccountLinkControllerFindOneData
3342
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
3107
3343
  return __request(OpenAPI, {
3108
3344
  method: 'GET',
3109
- url: '/api/v1/{region}/bean/import/parser-coverage-metrics',
3345
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3110
3346
  path: {
3347
+ id: data.id,
3111
3348
  region: data.region
3112
3349
  },
3113
- query: {
3114
- topN: data.topN
3350
+ errors: {
3351
+ 422: 'Link not found or not owned by the user.'
3115
3352
  }
3116
3353
  });
3117
3354
  }
3118
- }
3119
3355
 
3120
- export class BeanNlpService {
3121
3356
  /**
3122
- * Process natural language input
3123
- * Parse natural language text (Chinese/English) describing a transaction. Supports multi-turn dialogue for collecting missing information. When confidence < 0.75, returns "confirm" action requiring user verification. User can reply with confirmation words (确认/yes/ok) or provide corrections. Examples: "yesterday Starbucks spent 35 yuan", "today lunch 28 yuan", "spent $50 at Walmart"
3357
+ * Soft-delete (disconnect) an external account link
3124
3358
  * @param data The data for the request.
3359
+ * @param data.id
3125
3360
  * @param data.region Region code for tenant context
3126
- * @param data.requestBody Natural language transaction input with optional session ID
3127
- * @returns NlpResponseDto NLP processing result - either created transaction or asking for more info
3361
+ * @returns void Link soft-deleted; historical transactions are unaffected.
3128
3362
  * @throws ApiError
3129
3363
  */
3130
- public static nlpControllerProcessNaturalLanguage(
3131
- data: NlpControllerProcessNaturalLanguageData
3132
- ): CancelablePromise<NlpControllerProcessNaturalLanguageResponse> {
3364
+ public static externalAccountLinkControllerRemove(
3365
+ data: ExternalAccountLinkControllerRemoveData
3366
+ ): CancelablePromise<ExternalAccountLinkControllerRemoveResponse> {
3133
3367
  return __request(OpenAPI, {
3134
- method: 'POST',
3135
- url: '/api/v1/{region}/bean/nlp/process',
3368
+ method: 'DELETE',
3369
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3136
3370
  path: {
3371
+ id: data.id,
3137
3372
  region: data.region
3138
- },
3139
- body: data.requestBody,
3140
- mediaType: 'application/json',
3141
- errors: {
3142
- 400: 'Invalid input',
3143
- 401: 'Unauthorized'
3144
3373
  }
3145
3374
  });
3146
3375
  }
3376
+ }
3147
3377
 
3378
+ export class ImportTelemetryService {
3148
3379
  /**
3149
- * Clear dialogue session
3150
- * Clear the current NLP dialogue session. Use this to cancel an ongoing multi-turn dialogue.
3380
+ * Receive anonymous parser failure telemetry
3151
3381
  * @param data The data for the request.
3152
3382
  * @param data.region Region code for tenant context
3153
- * @param data.sessionId Specific session ID to clear (defaults to user session)
3154
- * @returns void Session cleared successfully
3383
+ * @param data.requestBody
3384
+ * @returns unknown Telemetry report received
3155
3385
  * @throws ApiError
3156
3386
  */
3157
- public static nlpControllerClearSession(
3158
- data: NlpControllerClearSessionData
3159
- ): CancelablePromise<NlpControllerClearSessionResponse> {
3387
+ public static telemetryControllerReportTelemetry(
3388
+ data: TelemetryControllerReportTelemetryData
3389
+ ): CancelablePromise<TelemetryControllerReportTelemetryResponse> {
3160
3390
  return __request(OpenAPI, {
3161
- method: 'DELETE',
3162
- url: '/api/v1/{region}/bean/nlp/session',
3391
+ method: 'POST',
3392
+ url: '/api/v1/{region}/bean/import/parser-telemetry',
3163
3393
  path: {
3164
3394
  region: data.region
3165
3395
  },
3166
- query: {
3167
- sessionId: data.sessionId
3168
- },
3396
+ body: data.requestBody,
3397
+ mediaType: 'application/json',
3169
3398
  errors: {
3170
3399
  401: 'Unauthorized'
3171
3400
  }
@@ -3173,318 +3402,402 @@ export class BeanNlpService {
3173
3402
  }
3174
3403
 
3175
3404
  /**
3176
- * Get current session state
3177
- * Get the current NLP dialogue session state. Useful for debugging and displaying session context in UI.
3405
+ * Receive anonymous zero-hit coverage miss report
3178
3406
  * @param data The data for the request.
3179
3407
  * @param data.region Region code for tenant context
3180
- * @param data.sessionId Specific session ID to get (defaults to user session)
3181
- * @returns unknown Current session state (or null if no active session)
3408
+ * @param data.requestBody
3409
+ * @returns unknown Coverage miss report received
3182
3410
  * @throws ApiError
3183
3411
  */
3184
- public static nlpControllerGetSession(
3185
- data: NlpControllerGetSessionData
3186
- ): CancelablePromise<NlpControllerGetSessionResponse> {
3412
+ public static telemetryControllerReportCoverageMiss(
3413
+ data: TelemetryControllerReportCoverageMissData
3414
+ ): CancelablePromise<TelemetryControllerReportCoverageMissResponse> {
3187
3415
  return __request(OpenAPI, {
3188
- method: 'GET',
3189
- url: '/api/v1/{region}/bean/nlp/session',
3416
+ method: 'POST',
3417
+ url: '/api/v1/{region}/bean/import/parser-coverage-miss',
3190
3418
  path: {
3191
3419
  region: data.region
3192
3420
  },
3193
- query: {
3194
- sessionId: data.sessionId
3195
- },
3421
+ body: data.requestBody,
3422
+ mediaType: 'application/json',
3196
3423
  errors: {
3197
3424
  401: 'Unauthorized'
3198
3425
  }
3199
3426
  });
3200
3427
  }
3201
- }
3202
3428
 
3203
- export class DashboardService {
3204
3429
  /**
3205
- * Get net worth overview
3206
- * Returns total net worth with breakdown of assets and liabilities
3430
+ * Coverage metrics (uncovered format aggregation)
3207
3431
  * @param data The data for the request.
3208
3432
  * @param data.region Region code for tenant context
3209
- * @param data.date Date for balance calculation (ISO 8601 format)
3210
- * @returns NetWorthResponseDto Net worth retrieved successfully
3433
+ * @param data.topN Top-N uncovered formats (default 10)
3434
+ * @returns unknown Coverage metrics
3211
3435
  * @throws ApiError
3212
3436
  */
3213
- public static dashboardControllerGetNetWorth(
3214
- data: DashboardControllerGetNetWorthData
3215
- ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3437
+ public static telemetryControllerGetCoverageMetrics(
3438
+ data: TelemetryControllerGetCoverageMetricsData
3439
+ ): CancelablePromise<TelemetryControllerGetCoverageMetricsResponse> {
3216
3440
  return __request(OpenAPI, {
3217
3441
  method: 'GET',
3218
- url: '/api/v1/{region}/dashboard/net-worth',
3442
+ url: '/api/v1/{region}/bean/import/parser-coverage-metrics',
3219
3443
  path: {
3220
3444
  region: data.region
3221
3445
  },
3222
3446
  query: {
3223
- date: data.date
3224
- },
3225
- errors: {
3226
- 401: 'User not authenticated'
3447
+ topN: data.topN
3227
3448
  }
3228
3449
  });
3229
3450
  }
3451
+ }
3230
3452
 
3453
+ export class BeanNlpService {
3231
3454
  /**
3232
- * Get accounts grouped by platform
3233
- * Returns accounts with balances grouped by financial platform
3455
+ * Process natural language input
3456
+ * Parse natural language text (Chinese/English) describing a transaction. Supports multi-turn dialogue for collecting missing information. When confidence < 0.75, returns "confirm" action requiring user verification. User can reply with confirmation words (确认/yes/ok) or provide corrections. Examples: "yesterday Starbucks spent 35 yuan", "today lunch 28 yuan", "spent $50 at Walmart"
3234
3457
  * @param data The data for the request.
3235
3458
  * @param data.region Region code for tenant context
3236
- * @param data.groupBy Grouping strategy
3237
- * @param data.date Date for balance calculation (ISO 8601 format)
3238
- * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3239
- * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3459
+ * @param data.requestBody Natural language transaction input with optional session ID
3460
+ * @returns NlpResponseDto NLP processing result - either created transaction or asking for more info
3240
3461
  * @throws ApiError
3241
3462
  */
3242
- public static dashboardControllerGetAccounts(
3243
- data: DashboardControllerGetAccountsData
3244
- ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3463
+ public static nlpControllerProcessNaturalLanguage(
3464
+ data: NlpControllerProcessNaturalLanguageData
3465
+ ): CancelablePromise<NlpControllerProcessNaturalLanguageResponse> {
3245
3466
  return __request(OpenAPI, {
3246
- method: 'GET',
3247
- url: '/api/v1/{region}/dashboard/accounts',
3467
+ method: 'POST',
3468
+ url: '/api/v1/{region}/bean/nlp/process',
3248
3469
  path: {
3249
3470
  region: data.region
3250
3471
  },
3251
- query: {
3252
- groupBy: data.groupBy,
3253
- date: data.date,
3254
- accountId: data.accountId
3255
- },
3472
+ body: data.requestBody,
3473
+ mediaType: 'application/json',
3256
3474
  errors: {
3257
- 401: 'User not authenticated'
3475
+ 400: 'Invalid input',
3476
+ 401: 'Unauthorized'
3258
3477
  }
3259
3478
  });
3260
3479
  }
3261
3480
 
3262
3481
  /**
3263
- * Get cash flow summary
3264
- * Returns income, expenses, and savings for a monthly period
3482
+ * Clear dialogue session
3483
+ * Clear the current NLP dialogue session. Use this to cancel an ongoing multi-turn dialogue.
3265
3484
  * @param data The data for the request.
3266
- * @param data.period Period in YYYY-MM format
3267
3485
  * @param data.region Region code for tenant context
3268
- * @returns CashFlowResponseDto Cash flow retrieved successfully
3486
+ * @param data.sessionId Specific session ID to clear (defaults to user session)
3487
+ * @returns void Session cleared successfully
3269
3488
  * @throws ApiError
3270
3489
  */
3271
- public static dashboardControllerGetCashFlow(
3272
- data: DashboardControllerGetCashFlowData
3273
- ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3490
+ public static nlpControllerClearSession(
3491
+ data: NlpControllerClearSessionData
3492
+ ): CancelablePromise<NlpControllerClearSessionResponse> {
3274
3493
  return __request(OpenAPI, {
3275
- method: 'GET',
3276
- url: '/api/v1/{region}/dashboard/cash-flow',
3494
+ method: 'DELETE',
3495
+ url: '/api/v1/{region}/bean/nlp/session',
3277
3496
  path: {
3278
3497
  region: data.region
3279
3498
  },
3280
3499
  query: {
3281
- period: data.period
3500
+ sessionId: data.sessionId
3282
3501
  },
3283
3502
  errors: {
3284
- 400: 'Invalid period format',
3285
- 401: 'User not authenticated'
3503
+ 401: 'Unauthorized'
3286
3504
  }
3287
3505
  });
3288
3506
  }
3289
- }
3290
3507
 
3291
- export class InvestmentService {
3292
3508
  /**
3293
- * Get per-holding unrealized + realized P&L
3294
- * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3509
+ * Get current session state
3510
+ * Get the current NLP dialogue session state. Useful for debugging and displaying session context in UI.
3295
3511
  * @param data The data for the request.
3296
3512
  * @param data.region Region code for tenant context
3297
- * @param data.asOf As-of date (ISO 8601), defaults to today
3298
- * @param data.accountId Scope to a single account
3299
- * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3300
- * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3513
+ * @param data.sessionId Specific session ID to get (defaults to user session)
3514
+ * @returns unknown Current session state (or null if no active session)
3301
3515
  * @throws ApiError
3302
3516
  */
3303
- public static holdingPnlControllerGetHoldingPnl(
3304
- data: HoldingPnlControllerGetHoldingPnlData
3305
- ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3517
+ public static nlpControllerGetSession(
3518
+ data: NlpControllerGetSessionData
3519
+ ): CancelablePromise<NlpControllerGetSessionResponse> {
3306
3520
  return __request(OpenAPI, {
3307
3521
  method: 'GET',
3308
- url: '/api/v1/{region}/investment/holdings/pnl',
3522
+ url: '/api/v1/{region}/bean/nlp/session',
3309
3523
  path: {
3310
3524
  region: data.region
3311
3525
  },
3312
3526
  query: {
3313
- asOf: data.asOf,
3314
- accountId: data.accountId,
3315
- method: data.method
3527
+ sessionId: data.sessionId
3316
3528
  },
3317
3529
  errors: {
3318
- 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3319
- 401: 'User not authenticated'
3530
+ 401: 'Unauthorized'
3320
3531
  }
3321
3532
  });
3322
3533
  }
3323
3534
  }
3324
3535
 
3325
- export class BeanPricesService {
3536
+ export class BeanPlatformsService {
3326
3537
  /**
3327
- * Create a new price
3328
- * Creates a new price entry for the authenticated user
3538
+ * Get all platforms with statistics
3539
+ * @returns unknown List of platforms with binding and account counts
3540
+ * @throws ApiError
3541
+ */
3542
+ public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
3543
+ return __request(OpenAPI, {
3544
+ method: 'GET',
3545
+ url: '/api/v1/bean/platforms'
3546
+ });
3547
+ }
3548
+
3549
+ /**
3550
+ * Create a new platform
3329
3551
  * @param data The data for the request.
3330
- * @param data.region Region code for tenant context
3331
3552
  * @param data.requestBody
3332
- * @returns PriceResponseDto Price created successfully
3553
+ * @returns unknown Platform created successfully
3333
3554
  * @throws ApiError
3334
3555
  */
3335
- public static priceControllerCreate(
3336
- data: PriceControllerCreateData
3337
- ): CancelablePromise<PriceControllerCreateResponse> {
3556
+ public static platformControllerCreate(
3557
+ data: PlatformControllerCreateData
3558
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3338
3559
  return __request(OpenAPI, {
3339
3560
  method: 'POST',
3340
- url: '/api/v1/{region}/bean/prices',
3341
- path: {
3561
+ url: '/api/v1/bean/platforms',
3562
+ body: data.requestBody,
3563
+ mediaType: 'application/json',
3564
+ errors: {
3565
+ 409: 'Platform already exists'
3566
+ }
3567
+ });
3568
+ }
3569
+
3570
+ /**
3571
+ * Get platform list for current user
3572
+ * @returns PlatformListItemDto List of platforms with user binding status
3573
+ * @throws ApiError
3574
+ */
3575
+ public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3576
+ return __request(OpenAPI, {
3577
+ method: 'GET',
3578
+ url: '/api/v1/bean/platforms/list'
3579
+ });
3580
+ }
3581
+
3582
+ /**
3583
+ * Match platforms by name or alias
3584
+ * @param data The data for the request.
3585
+ * @param data.q Search query — Chinese name, English name, or abbreviation
3586
+ * @param data.region Region code for category override lookup
3587
+ * @returns PlatformMatchResponseDto Matching platforms with overall match type and truncation flag
3588
+ * @throws ApiError
3589
+ */
3590
+ public static platformControllerMatchPlatforms(
3591
+ data: PlatformControllerMatchPlatformsData
3592
+ ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3593
+ return __request(OpenAPI, {
3594
+ method: 'GET',
3595
+ url: '/api/v1/bean/platforms/match',
3596
+ query: {
3597
+ q: data.q,
3342
3598
  region: data.region
3599
+ }
3600
+ });
3601
+ }
3602
+
3603
+ /**
3604
+ * Update a platform
3605
+ * @param data The data for the request.
3606
+ * @param data.id Platform ID
3607
+ * @param data.requestBody
3608
+ * @returns unknown Platform updated successfully
3609
+ * @throws ApiError
3610
+ */
3611
+ public static platformControllerUpdate(
3612
+ data: PlatformControllerUpdateData
3613
+ ): CancelablePromise<PlatformControllerUpdateResponse> {
3614
+ return __request(OpenAPI, {
3615
+ method: 'PUT',
3616
+ url: '/api/v1/bean/platforms/{id}',
3617
+ path: {
3618
+ id: data.id
3343
3619
  },
3344
3620
  body: data.requestBody,
3345
3621
  mediaType: 'application/json',
3346
3622
  errors: {
3347
- 404: 'Currency or quoteCurrency commodity not found',
3348
- 409: 'Price already exists for this currency pair and date'
3623
+ 404: 'Platform not found'
3349
3624
  }
3350
3625
  });
3351
3626
  }
3352
3627
 
3353
3628
  /**
3354
- * List user prices
3355
- * Returns all price entries for the authenticated user with optional filtering
3629
+ * Delete a platform
3630
+ * @param data The data for the request.
3631
+ * @param data.id Platform ID
3632
+ * @returns void Platform deleted successfully
3633
+ * @throws ApiError
3634
+ */
3635
+ public static platformControllerDelete(
3636
+ data: PlatformControllerDeleteData
3637
+ ): CancelablePromise<PlatformControllerDeleteResponse> {
3638
+ return __request(OpenAPI, {
3639
+ method: 'DELETE',
3640
+ url: '/api/v1/bean/platforms/{id}',
3641
+ path: {
3642
+ id: data.id
3643
+ },
3644
+ errors: {
3645
+ 404: 'Platform not found'
3646
+ }
3647
+ });
3648
+ }
3649
+ }
3650
+
3651
+ export class DashboardService {
3652
+ /**
3653
+ * Get net worth overview
3654
+ * Returns total net worth with breakdown of assets and liabilities
3356
3655
  * @param data The data for the request.
3357
3656
  * @param data.region Region code for tenant context
3358
- * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
3359
- * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
3360
- * @param data.dateFrom Filter prices from this date (ISO 8601 format)
3361
- * @param data.dateTo Filter prices to this date (ISO 8601 format)
3362
- * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
3363
- * @param data.page Page number for pagination (default: 1)
3364
- * @param data.limit Number of items per page (default: 20, max: 100)
3365
- * @returns PriceListResponseDto Prices retrieved successfully
3657
+ * @param data.date Date for balance calculation (ISO 8601 format)
3658
+ * @returns NetWorthResponseDto Net worth retrieved successfully
3366
3659
  * @throws ApiError
3367
3660
  */
3368
- public static priceControllerFindAll(
3369
- data: PriceControllerFindAllData
3370
- ): CancelablePromise<PriceControllerFindAllResponse> {
3661
+ public static dashboardControllerGetNetWorth(
3662
+ data: DashboardControllerGetNetWorthData
3663
+ ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3371
3664
  return __request(OpenAPI, {
3372
3665
  method: 'GET',
3373
- url: '/api/v1/{region}/bean/prices',
3666
+ url: '/api/v1/{region}/dashboard/net-worth',
3374
3667
  path: {
3375
3668
  region: data.region
3376
3669
  },
3377
3670
  query: {
3378
- currency: data.currency,
3379
- quoteCurrency: data.quoteCurrency,
3380
- dateFrom: data.dateFrom,
3381
- dateTo: data.dateTo,
3382
- search: data.search,
3383
- page: data.page,
3384
- limit: data.limit
3671
+ date: data.date
3672
+ },
3673
+ errors: {
3674
+ 401: 'User not authenticated'
3385
3675
  }
3386
3676
  });
3387
3677
  }
3388
3678
 
3389
3679
  /**
3390
- * Get price by ID
3391
- * Returns a single price entry by its ID
3680
+ * Get accounts grouped by platform
3681
+ * Returns accounts with balances grouped by financial platform
3392
3682
  * @param data The data for the request.
3393
- * @param data.id Price ID
3394
3683
  * @param data.region Region code for tenant context
3395
- * @returns PriceResponseDto Price retrieved successfully
3684
+ * @param data.groupBy Grouping strategy
3685
+ * @param data.date Date for balance calculation (ISO 8601 format)
3686
+ * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3687
+ * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3396
3688
  * @throws ApiError
3397
3689
  */
3398
- public static priceControllerFindOne(
3399
- data: PriceControllerFindOneData
3400
- ): CancelablePromise<PriceControllerFindOneResponse> {
3690
+ public static dashboardControllerGetAccounts(
3691
+ data: DashboardControllerGetAccountsData
3692
+ ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3401
3693
  return __request(OpenAPI, {
3402
3694
  method: 'GET',
3403
- url: '/api/v1/{region}/bean/prices/{id}',
3695
+ url: '/api/v1/{region}/dashboard/accounts',
3404
3696
  path: {
3405
- id: data.id,
3406
3697
  region: data.region
3407
3698
  },
3699
+ query: {
3700
+ groupBy: data.groupBy,
3701
+ date: data.date,
3702
+ accountId: data.accountId
3703
+ },
3408
3704
  errors: {
3409
- 404: 'Price not found'
3705
+ 401: 'User not authenticated'
3410
3706
  }
3411
3707
  });
3412
3708
  }
3413
3709
 
3414
3710
  /**
3415
- * Update a price
3416
- * Updates an existing price entry
3711
+ * Get cash flow summary
3712
+ * Returns income, expenses, and savings for a monthly period
3417
3713
  * @param data The data for the request.
3418
- * @param data.id Price ID
3714
+ * @param data.period Period in YYYY-MM format
3419
3715
  * @param data.region Region code for tenant context
3420
- * @param data.requestBody
3421
- * @returns PriceResponseDto Price updated successfully
3716
+ * @returns CashFlowResponseDto Cash flow retrieved successfully
3422
3717
  * @throws ApiError
3423
3718
  */
3424
- public static priceControllerUpdate(
3425
- data: PriceControllerUpdateData
3426
- ): CancelablePromise<PriceControllerUpdateResponse> {
3719
+ public static dashboardControllerGetCashFlow(
3720
+ data: DashboardControllerGetCashFlowData
3721
+ ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3427
3722
  return __request(OpenAPI, {
3428
- method: 'PUT',
3429
- url: '/api/v1/{region}/bean/prices/{id}',
3723
+ method: 'GET',
3724
+ url: '/api/v1/{region}/dashboard/cash-flow',
3430
3725
  path: {
3431
- id: data.id,
3432
3726
  region: data.region
3433
3727
  },
3434
- body: data.requestBody,
3435
- mediaType: 'application/json',
3728
+ query: {
3729
+ period: data.period
3730
+ },
3436
3731
  errors: {
3437
- 404: 'Price not found',
3438
- 409: 'Updated price conflicts with existing price'
3732
+ 400: 'Invalid period format',
3733
+ 401: 'User not authenticated'
3439
3734
  }
3440
3735
  });
3441
3736
  }
3442
3737
 
3443
3738
  /**
3444
- * Delete a price
3445
- * Deletes a price entry (hard delete)
3739
+ * Get expenses/income grouped by functional category
3740
+ * 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)
3446
3741
  * @param data The data for the request.
3447
- * @param data.id Price ID
3448
3742
  * @param data.region Region code for tenant context
3449
- * @returns void Price deleted successfully
3743
+ * @param data.groupBy Grouping strategy
3744
+ * @param data.period Time window (1m = current calendar month)
3745
+ * @param data.flow Account root to aggregate (expense → ^Expenses:, income → ^Income:)
3746
+ * @returns ExpensesByCategoryResponseDto Expenses retrieved successfully
3450
3747
  * @throws ApiError
3451
3748
  */
3452
- public static priceControllerDelete(
3453
- data: PriceControllerDeleteData
3454
- ): CancelablePromise<PriceControllerDeleteResponse> {
3749
+ public static dashboardControllerGetExpenses(
3750
+ data: DashboardControllerGetExpensesData
3751
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3455
3752
  return __request(OpenAPI, {
3456
- method: 'DELETE',
3457
- url: '/api/v1/{region}/bean/prices/{id}',
3753
+ method: 'GET',
3754
+ url: '/api/v1/{region}/dashboard/expenses',
3458
3755
  path: {
3459
- id: data.id,
3460
3756
  region: data.region
3461
3757
  },
3758
+ query: {
3759
+ groupBy: data.groupBy,
3760
+ period: data.period,
3761
+ flow: data.flow
3762
+ },
3462
3763
  errors: {
3463
- 404: 'Price not found'
3764
+ 400: 'Invalid groupBy or period',
3765
+ 401: 'User not authenticated'
3464
3766
  }
3465
3767
  });
3466
3768
  }
3769
+ }
3467
3770
 
3771
+ export class InvestmentService {
3468
3772
  /**
3469
- * Bulk create prices
3470
- * Creates multiple price entries at once (skips duplicates)
3773
+ * Get per-holding unrealized + realized P&L
3774
+ * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3471
3775
  * @param data The data for the request.
3472
3776
  * @param data.region Region code for tenant context
3473
- * @param data.requestBody
3474
- * @returns PriceResponseDto Prices created successfully
3777
+ * @param data.asOf As-of date (ISO 8601), defaults to today
3778
+ * @param data.accountId Scope to a single account
3779
+ * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3780
+ * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3475
3781
  * @throws ApiError
3476
3782
  */
3477
- public static priceControllerBulkCreate(
3478
- data: PriceControllerBulkCreateData
3479
- ): CancelablePromise<PriceControllerBulkCreateResponse> {
3783
+ public static holdingPnlControllerGetHoldingPnl(
3784
+ data: HoldingPnlControllerGetHoldingPnlData
3785
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3480
3786
  return __request(OpenAPI, {
3481
- method: 'POST',
3482
- url: '/api/v1/{region}/bean/prices/bulk',
3787
+ method: 'GET',
3788
+ url: '/api/v1/{region}/investment/holdings/pnl',
3483
3789
  path: {
3484
3790
  region: data.region
3485
3791
  },
3486
- body: data.requestBody,
3487
- mediaType: 'application/json'
3792
+ query: {
3793
+ asOf: data.asOf,
3794
+ accountId: data.accountId,
3795
+ method: data.method
3796
+ },
3797
+ errors: {
3798
+ 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3799
+ 401: 'User not authenticated'
3800
+ }
3488
3801
  });
3489
3802
  }
3490
3803
  }