@firela/api-types 0.0.0-canary.614ff760 → 0.0.0-canary.63a53b7d

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,
@@ -171,6 +185,28 @@ import type {
171
185
  PropertyControllerUpdateResponse,
172
186
  PropertyControllerDeleteData,
173
187
  PropertyControllerDeleteResponse,
188
+ EventControllerCreateData,
189
+ EventControllerCreateResponse,
190
+ EventControllerFindAllData,
191
+ EventControllerFindAllResponse,
192
+ EventControllerFindOneData,
193
+ EventControllerFindOneResponse,
194
+ EventControllerUpdateData,
195
+ EventControllerUpdateResponse,
196
+ EventControllerDeleteData,
197
+ EventControllerDeleteResponse,
198
+ EventControllerGetSliceData,
199
+ EventControllerGetSliceResponse,
200
+ OnboardingControllerBootstrapData,
201
+ OnboardingControllerBootstrapResponse,
202
+ ReconciliationControllerComputeData,
203
+ ReconciliationControllerComputeResponse,
204
+ ReconciliationControllerAssertData,
205
+ ReconciliationControllerAssertResponse,
206
+ ReconciliationControllerPadData,
207
+ ReconciliationControllerPadResponse,
208
+ ReconciliationControllerHistoryData,
209
+ ReconciliationControllerHistoryResponse,
174
210
  ExportControllerExportBeancountResponse,
175
211
  FileImportControllerImportFileData,
176
212
  FileImportControllerImportFileResponse,
@@ -184,38 +220,56 @@ import type {
184
220
  ImporterConfigControllerUpdateConfigResponse,
185
221
  ImporterConfigControllerResetConfigData,
186
222
  ImporterConfigControllerResetConfigResponse,
187
- PlatformControllerFindAllResponse,
188
- PlatformControllerCreateData,
189
- PlatformControllerCreateResponse,
190
- PlatformControllerGetPlatformListResponse,
191
- PlatformControllerMatchPlatformsData,
192
- PlatformControllerMatchPlatformsResponse,
193
- PlatformControllerUpdateData,
194
- PlatformControllerUpdateResponse,
195
- PlatformControllerDeleteData,
196
- PlatformControllerDeleteResponse,
197
223
  ProviderSyncControllerSyncData,
198
224
  ProviderSyncControllerSyncResponse,
199
225
  ProviderSyncControllerGetSupportedProvidersData,
200
226
  ProviderSyncControllerGetSupportedProvidersResponse,
201
227
  ProviderSyncControllerIsProviderSupportedData,
202
228
  ProviderSyncControllerIsProviderSupportedResponse,
229
+ ExternalAccountLinkControllerCreateData,
230
+ ExternalAccountLinkControllerCreateResponse,
231
+ ExternalAccountLinkControllerFindAllData,
232
+ ExternalAccountLinkControllerFindAllResponse,
233
+ ExternalAccountLinkControllerFindOneData,
234
+ ExternalAccountLinkControllerFindOneResponse,
235
+ ExternalAccountLinkControllerRemoveData,
236
+ ExternalAccountLinkControllerRemoveResponse,
203
237
  TelemetryControllerReportTelemetryData,
204
238
  TelemetryControllerReportTelemetryResponse,
239
+ TelemetryControllerReportCoverageMissData,
240
+ TelemetryControllerReportCoverageMissResponse,
241
+ TelemetryControllerGetCoverageMetricsData,
242
+ TelemetryControllerGetCoverageMetricsResponse,
205
243
  NlpControllerProcessNaturalLanguageData,
206
244
  NlpControllerProcessNaturalLanguageResponse,
207
245
  NlpControllerClearSessionData,
208
246
  NlpControllerClearSessionResponse,
209
247
  NlpControllerGetSessionData,
210
248
  NlpControllerGetSessionResponse,
249
+ PlatformControllerFindAllResponse,
250
+ PlatformControllerCreateData,
251
+ PlatformControllerCreateResponse,
252
+ PlatformControllerGetPlatformListResponse,
253
+ PlatformControllerMatchPlatformsData,
254
+ PlatformControllerMatchPlatformsResponse,
255
+ PlatformControllerUpdateData,
256
+ PlatformControllerUpdateResponse,
257
+ PlatformControllerDeleteData,
258
+ PlatformControllerDeleteResponse,
211
259
  DashboardControllerGetNetWorthData,
212
260
  DashboardControllerGetNetWorthResponse,
213
261
  DashboardControllerGetAccountsData,
214
262
  DashboardControllerGetAccountsResponse,
215
263
  DashboardControllerGetCashFlowData,
216
264
  DashboardControllerGetCashFlowResponse,
265
+ DashboardControllerGetExpensesData,
266
+ DashboardControllerGetExpensesResponse,
267
+ HoldingPnlControllerGetHoldingPnlData,
268
+ HoldingPnlControllerGetHoldingPnlResponse,
217
269
  ReportingControllerGetPortfolioTrendsData,
218
270
  ReportingControllerGetPortfolioTrendsResponse,
271
+ ReportingControllerGetCashFlowTrendsData,
272
+ ReportingControllerGetCashFlowTrendsResponse,
219
273
  ReportingControllerGenerateSnapshotData,
220
274
  ReportingControllerGenerateSnapshotResponse,
221
275
  ReportingControllerBackfillSnapshotsData,
@@ -272,7 +326,7 @@ export class BeanAccountsService {
272
326
  * @param data.type Filter by account type
273
327
  * @param data.status Filter by status
274
328
  * @param data.isCustom Filter by custom (user-created) accounts only
275
- * @param data.search Search term for path or i18nKey
329
+ * @param data.search Search term for account path
276
330
  * @param data.limit Maximum number of results
277
331
  * @param data.offset Number of results to skip
278
332
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -434,6 +488,35 @@ export class BeanAccountsService {
434
488
  }
435
489
  });
436
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
+ }
437
520
  }
438
521
 
439
522
  export class BeanAccountStandardsService {
@@ -465,7 +548,7 @@ export class BeanAccountStandardsService {
465
548
 
466
549
  /**
467
550
  * Get template metadata for an account path
468
- * Returns extendable status and root type for a template path.
551
+ * Returns root type for a template path.
469
552
  * @param data The data for the request.
470
553
  * @param data.region Region code for tenant context
471
554
  * @param data.path Account path to check
@@ -551,6 +634,7 @@ export class BeanTransactionsService {
551
634
  * @param data.status Filter by transaction status
552
635
  * @param data.search Search in narration and payee fields (max 200 chars)
553
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
554
638
  * @returns TransactionListResponseDto Transaction list
555
639
  * @throws ApiError
556
640
  */
@@ -570,7 +654,8 @@ export class BeanTransactionsService {
570
654
  dateTo: data.dateTo,
571
655
  status: data.status,
572
656
  search: data.search,
573
- accountId: data.accountId
657
+ accountId: data.accountId,
658
+ category: data.category
574
659
  },
575
660
  errors: {
576
661
  400: 'Validation failed',
@@ -758,7 +843,7 @@ export class BeanBalancesService {
758
843
  * Query account balance
759
844
  * Calculate account balance at a specific date for a single currency
760
845
  * @param data The data for the request.
761
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
846
+ * @param data.account Account name (e.g., "Assets:Checking")
762
847
  * @param data.region Region code for tenant context
763
848
  * @param data.date Date to calculate balance at (ISO 8601 format)
764
849
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -1479,6 +1564,173 @@ export class BeanCommoditiesService {
1479
1564
  }
1480
1565
  }
1481
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
+
1482
1734
  export class RecurringRulesService {
1483
1735
  /**
1484
1736
  * Create a new recurring rule
@@ -2442,294 +2694,487 @@ export class PropertiesService {
2442
2694
  }
2443
2695
  }
2444
2696
 
2445
- export class BeanExportService {
2446
- /**
2447
- * Export Beancount ledger as ZIP
2448
- * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
2449
- * @returns unknown
2450
- * @throws ApiError
2451
- */
2452
- public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
2453
- return __request(OpenAPI, {
2454
- method: 'GET',
2455
- url: '/api/v1/{region}/bean/export/beancount'
2456
- });
2457
- }
2458
- }
2459
-
2460
- export class BeanImportService {
2697
+ export class LifeEventsService {
2461
2698
  /**
2462
- * Import a bill file
2463
- * 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).
2699
+ * Create a new life event
2700
+ * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
2464
2701
  * @param data The data for the request.
2465
- * @param data.region Region code for tenant context
2466
- * @param data.formData Bill file to import
2467
- * @returns ImportResultDto File imported successfully
2702
+ * @param data.region Region code for tenant context (decorative for life events)
2703
+ * @param data.requestBody
2704
+ * @returns EventResponseDto Life event created successfully
2468
2705
  * @throws ApiError
2469
2706
  */
2470
- public static fileImportControllerImportFile(
2471
- data: FileImportControllerImportFileData
2472
- ): CancelablePromise<FileImportControllerImportFileResponse> {
2707
+ public static eventControllerCreate(
2708
+ data: EventControllerCreateData
2709
+ ): CancelablePromise<EventControllerCreateResponse> {
2473
2710
  return __request(OpenAPI, {
2474
2711
  method: 'POST',
2475
- url: '/api/v1/{region}/bean/import/file',
2712
+ url: '/api/v1/{region}/bean/events',
2476
2713
  path: {
2477
2714
  region: data.region
2478
2715
  },
2479
- formData: data.formData,
2480
- mediaType: 'multipart/form-data',
2716
+ body: data.requestBody,
2717
+ mediaType: 'application/json',
2481
2718
  errors: {
2482
- 400: 'Bad request - file-format-unsupported or file-import-failed',
2483
- 413: 'Payload too large - file exceeds 50MB limit',
2484
- 429: 'Too many requests - user already has import in progress',
2485
- 500: 'Internal server error - DATABASE_ERROR'
2719
+ 409: 'Life event already exists for this (userId, type, date) combination'
2486
2720
  }
2487
2721
  });
2488
2722
  }
2489
2723
 
2490
2724
  /**
2491
- * Identify file type
2492
- * 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.
2725
+ * List user life events
2726
+ * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2493
2727
  * @param data The data for the request.
2494
- * @param data.region Region code for tenant context
2495
- * @param data.formData File to identify
2496
- * @returns IdentifyResultDto File identification result
2728
+ * @param data.region Region code for tenant context (decorative for life events)
2729
+ * @param data.type Filter by life event type (exact match)
2730
+ * @param data.q Search term for description (case-insensitive partial match)
2731
+ * @param data.from Filter life events from this date (ISO 8601 format)
2732
+ * @param data.to Filter life events to this date (ISO 8601 format)
2733
+ * @param data.page Page number for pagination (default: 1)
2734
+ * @param data.limit Number of items per page (default: 20, max: 100)
2735
+ * @returns EventListResponseDto Life events retrieved successfully
2497
2736
  * @throws ApiError
2498
2737
  */
2499
- public static fileImportControllerIdentifyFile(
2500
- data: FileImportControllerIdentifyFileData
2501
- ): CancelablePromise<FileImportControllerIdentifyFileResponse> {
2738
+ public static eventControllerFindAll(
2739
+ data: EventControllerFindAllData
2740
+ ): CancelablePromise<EventControllerFindAllResponse> {
2502
2741
  return __request(OpenAPI, {
2503
- method: 'POST',
2504
- url: '/api/v1/{region}/bean/import/identify',
2742
+ method: 'GET',
2743
+ url: '/api/v1/{region}/bean/events',
2505
2744
  path: {
2506
2745
  region: data.region
2507
2746
  },
2508
- formData: data.formData,
2509
- mediaType: 'multipart/form-data',
2510
- errors: {
2511
- 400: 'Bad request - No file uploaded'
2747
+ query: {
2748
+ type: data.type,
2749
+ q: data.q,
2750
+ from: data.from,
2751
+ to: data.to,
2752
+ page: data.page,
2753
+ limit: data.limit
2512
2754
  }
2513
2755
  });
2514
2756
  }
2515
2757
 
2516
2758
  /**
2517
- * Import a Beancount file in community format
2518
- * 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.
2759
+ * Get life event by ID
2760
+ * Returns a single life event by its ID. Returns ETag header.
2519
2761
  * @param data The data for the request.
2520
- * @param data.region Region code for tenant context
2521
- * @param data.formData Beancount file to import
2522
- * @returns unknown Beancount file imported successfully
2762
+ * @param data.id Life event ID
2763
+ * @param data.region Region code for tenant context (decorative for life events)
2764
+ * @returns EventResponseDto Life event retrieved successfully
2523
2765
  * @throws ApiError
2524
2766
  */
2525
- public static fileImportControllerImportBeancount(
2526
- data: FileImportControllerImportBeancountData
2527
- ): CancelablePromise<FileImportControllerImportBeancountResponse> {
2767
+ public static eventControllerFindOne(
2768
+ data: EventControllerFindOneData
2769
+ ): CancelablePromise<EventControllerFindOneResponse> {
2528
2770
  return __request(OpenAPI, {
2529
- method: 'POST',
2530
- url: '/api/v1/{region}/bean/import/beancount',
2771
+ method: 'GET',
2772
+ url: '/api/v1/{region}/bean/events/{id}',
2531
2773
  path: {
2774
+ id: data.id,
2532
2775
  region: data.region
2533
2776
  },
2534
- formData: data.formData,
2535
- mediaType: 'multipart/form-data',
2536
2777
  errors: {
2537
- 400: 'Bad request - invalid file or no file uploaded'
2778
+ 404: 'Life event not found'
2538
2779
  }
2539
2780
  });
2540
2781
  }
2541
2782
 
2542
2783
  /**
2543
- * Get importer configuration
2544
- * Returns the current configuration for the specified importer. Creates default configuration if none exists.
2784
+ * Update a life event
2785
+ * Updates an existing life event. If If-Match header is provided, performs optimistic concurrency check; mismatched updatedAt returns 412.
2545
2786
  * @param data The data for the request.
2546
- * @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
2547
- * @param data.region Region code for tenant context
2548
- * @returns ImporterConfigDto Configuration retrieved successfully
2787
+ * @param data.id Life event ID
2788
+ * @param data.region Region code for tenant context (decorative for life events)
2789
+ * @param data.requestBody
2790
+ * @returns EventResponseDto Life event updated successfully
2549
2791
  * @throws ApiError
2550
2792
  */
2551
- public static importerConfigControllerGetConfig(
2552
- data: ImporterConfigControllerGetConfigData
2553
- ): CancelablePromise<ImporterConfigControllerGetConfigResponse> {
2793
+ public static eventControllerUpdate(
2794
+ data: EventControllerUpdateData
2795
+ ): CancelablePromise<EventControllerUpdateResponse> {
2554
2796
  return __request(OpenAPI, {
2555
- method: 'GET',
2556
- url: '/api/v1/{region}/bean/import/config/{importerId}',
2797
+ method: 'PUT',
2798
+ url: '/api/v1/{region}/bean/events/{id}',
2557
2799
  path: {
2558
- importerId: data.importerId,
2800
+ id: data.id,
2559
2801
  region: data.region
2560
2802
  },
2803
+ body: data.requestBody,
2804
+ mediaType: 'application/json',
2561
2805
  errors: {
2562
- 400: 'Invalid input - Unsupported importer',
2563
- 401: 'Unauthorized - Authentication required'
2806
+ 400: 'If-Match header is not a valid ISO 8601 date',
2807
+ 404: 'Life event not found',
2808
+ 409: 'Updated event conflicts with an existing (userId, type, date) combination',
2809
+ 412: 'If-Match precondition failed (updatedAt mismatch)'
2564
2810
  }
2565
2811
  });
2566
2812
  }
2567
2813
 
2568
2814
  /**
2569
- * Update importer configuration
2570
- * Updates the configuration for the specified importer. Partial updates are supported.
2815
+ * Delete a life event
2816
+ * Deletes a life event entry (hard delete). Returns 204.
2571
2817
  * @param data The data for the request.
2572
- * @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
2573
- * @param data.region Region code for tenant context
2574
- * @param data.requestBody Partial configuration update. Only provided fields will be updated.
2575
- * @returns ImporterConfigDto Configuration updated successfully
2818
+ * @param data.id Life event ID
2819
+ * @param data.region Region code for tenant context (decorative for life events)
2820
+ * @returns void Life event deleted successfully
2576
2821
  * @throws ApiError
2577
2822
  */
2578
- public static importerConfigControllerUpdateConfig(
2579
- data: ImporterConfigControllerUpdateConfigData
2580
- ): CancelablePromise<ImporterConfigControllerUpdateConfigResponse> {
2823
+ public static eventControllerDelete(
2824
+ data: EventControllerDeleteData
2825
+ ): CancelablePromise<EventControllerDeleteResponse> {
2581
2826
  return __request(OpenAPI, {
2582
- method: 'PUT',
2583
- url: '/api/v1/{region}/bean/import/config/{importerId}',
2827
+ method: 'DELETE',
2828
+ url: '/api/v1/{region}/bean/events/{id}',
2584
2829
  path: {
2585
- importerId: data.importerId,
2830
+ id: data.id,
2586
2831
  region: data.region
2587
2832
  },
2588
- body: data.requestBody,
2589
- mediaType: 'application/json',
2590
2833
  errors: {
2591
- 400: 'Invalid input - Validation failed',
2592
- 404: 'Configuration not found'
2834
+ 404: 'Life event not found'
2593
2835
  }
2594
2836
  });
2595
2837
  }
2596
2838
 
2597
2839
  /**
2598
- * Reset configuration to default
2599
- * Resets the configuration for the specified importer to default values. This operation overwrites all existing configuration.
2840
+ * Slice time-series by a life event (Phase 79)
2841
+ * Returns aggregated time-series for postings matching accountPattern within the half-open date range of the given life event.
2842
+ * @param data The data for the request.
2843
+ * @param data.id Life event ID
2844
+ * @param data.accountPattern
2845
+ * @param data.granularity
2846
+ * @param data.region Region code for tenant context (decorative for life events)
2847
+ * @returns unknown Time-series sliced by the life event range
2848
+ * @throws ApiError
2849
+ */
2850
+ public static eventControllerGetSlice(
2851
+ data: EventControllerGetSliceData
2852
+ ): CancelablePromise<EventControllerGetSliceResponse> {
2853
+ return __request(OpenAPI, {
2854
+ method: 'GET',
2855
+ url: '/api/v1/{region}/bean/events/{id}/slice',
2856
+ path: {
2857
+ id: data.id,
2858
+ region: data.region
2859
+ },
2860
+ query: {
2861
+ accountPattern: data.accountPattern,
2862
+ granularity: data.granularity
2863
+ },
2864
+ errors: {
2865
+ 400: 'accountPattern query param is empty',
2866
+ 404: 'Life event not found'
2867
+ }
2868
+ });
2869
+ }
2870
+ }
2871
+
2872
+ export class OnboardingService {
2873
+ /**
2874
+ * Bootstrap core accounts + register asset accounts with opening balances (ADR-0113)
2600
2875
  * @param data The data for the request.
2601
- * @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
2602
2876
  * @param data.region Region code for tenant context
2603
- * @returns ImporterConfigDto Configuration reset successfully
2877
+ * @param data.requestBody
2878
+ * @returns unknown Onboarding bootstrap result.
2604
2879
  * @throws ApiError
2605
2880
  */
2606
- public static importerConfigControllerResetConfig(
2607
- data: ImporterConfigControllerResetConfigData
2608
- ): CancelablePromise<ImporterConfigControllerResetConfigResponse> {
2881
+ public static onboardingControllerBootstrap(
2882
+ data: OnboardingControllerBootstrapData
2883
+ ): CancelablePromise<OnboardingControllerBootstrapResponse> {
2609
2884
  return __request(OpenAPI, {
2610
2885
  method: 'POST',
2611
- url: '/api/v1/{region}/bean/import/config/{importerId}/reset',
2886
+ url: '/api/v1/{region}/bean/onboarding',
2612
2887
  path: {
2613
- importerId: data.importerId,
2614
2888
  region: data.region
2615
2889
  },
2890
+ body: data.requestBody,
2891
+ mediaType: 'application/json',
2616
2892
  errors: {
2617
- 400: 'Invalid input - Unsupported importer'
2893
+ 422: 'Invalid region/account path/duplicate paths.'
2618
2894
  }
2619
2895
  });
2620
2896
  }
2621
2897
  }
2622
2898
 
2623
- export class BeanPlatformsService {
2899
+ export class BalanceReconciliationService {
2624
2900
  /**
2625
- * Get all platforms with statistics
2626
- * @returns unknown List of platforms with binding and account counts
2901
+ * Preview reconciliation (book vs actual)
2902
+ * Computes book balance, diff, Beancount-inferred tolerance, and suggested action without persisting.
2903
+ * @param data The data for the request.
2904
+ * @param data.region Region code for tenant context (decorative for reconciliation)
2905
+ * @param data.requestBody
2906
+ * @returns ReconciliationComputeResultDto Reconciliation preview
2627
2907
  * @throws ApiError
2628
2908
  */
2629
- public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
2909
+ public static reconciliationControllerCompute(
2910
+ data: ReconciliationControllerComputeData
2911
+ ): CancelablePromise<ReconciliationControllerComputeResponse> {
2630
2912
  return __request(OpenAPI, {
2631
- method: 'GET',
2632
- url: '/api/v1/bean/platforms'
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
+ }
2633
2923
  });
2634
2924
  }
2635
2925
 
2636
2926
  /**
2637
- * Create a new platform
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.
2638
2929
  * @param data The data for the request.
2930
+ * @param data.region Region code for tenant context (decorative for reconciliation)
2639
2931
  * @param data.requestBody
2640
- * @returns unknown Platform created successfully
2932
+ * @returns ReconciliationRecordDto Balance assertion recorded
2641
2933
  * @throws ApiError
2642
2934
  */
2643
- public static platformControllerCreate(
2644
- data: PlatformControllerCreateData
2645
- ): CancelablePromise<PlatformControllerCreateResponse> {
2935
+ public static reconciliationControllerAssert(
2936
+ data: ReconciliationControllerAssertData
2937
+ ): CancelablePromise<ReconciliationControllerAssertResponse> {
2646
2938
  return __request(OpenAPI, {
2647
2939
  method: 'POST',
2648
- url: '/api/v1/bean/platforms',
2940
+ url: '/api/v1/{region}/bean/reconciliations/assert',
2941
+ path: {
2942
+ region: data.region
2943
+ },
2649
2944
  body: data.requestBody,
2650
2945
  mediaType: 'application/json',
2651
2946
  errors: {
2652
- 409: 'Platform already exists'
2947
+ 404: 'Account not found'
2653
2948
  }
2654
2949
  });
2655
2950
  }
2656
2951
 
2657
2952
  /**
2658
- * Get platform list for current user
2659
- * @returns unknown List of platforms with user binding status
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
2660
2959
  * @throws ApiError
2661
2960
  */
2662
- public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
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> {
2663
2991
  return __request(OpenAPI, {
2664
2992
  method: 'GET',
2665
- url: '/api/v1/bean/platforms/list'
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
+ }
2666
3001
  });
2667
3002
  }
3003
+ }
2668
3004
 
3005
+ export class BeanExportService {
2669
3006
  /**
2670
- * Match platforms by name or alias
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).
2671
3024
  * @param data The data for the request.
2672
- * @param data.q Search query — Chinese name, English name, or abbreviation
2673
- * @param data.region Region code for category override lookup
2674
- * @returns unknown List of matching platforms with suggested segment names
3025
+ * @param data.region Region code for tenant context
3026
+ * @param data.formData Bill file to import
3027
+ * @returns ImportResultDto File imported successfully
2675
3028
  * @throws ApiError
2676
3029
  */
2677
- public static platformControllerMatchPlatforms(
2678
- data: PlatformControllerMatchPlatformsData
2679
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3030
+ public static fileImportControllerImportFile(
3031
+ data: FileImportControllerImportFileData
3032
+ ): CancelablePromise<FileImportControllerImportFileResponse> {
3033
+ return __request(OpenAPI, {
3034
+ method: 'POST',
3035
+ url: '/api/v1/{region}/bean/import/file',
3036
+ path: {
3037
+ region: data.region
3038
+ },
3039
+ formData: data.formData,
3040
+ mediaType: 'multipart/form-data',
3041
+ errors: {
3042
+ 400: 'Bad request - file-format-unsupported or file-import-failed',
3043
+ 413: 'Payload too large - file exceeds 50MB limit',
3044
+ 429: 'Too many requests - user already has import in progress',
3045
+ 500: 'Internal server error - DATABASE_ERROR'
3046
+ }
3047
+ });
3048
+ }
3049
+
3050
+ /**
3051
+ * Identify file type
3052
+ * 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.
3053
+ * @param data The data for the request.
3054
+ * @param data.region Region code for tenant context
3055
+ * @param data.formData File to identify
3056
+ * @returns IdentifyResultDto File identification result
3057
+ * @throws ApiError
3058
+ */
3059
+ public static fileImportControllerIdentifyFile(
3060
+ data: FileImportControllerIdentifyFileData
3061
+ ): CancelablePromise<FileImportControllerIdentifyFileResponse> {
3062
+ return __request(OpenAPI, {
3063
+ method: 'POST',
3064
+ url: '/api/v1/{region}/bean/import/identify',
3065
+ path: {
3066
+ region: data.region
3067
+ },
3068
+ formData: data.formData,
3069
+ mediaType: 'multipart/form-data',
3070
+ errors: {
3071
+ 400: 'Bad request - No file uploaded'
3072
+ }
3073
+ });
3074
+ }
3075
+
3076
+ /**
3077
+ * Import a Beancount file in community format
3078
+ * 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.
3079
+ * @param data The data for the request.
3080
+ * @param data.region Region code for tenant context
3081
+ * @param data.formData Beancount file to import
3082
+ * @returns unknown Beancount file imported successfully
3083
+ * @throws ApiError
3084
+ */
3085
+ public static fileImportControllerImportBeancount(
3086
+ data: FileImportControllerImportBeancountData
3087
+ ): CancelablePromise<FileImportControllerImportBeancountResponse> {
3088
+ return __request(OpenAPI, {
3089
+ method: 'POST',
3090
+ url: '/api/v1/{region}/bean/import/beancount',
3091
+ path: {
3092
+ region: data.region
3093
+ },
3094
+ formData: data.formData,
3095
+ mediaType: 'multipart/form-data',
3096
+ errors: {
3097
+ 400: 'Bad request - invalid file or no file uploaded'
3098
+ }
3099
+ });
3100
+ }
3101
+
3102
+ /**
3103
+ * Get importer configuration
3104
+ * Returns the current configuration for the specified importer. Creates default configuration if none exists.
3105
+ * @param data The data for the request.
3106
+ * @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
3107
+ * @param data.region Region code for tenant context
3108
+ * @returns ImporterConfigDto Configuration retrieved successfully
3109
+ * @throws ApiError
3110
+ */
3111
+ public static importerConfigControllerGetConfig(
3112
+ data: ImporterConfigControllerGetConfigData
3113
+ ): CancelablePromise<ImporterConfigControllerGetConfigResponse> {
2680
3114
  return __request(OpenAPI, {
2681
3115
  method: 'GET',
2682
- url: '/api/v1/bean/platforms/match',
2683
- query: {
2684
- q: data.q,
3116
+ url: '/api/v1/{region}/bean/import/config/{importerId}',
3117
+ path: {
3118
+ importerId: data.importerId,
2685
3119
  region: data.region
3120
+ },
3121
+ errors: {
3122
+ 400: 'Invalid input - Unsupported importer',
3123
+ 401: 'Unauthorized - Authentication required'
2686
3124
  }
2687
3125
  });
2688
3126
  }
2689
3127
 
2690
3128
  /**
2691
- * Update a platform
3129
+ * Update importer configuration
3130
+ * Updates the configuration for the specified importer. Partial updates are supported.
2692
3131
  * @param data The data for the request.
2693
- * @param data.id Platform ID
2694
- * @param data.requestBody
2695
- * @returns unknown Platform updated successfully
3132
+ * @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
3133
+ * @param data.region Region code for tenant context
3134
+ * @param data.requestBody Partial configuration update. Only provided fields will be updated.
3135
+ * @returns ImporterConfigDto Configuration updated successfully
2696
3136
  * @throws ApiError
2697
3137
  */
2698
- public static platformControllerUpdate(
2699
- data: PlatformControllerUpdateData
2700
- ): CancelablePromise<PlatformControllerUpdateResponse> {
3138
+ public static importerConfigControllerUpdateConfig(
3139
+ data: ImporterConfigControllerUpdateConfigData
3140
+ ): CancelablePromise<ImporterConfigControllerUpdateConfigResponse> {
2701
3141
  return __request(OpenAPI, {
2702
3142
  method: 'PUT',
2703
- url: '/api/v1/bean/platforms/{id}',
3143
+ url: '/api/v1/{region}/bean/import/config/{importerId}',
2704
3144
  path: {
2705
- id: data.id
3145
+ importerId: data.importerId,
3146
+ region: data.region
2706
3147
  },
2707
3148
  body: data.requestBody,
2708
3149
  mediaType: 'application/json',
2709
3150
  errors: {
2710
- 404: 'Platform not found'
3151
+ 400: 'Invalid input - Validation failed',
3152
+ 404: 'Configuration not found'
2711
3153
  }
2712
3154
  });
2713
3155
  }
2714
3156
 
2715
3157
  /**
2716
- * Delete a platform
3158
+ * Reset configuration to default
3159
+ * Resets the configuration for the specified importer to default values. This operation overwrites all existing configuration.
2717
3160
  * @param data The data for the request.
2718
- * @param data.id Platform ID
2719
- * @returns void Platform deleted successfully
3161
+ * @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
3162
+ * @param data.region Region code for tenant context
3163
+ * @returns ImporterConfigDto Configuration reset successfully
2720
3164
  * @throws ApiError
2721
3165
  */
2722
- public static platformControllerDelete(
2723
- data: PlatformControllerDeleteData
2724
- ): CancelablePromise<PlatformControllerDeleteResponse> {
3166
+ public static importerConfigControllerResetConfig(
3167
+ data: ImporterConfigControllerResetConfigData
3168
+ ): CancelablePromise<ImporterConfigControllerResetConfigResponse> {
2725
3169
  return __request(OpenAPI, {
2726
- method: 'DELETE',
2727
- url: '/api/v1/bean/platforms/{id}',
3170
+ method: 'POST',
3171
+ url: '/api/v1/{region}/bean/import/config/{importerId}/reset',
2728
3172
  path: {
2729
- id: data.id
3173
+ importerId: data.importerId,
3174
+ region: data.region
2730
3175
  },
2731
3176
  errors: {
2732
- 404: 'Platform not found'
3177
+ 400: 'Invalid input - Unsupported importer'
2733
3178
  }
2734
3179
  });
2735
3180
  }
@@ -2761,7 +3206,7 @@ export class ProviderSyncService {
2761
3206
  *
2762
3207
  * @param data The data for the request.
2763
3208
  * @param data.providerName Provider name
2764
- * @param data.region Region code
3209
+ * @param data.region Region code for tenant context
2765
3210
  * @param data.requestBody
2766
3211
  * @returns ProviderSyncResponseDto Sync completed successfully
2767
3212
  * @throws ApiError
@@ -2773,63 +3218,158 @@ export class ProviderSyncService {
2773
3218
  method: 'POST',
2774
3219
  url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
2775
3220
  path: {
2776
- providerName: data.providerName,
3221
+ providerName: data.providerName,
3222
+ region: data.region
3223
+ },
3224
+ body: data.requestBody,
3225
+ mediaType: 'application/json',
3226
+ errors: {
3227
+ 400: 'Invalid request data',
3228
+ 401: 'Missing or invalid authentication',
3229
+ 404: 'Provider not supported'
3230
+ }
3231
+ });
3232
+ }
3233
+
3234
+ /**
3235
+ * Get supported providers
3236
+ * Returns a list of all providers supported by the sync endpoint.
3237
+ * @param data The data for the request.
3238
+ * @param data.region Region code for tenant context
3239
+ * @returns SupportedProvidersResponseDto List of supported providers
3240
+ * @throws ApiError
3241
+ */
3242
+ public static providerSyncControllerGetSupportedProviders(
3243
+ data: ProviderSyncControllerGetSupportedProvidersData
3244
+ ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
3245
+ return __request(OpenAPI, {
3246
+ method: 'GET',
3247
+ url: '/api/v1/{region}/bean/import/provider/supported',
3248
+ path: {
3249
+ region: data.region
3250
+ },
3251
+ errors: {
3252
+ 401: 'Missing or invalid authentication'
3253
+ }
3254
+ });
3255
+ }
3256
+
3257
+ /**
3258
+ * Check if provider is supported
3259
+ * Returns whether a specific provider is supported.
3260
+ * @param data The data for the request.
3261
+ * @param data.providerName Provider name to check
3262
+ * @param data.region Region code for tenant context
3263
+ * @returns unknown Provider support status
3264
+ * @throws ApiError
3265
+ */
3266
+ public static providerSyncControllerIsProviderSupported(
3267
+ data: ProviderSyncControllerIsProviderSupportedData
3268
+ ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
3269
+ return __request(OpenAPI, {
3270
+ method: 'GET',
3271
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3272
+ path: {
3273
+ providerName: data.providerName,
3274
+ region: data.region
3275
+ },
3276
+ errors: {
3277
+ 401: 'Missing or invalid authentication'
3278
+ }
3279
+ });
3280
+ }
3281
+ }
3282
+
3283
+ export class ExternalAccountLinksService {
3284
+ /**
3285
+ * Create an external account → BeanAccount mapping (ADR-0113)
3286
+ * @param data The data for the request.
3287
+ * @param data.region Region code for tenant context
3288
+ * @param data.requestBody
3289
+ * @returns ExternalAccountLinkResponseDto Link created.
3290
+ * @throws ApiError
3291
+ */
3292
+ public static externalAccountLinkControllerCreate(
3293
+ data: ExternalAccountLinkControllerCreateData
3294
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
3295
+ return __request(OpenAPI, {
3296
+ method: 'POST',
3297
+ url: '/api/v1/{region}/bean/external-account-links',
3298
+ path: {
2777
3299
  region: data.region
2778
3300
  },
2779
3301
  body: data.requestBody,
2780
3302
  mediaType: 'application/json',
2781
3303
  errors: {
2782
- 400: 'Invalid request data',
2783
- 401: 'Missing or invalid authentication',
2784
- 404: 'Provider not supported'
3304
+ 422: 'beanAccountId not owned, or an active link already exists.'
2785
3305
  }
2786
3306
  });
2787
3307
  }
2788
3308
 
2789
3309
  /**
2790
- * Get supported providers
2791
- * Returns a list of all providers supported by the sync endpoint.
3310
+ * List the user's active external account links
2792
3311
  * @param data The data for the request.
3312
+ * @param data.provider
2793
3313
  * @param data.region Region code for tenant context
2794
- * @returns SupportedProvidersResponseDto List of supported providers
3314
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
2795
3315
  * @throws ApiError
2796
3316
  */
2797
- public static providerSyncControllerGetSupportedProviders(
2798
- data: ProviderSyncControllerGetSupportedProvidersData
2799
- ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
3317
+ public static externalAccountLinkControllerFindAll(
3318
+ data: ExternalAccountLinkControllerFindAllData
3319
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
2800
3320
  return __request(OpenAPI, {
2801
3321
  method: 'GET',
2802
- url: '/api/v1/{region}/bean/import/provider/supported',
3322
+ url: '/api/v1/{region}/bean/external-account-links',
2803
3323
  path: {
2804
3324
  region: data.region
2805
3325
  },
2806
- errors: {
2807
- 401: 'Missing or invalid authentication'
3326
+ query: {
3327
+ provider: data.provider
2808
3328
  }
2809
3329
  });
2810
3330
  }
2811
3331
 
2812
3332
  /**
2813
- * Check if provider is supported
2814
- * Returns whether a specific provider is supported.
3333
+ * Get a single external account link
2815
3334
  * @param data The data for the request.
2816
- * @param data.providerName Provider name to check
3335
+ * @param data.id
2817
3336
  * @param data.region Region code for tenant context
2818
- * @returns unknown Provider support status
3337
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
2819
3338
  * @throws ApiError
2820
3339
  */
2821
- public static providerSyncControllerIsProviderSupported(
2822
- data: ProviderSyncControllerIsProviderSupportedData
2823
- ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
3340
+ public static externalAccountLinkControllerFindOne(
3341
+ data: ExternalAccountLinkControllerFindOneData
3342
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
2824
3343
  return __request(OpenAPI, {
2825
3344
  method: 'GET',
2826
- url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3345
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
2827
3346
  path: {
2828
- providerName: data.providerName,
3347
+ id: data.id,
2829
3348
  region: data.region
2830
3349
  },
2831
3350
  errors: {
2832
- 401: 'Missing or invalid authentication'
3351
+ 422: 'Link not found or not owned by the user.'
3352
+ }
3353
+ });
3354
+ }
3355
+
3356
+ /**
3357
+ * Soft-delete (disconnect) an external account link
3358
+ * @param data The data for the request.
3359
+ * @param data.id
3360
+ * @param data.region Region code for tenant context
3361
+ * @returns void Link soft-deleted; historical transactions are unaffected.
3362
+ * @throws ApiError
3363
+ */
3364
+ public static externalAccountLinkControllerRemove(
3365
+ data: ExternalAccountLinkControllerRemoveData
3366
+ ): CancelablePromise<ExternalAccountLinkControllerRemoveResponse> {
3367
+ return __request(OpenAPI, {
3368
+ method: 'DELETE',
3369
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3370
+ path: {
3371
+ id: data.id,
3372
+ region: data.region
2833
3373
  }
2834
3374
  });
2835
3375
  }
@@ -2860,6 +3400,54 @@ export class ImportTelemetryService {
2860
3400
  }
2861
3401
  });
2862
3402
  }
3403
+
3404
+ /**
3405
+ * Receive anonymous zero-hit coverage miss report
3406
+ * @param data The data for the request.
3407
+ * @param data.region Region code for tenant context
3408
+ * @param data.requestBody
3409
+ * @returns unknown Coverage miss report received
3410
+ * @throws ApiError
3411
+ */
3412
+ public static telemetryControllerReportCoverageMiss(
3413
+ data: TelemetryControllerReportCoverageMissData
3414
+ ): CancelablePromise<TelemetryControllerReportCoverageMissResponse> {
3415
+ return __request(OpenAPI, {
3416
+ method: 'POST',
3417
+ url: '/api/v1/{region}/bean/import/parser-coverage-miss',
3418
+ path: {
3419
+ region: data.region
3420
+ },
3421
+ body: data.requestBody,
3422
+ mediaType: 'application/json',
3423
+ errors: {
3424
+ 401: 'Unauthorized'
3425
+ }
3426
+ });
3427
+ }
3428
+
3429
+ /**
3430
+ * Coverage metrics (uncovered format aggregation)
3431
+ * @param data The data for the request.
3432
+ * @param data.region Region code for tenant context
3433
+ * @param data.topN Top-N uncovered formats (default 10)
3434
+ * @returns unknown Coverage metrics
3435
+ * @throws ApiError
3436
+ */
3437
+ public static telemetryControllerGetCoverageMetrics(
3438
+ data: TelemetryControllerGetCoverageMetricsData
3439
+ ): CancelablePromise<TelemetryControllerGetCoverageMetricsResponse> {
3440
+ return __request(OpenAPI, {
3441
+ method: 'GET',
3442
+ url: '/api/v1/{region}/bean/import/parser-coverage-metrics',
3443
+ path: {
3444
+ region: data.region
3445
+ },
3446
+ query: {
3447
+ topN: data.topN
3448
+ }
3449
+ });
3450
+ }
2863
3451
  }
2864
3452
 
2865
3453
  export class BeanNlpService {
@@ -2945,6 +3533,121 @@ export class BeanNlpService {
2945
3533
  }
2946
3534
  }
2947
3535
 
3536
+ export class BeanPlatformsService {
3537
+ /**
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
3551
+ * @param data The data for the request.
3552
+ * @param data.requestBody
3553
+ * @returns unknown Platform created successfully
3554
+ * @throws ApiError
3555
+ */
3556
+ public static platformControllerCreate(
3557
+ data: PlatformControllerCreateData
3558
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3559
+ return __request(OpenAPI, {
3560
+ method: 'POST',
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 unknown 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 unknown List of matching platforms with suggested segment names
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,
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
3619
+ },
3620
+ body: data.requestBody,
3621
+ mediaType: 'application/json',
3622
+ errors: {
3623
+ 404: 'Platform not found'
3624
+ }
3625
+ });
3626
+ }
3627
+
3628
+ /**
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
+
2948
3651
  export class DashboardService {
2949
3652
  /**
2950
3653
  * Get net worth overview
@@ -2980,6 +3683,7 @@ export class DashboardService {
2980
3683
  * @param data.region Region code for tenant context
2981
3684
  * @param data.groupBy Grouping strategy
2982
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)
2983
3687
  * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
2984
3688
  * @throws ApiError
2985
3689
  */
@@ -2994,7 +3698,8 @@ export class DashboardService {
2994
3698
  },
2995
3699
  query: {
2996
3700
  groupBy: data.groupBy,
2997
- date: data.date
3701
+ date: data.date,
3702
+ accountId: data.accountId
2998
3703
  },
2999
3704
  errors: {
3000
3705
  401: 'User not authenticated'
@@ -3029,6 +3734,72 @@ export class DashboardService {
3029
3734
  }
3030
3735
  });
3031
3736
  }
3737
+
3738
+ /**
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)
3741
+ * @param data The data for the request.
3742
+ * @param data.region Region code for tenant context
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
3747
+ * @throws ApiError
3748
+ */
3749
+ public static dashboardControllerGetExpenses(
3750
+ data: DashboardControllerGetExpensesData
3751
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3752
+ return __request(OpenAPI, {
3753
+ method: 'GET',
3754
+ url: '/api/v1/{region}/dashboard/expenses',
3755
+ path: {
3756
+ region: data.region
3757
+ },
3758
+ query: {
3759
+ groupBy: data.groupBy,
3760
+ period: data.period,
3761
+ flow: data.flow
3762
+ },
3763
+ errors: {
3764
+ 400: 'Invalid groupBy or period',
3765
+ 401: 'User not authenticated'
3766
+ }
3767
+ });
3768
+ }
3769
+ }
3770
+
3771
+ export class InvestmentService {
3772
+ /**
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).
3775
+ * @param data The data for the request.
3776
+ * @param data.region Region code for tenant context
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
3781
+ * @throws ApiError
3782
+ */
3783
+ public static holdingPnlControllerGetHoldingPnl(
3784
+ data: HoldingPnlControllerGetHoldingPnlData
3785
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3786
+ return __request(OpenAPI, {
3787
+ method: 'GET',
3788
+ url: '/api/v1/{region}/investment/holdings/pnl',
3789
+ path: {
3790
+ region: data.region
3791
+ },
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
+ }
3801
+ });
3802
+ }
3032
3803
  }
3033
3804
 
3034
3805
  export class ReportingService {
@@ -3072,6 +3843,42 @@ export class ReportingService {
3072
3843
  });
3073
3844
  }
3074
3845
 
3846
+ /**
3847
+ * Get cash-flow trends
3848
+ *
3849
+ * Monthly income / expense / netSavings over a fixed N-month window
3850
+ * (current month + N−1 prior). Missing months are zero-filled (flow metric).
3851
+ *
3852
+ * **Parameters:**
3853
+ * - `period`: 1m | 3m | 6m | 1y (default 6m)
3854
+ * - `granularity`: accepted for API symmetry; v1 returns month buckets
3855
+ *
3856
+ * @param data The data for the request.
3857
+ * @param data.region Region code for tenant context
3858
+ * @param data.period Time period
3859
+ * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
3860
+ * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
3861
+ * @throws ApiError
3862
+ */
3863
+ public static reportingControllerGetCashFlowTrends(
3864
+ data: ReportingControllerGetCashFlowTrendsData
3865
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
3866
+ return __request(OpenAPI, {
3867
+ method: 'GET',
3868
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
3869
+ path: {
3870
+ region: data.region
3871
+ },
3872
+ query: {
3873
+ period: data.period,
3874
+ granularity: data.granularity
3875
+ },
3876
+ errors: {
3877
+ 401: 'User not authenticated'
3878
+ }
3879
+ });
3880
+ }
3881
+
3075
3882
  /**
3076
3883
  * Generate portfolio snapshot
3077
3884
  *