@firela/api-types 0.0.0-canary.5fa96f73 → 0.0.0-canary.6124bf97

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,48 @@ import type {
97
99
  CommodityControllerGetOrCreateResponse,
98
100
  CommodityControllerBulkCreateData,
99
101
  CommodityControllerBulkCreateResponse,
102
+ ReportingControllerGetPortfolioTrendsData,
103
+ ReportingControllerGetPortfolioTrendsResponse,
104
+ ReportingControllerGetCashFlowTrendsData,
105
+ ReportingControllerGetCashFlowTrendsResponse,
106
+ ReportingControllerGenerateSnapshotData,
107
+ ReportingControllerGenerateSnapshotResponse,
108
+ ReportingControllerBackfillSnapshotsData,
109
+ ReportingControllerBackfillSnapshotsResponse,
110
+ PriceControllerCreateData,
111
+ PriceControllerCreateResponse,
112
+ PriceControllerFindAllData,
113
+ PriceControllerFindAllResponse,
114
+ PriceControllerFindOneData,
115
+ PriceControllerFindOneResponse,
116
+ PriceControllerUpdateData,
117
+ PriceControllerUpdateResponse,
118
+ PriceControllerDeleteData,
119
+ PriceControllerDeleteResponse,
120
+ PriceControllerBulkCreateData,
121
+ PriceControllerBulkCreateResponse,
122
+ UserControllerDeleteOwnUserData,
123
+ UserControllerDeleteOwnUserResponse,
124
+ UserControllerGetUserData,
125
+ UserControllerGetUserResponse,
126
+ UserControllerSignupUserData,
127
+ UserControllerSignupUserResponse,
128
+ UserControllerDeleteUserData,
129
+ UserControllerDeleteUserResponse,
130
+ UserControllerGetUserInfoData,
131
+ UserControllerGetUserInfoResponse,
132
+ UserControllerUpdateUserSettingData,
133
+ UserControllerUpdateUserSettingResponse,
134
+ UserControllerGetAllUserSettingsByPageData,
135
+ UserControllerGetAllUserSettingsByPageResponse,
136
+ UserControllerGetAssetLiabilitySummaryResponse,
137
+ PropertyControllerGetAllResponse,
138
+ PropertyControllerGetByKeyData,
139
+ PropertyControllerGetByKeyResponse,
140
+ PropertyControllerUpdateData,
141
+ PropertyControllerUpdateResponse,
142
+ PropertyControllerDeleteData,
143
+ PropertyControllerDeleteResponse,
100
144
  RecurringRuleControllerCreateData,
101
145
  RecurringRuleControllerCreateResponse,
102
146
  RecurringRuleControllerFindAllData,
@@ -149,28 +193,8 @@ import type {
149
193
  TransactionRuleControllerDeleteResponse,
150
194
  TransactionRuleControllerTestData,
151
195
  TransactionRuleControllerTestResponse,
152
- UserControllerDeleteOwnUserData,
153
- UserControllerDeleteOwnUserResponse,
154
- UserControllerGetUserData,
155
- UserControllerGetUserResponse,
156
- UserControllerSignupUserData,
157
- UserControllerSignupUserResponse,
158
- UserControllerDeleteUserData,
159
- UserControllerDeleteUserResponse,
160
- UserControllerGetUserInfoData,
161
- UserControllerGetUserInfoResponse,
162
- UserControllerUpdateUserSettingData,
163
- UserControllerUpdateUserSettingResponse,
164
- UserControllerGetAllUserSettingsByPageData,
165
- UserControllerGetAllUserSettingsByPageResponse,
166
- UserControllerGetAssetLiabilitySummaryResponse,
167
- PropertyControllerGetAllResponse,
168
- PropertyControllerGetByKeyData,
169
- PropertyControllerGetByKeyResponse,
170
- PropertyControllerUpdateData,
171
- PropertyControllerUpdateResponse,
172
- PropertyControllerDeleteData,
173
- PropertyControllerDeleteResponse,
196
+ CategoryCatalogControllerListData,
197
+ CategoryCatalogControllerListResponse,
174
198
  EventControllerCreateData,
175
199
  EventControllerCreateResponse,
176
200
  EventControllerFindAllData,
@@ -183,6 +207,16 @@ import type {
183
207
  EventControllerDeleteResponse,
184
208
  EventControllerGetSliceData,
185
209
  EventControllerGetSliceResponse,
210
+ OnboardingControllerBootstrapData,
211
+ OnboardingControllerBootstrapResponse,
212
+ ReconciliationControllerComputeData,
213
+ ReconciliationControllerComputeResponse,
214
+ ReconciliationControllerAssertData,
215
+ ReconciliationControllerAssertResponse,
216
+ ReconciliationControllerPadData,
217
+ ReconciliationControllerPadResponse,
218
+ ReconciliationControllerHistoryData,
219
+ ReconciliationControllerHistoryResponse,
186
220
  ExportControllerExportBeancountResponse,
187
221
  FileImportControllerImportFileData,
188
222
  FileImportControllerImportFileResponse,
@@ -196,22 +230,20 @@ import type {
196
230
  ImporterConfigControllerUpdateConfigResponse,
197
231
  ImporterConfigControllerResetConfigData,
198
232
  ImporterConfigControllerResetConfigResponse,
199
- PlatformControllerFindAllResponse,
200
- PlatformControllerCreateData,
201
- PlatformControllerCreateResponse,
202
- PlatformControllerGetPlatformListResponse,
203
- PlatformControllerMatchPlatformsData,
204
- PlatformControllerMatchPlatformsResponse,
205
- PlatformControllerUpdateData,
206
- PlatformControllerUpdateResponse,
207
- PlatformControllerDeleteData,
208
- PlatformControllerDeleteResponse,
209
233
  ProviderSyncControllerSyncData,
210
234
  ProviderSyncControllerSyncResponse,
211
235
  ProviderSyncControllerGetSupportedProvidersData,
212
236
  ProviderSyncControllerGetSupportedProvidersResponse,
213
237
  ProviderSyncControllerIsProviderSupportedData,
214
238
  ProviderSyncControllerIsProviderSupportedResponse,
239
+ ExternalAccountLinkControllerCreateData,
240
+ ExternalAccountLinkControllerCreateResponse,
241
+ ExternalAccountLinkControllerFindAllData,
242
+ ExternalAccountLinkControllerFindAllResponse,
243
+ ExternalAccountLinkControllerFindOneData,
244
+ ExternalAccountLinkControllerFindOneResponse,
245
+ ExternalAccountLinkControllerRemoveData,
246
+ ExternalAccountLinkControllerRemoveResponse,
215
247
  TelemetryControllerReportTelemetryData,
216
248
  TelemetryControllerReportTelemetryResponse,
217
249
  TelemetryControllerReportCoverageMissData,
@@ -224,6 +256,19 @@ import type {
224
256
  NlpControllerClearSessionResponse,
225
257
  NlpControllerGetSessionData,
226
258
  NlpControllerGetSessionResponse,
259
+ PlatformControllerFindAllResponse,
260
+ PlatformControllerCreateData,
261
+ PlatformControllerCreateResponse,
262
+ PlatformControllerGetPlatformListData,
263
+ PlatformControllerGetPlatformListResponse,
264
+ PlatformControllerMatchPlatformsData,
265
+ PlatformControllerMatchPlatformsResponse,
266
+ PlatformControllerGetPlatformStandardsData,
267
+ PlatformControllerGetPlatformStandardsResponse,
268
+ PlatformControllerUpdateData,
269
+ PlatformControllerUpdateResponse,
270
+ PlatformControllerDeleteData,
271
+ PlatformControllerDeleteResponse,
227
272
  DashboardControllerGetNetWorthData,
228
273
  DashboardControllerGetNetWorthResponse,
229
274
  DashboardControllerGetAccountsData,
@@ -234,29 +279,11 @@ import type {
234
279
  DashboardControllerGetExpensesResponse,
235
280
  HoldingPnlControllerGetHoldingPnlData,
236
281
  HoldingPnlControllerGetHoldingPnlResponse,
237
- PriceControllerCreateData,
238
- PriceControllerCreateResponse,
239
- PriceControllerFindAllData,
240
- PriceControllerFindAllResponse,
241
- PriceControllerFindOneData,
242
- PriceControllerFindOneResponse,
243
- PriceControllerUpdateData,
244
- PriceControllerUpdateResponse,
245
- PriceControllerDeleteData,
246
- PriceControllerDeleteResponse,
247
- PriceControllerBulkCreateData,
248
- PriceControllerBulkCreateResponse,
249
- ReportingControllerGetPortfolioTrendsData,
250
- ReportingControllerGetPortfolioTrendsResponse,
251
- ReportingControllerGetCashFlowTrendsData,
252
- ReportingControllerGetCashFlowTrendsResponse,
253
- ReportingControllerGenerateSnapshotData,
254
- ReportingControllerGenerateSnapshotResponse,
255
- ReportingControllerBackfillSnapshotsData,
256
- ReportingControllerBackfillSnapshotsResponse,
257
282
  ApiKeysControllerCreateApiKeyResponse,
258
283
  AuthControllerAccessTokenLoginData,
259
284
  AuthControllerAccessTokenLoginResponse,
285
+ ParserContributionControllerCreateData,
286
+ ParserContributionControllerCreateResponse,
260
287
  CacheControllerFlushCacheResponse,
261
288
  ExchangeRateControllerGetExchangeRateData,
262
289
  ExchangeRateControllerGetExchangeRateResponse,
@@ -268,7 +295,11 @@ import type {
268
295
  HealthControllerResetCircuitBreakerData,
269
296
  HealthControllerResetCircuitBreakerResponse,
270
297
  HealthControllerGetMetricsResponse,
271
- InfoControllerGetInfoResponse
298
+ InfoControllerGetInfoResponse,
299
+ SymbolControllerSearchData,
300
+ SymbolControllerSearchResponse,
301
+ SymbolControllerGetQuoteData,
302
+ SymbolControllerGetQuoteResponse
272
303
  } from './types.gen';
273
304
 
274
305
  export class BeanAccountsService {
@@ -306,7 +337,7 @@ export class BeanAccountsService {
306
337
  * @param data.type Filter by account type
307
338
  * @param data.status Filter by status
308
339
  * @param data.isCustom Filter by custom (user-created) accounts only
309
- * @param data.search Search term for path or i18nKey
340
+ * @param data.search Search term matched against account path and user-set display name (case-insensitive)
310
341
  * @param data.limit Maximum number of results
311
342
  * @param data.offset Number of results to skip
312
343
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -387,7 +418,7 @@ export class BeanAccountsService {
387
418
 
388
419
  /**
389
420
  * Delete account
390
- * Deletes an account (only if no transactions)
421
+ * Deletes an account (only if no active transactions; voided/superseded residual postings are cleaned up)
391
422
  * @param data The data for the request.
392
423
  * @param data.id Account UUID
393
424
  * @param data.region Region code for tenant context
@@ -406,7 +437,7 @@ export class BeanAccountsService {
406
437
  },
407
438
  errors: {
408
439
  404: 'Account not found',
409
- 409: 'Account has transactions and cannot be deleted'
440
+ 409: 'Account has active transactions and cannot be deleted'
410
441
  }
411
442
  });
412
443
  }
@@ -468,16 +499,45 @@ export class BeanAccountsService {
468
499
  }
469
500
  });
470
501
  }
502
+
503
+ /**
504
+ * Post an opening-balance transaction
505
+ * 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.
506
+ * @param data The data for the request.
507
+ * @param data.id Account UUID
508
+ * @param data.region Region code for tenant context
509
+ * @param data.requestBody
510
+ * @returns OpeningBalanceResultDto Opening-balance transaction created
511
+ * @throws ApiError
512
+ */
513
+ public static accountControllerAddOpeningBalance(
514
+ data: AccountControllerAddOpeningBalanceData
515
+ ): CancelablePromise<AccountControllerAddOpeningBalanceResponse> {
516
+ return __request(OpenAPI, {
517
+ method: 'POST',
518
+ url: '/api/v1/{region}/bean/accounts/{id}/opening-balance',
519
+ path: {
520
+ id: data.id,
521
+ region: data.region
522
+ },
523
+ body: data.requestBody,
524
+ mediaType: 'application/json',
525
+ errors: {
526
+ 404: 'Account not found',
527
+ 409: 'An opening balance already exists for this account'
528
+ }
529
+ });
530
+ }
471
531
  }
472
532
 
473
533
  export class BeanAccountStandardsService {
474
534
  /**
475
535
  * Get account templates
476
- * Returns predefined account templates for a region. Supports filtering by account type and search term.
536
+ * Returns predefined account templates for a region. Supports filtering by account type and search term. Not-yet-open region codes return the universal-only catalog (#759).
477
537
  * @param data The data for the request.
478
- * @param data.region Region code (cn, us, de)
538
+ * @param data.region Region code (any ISO alpha-2; not-yet-open codes return the universal-only catalog)
479
539
  * @param data.type Filter by account type
480
- * @param data.search Search term for path or description
540
+ * @param data.search Search term for path, description, aliases, or localized display name
481
541
  * @returns AccountStandardListResponseDto Account templates retrieved successfully
482
542
  * @throws ApiError
483
543
  */
@@ -499,9 +559,9 @@ export class BeanAccountStandardsService {
499
559
 
500
560
  /**
501
561
  * Get template metadata for an account path
502
- * Returns extendable status and root type for a template path.
562
+ * Returns root type for a template path.
503
563
  * @param data The data for the request.
504
- * @param data.region Region code for tenant context
564
+ * @param data.region Region code for tenant context. Not-yet-open codes degrade to the universal-only catalog (#759)
505
565
  * @param data.path Account path to check
506
566
  * @returns TemplateMetadataResponseDto Template metadata retrieved successfully
507
567
  * @throws ApiError
@@ -523,9 +583,9 @@ export class BeanAccountStandardsService {
523
583
 
524
584
  /**
525
585
  * Get available regions with hierarchy
526
- * Returns supported regions with inheritance metadata
586
+ * Returns the full region catalog (every ISO 3166-1 entry) with an 'open' flag and inheritance metadata (#759)
527
587
  * @param data The data for the request.
528
- * @param data.region Region code for tenant context
588
+ * @param data.region Region code for tenant context. Not-yet-open codes degrade to the universal-only catalog (#759)
529
589
  * @returns RegionsMetadataResponseDto Regions metadata retrieved successfully
530
590
  * @throws ApiError
531
591
  */
@@ -582,10 +642,11 @@ export class BeanTransactionsService {
582
642
  * @param data.offset Number of items to skip (default: 0)
583
643
  * @param data.dateFrom Filter by start date (inclusive), format: YYYY-MM-DD
584
644
  * @param data.dateTo Filter by end date (inclusive), format: YYYY-MM-DD
585
- * @param data.status Filter by transaction status
645
+ * @param data.status Filter by transaction status: single value, comma-separated multi-value (e.g. VOIDED,SUPERSEDED), or ALL to include audit rows. Defaults to ACTIVE-only (ADR-0128; previously unfiltered — breaking change).
586
646
  * @param data.search Search in narration and payee fields (max 200 chars)
587
647
  * @param data.accountId Filter by account ID (transactions with postings to this account)
588
- * @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
648
+ * @param data.category Filter by ADR-0075 functional category (Group segment); matches any posting to an account whose derived Group segment equals this value. Must be accompanied by flow (ADR-0126).
649
+ * @param data.flow Required when category is present (400 otherwise) and vice versa (ADR-0126). Restricts the category account set to the flow root (income → Income:, expense → Expenses:) and drives the per-leg sign normalization of row viewpointAmount and the summary. OpenAPI cannot express conditional requiredness — the pairing is enforced at runtime.
589
650
  * @returns TransactionListResponseDto Transaction list
590
651
  * @throws ApiError
591
652
  */
@@ -606,7 +667,8 @@ export class BeanTransactionsService {
606
667
  status: data.status,
607
668
  search: data.search,
608
669
  accountId: data.accountId,
609
- category: data.category
670
+ category: data.category,
671
+ flow: data.flow
610
672
  },
611
673
  errors: {
612
674
  400: 'Validation failed',
@@ -794,7 +856,7 @@ export class BeanBalancesService {
794
856
  * Query account balance
795
857
  * Calculate account balance at a specific date for a single currency
796
858
  * @param data The data for the request.
797
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
859
+ * @param data.account Account name (e.g., "Assets:Checking")
798
860
  * @param data.region Region code for tenant context
799
861
  * @param data.date Date to calculate balance at (ISO 8601 format)
800
862
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -1319,7 +1381,7 @@ export class AdminPayeeProfilesService {
1319
1381
  * Removes verification status by setting verifiedAt to null.
1320
1382
  * @param data The data for the request.
1321
1383
  * @param data.id Payee profile ID (UUID)
1322
- * @returns PayeeProfileResponseDto Payee profile unverified successfully
1384
+ * @returns void Payee profile unverified successfully
1323
1385
  * @throws ApiError
1324
1386
  */
1325
1387
  public static payeeProfileAdminControllerUnverify(
@@ -1515,361 +1577,940 @@ export class BeanCommoditiesService {
1515
1577
  }
1516
1578
  }
1517
1579
 
1518
- export class RecurringRulesService {
1580
+ export class ReportingService {
1519
1581
  /**
1520
- * Create a new recurring rule
1521
- * Creates a new recurring transaction rule for the authenticated user
1582
+ * Get portfolio value trends
1583
+ *
1584
+ * Returns time series data of portfolio net worth.
1585
+ *
1586
+ * **Multi-currency Support:**
1587
+ * - `series[].byCurrency` - Currency breakdown for each data point
1588
+ * - `byCurrency` - Separate time series grouped by currency
1589
+ * - `warnings` - Exchange rate warnings if conversion failed
1590
+ *
1591
+ * **Parameters:**
1592
+ * - `period`: Time period (1m, 3m, 6m, 1y)
1593
+ * - `granularity`: Data granularity (day, week, month)
1594
+ *
1522
1595
  * @param data The data for the request.
1523
1596
  * @param data.region Region code for tenant context
1524
- * @param data.requestBody
1525
- * @returns RecurringRuleResponseDto Rule created successfully
1597
+ * @param data.period Time period
1598
+ * @param data.granularity Data granularity
1599
+ * @returns PortfolioTrendsResponseDto Trends retrieved successfully
1526
1600
  * @throws ApiError
1527
1601
  */
1528
- public static recurringRuleControllerCreate(
1529
- data: RecurringRuleControllerCreateData
1530
- ): CancelablePromise<RecurringRuleControllerCreateResponse> {
1602
+ public static reportingControllerGetPortfolioTrends(
1603
+ data: ReportingControllerGetPortfolioTrendsData
1604
+ ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
1531
1605
  return __request(OpenAPI, {
1532
- method: 'POST',
1533
- url: '/api/v1/{region}/bean/recurring-rules',
1606
+ method: 'GET',
1607
+ url: '/api/v1/{region}/reporting/portfolio/trends',
1534
1608
  path: {
1535
1609
  region: data.region
1536
1610
  },
1537
- body: data.requestBody,
1538
- mediaType: 'application/json',
1611
+ query: {
1612
+ period: data.period,
1613
+ granularity: data.granularity
1614
+ },
1539
1615
  errors: {
1540
- 400: 'Invalid input data (e.g., autoCreate without accounts)',
1541
- 409: 'Rule with same name already exists'
1616
+ 401: 'User not authenticated'
1542
1617
  }
1543
1618
  });
1544
1619
  }
1545
1620
 
1546
1621
  /**
1547
- * List recurring rules
1548
- * Returns all recurring rules for the authenticated user with optional filtering
1622
+ * Get cash-flow trends
1623
+ *
1624
+ * Monthly income / expense / netSavings over a fixed N-month window
1625
+ * (current month + N−1 prior). Missing months are zero-filled (flow metric).
1626
+ *
1627
+ * **Parameters:**
1628
+ * - `period`: 1m | 3m | 6m | 1y (default 6m)
1629
+ * - `granularity`: accepted for API symmetry; v1 returns month buckets
1630
+ *
1549
1631
  * @param data The data for the request.
1550
1632
  * @param data.region Region code for tenant context
1551
- * @param data.isActive Filter by active status
1552
- * @param data.frequency Filter by frequency (WEEKLY, MONTHLY, etc.)
1553
- * @param data.hasAutoCreate Filter by autoCreate enabled
1554
- * @returns RecurringRuleResponseDto Rules retrieved successfully
1633
+ * @param data.period Time period
1634
+ * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
1635
+ * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
1555
1636
  * @throws ApiError
1556
1637
  */
1557
- public static recurringRuleControllerFindAll(
1558
- data: RecurringRuleControllerFindAllData
1559
- ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
1638
+ public static reportingControllerGetCashFlowTrends(
1639
+ data: ReportingControllerGetCashFlowTrendsData
1640
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
1560
1641
  return __request(OpenAPI, {
1561
1642
  method: 'GET',
1562
- url: '/api/v1/{region}/bean/recurring-rules',
1643
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
1563
1644
  path: {
1564
1645
  region: data.region
1565
1646
  },
1566
1647
  query: {
1567
- isActive: data.isActive,
1568
- frequency: data.frequency,
1569
- hasAutoCreate: data.hasAutoCreate
1648
+ period: data.period,
1649
+ granularity: data.granularity
1650
+ },
1651
+ errors: {
1652
+ 401: 'User not authenticated'
1570
1653
  }
1571
1654
  });
1572
1655
  }
1573
1656
 
1574
1657
  /**
1575
- * Create recurring rule from transaction
1576
- * Auto-creates a recurring rule using transaction data. User only confirms frequency.
1658
+ * Generate portfolio snapshot
1659
+ *
1660
+ * Manually generate a portfolio snapshot for a specific date.
1661
+ *
1662
+ * **Multi-currency Support:**
1663
+ * - Fetches balances grouped by currency
1664
+ * - Uses user's baseCurrency setting for conversion
1665
+ * - Stores exchange rates and warnings
1666
+ *
1667
+ * **Use Cases:**
1668
+ * - Testing snapshot generation
1669
+ * - Force regeneration after data correction
1670
+ * - Initial setup for new users
1671
+ *
1577
1672
  * @param data The data for the request.
1578
- * @param data.transactionId Source transaction ID
1579
1673
  * @param data.region Region code for tenant context
1580
- * @param data.requestBody
1581
- * @returns RecurringRuleResponseDto Rule created successfully
1674
+ * @param data.requestBody Optional date (defaults to today)
1675
+ * @returns GenerateSnapshotResponse Snapshot generated successfully
1582
1676
  * @throws ApiError
1583
1677
  */
1584
- public static recurringRuleControllerCreateFromTransaction(
1585
- data: RecurringRuleControllerCreateFromTransactionData
1586
- ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
1678
+ public static reportingControllerGenerateSnapshot(
1679
+ data: ReportingControllerGenerateSnapshotData
1680
+ ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
1587
1681
  return __request(OpenAPI, {
1588
1682
  method: 'POST',
1589
- url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
1683
+ url: '/api/v1/{region}/reporting/snapshots/generate',
1590
1684
  path: {
1591
- transactionId: data.transactionId,
1592
1685
  region: data.region
1593
1686
  },
1594
1687
  body: data.requestBody,
1595
1688
  mediaType: 'application/json',
1596
1689
  errors: {
1597
- 404: 'Transaction not found',
1598
- 409: 'Rule with same name already exists or transaction already linked'
1690
+ 400: 'Invalid date format',
1691
+ 401: 'User not authenticated'
1599
1692
  }
1600
1693
  });
1601
1694
  }
1602
1695
 
1603
1696
  /**
1604
- * Get recurring rule by ID
1605
- * Returns a specific recurring rule with its details
1697
+ * Backfill portfolio snapshots
1698
+ *
1699
+ * Generate snapshots for a date range (historical data backfill).
1700
+ *
1701
+ * **Multi-currency Support:**
1702
+ * - Each snapshot includes multi-currency data
1703
+ * - Uses exchange rates available at generation time
1704
+ * - Warnings stored for missing exchange rates
1705
+ *
1706
+ * **Best Practices:**
1707
+ * - Use for initial setup after account configuration
1708
+ * - Run during low-traffic periods for large date ranges
1709
+ * - Existing snapshots are skipped (not regenerated)
1710
+ *
1606
1711
  * @param data The data for the request.
1607
- * @param data.id Rule ID
1608
1712
  * @param data.region Region code for tenant context
1609
- * @returns RecurringRuleResponseDto Rule retrieved successfully
1713
+ * @param data.requestBody
1714
+ * @returns BackfillSnapshotsResponse Backfill completed successfully
1610
1715
  * @throws ApiError
1611
1716
  */
1612
- public static recurringRuleControllerFindOne(
1613
- data: RecurringRuleControllerFindOneData
1614
- ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
1717
+ public static reportingControllerBackfillSnapshots(
1718
+ data: ReportingControllerBackfillSnapshotsData
1719
+ ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
1615
1720
  return __request(OpenAPI, {
1616
- method: 'GET',
1617
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
1721
+ method: 'POST',
1722
+ url: '/api/v1/{region}/reporting/snapshots/backfill',
1618
1723
  path: {
1619
- id: data.id,
1620
1724
  region: data.region
1621
1725
  },
1726
+ body: data.requestBody,
1727
+ mediaType: 'application/json',
1622
1728
  errors: {
1623
- 404: 'Rule not found'
1729
+ 400: 'Invalid date format or range',
1730
+ 401: 'User not authenticated',
1731
+ 409: 'Backfill already in progress for this user'
1624
1732
  }
1625
1733
  });
1626
1734
  }
1735
+ }
1627
1736
 
1737
+ export class BeanPricesService {
1628
1738
  /**
1629
- * Update recurring rule
1630
- * Updates an existing recurring rule
1739
+ * Create a new price
1740
+ * Creates a new price entry for the authenticated user
1631
1741
  * @param data The data for the request.
1632
- * @param data.id Rule ID
1633
1742
  * @param data.region Region code for tenant context
1634
1743
  * @param data.requestBody
1635
- * @returns RecurringRuleResponseDto Rule updated successfully
1744
+ * @returns PriceResponseDto Price created successfully
1636
1745
  * @throws ApiError
1637
1746
  */
1638
- public static recurringRuleControllerUpdate(
1639
- data: RecurringRuleControllerUpdateData
1640
- ): CancelablePromise<RecurringRuleControllerUpdateResponse> {
1747
+ public static priceControllerCreate(
1748
+ data: PriceControllerCreateData
1749
+ ): CancelablePromise<PriceControllerCreateResponse> {
1641
1750
  return __request(OpenAPI, {
1642
- method: 'PATCH',
1643
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
1751
+ method: 'POST',
1752
+ url: '/api/v1/{region}/bean/prices',
1644
1753
  path: {
1645
- id: data.id,
1646
1754
  region: data.region
1647
1755
  },
1648
1756
  body: data.requestBody,
1649
1757
  mediaType: 'application/json',
1650
1758
  errors: {
1651
- 400: 'Invalid input data',
1652
- 404: 'Rule not found'
1759
+ 404: 'Currency or quoteCurrency commodity not found',
1760
+ 409: 'Price already exists for this currency pair and date'
1653
1761
  }
1654
1762
  });
1655
1763
  }
1656
1764
 
1657
1765
  /**
1658
- * Delete recurring rule
1659
- * Soft deletes a recurring rule (sets isActive to false)
1766
+ * List user prices
1767
+ * Returns all price entries for the authenticated user with optional filtering
1660
1768
  * @param data The data for the request.
1661
- * @param data.id Rule ID
1662
1769
  * @param data.region Region code for tenant context
1663
- * @returns void Rule deleted successfully
1770
+ * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
1771
+ * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
1772
+ * @param data.dateFrom Filter prices from this date (ISO 8601 format)
1773
+ * @param data.dateTo Filter prices to this date (ISO 8601 format)
1774
+ * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
1775
+ * @param data.page Page number for pagination (default: 1)
1776
+ * @param data.limit Number of items per page (default: 20, max: 100)
1777
+ * @returns PriceListResponseDto Prices retrieved successfully
1664
1778
  * @throws ApiError
1665
1779
  */
1666
- public static recurringRuleControllerDelete(
1667
- data: RecurringRuleControllerDeleteData
1668
- ): CancelablePromise<RecurringRuleControllerDeleteResponse> {
1780
+ public static priceControllerFindAll(
1781
+ data: PriceControllerFindAllData
1782
+ ): CancelablePromise<PriceControllerFindAllResponse> {
1669
1783
  return __request(OpenAPI, {
1670
- method: 'DELETE',
1671
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
1784
+ method: 'GET',
1785
+ url: '/api/v1/{region}/bean/prices',
1672
1786
  path: {
1673
- id: data.id,
1674
1787
  region: data.region
1675
1788
  },
1676
- errors: {
1677
- 404: 'Rule not found'
1789
+ query: {
1790
+ currency: data.currency,
1791
+ quoteCurrency: data.quoteCurrency,
1792
+ dateFrom: data.dateFrom,
1793
+ dateTo: data.dateTo,
1794
+ search: data.search,
1795
+ page: data.page,
1796
+ limit: data.limit
1678
1797
  }
1679
1798
  });
1680
1799
  }
1681
1800
 
1682
1801
  /**
1683
- * Get rule with statistics
1684
- * Returns a rule with pending/overdue counts and next expected date
1802
+ * Get price by ID
1803
+ * Returns a single price entry by its ID
1685
1804
  * @param data The data for the request.
1686
- * @param data.id Rule ID
1805
+ * @param data.id Price ID
1687
1806
  * @param data.region Region code for tenant context
1688
- * @returns RecurringRuleWithStatsResponseDto Rule with stats retrieved successfully
1807
+ * @returns PriceResponseDto Price retrieved successfully
1689
1808
  * @throws ApiError
1690
1809
  */
1691
- public static recurringRuleControllerGetWithStats(
1692
- data: RecurringRuleControllerGetWithStatsData
1693
- ): CancelablePromise<RecurringRuleControllerGetWithStatsResponse> {
1810
+ public static priceControllerFindOne(
1811
+ data: PriceControllerFindOneData
1812
+ ): CancelablePromise<PriceControllerFindOneResponse> {
1694
1813
  return __request(OpenAPI, {
1695
1814
  method: 'GET',
1696
- url: '/api/v1/{region}/bean/recurring-rules/{id}/stats',
1815
+ url: '/api/v1/{region}/bean/prices/{id}',
1697
1816
  path: {
1698
1817
  id: data.id,
1699
1818
  region: data.region
1700
1819
  },
1701
1820
  errors: {
1702
- 404: 'Rule not found'
1821
+ 404: 'Price not found'
1703
1822
  }
1704
1823
  });
1705
1824
  }
1706
- }
1707
1825
 
1708
- export class ExpectedTransactionsService {
1709
1826
  /**
1710
- * List expected transactions
1711
- * Returns expected transactions for the authenticated user with optional filtering
1827
+ * Update a price
1828
+ * Updates an existing price entry
1712
1829
  * @param data The data for the request.
1830
+ * @param data.id Price ID
1713
1831
  * @param data.region Region code for tenant context
1714
- * @param data.ruleId Filter by recurring rule ID
1715
- * @param data.status Filter by status (PENDING, COMPLETED, SKIPPED)
1716
- * @param data.fromDate Filter by date range start (YYYY-MM-DD)
1717
- * @param data.toDate Filter by date range end (YYYY-MM-DD)
1718
- * @returns ExpectedTransactionListResponseDto Expected transactions retrieved successfully
1832
+ * @param data.requestBody
1833
+ * @returns PriceResponseDto Price updated successfully
1719
1834
  * @throws ApiError
1720
1835
  */
1721
- public static expectedTransactionControllerFindAll(
1722
- data: ExpectedTransactionControllerFindAllData
1723
- ): CancelablePromise<ExpectedTransactionControllerFindAllResponse> {
1836
+ public static priceControllerUpdate(
1837
+ data: PriceControllerUpdateData
1838
+ ): CancelablePromise<PriceControllerUpdateResponse> {
1724
1839
  return __request(OpenAPI, {
1725
- method: 'GET',
1726
- url: '/api/v1/{region}/bean/expected-transactions',
1840
+ method: 'PUT',
1841
+ url: '/api/v1/{region}/bean/prices/{id}',
1727
1842
  path: {
1843
+ id: data.id,
1728
1844
  region: data.region
1729
1845
  },
1730
- query: {
1731
- ruleId: data.ruleId,
1732
- status: data.status,
1733
- fromDate: data.fromDate,
1734
- toDate: data.toDate
1846
+ body: data.requestBody,
1847
+ mediaType: 'application/json',
1848
+ errors: {
1849
+ 404: 'Price not found',
1850
+ 409: 'Updated price conflicts with existing price'
1735
1851
  }
1736
1852
  });
1737
1853
  }
1738
1854
 
1739
1855
  /**
1740
- * List overdue expected transactions
1741
- * Returns all overdue expected transactions (PENDING past tolerance)
1856
+ * Delete a price
1857
+ * Deletes a price entry (hard delete)
1742
1858
  * @param data The data for the request.
1859
+ * @param data.id Price ID
1743
1860
  * @param data.region Region code for tenant context
1744
- * @returns ExpectedTransactionListResponseDto Overdue transactions retrieved successfully
1861
+ * @returns void Price deleted successfully
1745
1862
  * @throws ApiError
1746
1863
  */
1747
- public static expectedTransactionControllerFindOverdue(
1748
- data: ExpectedTransactionControllerFindOverdueData
1749
- ): CancelablePromise<ExpectedTransactionControllerFindOverdueResponse> {
1864
+ public static priceControllerDelete(
1865
+ data: PriceControllerDeleteData
1866
+ ): CancelablePromise<PriceControllerDeleteResponse> {
1750
1867
  return __request(OpenAPI, {
1751
- method: 'GET',
1752
- url: '/api/v1/{region}/bean/expected-transactions/overdue',
1868
+ method: 'DELETE',
1869
+ url: '/api/v1/{region}/bean/prices/{id}',
1753
1870
  path: {
1871
+ id: data.id,
1754
1872
  region: data.region
1873
+ },
1874
+ errors: {
1875
+ 404: 'Price not found'
1755
1876
  }
1756
1877
  });
1757
1878
  }
1758
1879
 
1759
1880
  /**
1760
- * Get expected transaction by ID
1761
- * Returns a specific expected transaction with rule details
1881
+ * Bulk create prices
1882
+ * Creates multiple price entries at once (skips duplicates)
1762
1883
  * @param data The data for the request.
1763
- * @param data.id Expected transaction ID
1764
1884
  * @param data.region Region code for tenant context
1765
- * @returns ExpectedTransactionResponseDto Expected transaction retrieved successfully
1885
+ * @param data.requestBody
1886
+ * @returns PriceResponseDto Prices created successfully
1766
1887
  * @throws ApiError
1767
1888
  */
1768
- public static expectedTransactionControllerFindOne(
1769
- data: ExpectedTransactionControllerFindOneData
1770
- ): CancelablePromise<ExpectedTransactionControllerFindOneResponse> {
1889
+ public static priceControllerBulkCreate(
1890
+ data: PriceControllerBulkCreateData
1891
+ ): CancelablePromise<PriceControllerBulkCreateResponse> {
1771
1892
  return __request(OpenAPI, {
1772
- method: 'GET',
1773
- url: '/api/v1/{region}/bean/expected-transactions/{id}',
1893
+ method: 'POST',
1894
+ url: '/api/v1/{region}/bean/prices/bulk',
1774
1895
  path: {
1775
- id: data.id,
1776
1896
  region: data.region
1777
1897
  },
1778
- errors: {
1779
- 404: 'Expected transaction not found'
1780
- }
1898
+ body: data.requestBody,
1899
+ mediaType: 'application/json'
1781
1900
  });
1782
1901
  }
1902
+ }
1783
1903
 
1904
+ export class UsersService {
1784
1905
  /**
1785
- * Skip expected transaction
1786
- * Marks an expected transaction as skipped (PENDING -> SKIPPED)
1906
+ * Delete own user account
1787
1907
  * @param data The data for the request.
1788
- * @param data.id Expected transaction ID
1789
- * @param data.region Region code for tenant context
1790
- * @returns ExpectedTransactionResponseDto Expected transaction skipped successfully
1908
+ * @param data.requestBody
1909
+ * @returns void User deleted successfully
1791
1910
  * @throws ApiError
1792
1911
  */
1793
- public static expectedTransactionControllerSkip(
1794
- data: ExpectedTransactionControllerSkipData
1795
- ): CancelablePromise<ExpectedTransactionControllerSkipResponse> {
1912
+ public static userControllerDeleteOwnUser(
1913
+ data: UserControllerDeleteOwnUserData
1914
+ ): CancelablePromise<UserControllerDeleteOwnUserResponse> {
1796
1915
  return __request(OpenAPI, {
1797
- method: 'POST',
1798
- url: '/api/v1/{region}/bean/expected-transactions/{id}/skip',
1799
- path: {
1800
- id: data.id,
1801
- region: data.region
1802
- },
1916
+ method: 'DELETE',
1917
+ url: '/api/v1/users',
1918
+ body: data.requestBody,
1919
+ mediaType: 'application/json',
1803
1920
  errors: {
1804
- 400: 'Cannot skip - not in PENDING status',
1805
- 404: 'Expected transaction not found'
1921
+ 403: 'Invalid access token'
1806
1922
  }
1807
1923
  });
1808
1924
  }
1809
1925
 
1810
1926
  /**
1811
- * Undo skip
1812
- * Reverses a skip operation (SKIPPED -> PENDING)
1927
+ * Get current authenticated user
1813
1928
  * @param data The data for the request.
1814
- * @param data.id Expected transaction ID
1815
- * @param data.region Region code for tenant context
1816
- * @returns ExpectedTransactionResponseDto Skip undone successfully
1929
+ * @param data.acceptLanguage
1930
+ * @returns UserResponseDto User retrieved successfully
1817
1931
  * @throws ApiError
1818
1932
  */
1819
- public static expectedTransactionControllerUndoSkip(
1820
- data: ExpectedTransactionControllerUndoSkipData
1821
- ): CancelablePromise<ExpectedTransactionControllerUndoSkipResponse> {
1933
+ public static userControllerGetUser(
1934
+ data: UserControllerGetUserData
1935
+ ): CancelablePromise<UserControllerGetUserResponse> {
1822
1936
  return __request(OpenAPI, {
1823
- method: 'DELETE',
1824
- url: '/api/v1/{region}/bean/expected-transactions/{id}/skip',
1825
- path: {
1826
- id: data.id,
1827
- region: data.region
1828
- },
1829
- errors: {
1830
- 400: 'Cannot undo - not in SKIPPED status',
1831
- 404: 'Expected transaction not found'
1937
+ method: 'GET',
1938
+ url: '/api/v1/users',
1939
+ headers: {
1940
+ 'accept-language': data.acceptLanguage
1832
1941
  }
1833
1942
  });
1834
1943
  }
1835
1944
 
1836
1945
  /**
1837
- * Confirm transaction match
1838
- * Manually matches an expected transaction with an actual transaction
1946
+ * Sign up new user
1947
+ * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
1839
1948
  * @param data The data for the request.
1840
- * @param data.id Expected transaction ID
1841
- * @param data.region Region code for tenant context
1842
1949
  * @param data.requestBody
1843
- * @returns unknown Match confirmed successfully
1950
+ * @returns SignupResponseDto User created successfully
1844
1951
  * @throws ApiError
1845
1952
  */
1846
- public static expectedTransactionControllerConfirmMatch(
1847
- data: ExpectedTransactionControllerConfirmMatchData
1848
- ): CancelablePromise<ExpectedTransactionControllerConfirmMatchResponse> {
1953
+ public static userControllerSignupUser(
1954
+ data: UserControllerSignupUserData
1955
+ ): CancelablePromise<UserControllerSignupUserResponse> {
1849
1956
  return __request(OpenAPI, {
1850
1957
  method: 'POST',
1851
- url: '/api/v1/{region}/bean/expected-transactions/{id}/match',
1852
- path: {
1853
- id: data.id,
1854
- region: data.region
1855
- },
1958
+ url: '/api/v1/users',
1856
1959
  body: data.requestBody,
1857
1960
  mediaType: 'application/json',
1858
1961
  errors: {
1859
- 400: 'Cannot match - not in PENDING status',
1860
- 404: 'Expected or actual transaction not found',
1861
- 409: 'Actual transaction already matched to another rule'
1962
+ 400: 'Invalid Turnstile token (when Turnstile is enabled)',
1963
+ 403: 'User signup is disabled'
1862
1964
  }
1863
1965
  });
1864
1966
  }
1865
1967
 
1866
1968
  /**
1867
- * Unmatch transaction
1868
- * Removes the match between expected and actual transaction (COMPLETED -> PENDING)
1969
+ * Delete user by ID (admin only)
1970
+ * @param data The data for the request.
1971
+ * @param data.id User ID to delete
1972
+ * @returns void User deleted successfully
1973
+ * @throws ApiError
1974
+ */
1975
+ public static userControllerDeleteUser(
1976
+ data: UserControllerDeleteUserData
1977
+ ): CancelablePromise<UserControllerDeleteUserResponse> {
1978
+ return __request(OpenAPI, {
1979
+ method: 'DELETE',
1980
+ url: '/api/v1/users/{id}',
1981
+ path: {
1982
+ id: data.id
1983
+ },
1984
+ errors: {
1985
+ 403: 'Cannot delete own account or insufficient permissions'
1986
+ }
1987
+ });
1988
+ }
1989
+
1990
+ /**
1991
+ * Get user info by user ID
1992
+ * @param data The data for the request.
1993
+ * @param data.id User ID
1994
+ * @returns unknown User info retrieved successfully
1995
+ * @throws ApiError
1996
+ */
1997
+ public static userControllerGetUserInfo(
1998
+ data: UserControllerGetUserInfoData
1999
+ ): CancelablePromise<UserControllerGetUserInfoResponse> {
2000
+ return __request(OpenAPI, {
2001
+ method: 'GET',
2002
+ url: '/api/v1/users/{id}/info',
2003
+ path: {
2004
+ id: data.id
2005
+ },
2006
+ errors: {
2007
+ 403: 'Cannot access other user info without admin permission'
2008
+ }
2009
+ });
2010
+ }
2011
+
2012
+ /**
2013
+ * Update user settings
2014
+ * @param data The data for the request.
2015
+ * @param data.requestBody
2016
+ * @returns unknown Settings updated successfully
2017
+ * @throws ApiError
2018
+ */
2019
+ public static userControllerUpdateUserSetting(
2020
+ data: UserControllerUpdateUserSettingData
2021
+ ): CancelablePromise<UserControllerUpdateUserSettingResponse> {
2022
+ return __request(OpenAPI, {
2023
+ method: 'PUT',
2024
+ url: '/api/v1/users/setting',
2025
+ body: data.requestBody,
2026
+ mediaType: 'application/json',
2027
+ errors: {
2028
+ 403: 'Insufficient permissions'
2029
+ }
2030
+ });
2031
+ }
2032
+
2033
+ /**
2034
+ * Get all user settings paginated (admin only)
2035
+ * @param data The data for the request.
2036
+ * @param data.pageNo Page number
2037
+ * @param data.pageSize Page size
2038
+ * @returns unknown Settings list retrieved successfully
2039
+ * @throws ApiError
2040
+ */
2041
+ public static userControllerGetAllUserSettingsByPage(
2042
+ data: UserControllerGetAllUserSettingsByPageData
2043
+ ): CancelablePromise<UserControllerGetAllUserSettingsByPageResponse> {
2044
+ return __request(OpenAPI, {
2045
+ method: 'GET',
2046
+ url: '/api/v1/users/settings-by-page',
2047
+ query: {
2048
+ pageNo: data.pageNo,
2049
+ pageSize: data.pageSize
2050
+ }
2051
+ });
2052
+ }
2053
+
2054
+ /**
2055
+ * Get asset and liability summary for current user
2056
+ * @returns unknown Summary retrieved successfully
2057
+ * @throws ApiError
2058
+ */
2059
+ public static userControllerGetAssetLiabilitySummary(): CancelablePromise<UserControllerGetAssetLiabilitySummaryResponse> {
2060
+ return __request(OpenAPI, {
2061
+ method: 'GET',
2062
+ url: '/api/v1/users/asset-liability-summary'
2063
+ });
2064
+ }
2065
+ }
2066
+
2067
+ export class PropertiesService {
2068
+ /**
2069
+ * Get all system properties
2070
+ * @returns unknown Properties retrieved successfully
2071
+ * @throws ApiError
2072
+ */
2073
+ public static propertyControllerGetAll(): CancelablePromise<PropertyControllerGetAllResponse> {
2074
+ return __request(OpenAPI, {
2075
+ method: 'GET',
2076
+ url: '/api/v1/admin/properties',
2077
+ errors: {
2078
+ 401: 'Unauthorized',
2079
+ 403: 'Forbidden - insufficient permissions'
2080
+ }
2081
+ });
2082
+ }
2083
+
2084
+ /**
2085
+ * Get property by key
2086
+ * @param data The data for the request.
2087
+ * @param data.key Property key
2088
+ * @returns unknown Property retrieved successfully
2089
+ * @throws ApiError
2090
+ */
2091
+ public static propertyControllerGetByKey(
2092
+ data: PropertyControllerGetByKeyData
2093
+ ): CancelablePromise<PropertyControllerGetByKeyResponse> {
2094
+ return __request(OpenAPI, {
2095
+ method: 'GET',
2096
+ url: '/api/v1/admin/properties/{key}',
2097
+ path: {
2098
+ key: data.key
2099
+ },
2100
+ errors: {
2101
+ 401: 'Unauthorized',
2102
+ 403: 'Forbidden - insufficient permissions',
2103
+ 404: 'Property not found'
2104
+ }
2105
+ });
2106
+ }
2107
+
2108
+ /**
2109
+ * Update a system property
2110
+ * @param data The data for the request.
2111
+ * @param data.key Property key
2112
+ * @param data.requestBody
2113
+ * @returns unknown Property updated successfully
2114
+ * @throws ApiError
2115
+ */
2116
+ public static propertyControllerUpdate(
2117
+ data: PropertyControllerUpdateData
2118
+ ): CancelablePromise<PropertyControllerUpdateResponse> {
2119
+ return __request(OpenAPI, {
2120
+ method: 'PUT',
2121
+ url: '/api/v1/admin/properties/{key}',
2122
+ path: {
2123
+ key: data.key
2124
+ },
2125
+ body: data.requestBody,
2126
+ mediaType: 'application/json',
2127
+ errors: {
2128
+ 401: 'Unauthorized',
2129
+ 403: 'Forbidden - insufficient permissions'
2130
+ }
2131
+ });
2132
+ }
2133
+
2134
+ /**
2135
+ * Delete a system property
2136
+ * @param data The data for the request.
2137
+ * @param data.key Property key
2138
+ * @returns void Property deleted successfully
2139
+ * @throws ApiError
2140
+ */
2141
+ public static propertyControllerDelete(
2142
+ data: PropertyControllerDeleteData
2143
+ ): CancelablePromise<PropertyControllerDeleteResponse> {
2144
+ return __request(OpenAPI, {
2145
+ method: 'DELETE',
2146
+ url: '/api/v1/admin/properties/{key}',
2147
+ path: {
2148
+ key: data.key
2149
+ },
2150
+ errors: {
2151
+ 401: 'Unauthorized',
2152
+ 403: 'Forbidden - insufficient permissions',
2153
+ 404: 'Property not found'
2154
+ }
2155
+ });
2156
+ }
2157
+ }
2158
+
2159
+ export class RecurringRulesService {
2160
+ /**
2161
+ * Create a new recurring rule
2162
+ * Creates a new recurring transaction rule for the authenticated user
2163
+ * @param data The data for the request.
2164
+ * @param data.region Region code for tenant context
2165
+ * @param data.requestBody
2166
+ * @returns RecurringRuleResponseDto Rule created successfully
2167
+ * @throws ApiError
2168
+ */
2169
+ public static recurringRuleControllerCreate(
2170
+ data: RecurringRuleControllerCreateData
2171
+ ): CancelablePromise<RecurringRuleControllerCreateResponse> {
2172
+ return __request(OpenAPI, {
2173
+ method: 'POST',
2174
+ url: '/api/v1/{region}/bean/recurring-rules',
2175
+ path: {
2176
+ region: data.region
2177
+ },
2178
+ body: data.requestBody,
2179
+ mediaType: 'application/json',
2180
+ errors: {
2181
+ 400: 'Invalid input data (e.g., autoCreate without accounts)',
2182
+ 409: 'Rule with same name already exists'
2183
+ }
2184
+ });
2185
+ }
2186
+
2187
+ /**
2188
+ * List recurring rules
2189
+ * Returns all recurring rules for the authenticated user with optional filtering
2190
+ * @param data The data for the request.
2191
+ * @param data.region Region code for tenant context
2192
+ * @param data.isActive Filter by active status
2193
+ * @param data.frequency Filter by frequency (WEEKLY, MONTHLY, etc.)
2194
+ * @param data.hasAutoCreate Filter by autoCreate enabled
2195
+ * @returns RecurringRuleResponseDto Rules retrieved successfully
2196
+ * @throws ApiError
2197
+ */
2198
+ public static recurringRuleControllerFindAll(
2199
+ data: RecurringRuleControllerFindAllData
2200
+ ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
2201
+ return __request(OpenAPI, {
2202
+ method: 'GET',
2203
+ url: '/api/v1/{region}/bean/recurring-rules',
2204
+ path: {
2205
+ region: data.region
2206
+ },
2207
+ query: {
2208
+ isActive: data.isActive,
2209
+ frequency: data.frequency,
2210
+ hasAutoCreate: data.hasAutoCreate
2211
+ }
2212
+ });
2213
+ }
2214
+
2215
+ /**
2216
+ * Create recurring rule from transaction
2217
+ * Auto-creates a recurring rule using transaction data. User only confirms frequency.
2218
+ * @param data The data for the request.
2219
+ * @param data.transactionId Source transaction ID
2220
+ * @param data.region Region code for tenant context
2221
+ * @param data.requestBody
2222
+ * @returns RecurringRuleResponseDto Rule created successfully
2223
+ * @throws ApiError
2224
+ */
2225
+ public static recurringRuleControllerCreateFromTransaction(
2226
+ data: RecurringRuleControllerCreateFromTransactionData
2227
+ ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
2228
+ return __request(OpenAPI, {
2229
+ method: 'POST',
2230
+ url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
2231
+ path: {
2232
+ transactionId: data.transactionId,
2233
+ region: data.region
2234
+ },
2235
+ body: data.requestBody,
2236
+ mediaType: 'application/json',
2237
+ errors: {
2238
+ 404: 'Transaction not found',
2239
+ 409: 'Rule with same name already exists or transaction already linked'
2240
+ }
2241
+ });
2242
+ }
2243
+
2244
+ /**
2245
+ * Get recurring rule by ID
2246
+ * Returns a specific recurring rule with its details
2247
+ * @param data The data for the request.
2248
+ * @param data.id Rule ID
2249
+ * @param data.region Region code for tenant context
2250
+ * @returns RecurringRuleResponseDto Rule retrieved successfully
2251
+ * @throws ApiError
2252
+ */
2253
+ public static recurringRuleControllerFindOne(
2254
+ data: RecurringRuleControllerFindOneData
2255
+ ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
2256
+ return __request(OpenAPI, {
2257
+ method: 'GET',
2258
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
2259
+ path: {
2260
+ id: data.id,
2261
+ region: data.region
2262
+ },
2263
+ errors: {
2264
+ 404: 'Rule not found'
2265
+ }
2266
+ });
2267
+ }
2268
+
2269
+ /**
2270
+ * Update recurring rule
2271
+ * Updates an existing recurring rule
2272
+ * @param data The data for the request.
2273
+ * @param data.id Rule ID
2274
+ * @param data.region Region code for tenant context
2275
+ * @param data.requestBody
2276
+ * @returns RecurringRuleResponseDto Rule updated successfully
2277
+ * @throws ApiError
2278
+ */
2279
+ public static recurringRuleControllerUpdate(
2280
+ data: RecurringRuleControllerUpdateData
2281
+ ): CancelablePromise<RecurringRuleControllerUpdateResponse> {
2282
+ return __request(OpenAPI, {
2283
+ method: 'PATCH',
2284
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
2285
+ path: {
2286
+ id: data.id,
2287
+ region: data.region
2288
+ },
2289
+ body: data.requestBody,
2290
+ mediaType: 'application/json',
2291
+ errors: {
2292
+ 400: 'Invalid input data',
2293
+ 404: 'Rule not found'
2294
+ }
2295
+ });
2296
+ }
2297
+
2298
+ /**
2299
+ * Delete recurring rule
2300
+ * Soft deletes a recurring rule (sets isActive to false)
2301
+ * @param data The data for the request.
2302
+ * @param data.id Rule ID
2303
+ * @param data.region Region code for tenant context
2304
+ * @returns void Rule deleted successfully
2305
+ * @throws ApiError
2306
+ */
2307
+ public static recurringRuleControllerDelete(
2308
+ data: RecurringRuleControllerDeleteData
2309
+ ): CancelablePromise<RecurringRuleControllerDeleteResponse> {
2310
+ return __request(OpenAPI, {
2311
+ method: 'DELETE',
2312
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
2313
+ path: {
2314
+ id: data.id,
2315
+ region: data.region
2316
+ },
2317
+ errors: {
2318
+ 404: 'Rule not found'
2319
+ }
2320
+ });
2321
+ }
2322
+
2323
+ /**
2324
+ * Get rule with statistics
2325
+ * Returns a rule with pending/overdue counts and next expected date
2326
+ * @param data The data for the request.
2327
+ * @param data.id Rule ID
2328
+ * @param data.region Region code for tenant context
2329
+ * @returns RecurringRuleWithStatsResponseDto Rule with stats retrieved successfully
2330
+ * @throws ApiError
2331
+ */
2332
+ public static recurringRuleControllerGetWithStats(
2333
+ data: RecurringRuleControllerGetWithStatsData
2334
+ ): CancelablePromise<RecurringRuleControllerGetWithStatsResponse> {
2335
+ return __request(OpenAPI, {
2336
+ method: 'GET',
2337
+ url: '/api/v1/{region}/bean/recurring-rules/{id}/stats',
2338
+ path: {
2339
+ id: data.id,
2340
+ region: data.region
2341
+ },
2342
+ errors: {
2343
+ 404: 'Rule not found'
2344
+ }
2345
+ });
2346
+ }
2347
+ }
2348
+
2349
+ export class ExpectedTransactionsService {
2350
+ /**
2351
+ * List expected transactions
2352
+ * Returns expected transactions for the authenticated user with optional filtering
2353
+ * @param data The data for the request.
2354
+ * @param data.region Region code for tenant context
2355
+ * @param data.ruleId Filter by recurring rule ID
2356
+ * @param data.status Filter by status (PENDING, COMPLETED, SKIPPED)
2357
+ * @param data.fromDate Filter by date range start (YYYY-MM-DD)
2358
+ * @param data.toDate Filter by date range end (YYYY-MM-DD)
2359
+ * @returns ExpectedTransactionListResponseDto Expected transactions retrieved successfully
2360
+ * @throws ApiError
2361
+ */
2362
+ public static expectedTransactionControllerFindAll(
2363
+ data: ExpectedTransactionControllerFindAllData
2364
+ ): CancelablePromise<ExpectedTransactionControllerFindAllResponse> {
2365
+ return __request(OpenAPI, {
2366
+ method: 'GET',
2367
+ url: '/api/v1/{region}/bean/expected-transactions',
2368
+ path: {
2369
+ region: data.region
2370
+ },
2371
+ query: {
2372
+ ruleId: data.ruleId,
2373
+ status: data.status,
2374
+ fromDate: data.fromDate,
2375
+ toDate: data.toDate
2376
+ }
2377
+ });
2378
+ }
2379
+
2380
+ /**
2381
+ * List overdue expected transactions
2382
+ * Returns all overdue expected transactions (PENDING past tolerance)
2383
+ * @param data The data for the request.
2384
+ * @param data.region Region code for tenant context
2385
+ * @returns ExpectedTransactionListResponseDto Overdue transactions retrieved successfully
2386
+ * @throws ApiError
2387
+ */
2388
+ public static expectedTransactionControllerFindOverdue(
2389
+ data: ExpectedTransactionControllerFindOverdueData
2390
+ ): CancelablePromise<ExpectedTransactionControllerFindOverdueResponse> {
2391
+ return __request(OpenAPI, {
2392
+ method: 'GET',
2393
+ url: '/api/v1/{region}/bean/expected-transactions/overdue',
2394
+ path: {
2395
+ region: data.region
2396
+ }
2397
+ });
2398
+ }
2399
+
2400
+ /**
2401
+ * Get expected transaction by ID
2402
+ * Returns a specific expected transaction with rule details
1869
2403
  * @param data The data for the request.
1870
2404
  * @param data.id Expected transaction ID
1871
2405
  * @param data.region Region code for tenant context
1872
- * @returns unknown Match removed successfully
2406
+ * @returns ExpectedTransactionResponseDto Expected transaction retrieved successfully
2407
+ * @throws ApiError
2408
+ */
2409
+ public static expectedTransactionControllerFindOne(
2410
+ data: ExpectedTransactionControllerFindOneData
2411
+ ): CancelablePromise<ExpectedTransactionControllerFindOneResponse> {
2412
+ return __request(OpenAPI, {
2413
+ method: 'GET',
2414
+ url: '/api/v1/{region}/bean/expected-transactions/{id}',
2415
+ path: {
2416
+ id: data.id,
2417
+ region: data.region
2418
+ },
2419
+ errors: {
2420
+ 404: 'Expected transaction not found'
2421
+ }
2422
+ });
2423
+ }
2424
+
2425
+ /**
2426
+ * Skip expected transaction
2427
+ * Marks an expected transaction as skipped (PENDING -> SKIPPED)
2428
+ * @param data The data for the request.
2429
+ * @param data.id Expected transaction ID
2430
+ * @param data.region Region code for tenant context
2431
+ * @returns ExpectedTransactionResponseDto Expected transaction skipped successfully
2432
+ * @throws ApiError
2433
+ */
2434
+ public static expectedTransactionControllerSkip(
2435
+ data: ExpectedTransactionControllerSkipData
2436
+ ): CancelablePromise<ExpectedTransactionControllerSkipResponse> {
2437
+ return __request(OpenAPI, {
2438
+ method: 'POST',
2439
+ url: '/api/v1/{region}/bean/expected-transactions/{id}/skip',
2440
+ path: {
2441
+ id: data.id,
2442
+ region: data.region
2443
+ },
2444
+ errors: {
2445
+ 400: 'Cannot skip - not in PENDING status',
2446
+ 404: 'Expected transaction not found'
2447
+ }
2448
+ });
2449
+ }
2450
+
2451
+ /**
2452
+ * Undo skip
2453
+ * Reverses a skip operation (SKIPPED -> PENDING)
2454
+ * @param data The data for the request.
2455
+ * @param data.id Expected transaction ID
2456
+ * @param data.region Region code for tenant context
2457
+ * @returns void Skip undone successfully
2458
+ * @throws ApiError
2459
+ */
2460
+ public static expectedTransactionControllerUndoSkip(
2461
+ data: ExpectedTransactionControllerUndoSkipData
2462
+ ): CancelablePromise<ExpectedTransactionControllerUndoSkipResponse> {
2463
+ return __request(OpenAPI, {
2464
+ method: 'DELETE',
2465
+ url: '/api/v1/{region}/bean/expected-transactions/{id}/skip',
2466
+ path: {
2467
+ id: data.id,
2468
+ region: data.region
2469
+ },
2470
+ errors: {
2471
+ 400: 'Cannot undo - not in SKIPPED status',
2472
+ 404: 'Expected transaction not found'
2473
+ }
2474
+ });
2475
+ }
2476
+
2477
+ /**
2478
+ * Confirm transaction match
2479
+ * Manually matches an expected transaction with an actual transaction
2480
+ * @param data The data for the request.
2481
+ * @param data.id Expected transaction ID
2482
+ * @param data.region Region code for tenant context
2483
+ * @param data.requestBody
2484
+ * @returns unknown Match confirmed successfully
2485
+ * @throws ApiError
2486
+ */
2487
+ public static expectedTransactionControllerConfirmMatch(
2488
+ data: ExpectedTransactionControllerConfirmMatchData
2489
+ ): CancelablePromise<ExpectedTransactionControllerConfirmMatchResponse> {
2490
+ return __request(OpenAPI, {
2491
+ method: 'POST',
2492
+ url: '/api/v1/{region}/bean/expected-transactions/{id}/match',
2493
+ path: {
2494
+ id: data.id,
2495
+ region: data.region
2496
+ },
2497
+ body: data.requestBody,
2498
+ mediaType: 'application/json',
2499
+ errors: {
2500
+ 400: 'Cannot match - not in PENDING status',
2501
+ 404: 'Expected or actual transaction not found',
2502
+ 409: 'Actual transaction already matched to another rule'
2503
+ }
2504
+ });
2505
+ }
2506
+
2507
+ /**
2508
+ * Unmatch transaction
2509
+ * Removes the match between expected and actual transaction (COMPLETED -> PENDING)
2510
+ * @param data The data for the request.
2511
+ * @param data.id Expected transaction ID
2512
+ * @param data.region Region code for tenant context
2513
+ * @returns void Match removed successfully
1873
2514
  * @throws ApiError
1874
2515
  */
1875
2516
  public static expectedTransactionControllerUnmatch(
@@ -2148,506 +2789,412 @@ export class BeanTransactionRulesService {
2148
2789
  data: TransactionRuleControllerUpdateData
2149
2790
  ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2150
2791
  return __request(OpenAPI, {
2151
- method: 'PUT',
2152
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2153
- path: {
2154
- ruleId: data.ruleId,
2155
- region: data.region
2156
- },
2157
- body: data.requestBody,
2158
- mediaType: 'application/json',
2159
- errors: {
2160
- 400: 'Validation failed',
2161
- 401: 'Unauthorized',
2162
- 403: 'Forbidden - not owner of rule',
2163
- 404: 'Rule not found',
2164
- 409: 'Resource conflict - rule is being modified by another process'
2165
- }
2166
- });
2167
- }
2168
-
2169
- /**
2170
- * Delete a transaction rule
2171
- * @param data The data for the request.
2172
- * @param data.ruleId Rule ID to delete
2173
- * @param data.region Region code for tenant context
2174
- * @returns void Rule deleted successfully
2175
- * @throws ApiError
2176
- */
2177
- public static transactionRuleControllerDelete(
2178
- data: TransactionRuleControllerDeleteData
2179
- ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2180
- return __request(OpenAPI, {
2181
- method: 'DELETE',
2182
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2183
- path: {
2184
- ruleId: data.ruleId,
2185
- region: data.region
2186
- },
2187
- errors: {
2188
- 401: 'Unauthorized',
2189
- 403: 'Forbidden - not owner of rule',
2190
- 404: 'Rule not found',
2191
- 409: 'Resource conflict - rule is being modified by another process'
2192
- }
2193
- });
2194
- }
2195
-
2196
- /**
2197
- * Test rule matching
2198
- * @param data The data for the request.
2199
- * @param data.ruleId Rule ID to test
2200
- * @param data.region Region code for tenant context
2201
- * @param data.requestBody
2202
- * @returns TestRuleResponseDto Test result
2203
- * @throws ApiError
2204
- */
2205
- public static transactionRuleControllerTest(
2206
- data: TransactionRuleControllerTestData
2207
- ): CancelablePromise<TransactionRuleControllerTestResponse> {
2208
- return __request(OpenAPI, {
2209
- method: 'POST',
2210
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2211
- path: {
2212
- ruleId: data.ruleId,
2213
- region: data.region
2214
- },
2215
- body: data.requestBody,
2216
- mediaType: 'application/json',
2217
- errors: {
2218
- 401: 'Unauthorized',
2219
- 403: 'Forbidden - not owner of rule',
2220
- 404: 'Rule not found'
2221
- }
2222
- });
2223
- }
2224
- }
2225
-
2226
- export class UsersService {
2227
- /**
2228
- * Delete own user account
2229
- * @param data The data for the request.
2230
- * @param data.requestBody
2231
- * @returns void User deleted successfully
2232
- * @throws ApiError
2233
- */
2234
- public static userControllerDeleteOwnUser(
2235
- data: UserControllerDeleteOwnUserData
2236
- ): CancelablePromise<UserControllerDeleteOwnUserResponse> {
2237
- return __request(OpenAPI, {
2238
- method: 'DELETE',
2239
- url: '/api/v1/users',
2240
- body: data.requestBody,
2241
- mediaType: 'application/json',
2242
- errors: {
2243
- 403: 'Invalid access token'
2244
- }
2245
- });
2246
- }
2247
-
2248
- /**
2249
- * Get current authenticated user
2250
- * @param data The data for the request.
2251
- * @param data.acceptLanguage
2252
- * @returns unknown User retrieved successfully
2253
- * @throws ApiError
2254
- */
2255
- public static userControllerGetUser(
2256
- data: UserControllerGetUserData
2257
- ): CancelablePromise<UserControllerGetUserResponse> {
2258
- return __request(OpenAPI, {
2259
- method: 'GET',
2260
- url: '/api/v1/users',
2261
- headers: {
2262
- 'accept-language': data.acceptLanguage
2263
- }
2264
- });
2265
- }
2266
-
2267
- /**
2268
- * Sign up new user
2269
- * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
2270
- * @param data The data for the request.
2271
- * @param data.requestBody
2272
- * @returns unknown User created successfully
2273
- * @throws ApiError
2274
- */
2275
- public static userControllerSignupUser(
2276
- data: UserControllerSignupUserData
2277
- ): CancelablePromise<UserControllerSignupUserResponse> {
2278
- return __request(OpenAPI, {
2279
- method: 'POST',
2280
- url: '/api/v1/users',
2281
- body: data.requestBody,
2282
- mediaType: 'application/json',
2283
- errors: {
2284
- 400: 'Invalid Turnstile token (when Turnstile is enabled)',
2285
- 403: 'User signup is disabled'
2286
- }
2287
- });
2288
- }
2289
-
2290
- /**
2291
- * Delete user by ID (admin only)
2292
- * @param data The data for the request.
2293
- * @param data.id User ID to delete
2294
- * @returns void User deleted successfully
2295
- * @throws ApiError
2296
- */
2297
- public static userControllerDeleteUser(
2298
- data: UserControllerDeleteUserData
2299
- ): CancelablePromise<UserControllerDeleteUserResponse> {
2300
- return __request(OpenAPI, {
2301
- method: 'DELETE',
2302
- url: '/api/v1/users/{id}',
2792
+ method: 'PUT',
2793
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2303
2794
  path: {
2304
- id: data.id
2795
+ ruleId: data.ruleId,
2796
+ region: data.region
2305
2797
  },
2798
+ body: data.requestBody,
2799
+ mediaType: 'application/json',
2306
2800
  errors: {
2307
- 403: 'Cannot delete own account or insufficient permissions'
2801
+ 400: 'Validation failed',
2802
+ 401: 'Unauthorized',
2803
+ 403: 'Forbidden - not owner of rule',
2804
+ 404: 'Rule not found',
2805
+ 409: 'Resource conflict - rule is being modified by another process'
2308
2806
  }
2309
2807
  });
2310
2808
  }
2311
2809
 
2312
2810
  /**
2313
- * Get user info by user ID
2811
+ * Delete a transaction rule
2314
2812
  * @param data The data for the request.
2315
- * @param data.id User ID
2316
- * @returns unknown User info retrieved successfully
2813
+ * @param data.ruleId Rule ID to delete
2814
+ * @param data.region Region code for tenant context
2815
+ * @returns void Rule deleted successfully
2317
2816
  * @throws ApiError
2318
2817
  */
2319
- public static userControllerGetUserInfo(
2320
- data: UserControllerGetUserInfoData
2321
- ): CancelablePromise<UserControllerGetUserInfoResponse> {
2818
+ public static transactionRuleControllerDelete(
2819
+ data: TransactionRuleControllerDeleteData
2820
+ ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2322
2821
  return __request(OpenAPI, {
2323
- method: 'GET',
2324
- url: '/api/v1/users/{id}/info',
2822
+ method: 'DELETE',
2823
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2325
2824
  path: {
2326
- id: data.id
2825
+ ruleId: data.ruleId,
2826
+ region: data.region
2327
2827
  },
2328
2828
  errors: {
2329
- 403: 'Cannot access other user info without admin permission'
2829
+ 401: 'Unauthorized',
2830
+ 403: 'Forbidden - not owner of rule',
2831
+ 404: 'Rule not found',
2832
+ 409: 'Resource conflict - rule is being modified by another process'
2330
2833
  }
2331
2834
  });
2332
2835
  }
2333
2836
 
2334
2837
  /**
2335
- * Update user settings
2838
+ * Test rule matching
2336
2839
  * @param data The data for the request.
2840
+ * @param data.ruleId Rule ID to test
2841
+ * @param data.region Region code for tenant context
2337
2842
  * @param data.requestBody
2338
- * @returns unknown Settings updated successfully
2843
+ * @returns TestRuleResponseDto Test result
2339
2844
  * @throws ApiError
2340
2845
  */
2341
- public static userControllerUpdateUserSetting(
2342
- data: UserControllerUpdateUserSettingData
2343
- ): CancelablePromise<UserControllerUpdateUserSettingResponse> {
2846
+ public static transactionRuleControllerTest(
2847
+ data: TransactionRuleControllerTestData
2848
+ ): CancelablePromise<TransactionRuleControllerTestResponse> {
2344
2849
  return __request(OpenAPI, {
2345
- method: 'PUT',
2346
- url: '/api/v1/users/setting',
2850
+ method: 'POST',
2851
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2852
+ path: {
2853
+ ruleId: data.ruleId,
2854
+ region: data.region
2855
+ },
2347
2856
  body: data.requestBody,
2348
2857
  mediaType: 'application/json',
2349
2858
  errors: {
2350
- 403: 'Insufficient permissions'
2859
+ 401: 'Unauthorized',
2860
+ 403: 'Forbidden - not owner of rule',
2861
+ 404: 'Rule not found'
2351
2862
  }
2352
2863
  });
2353
2864
  }
2865
+ }
2354
2866
 
2867
+ export class BeanCategoryCatalogService {
2355
2868
  /**
2356
- * Get all user settings paginated (admin only)
2869
+ * List category catalog for a region
2870
+ * Returns the region-scoped category slugs (expense/income/investment/banking/transfer/payment) for the NLP result picker, each with the categoryAccount paths the region-enabled system rules map it to (#816). CN-exclusive payment instruments (huabei/baitiao) appear only under /cn.
2357
2871
  * @param data The data for the request.
2358
- * @param data.pageNo Page number
2359
- * @param data.pageSize Page size
2360
- * @returns unknown Settings list retrieved successfully
2872
+ * @param data.region Region code for tenant context
2873
+ * @param data.scenario Filter by scenario
2874
+ * @param data.routeBearing Filter by routeBearing (entity-router route() consumes it)
2875
+ * @returns CategoryCatalogListResponseDto Category catalog retrieved successfully
2361
2876
  * @throws ApiError
2362
2877
  */
2363
- public static userControllerGetAllUserSettingsByPage(
2364
- data: UserControllerGetAllUserSettingsByPageData
2365
- ): CancelablePromise<UserControllerGetAllUserSettingsByPageResponse> {
2878
+ public static categoryCatalogControllerList(
2879
+ data: CategoryCatalogControllerListData
2880
+ ): CancelablePromise<CategoryCatalogControllerListResponse> {
2366
2881
  return __request(OpenAPI, {
2367
2882
  method: 'GET',
2368
- url: '/api/v1/users/settings-by-page',
2883
+ url: '/api/v1/{region}/bean/categories',
2884
+ path: {
2885
+ region: data.region
2886
+ },
2369
2887
  query: {
2370
- pageNo: data.pageNo,
2371
- pageSize: data.pageSize
2888
+ scenario: data.scenario,
2889
+ routeBearing: data.routeBearing
2372
2890
  }
2373
2891
  });
2374
2892
  }
2893
+ }
2375
2894
 
2895
+ export class LifeEventsService {
2376
2896
  /**
2377
- * Get asset and liability summary for current user
2378
- * @returns unknown Summary retrieved successfully
2897
+ * Create a new life event
2898
+ * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
2899
+ * @param data The data for the request.
2900
+ * @param data.region Region code for tenant context (decorative for life events)
2901
+ * @param data.requestBody
2902
+ * @returns EventResponseDto Life event created successfully
2379
2903
  * @throws ApiError
2380
2904
  */
2381
- public static userControllerGetAssetLiabilitySummary(): CancelablePromise<UserControllerGetAssetLiabilitySummaryResponse> {
2905
+ public static eventControllerCreate(
2906
+ data: EventControllerCreateData
2907
+ ): CancelablePromise<EventControllerCreateResponse> {
2382
2908
  return __request(OpenAPI, {
2383
- method: 'GET',
2384
- url: '/api/v1/users/asset-liability-summary'
2909
+ method: 'POST',
2910
+ url: '/api/v1/{region}/bean/events',
2911
+ path: {
2912
+ region: data.region
2913
+ },
2914
+ body: data.requestBody,
2915
+ mediaType: 'application/json',
2916
+ errors: {
2917
+ 409: 'Life event already exists for this (userId, type, date) combination'
2918
+ }
2385
2919
  });
2386
2920
  }
2387
- }
2388
2921
 
2389
- export class PropertiesService {
2390
2922
  /**
2391
- * Get all system properties
2392
- * @returns unknown Properties retrieved successfully
2923
+ * List user life events
2924
+ * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2925
+ * @param data The data for the request.
2926
+ * @param data.region Region code for tenant context (decorative for life events)
2927
+ * @param data.type Filter by life event type (exact match)
2928
+ * @param data.q Search term for description (case-insensitive partial match)
2929
+ * @param data.from Filter life events from this date (ISO 8601 format)
2930
+ * @param data.to Filter life events to this date (ISO 8601 format)
2931
+ * @param data.page Page number for pagination (default: 1)
2932
+ * @param data.limit Number of items per page (default: 20, max: 100)
2933
+ * @returns EventListResponseDto Life events retrieved successfully
2393
2934
  * @throws ApiError
2394
2935
  */
2395
- public static propertyControllerGetAll(): CancelablePromise<PropertyControllerGetAllResponse> {
2936
+ public static eventControllerFindAll(
2937
+ data: EventControllerFindAllData
2938
+ ): CancelablePromise<EventControllerFindAllResponse> {
2396
2939
  return __request(OpenAPI, {
2397
2940
  method: 'GET',
2398
- url: '/api/v1/admin/properties',
2399
- errors: {
2400
- 401: 'Unauthorized',
2401
- 403: 'Forbidden - insufficient permissions'
2941
+ url: '/api/v1/{region}/bean/events',
2942
+ path: {
2943
+ region: data.region
2944
+ },
2945
+ query: {
2946
+ type: data.type,
2947
+ q: data.q,
2948
+ from: data.from,
2949
+ to: data.to,
2950
+ page: data.page,
2951
+ limit: data.limit
2402
2952
  }
2403
2953
  });
2404
2954
  }
2405
2955
 
2406
2956
  /**
2407
- * Get property by key
2957
+ * Get life event by ID
2958
+ * Returns a single life event by its ID. Returns ETag header.
2408
2959
  * @param data The data for the request.
2409
- * @param data.key Property key
2410
- * @returns unknown Property retrieved successfully
2960
+ * @param data.id Life event ID
2961
+ * @param data.region Region code for tenant context (decorative for life events)
2962
+ * @returns EventResponseDto Life event retrieved successfully
2411
2963
  * @throws ApiError
2412
2964
  */
2413
- public static propertyControllerGetByKey(
2414
- data: PropertyControllerGetByKeyData
2415
- ): CancelablePromise<PropertyControllerGetByKeyResponse> {
2965
+ public static eventControllerFindOne(
2966
+ data: EventControllerFindOneData
2967
+ ): CancelablePromise<EventControllerFindOneResponse> {
2416
2968
  return __request(OpenAPI, {
2417
2969
  method: 'GET',
2418
- url: '/api/v1/admin/properties/{key}',
2970
+ url: '/api/v1/{region}/bean/events/{id}',
2419
2971
  path: {
2420
- key: data.key
2972
+ id: data.id,
2973
+ region: data.region
2421
2974
  },
2422
2975
  errors: {
2423
- 401: 'Unauthorized',
2424
- 403: 'Forbidden - insufficient permissions',
2425
- 404: 'Property not found'
2976
+ 404: 'Life event not found'
2426
2977
  }
2427
2978
  });
2428
2979
  }
2429
2980
 
2430
2981
  /**
2431
- * Update a system property
2982
+ * Update a life event
2983
+ * Updates an existing life event. If If-Match header is provided, performs optimistic concurrency check; mismatched updatedAt returns 412.
2432
2984
  * @param data The data for the request.
2433
- * @param data.key Property key
2985
+ * @param data.id Life event ID
2986
+ * @param data.region Region code for tenant context (decorative for life events)
2434
2987
  * @param data.requestBody
2435
- * @returns unknown Property updated successfully
2988
+ * @returns EventResponseDto Life event updated successfully
2436
2989
  * @throws ApiError
2437
2990
  */
2438
- public static propertyControllerUpdate(
2439
- data: PropertyControllerUpdateData
2440
- ): CancelablePromise<PropertyControllerUpdateResponse> {
2991
+ public static eventControllerUpdate(
2992
+ data: EventControllerUpdateData
2993
+ ): CancelablePromise<EventControllerUpdateResponse> {
2441
2994
  return __request(OpenAPI, {
2442
2995
  method: 'PUT',
2443
- url: '/api/v1/admin/properties/{key}',
2996
+ url: '/api/v1/{region}/bean/events/{id}',
2444
2997
  path: {
2445
- key: data.key
2998
+ id: data.id,
2999
+ region: data.region
2446
3000
  },
2447
3001
  body: data.requestBody,
2448
3002
  mediaType: 'application/json',
2449
3003
  errors: {
2450
- 401: 'Unauthorized',
2451
- 403: 'Forbidden - insufficient permissions'
3004
+ 400: 'If-Match header is not a valid ISO 8601 date',
3005
+ 404: 'Life event not found',
3006
+ 409: 'Updated event conflicts with an existing (userId, type, date) combination',
3007
+ 412: 'If-Match precondition failed (updatedAt mismatch)'
2452
3008
  }
2453
3009
  });
2454
3010
  }
2455
3011
 
2456
3012
  /**
2457
- * Delete a system property
3013
+ * Delete a life event
3014
+ * Deletes a life event entry (hard delete). Returns 204.
2458
3015
  * @param data The data for the request.
2459
- * @param data.key Property key
2460
- * @returns void Property deleted successfully
3016
+ * @param data.id Life event ID
3017
+ * @param data.region Region code for tenant context (decorative for life events)
3018
+ * @returns void Life event deleted successfully
2461
3019
  * @throws ApiError
2462
3020
  */
2463
- public static propertyControllerDelete(
2464
- data: PropertyControllerDeleteData
2465
- ): CancelablePromise<PropertyControllerDeleteResponse> {
3021
+ public static eventControllerDelete(
3022
+ data: EventControllerDeleteData
3023
+ ): CancelablePromise<EventControllerDeleteResponse> {
2466
3024
  return __request(OpenAPI, {
2467
3025
  method: 'DELETE',
2468
- url: '/api/v1/admin/properties/{key}',
3026
+ url: '/api/v1/{region}/bean/events/{id}',
2469
3027
  path: {
2470
- key: data.key
3028
+ id: data.id,
3029
+ region: data.region
2471
3030
  },
2472
3031
  errors: {
2473
- 401: 'Unauthorized',
2474
- 403: 'Forbidden - insufficient permissions',
2475
- 404: 'Property not found'
3032
+ 404: 'Life event not found'
2476
3033
  }
2477
3034
  });
2478
3035
  }
2479
- }
2480
3036
 
2481
- export class LifeEventsService {
2482
3037
  /**
2483
- * Create a new life event
2484
- * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
3038
+ * Slice time-series by a life event (Phase 79)
3039
+ * Returns aggregated time-series for postings matching accountPattern within the half-open date range of the given life event.
2485
3040
  * @param data The data for the request.
3041
+ * @param data.id Life event ID
3042
+ * @param data.accountPattern
3043
+ * @param data.granularity
2486
3044
  * @param data.region Region code for tenant context (decorative for life events)
2487
- * @param data.requestBody
2488
- * @returns EventResponseDto Life event created successfully
3045
+ * @returns unknown Time-series sliced by the life event range
2489
3046
  * @throws ApiError
2490
3047
  */
2491
- public static eventControllerCreate(
2492
- data: EventControllerCreateData
2493
- ): CancelablePromise<EventControllerCreateResponse> {
3048
+ public static eventControllerGetSlice(
3049
+ data: EventControllerGetSliceData
3050
+ ): CancelablePromise<EventControllerGetSliceResponse> {
2494
3051
  return __request(OpenAPI, {
2495
- method: 'POST',
2496
- url: '/api/v1/{region}/bean/events',
3052
+ method: 'GET',
3053
+ url: '/api/v1/{region}/bean/events/{id}/slice',
2497
3054
  path: {
3055
+ id: data.id,
2498
3056
  region: data.region
2499
3057
  },
2500
- body: data.requestBody,
2501
- mediaType: 'application/json',
3058
+ query: {
3059
+ accountPattern: data.accountPattern,
3060
+ granularity: data.granularity
3061
+ },
2502
3062
  errors: {
2503
- 409: 'Life event already exists for this (userId, type, date) combination'
3063
+ 400: 'accountPattern query param is empty',
3064
+ 404: 'Life event not found'
2504
3065
  }
2505
3066
  });
2506
3067
  }
3068
+ }
2507
3069
 
3070
+ export class OnboardingService {
2508
3071
  /**
2509
- * List user life events
2510
- * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
3072
+ * Bootstrap core accounts + register asset accounts with opening balances (ADR-0113)
2511
3073
  * @param data The data for the request.
2512
- * @param data.region Region code for tenant context (decorative for life events)
2513
- * @param data.type Filter by life event type (exact match)
2514
- * @param data.q Search term for description (case-insensitive partial match)
2515
- * @param data.from Filter life events from this date (ISO 8601 format)
2516
- * @param data.to Filter life events to this date (ISO 8601 format)
2517
- * @param data.page Page number for pagination (default: 1)
2518
- * @param data.limit Number of items per page (default: 20, max: 100)
2519
- * @returns EventListResponseDto Life events retrieved successfully
3074
+ * @param data.region Region code for tenant context. Not-yet-open codes are accepted: the universal catalog backs onboarding regardless of region (#759)
3075
+ * @param data.requestBody
3076
+ * @returns unknown Onboarding bootstrap result.
2520
3077
  * @throws ApiError
2521
- */
2522
- public static eventControllerFindAll(
2523
- data: EventControllerFindAllData
2524
- ): CancelablePromise<EventControllerFindAllResponse> {
3078
+ */
3079
+ public static onboardingControllerBootstrap(
3080
+ data: OnboardingControllerBootstrapData
3081
+ ): CancelablePromise<OnboardingControllerBootstrapResponse> {
2525
3082
  return __request(OpenAPI, {
2526
- method: 'GET',
2527
- url: '/api/v1/{region}/bean/events',
3083
+ method: 'POST',
3084
+ url: '/api/v1/{region}/bean/onboarding',
2528
3085
  path: {
2529
3086
  region: data.region
2530
3087
  },
2531
- query: {
2532
- type: data.type,
2533
- q: data.q,
2534
- from: data.from,
2535
- to: data.to,
2536
- page: data.page,
2537
- limit: data.limit
3088
+ body: data.requestBody,
3089
+ mediaType: 'application/json',
3090
+ errors: {
3091
+ 422: 'Invalid region/account path/duplicate paths.'
2538
3092
  }
2539
3093
  });
2540
3094
  }
3095
+ }
2541
3096
 
3097
+ export class BalanceReconciliationService {
2542
3098
  /**
2543
- * Get life event by ID
2544
- * Returns a single life event by its ID. Returns ETag header.
3099
+ * Preview reconciliation (book vs actual)
3100
+ * Computes book balance, diff, Beancount-inferred tolerance, and suggested action without persisting.
2545
3101
  * @param data The data for the request.
2546
- * @param data.id Life event ID
2547
- * @param data.region Region code for tenant context (decorative for life events)
2548
- * @returns EventResponseDto Life event retrieved successfully
3102
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3103
+ * @param data.requestBody
3104
+ * @returns ReconciliationComputeResultDto Reconciliation preview
2549
3105
  * @throws ApiError
2550
3106
  */
2551
- public static eventControllerFindOne(
2552
- data: EventControllerFindOneData
2553
- ): CancelablePromise<EventControllerFindOneResponse> {
3107
+ public static reconciliationControllerCompute(
3108
+ data: ReconciliationControllerComputeData
3109
+ ): CancelablePromise<ReconciliationControllerComputeResponse> {
2554
3110
  return __request(OpenAPI, {
2555
- method: 'GET',
2556
- url: '/api/v1/{region}/bean/events/{id}',
3111
+ method: 'POST',
3112
+ url: '/api/v1/{region}/bean/reconciliations',
2557
3113
  path: {
2558
- id: data.id,
2559
3114
  region: data.region
2560
3115
  },
3116
+ body: data.requestBody,
3117
+ mediaType: 'application/json',
2561
3118
  errors: {
2562
- 404: 'Life event not found'
3119
+ 404: 'Account not found'
2563
3120
  }
2564
3121
  });
2565
3122
  }
2566
3123
 
2567
3124
  /**
2568
- * Update a life event
2569
- * Updates an existing life event. If If-Match header is provided, performs optimistic concurrency check; mismatched updatedAt returns 412.
3125
+ * Record a balance assertion
3126
+ * Persists the reconciliation as a BeanBalance assertion (amount = actual, diffAmount = book − actual). Re-reconciling the same day/currency upserts.
2570
3127
  * @param data The data for the request.
2571
- * @param data.id Life event ID
2572
- * @param data.region Region code for tenant context (decorative for life events)
3128
+ * @param data.region Region code for tenant context (decorative for reconciliation)
2573
3129
  * @param data.requestBody
2574
- * @returns EventResponseDto Life event updated successfully
3130
+ * @returns ReconciliationRecordDto Balance assertion recorded
2575
3131
  * @throws ApiError
2576
3132
  */
2577
- public static eventControllerUpdate(
2578
- data: EventControllerUpdateData
2579
- ): CancelablePromise<EventControllerUpdateResponse> {
3133
+ public static reconciliationControllerAssert(
3134
+ data: ReconciliationControllerAssertData
3135
+ ): CancelablePromise<ReconciliationControllerAssertResponse> {
2580
3136
  return __request(OpenAPI, {
2581
- method: 'PUT',
2582
- url: '/api/v1/{region}/bean/events/{id}',
3137
+ method: 'POST',
3138
+ url: '/api/v1/{region}/bean/reconciliations/assert',
2583
3139
  path: {
2584
- id: data.id,
2585
3140
  region: data.region
2586
3141
  },
2587
3142
  body: data.requestBody,
2588
3143
  mediaType: 'application/json',
2589
3144
  errors: {
2590
- 400: 'If-Match header is not a valid ISO 8601 date',
2591
- 404: 'Life event not found',
2592
- 409: 'Updated event conflicts with an existing (userId, type, date) combination',
2593
- 412: 'If-Match precondition failed (updatedAt mismatch)'
3145
+ 404: 'Account not found'
2594
3146
  }
2595
3147
  });
2596
3148
  }
2597
3149
 
2598
3150
  /**
2599
- * Delete a life event
2600
- * Deletes a life event entry (hard delete). Returns 204.
3151
+ * Generate a pad adjusting entry
3152
+ * 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.
2601
3153
  * @param data The data for the request.
2602
- * @param data.id Life event ID
2603
- * @param data.region Region code for tenant context (decorative for life events)
2604
- * @returns void Life event deleted successfully
3154
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3155
+ * @param data.requestBody
3156
+ * @returns PadResultDto Pad adjusting entry generated
2605
3157
  * @throws ApiError
2606
3158
  */
2607
- public static eventControllerDelete(
2608
- data: EventControllerDeleteData
2609
- ): CancelablePromise<EventControllerDeleteResponse> {
3159
+ public static reconciliationControllerPad(
3160
+ data: ReconciliationControllerPadData
3161
+ ): CancelablePromise<ReconciliationControllerPadResponse> {
2610
3162
  return __request(OpenAPI, {
2611
- method: 'DELETE',
2612
- url: '/api/v1/{region}/bean/events/{id}',
3163
+ method: 'POST',
3164
+ url: '/api/v1/{region}/bean/reconciliations/pad',
2613
3165
  path: {
2614
- id: data.id,
2615
3166
  region: data.region
2616
3167
  },
3168
+ body: data.requestBody,
3169
+ mediaType: 'application/json',
2617
3170
  errors: {
2618
- 404: 'Life event not found'
3171
+ 400: 'Book already within tolerance — no pad needed',
3172
+ 404: 'Account not found'
2619
3173
  }
2620
3174
  });
2621
3175
  }
2622
3176
 
2623
3177
  /**
2624
- * Slice time-series by a life event (Phase 79)
2625
- * Returns aggregated time-series for postings matching accountPattern within the half-open date range of the given life event.
3178
+ * List reconciliation history for an account
3179
+ * Returns recorded balance assertions (most recent first). The latest drives the account-detail "Last <date>" badge.
2626
3180
  * @param data The data for the request.
2627
- * @param data.id Life event ID
2628
- * @param data.accountPattern
2629
- * @param data.granularity
2630
- * @param data.region Region code for tenant context (decorative for life events)
2631
- * @returns unknown Time-series sliced by the life event range
3181
+ * @param data.accountId BeanAccount id
3182
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3183
+ * @returns ReconciliationRecordDto Reconciliation history
2632
3184
  * @throws ApiError
2633
3185
  */
2634
- public static eventControllerGetSlice(
2635
- data: EventControllerGetSliceData
2636
- ): CancelablePromise<EventControllerGetSliceResponse> {
3186
+ public static reconciliationControllerHistory(
3187
+ data: ReconciliationControllerHistoryData
3188
+ ): CancelablePromise<ReconciliationControllerHistoryResponse> {
2637
3189
  return __request(OpenAPI, {
2638
3190
  method: 'GET',
2639
- url: '/api/v1/{region}/bean/events/{id}/slice',
3191
+ url: '/api/v1/{region}/bean/accounts/{accountId}/reconciliations',
2640
3192
  path: {
2641
- id: data.id,
3193
+ accountId: data.accountId,
2642
3194
  region: data.region
2643
3195
  },
2644
- query: {
2645
- accountPattern: data.accountPattern,
2646
- granularity: data.granularity
2647
- },
2648
3196
  errors: {
2649
- 400: 'accountPattern query param is empty',
2650
- 404: 'Life event not found'
3197
+ 404: 'Account not found'
2651
3198
  }
2652
3199
  });
2653
3200
  }
@@ -2657,7 +3204,7 @@ export class BeanExportService {
2657
3204
  /**
2658
3205
  * Export Beancount ledger as ZIP
2659
3206
  * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
2660
- * @returns unknown
3207
+ * @returns binary ZIP archive (application/zip) streamed as an attachment
2661
3208
  * @throws ApiError
2662
3209
  */
2663
3210
  public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
@@ -2831,216 +3378,196 @@ export class BeanImportService {
2831
3378
  }
2832
3379
  }
2833
3380
 
2834
- export class BeanPlatformsService {
2835
- /**
2836
- * Get all platforms with statistics
2837
- * @returns unknown List of platforms with binding and account counts
2838
- * @throws ApiError
2839
- */
2840
- public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
2841
- return __request(OpenAPI, {
2842
- method: 'GET',
2843
- url: '/api/v1/bean/platforms'
2844
- });
2845
- }
2846
-
3381
+ export class ProviderSyncService {
2847
3382
  /**
2848
- * Create a new platform
3383
+ * Sync transactions from financial data provider
3384
+ *
3385
+ * Accepts raw transactions from external financial data providers, transforms them to Beancount format, and processes them through the ingestion pipeline.
3386
+ *
3387
+ * **Supported Providers:**
3388
+ * - **plaid**: Plaid API (US, Canada, Europe)
3389
+ * - **teller**: Teller API (US)
3390
+ * - **truelayer**: TrueLayer Open Banking (UK, Europe)
3391
+ * - **gocardless**: GoCardless Bank Account Data (Europe)
3392
+ * - **simplefin**: SimpleFIN (Self-hosted)
3393
+ * - **yodlee**: Yodlee (Global)
3394
+ * - **beancount-direct**: Beancount format transactions
3395
+ * - **parsed-bill**: Client-side parsed bill transactions
3396
+ *
3397
+ * **Processing Flow:**
3398
+ * 1. Transform raw data via provider adapter
3399
+ * 2. Validate transaction format
3400
+ * 3. Deduplicate using originalId
3401
+ * 4. Classify using rule engine
3402
+ * 5. Route low-confidence to Review Center
3403
+ * 6. Persist validated transactions
3404
+ *
2849
3405
  * @param data The data for the request.
3406
+ * @param data.providerName Provider name
3407
+ * @param data.region Region code for tenant context
2850
3408
  * @param data.requestBody
2851
- * @returns unknown Platform created successfully
3409
+ * @returns ProviderSyncResponseDto Sync completed successfully
2852
3410
  * @throws ApiError
2853
3411
  */
2854
- public static platformControllerCreate(
2855
- data: PlatformControllerCreateData
2856
- ): CancelablePromise<PlatformControllerCreateResponse> {
3412
+ public static providerSyncControllerSync(
3413
+ data: ProviderSyncControllerSyncData
3414
+ ): CancelablePromise<ProviderSyncControllerSyncResponse> {
2857
3415
  return __request(OpenAPI, {
2858
3416
  method: 'POST',
2859
- url: '/api/v1/bean/platforms',
3417
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3418
+ path: {
3419
+ providerName: data.providerName,
3420
+ region: data.region
3421
+ },
2860
3422
  body: data.requestBody,
2861
3423
  mediaType: 'application/json',
2862
3424
  errors: {
2863
- 409: 'Platform already exists'
3425
+ 400: 'Invalid request data',
3426
+ 401: 'Missing or invalid authentication',
3427
+ 404: 'Provider not supported'
2864
3428
  }
2865
3429
  });
2866
3430
  }
2867
3431
 
2868
3432
  /**
2869
- * Get platform list for current user
2870
- * @returns unknown List of platforms with user binding status
2871
- * @throws ApiError
2872
- */
2873
- public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
2874
- return __request(OpenAPI, {
2875
- method: 'GET',
2876
- url: '/api/v1/bean/platforms/list'
2877
- });
2878
- }
2879
-
2880
- /**
2881
- * Match platforms by name or alias
3433
+ * Get supported providers
3434
+ * Returns a list of all providers supported by the sync endpoint.
2882
3435
  * @param data The data for the request.
2883
- * @param data.q Search query — Chinese name, English name, or abbreviation
2884
- * @param data.region Region code for category override lookup
2885
- * @returns unknown List of matching platforms with suggested segment names
3436
+ * @param data.region Region code for tenant context
3437
+ * @returns SupportedProvidersResponseDto List of supported providers
2886
3438
  * @throws ApiError
2887
3439
  */
2888
- public static platformControllerMatchPlatforms(
2889
- data: PlatformControllerMatchPlatformsData
2890
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3440
+ public static providerSyncControllerGetSupportedProviders(
3441
+ data: ProviderSyncControllerGetSupportedProvidersData
3442
+ ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
2891
3443
  return __request(OpenAPI, {
2892
3444
  method: 'GET',
2893
- url: '/api/v1/bean/platforms/match',
2894
- query: {
2895
- q: data.q,
3445
+ url: '/api/v1/{region}/bean/import/provider/supported',
3446
+ path: {
2896
3447
  region: data.region
3448
+ },
3449
+ errors: {
3450
+ 401: 'Missing or invalid authentication'
2897
3451
  }
2898
3452
  });
2899
3453
  }
2900
3454
 
2901
3455
  /**
2902
- * Update a platform
3456
+ * Check if provider is supported
3457
+ * Returns whether a specific provider is supported.
2903
3458
  * @param data The data for the request.
2904
- * @param data.id Platform ID
2905
- * @param data.requestBody
2906
- * @returns unknown Platform updated successfully
3459
+ * @param data.providerName Provider name to check
3460
+ * @param data.region Region code for tenant context
3461
+ * @returns unknown Provider support status
2907
3462
  * @throws ApiError
2908
3463
  */
2909
- public static platformControllerUpdate(
2910
- data: PlatformControllerUpdateData
2911
- ): CancelablePromise<PlatformControllerUpdateResponse> {
3464
+ public static providerSyncControllerIsProviderSupported(
3465
+ data: ProviderSyncControllerIsProviderSupportedData
3466
+ ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
2912
3467
  return __request(OpenAPI, {
2913
- method: 'PUT',
2914
- url: '/api/v1/bean/platforms/{id}',
3468
+ method: 'GET',
3469
+ url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
2915
3470
  path: {
2916
- id: data.id
3471
+ providerName: data.providerName,
3472
+ region: data.region
2917
3473
  },
2918
- body: data.requestBody,
2919
- mediaType: 'application/json',
2920
3474
  errors: {
2921
- 404: 'Platform not found'
3475
+ 401: 'Missing or invalid authentication'
2922
3476
  }
2923
3477
  });
2924
3478
  }
3479
+ }
2925
3480
 
3481
+ export class ExternalAccountLinksService {
2926
3482
  /**
2927
- * Delete a platform
3483
+ * Create an external account → BeanAccount mapping (ADR-0113)
2928
3484
  * @param data The data for the request.
2929
- * @param data.id Platform ID
2930
- * @returns void Platform deleted successfully
3485
+ * @param data.region Region code for tenant context
3486
+ * @param data.requestBody
3487
+ * @returns ExternalAccountLinkResponseDto Link created.
2931
3488
  * @throws ApiError
2932
3489
  */
2933
- public static platformControllerDelete(
2934
- data: PlatformControllerDeleteData
2935
- ): CancelablePromise<PlatformControllerDeleteResponse> {
3490
+ public static externalAccountLinkControllerCreate(
3491
+ data: ExternalAccountLinkControllerCreateData
3492
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
2936
3493
  return __request(OpenAPI, {
2937
- method: 'DELETE',
2938
- url: '/api/v1/bean/platforms/{id}',
3494
+ method: 'POST',
3495
+ url: '/api/v1/{region}/bean/external-account-links',
2939
3496
  path: {
2940
- id: data.id
3497
+ region: data.region
2941
3498
  },
3499
+ body: data.requestBody,
3500
+ mediaType: 'application/json',
2942
3501
  errors: {
2943
- 404: 'Platform not found'
3502
+ 422: 'beanAccountId not owned, or an active link already exists.'
2944
3503
  }
2945
3504
  });
2946
3505
  }
2947
- }
2948
3506
 
2949
- export class ProviderSyncService {
2950
3507
  /**
2951
- * Sync transactions from financial data provider
2952
- *
2953
- * Accepts raw transactions from external financial data providers, transforms them to Beancount format, and processes them through the ingestion pipeline.
2954
- *
2955
- * **Supported Providers:**
2956
- * - **plaid**: Plaid API (US, Canada, Europe)
2957
- * - **teller**: Teller API (US)
2958
- * - **truelayer**: TrueLayer Open Banking (UK, Europe)
2959
- * - **gocardless**: GoCardless Bank Account Data (Europe)
2960
- * - **simplefin**: SimpleFIN (Self-hosted)
2961
- * - **yodlee**: Yodlee (Global)
2962
- * - **beancount-direct**: Beancount format transactions
2963
- * - **parsed-bill**: Client-side parsed bill transactions
2964
- *
2965
- * **Processing Flow:**
2966
- * 1. Transform raw data via provider adapter
2967
- * 2. Validate transaction format
2968
- * 3. Deduplicate using originalId
2969
- * 4. Classify using rule engine
2970
- * 5. Route low-confidence to Review Center
2971
- * 6. Persist validated transactions
2972
- *
3508
+ * List the user's active external account links
2973
3509
  * @param data The data for the request.
2974
- * @param data.providerName Provider name
3510
+ * @param data.provider
2975
3511
  * @param data.region Region code for tenant context
2976
- * @param data.requestBody
2977
- * @returns ProviderSyncResponseDto Sync completed successfully
3512
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
2978
3513
  * @throws ApiError
2979
3514
  */
2980
- public static providerSyncControllerSync(
2981
- data: ProviderSyncControllerSyncData
2982
- ): CancelablePromise<ProviderSyncControllerSyncResponse> {
3515
+ public static externalAccountLinkControllerFindAll(
3516
+ data: ExternalAccountLinkControllerFindAllData
3517
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
2983
3518
  return __request(OpenAPI, {
2984
- method: 'POST',
2985
- url: '/api/v1/{region}/bean/import/provider/{providerName}/sync',
3519
+ method: 'GET',
3520
+ url: '/api/v1/{region}/bean/external-account-links',
2986
3521
  path: {
2987
- providerName: data.providerName,
2988
3522
  region: data.region
2989
3523
  },
2990
- body: data.requestBody,
2991
- mediaType: 'application/json',
2992
- errors: {
2993
- 400: 'Invalid request data',
2994
- 401: 'Missing or invalid authentication',
2995
- 404: 'Provider not supported'
3524
+ query: {
3525
+ provider: data.provider
2996
3526
  }
2997
3527
  });
2998
3528
  }
2999
3529
 
3000
3530
  /**
3001
- * Get supported providers
3002
- * Returns a list of all providers supported by the sync endpoint.
3531
+ * Get a single external account link
3003
3532
  * @param data The data for the request.
3533
+ * @param data.id
3004
3534
  * @param data.region Region code for tenant context
3005
- * @returns SupportedProvidersResponseDto List of supported providers
3535
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
3006
3536
  * @throws ApiError
3007
3537
  */
3008
- public static providerSyncControllerGetSupportedProviders(
3009
- data: ProviderSyncControllerGetSupportedProvidersData
3010
- ): CancelablePromise<ProviderSyncControllerGetSupportedProvidersResponse> {
3538
+ public static externalAccountLinkControllerFindOne(
3539
+ data: ExternalAccountLinkControllerFindOneData
3540
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
3011
3541
  return __request(OpenAPI, {
3012
3542
  method: 'GET',
3013
- url: '/api/v1/{region}/bean/import/provider/supported',
3543
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3014
3544
  path: {
3545
+ id: data.id,
3015
3546
  region: data.region
3016
3547
  },
3017
3548
  errors: {
3018
- 401: 'Missing or invalid authentication'
3549
+ 422: 'Link not found or not owned by the user.'
3019
3550
  }
3020
3551
  });
3021
3552
  }
3022
3553
 
3023
3554
  /**
3024
- * Check if provider is supported
3025
- * Returns whether a specific provider is supported.
3555
+ * Soft-delete (disconnect) an external account link
3026
3556
  * @param data The data for the request.
3027
- * @param data.providerName Provider name to check
3557
+ * @param data.id
3028
3558
  * @param data.region Region code for tenant context
3029
- * @returns unknown Provider support status
3559
+ * @returns void Link soft-deleted; historical transactions are unaffected.
3030
3560
  * @throws ApiError
3031
3561
  */
3032
- public static providerSyncControllerIsProviderSupported(
3033
- data: ProviderSyncControllerIsProviderSupportedData
3034
- ): CancelablePromise<ProviderSyncControllerIsProviderSupportedResponse> {
3562
+ public static externalAccountLinkControllerRemove(
3563
+ data: ExternalAccountLinkControllerRemoveData
3564
+ ): CancelablePromise<ExternalAccountLinkControllerRemoveResponse> {
3035
3565
  return __request(OpenAPI, {
3036
- method: 'GET',
3037
- url: '/api/v1/{region}/bean/import/provider/{providerName}/supported',
3566
+ method: 'DELETE',
3567
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3038
3568
  path: {
3039
- providerName: data.providerName,
3569
+ id: data.id,
3040
3570
  region: data.region
3041
- },
3042
- errors: {
3043
- 401: 'Missing or invalid authentication'
3044
3571
  }
3045
3572
  });
3046
3573
  }
@@ -3204,361 +3731,205 @@ export class BeanNlpService {
3204
3731
  }
3205
3732
  }
3206
3733
 
3207
- export class DashboardService {
3734
+ export class BeanPlatformsService {
3208
3735
  /**
3209
- * Get net worth overview
3210
- * Returns total net worth with breakdown of assets and liabilities
3211
- * @param data The data for the request.
3212
- * @param data.region Region code for tenant context
3213
- * @param data.date Date for balance calculation (ISO 8601 format)
3214
- * @returns NetWorthResponseDto Net worth retrieved successfully
3736
+ * Get all platforms with statistics
3737
+ * @returns unknown List of platforms with binding and account counts
3215
3738
  * @throws ApiError
3216
3739
  */
3217
- public static dashboardControllerGetNetWorth(
3218
- data: DashboardControllerGetNetWorthData
3219
- ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3740
+ public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
3220
3741
  return __request(OpenAPI, {
3221
3742
  method: 'GET',
3222
- url: '/api/v1/{region}/dashboard/net-worth',
3223
- path: {
3224
- region: data.region
3225
- },
3226
- query: {
3227
- date: data.date
3228
- },
3229
- errors: {
3230
- 401: 'User not authenticated'
3231
- }
3743
+ url: '/api/v1/bean/platforms'
3232
3744
  });
3233
3745
  }
3234
3746
 
3235
3747
  /**
3236
- * Get accounts grouped by platform
3237
- * Returns accounts with balances grouped by financial platform
3748
+ * Create a new platform
3238
3749
  * @param data The data for the request.
3239
- * @param data.region Region code for tenant context
3240
- * @param data.groupBy Grouping strategy
3241
- * @param data.date Date for balance calculation (ISO 8601 format)
3242
- * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3243
- * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3750
+ * @param data.requestBody
3751
+ * @returns unknown Platform created successfully
3244
3752
  * @throws ApiError
3245
3753
  */
3246
- public static dashboardControllerGetAccounts(
3247
- data: DashboardControllerGetAccountsData
3248
- ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3754
+ public static platformControllerCreate(
3755
+ data: PlatformControllerCreateData
3756
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3249
3757
  return __request(OpenAPI, {
3250
- method: 'GET',
3251
- url: '/api/v1/{region}/dashboard/accounts',
3252
- path: {
3253
- region: data.region
3254
- },
3255
- query: {
3256
- groupBy: data.groupBy,
3257
- date: data.date,
3258
- accountId: data.accountId
3259
- },
3758
+ method: 'POST',
3759
+ url: '/api/v1/bean/platforms',
3760
+ body: data.requestBody,
3761
+ mediaType: 'application/json',
3260
3762
  errors: {
3261
- 401: 'User not authenticated'
3763
+ 409: 'Platform already exists'
3262
3764
  }
3263
3765
  });
3264
3766
  }
3265
3767
 
3266
3768
  /**
3267
- * Get cash flow summary
3268
- * Returns income, expenses, and savings for a monthly period
3769
+ * Get platform list for current user
3269
3770
  * @param data The data for the request.
3270
- * @param data.period Period in YYYY-MM format
3271
- * @param data.region Region code for tenant context
3272
- * @returns CashFlowResponseDto Cash flow retrieved successfully
3771
+ * @param data.region Region code (ISO 3166-1 alpha-2) that biases within-type-bucket ordering (local-region platforms first). Case-insensitive — stored/compared UPPERCASE ("cn" == "CN").
3772
+ * @returns PlatformListItemDto List of platforms with user binding status
3273
3773
  * @throws ApiError
3274
3774
  */
3275
- public static dashboardControllerGetCashFlow(
3276
- data: DashboardControllerGetCashFlowData
3277
- ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3775
+ public static platformControllerGetPlatformList(
3776
+ data: PlatformControllerGetPlatformListData = {}
3777
+ ): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3278
3778
  return __request(OpenAPI, {
3279
3779
  method: 'GET',
3280
- url: '/api/v1/{region}/dashboard/cash-flow',
3281
- path: {
3282
- region: data.region
3283
- },
3780
+ url: '/api/v1/bean/platforms/list',
3284
3781
  query: {
3285
- period: data.period
3286
- },
3287
- errors: {
3288
- 400: 'Invalid period format',
3289
- 401: 'User not authenticated'
3290
- }
3291
- });
3292
- }
3293
-
3294
- /**
3295
- * Get expenses/income grouped by functional category
3296
- * 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)
3297
- * @param data The data for the request.
3298
- * @param data.region Region code for tenant context
3299
- * @param data.groupBy Grouping strategy
3300
- * @param data.period Time window (1m = current calendar month)
3301
- * @param data.flow Account root to aggregate (expense → ^Expenses:, income → ^Income:)
3302
- * @returns ExpensesByCategoryResponseDto Expenses retrieved successfully
3303
- * @throws ApiError
3304
- */
3305
- public static dashboardControllerGetExpenses(
3306
- data: DashboardControllerGetExpensesData
3307
- ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3308
- return __request(OpenAPI, {
3309
- method: 'GET',
3310
- url: '/api/v1/{region}/dashboard/expenses',
3311
- path: {
3312
3782
  region: data.region
3313
- },
3314
- query: {
3315
- groupBy: data.groupBy,
3316
- period: data.period,
3317
- flow: data.flow
3318
- },
3319
- errors: {
3320
- 400: 'Invalid groupBy or period',
3321
- 401: 'User not authenticated'
3322
3783
  }
3323
3784
  });
3324
3785
  }
3325
- }
3326
3786
 
3327
- export class InvestmentService {
3328
3787
  /**
3329
- * Get per-holding unrealized + realized P&L
3330
- * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3788
+ * Match platforms by name or alias
3331
3789
  * @param data The data for the request.
3332
- * @param data.region Region code for tenant context
3333
- * @param data.asOf As-of date (ISO 8601), defaults to today
3334
- * @param data.accountId Scope to a single account
3335
- * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3336
- * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3790
+ * @param data.q Search query — Chinese name, English name, or abbreviation
3791
+ * @param data.region Region code (ISO 3166-1 alpha-2) that biases within-tier ordering (local-region platforms first); also the intended categoryOverrides key. Case-insensitive — stored/compared UPPERCASE ("cn" == "CN").
3792
+ * @returns PlatformMatchResponseDto Matching platforms with overall match type and truncation flag
3337
3793
  * @throws ApiError
3338
3794
  */
3339
- public static holdingPnlControllerGetHoldingPnl(
3340
- data: HoldingPnlControllerGetHoldingPnlData
3341
- ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3795
+ public static platformControllerMatchPlatforms(
3796
+ data: PlatformControllerMatchPlatformsData
3797
+ ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3342
3798
  return __request(OpenAPI, {
3343
3799
  method: 'GET',
3344
- url: '/api/v1/{region}/investment/holdings/pnl',
3345
- path: {
3346
- region: data.region
3347
- },
3800
+ url: '/api/v1/bean/platforms/match',
3348
3801
  query: {
3349
- asOf: data.asOf,
3350
- accountId: data.accountId,
3351
- method: data.method
3352
- },
3353
- errors: {
3354
- 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3355
- 401: 'User not authenticated'
3356
- }
3357
- });
3358
- }
3359
- }
3360
-
3361
- export class BeanPricesService {
3362
- /**
3363
- * Create a new price
3364
- * Creates a new price entry for the authenticated user
3365
- * @param data The data for the request.
3366
- * @param data.region Region code for tenant context
3367
- * @param data.requestBody
3368
- * @returns PriceResponseDto Price created successfully
3369
- * @throws ApiError
3370
- */
3371
- public static priceControllerCreate(
3372
- data: PriceControllerCreateData
3373
- ): CancelablePromise<PriceControllerCreateResponse> {
3374
- return __request(OpenAPI, {
3375
- method: 'POST',
3376
- url: '/api/v1/{region}/bean/prices',
3377
- path: {
3802
+ q: data.q,
3378
3803
  region: data.region
3379
- },
3380
- body: data.requestBody,
3381
- mediaType: 'application/json',
3382
- errors: {
3383
- 404: 'Currency or quoteCurrency commodity not found',
3384
- 409: 'Price already exists for this currency pair and date'
3385
3804
  }
3386
3805
  });
3387
3806
  }
3388
3807
 
3389
3808
  /**
3390
- * List user prices
3391
- * Returns all price entries for the authenticated user with optional filtering
3809
+ * Get the region and candidate account standards for a platform
3392
3810
  * @param data The data for the request.
3393
- * @param data.region Region code for tenant context
3394
- * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
3395
- * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
3396
- * @param data.dateFrom Filter prices from this date (ISO 8601 format)
3397
- * @param data.dateTo Filter prices to this date (ISO 8601 format)
3398
- * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
3399
- * @param data.page Page number for pagination (default: 1)
3400
- * @param data.limit Number of items per page (default: 20, max: 100)
3401
- * @returns PriceListResponseDto Prices retrieved successfully
3811
+ * @param data.id Platform ID (from a match result)
3812
+ * @param data.region Region code (ISO 3166-1 alpha-2, case-insensitive). Required for global platforms (countryCode null) — resolved as their template region; ignored when the platform has its own countryCode.
3813
+ * @param data.type Filter templates by account type (path first segment)
3814
+ * @returns PlatformStandardsResponseDto Resolved region plus the merged account-standard catalog of that region (groupable by productCategory client-side)
3402
3815
  * @throws ApiError
3403
3816
  */
3404
- public static priceControllerFindAll(
3405
- data: PriceControllerFindAllData
3406
- ): CancelablePromise<PriceControllerFindAllResponse> {
3817
+ public static platformControllerGetPlatformStandards(
3818
+ data: PlatformControllerGetPlatformStandardsData
3819
+ ): CancelablePromise<PlatformControllerGetPlatformStandardsResponse> {
3407
3820
  return __request(OpenAPI, {
3408
3821
  method: 'GET',
3409
- url: '/api/v1/{region}/bean/prices',
3822
+ url: '/api/v1/bean/platforms/{id}/standards',
3410
3823
  path: {
3411
- region: data.region
3824
+ id: data.id
3412
3825
  },
3413
3826
  query: {
3414
- currency: data.currency,
3415
- quoteCurrency: data.quoteCurrency,
3416
- dateFrom: data.dateFrom,
3417
- dateTo: data.dateTo,
3418
- search: data.search,
3419
- page: data.page,
3420
- limit: data.limit
3421
- }
3422
- });
3423
- }
3424
-
3425
- /**
3426
- * Get price by ID
3427
- * Returns a single price entry by its ID
3428
- * @param data The data for the request.
3429
- * @param data.id Price ID
3430
- * @param data.region Region code for tenant context
3431
- * @returns PriceResponseDto Price retrieved successfully
3432
- * @throws ApiError
3433
- */
3434
- public static priceControllerFindOne(
3435
- data: PriceControllerFindOneData
3436
- ): CancelablePromise<PriceControllerFindOneResponse> {
3437
- return __request(OpenAPI, {
3438
- method: 'GET',
3439
- url: '/api/v1/{region}/bean/prices/{id}',
3440
- path: {
3441
- id: data.id,
3442
- region: data.region
3443
- },
3444
- errors: {
3445
- 404: 'Price not found'
3827
+ region: data.region,
3828
+ type: data.type
3446
3829
  }
3447
3830
  });
3448
3831
  }
3449
3832
 
3450
3833
  /**
3451
- * Update a price
3452
- * Updates an existing price entry
3834
+ * Update a platform
3453
3835
  * @param data The data for the request.
3454
- * @param data.id Price ID
3455
- * @param data.region Region code for tenant context
3836
+ * @param data.id Platform ID
3456
3837
  * @param data.requestBody
3457
- * @returns PriceResponseDto Price updated successfully
3838
+ * @returns unknown Platform updated successfully
3458
3839
  * @throws ApiError
3459
3840
  */
3460
- public static priceControllerUpdate(
3461
- data: PriceControllerUpdateData
3462
- ): CancelablePromise<PriceControllerUpdateResponse> {
3841
+ public static platformControllerUpdate(
3842
+ data: PlatformControllerUpdateData
3843
+ ): CancelablePromise<PlatformControllerUpdateResponse> {
3463
3844
  return __request(OpenAPI, {
3464
3845
  method: 'PUT',
3465
- url: '/api/v1/{region}/bean/prices/{id}',
3466
- path: {
3467
- id: data.id,
3468
- region: data.region
3846
+ url: '/api/v1/bean/platforms/{id}',
3847
+ path: {
3848
+ id: data.id
3469
3849
  },
3470
3850
  body: data.requestBody,
3471
3851
  mediaType: 'application/json',
3472
3852
  errors: {
3473
- 404: 'Price not found',
3474
- 409: 'Updated price conflicts with existing price'
3853
+ 404: 'Platform not found'
3475
3854
  }
3476
3855
  });
3477
3856
  }
3478
3857
 
3479
3858
  /**
3480
- * Delete a price
3481
- * Deletes a price entry (hard delete)
3859
+ * Delete a platform
3482
3860
  * @param data The data for the request.
3483
- * @param data.id Price ID
3484
- * @param data.region Region code for tenant context
3485
- * @returns void Price deleted successfully
3861
+ * @param data.id Platform ID
3862
+ * @returns void Platform deleted successfully
3486
3863
  * @throws ApiError
3487
3864
  */
3488
- public static priceControllerDelete(
3489
- data: PriceControllerDeleteData
3490
- ): CancelablePromise<PriceControllerDeleteResponse> {
3865
+ public static platformControllerDelete(
3866
+ data: PlatformControllerDeleteData
3867
+ ): CancelablePromise<PlatformControllerDeleteResponse> {
3491
3868
  return __request(OpenAPI, {
3492
3869
  method: 'DELETE',
3493
- url: '/api/v1/{region}/bean/prices/{id}',
3870
+ url: '/api/v1/bean/platforms/{id}',
3494
3871
  path: {
3495
- id: data.id,
3496
- region: data.region
3872
+ id: data.id
3497
3873
  },
3498
3874
  errors: {
3499
- 404: 'Price not found'
3875
+ 404: 'Platform not found'
3500
3876
  }
3501
3877
  });
3502
3878
  }
3879
+ }
3503
3880
 
3881
+ export class DashboardService {
3504
3882
  /**
3505
- * Bulk create prices
3506
- * Creates multiple price entries at once (skips duplicates)
3883
+ * Get net worth overview
3884
+ * Returns total net worth with breakdown of assets and liabilities
3507
3885
  * @param data The data for the request.
3508
3886
  * @param data.region Region code for tenant context
3509
- * @param data.requestBody
3510
- * @returns PriceResponseDto Prices created successfully
3887
+ * @param data.date Date for balance calculation (ISO 8601 format)
3888
+ * @returns NetWorthResponseDto Net worth retrieved successfully
3511
3889
  * @throws ApiError
3512
3890
  */
3513
- public static priceControllerBulkCreate(
3514
- data: PriceControllerBulkCreateData
3515
- ): CancelablePromise<PriceControllerBulkCreateResponse> {
3891
+ public static dashboardControllerGetNetWorth(
3892
+ data: DashboardControllerGetNetWorthData
3893
+ ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3516
3894
  return __request(OpenAPI, {
3517
- method: 'POST',
3518
- url: '/api/v1/{region}/bean/prices/bulk',
3895
+ method: 'GET',
3896
+ url: '/api/v1/{region}/dashboard/net-worth',
3519
3897
  path: {
3520
3898
  region: data.region
3521
3899
  },
3522
- body: data.requestBody,
3523
- mediaType: 'application/json'
3900
+ query: {
3901
+ date: data.date
3902
+ },
3903
+ errors: {
3904
+ 401: 'User not authenticated'
3905
+ }
3524
3906
  });
3525
3907
  }
3526
- }
3527
3908
 
3528
- export class ReportingService {
3529
3909
  /**
3530
- * Get portfolio value trends
3531
- *
3532
- * Returns time series data of portfolio net worth.
3533
- *
3534
- * **Multi-currency Support:**
3535
- * - `series[].byCurrency` - Currency breakdown for each data point
3536
- * - `byCurrency` - Separate time series grouped by currency
3537
- * - `warnings` - Exchange rate warnings if conversion failed
3538
- *
3539
- * **Parameters:**
3540
- * - `period`: Time period (1m, 3m, 6m, 1y)
3541
- * - `granularity`: Data granularity (day, week, month)
3542
- *
3910
+ * Get accounts grouped by platform
3911
+ * Returns accounts with balances grouped by financial platform
3543
3912
  * @param data The data for the request.
3544
3913
  * @param data.region Region code for tenant context
3545
- * @param data.period Time period
3546
- * @param data.granularity Data granularity
3547
- * @returns PortfolioTrendsResponseDto Trends retrieved successfully
3914
+ * @param data.groupBy Grouping strategy
3915
+ * @param data.date Date for balance calculation (ISO 8601 format)
3916
+ * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3917
+ * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3548
3918
  * @throws ApiError
3549
3919
  */
3550
- public static reportingControllerGetPortfolioTrends(
3551
- data: ReportingControllerGetPortfolioTrendsData
3552
- ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
3920
+ public static dashboardControllerGetAccounts(
3921
+ data: DashboardControllerGetAccountsData
3922
+ ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3553
3923
  return __request(OpenAPI, {
3554
3924
  method: 'GET',
3555
- url: '/api/v1/{region}/reporting/portfolio/trends',
3925
+ url: '/api/v1/{region}/dashboard/accounts',
3556
3926
  path: {
3557
3927
  region: data.region
3558
3928
  },
3559
3929
  query: {
3560
- period: data.period,
3561
- granularity: data.granularity
3930
+ groupBy: data.groupBy,
3931
+ date: data.date,
3932
+ accountId: data.accountId
3562
3933
  },
3563
3934
  errors: {
3564
3935
  401: 'User not authenticated'
@@ -3567,116 +3938,95 @@ export class ReportingService {
3567
3938
  }
3568
3939
 
3569
3940
  /**
3570
- * Get cash-flow trends
3571
- *
3572
- * Monthly income / expense / netSavings over a fixed N-month window
3573
- * (current month + N−1 prior). Missing months are zero-filled (flow metric).
3574
- *
3575
- * **Parameters:**
3576
- * - `period`: 1m | 3m | 6m | 1y (default 6m)
3577
- * - `granularity`: accepted for API symmetry; v1 returns month buckets
3578
- *
3941
+ * Get cash flow summary
3942
+ * Returns income, expenses, and savings for a monthly period
3579
3943
  * @param data The data for the request.
3944
+ * @param data.period Period in YYYY-MM format
3580
3945
  * @param data.region Region code for tenant context
3581
- * @param data.period Time period
3582
- * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
3583
- * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
3946
+ * @returns CashFlowResponseDto Cash flow retrieved successfully
3584
3947
  * @throws ApiError
3585
3948
  */
3586
- public static reportingControllerGetCashFlowTrends(
3587
- data: ReportingControllerGetCashFlowTrendsData
3588
- ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
3949
+ public static dashboardControllerGetCashFlow(
3950
+ data: DashboardControllerGetCashFlowData
3951
+ ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3589
3952
  return __request(OpenAPI, {
3590
3953
  method: 'GET',
3591
- url: '/api/v1/{region}/reporting/cash-flow/trends',
3954
+ url: '/api/v1/{region}/dashboard/cash-flow',
3592
3955
  path: {
3593
3956
  region: data.region
3594
3957
  },
3595
3958
  query: {
3596
- period: data.period,
3597
- granularity: data.granularity
3959
+ period: data.period
3598
3960
  },
3599
3961
  errors: {
3962
+ 400: 'Invalid period format',
3600
3963
  401: 'User not authenticated'
3601
3964
  }
3602
3965
  });
3603
3966
  }
3604
3967
 
3605
3968
  /**
3606
- * Generate portfolio snapshot
3607
- *
3608
- * Manually generate a portfolio snapshot for a specific date.
3609
- *
3610
- * **Multi-currency Support:**
3611
- * - Fetches balances grouped by currency
3612
- * - Uses user's baseCurrency setting for conversion
3613
- * - Stores exchange rates and warnings
3614
- *
3615
- * **Use Cases:**
3616
- * - Testing snapshot generation
3617
- * - Force regeneration after data correction
3618
- * - Initial setup for new users
3619
- *
3969
+ * Get expenses/income grouped by functional category
3970
+ * 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)
3620
3971
  * @param data The data for the request.
3621
3972
  * @param data.region Region code for tenant context
3622
- * @param data.requestBody Optional date (defaults to today)
3623
- * @returns GenerateSnapshotResponse Snapshot generated successfully
3973
+ * @param data.groupBy Grouping strategy
3974
+ * @param data.period Time window (1m = current calendar month)
3975
+ * @param data.flow Account root to aggregate (expense → ^Expenses:, income → ^Income:)
3976
+ * @returns ExpensesByCategoryResponseDto Expenses retrieved successfully
3624
3977
  * @throws ApiError
3625
3978
  */
3626
- public static reportingControllerGenerateSnapshot(
3627
- data: ReportingControllerGenerateSnapshotData
3628
- ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
3979
+ public static dashboardControllerGetExpenses(
3980
+ data: DashboardControllerGetExpensesData
3981
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3629
3982
  return __request(OpenAPI, {
3630
- method: 'POST',
3631
- url: '/api/v1/{region}/reporting/snapshots/generate',
3983
+ method: 'GET',
3984
+ url: '/api/v1/{region}/dashboard/expenses',
3632
3985
  path: {
3633
3986
  region: data.region
3634
3987
  },
3635
- body: data.requestBody,
3636
- mediaType: 'application/json',
3988
+ query: {
3989
+ groupBy: data.groupBy,
3990
+ period: data.period,
3991
+ flow: data.flow
3992
+ },
3637
3993
  errors: {
3638
- 400: 'Invalid date format',
3994
+ 400: 'Invalid groupBy or period',
3639
3995
  401: 'User not authenticated'
3640
3996
  }
3641
3997
  });
3642
3998
  }
3999
+ }
3643
4000
 
4001
+ export class InvestmentService {
3644
4002
  /**
3645
- * Backfill portfolio snapshots
3646
- *
3647
- * Generate snapshots for a date range (historical data backfill).
3648
- *
3649
- * **Multi-currency Support:**
3650
- * - Each snapshot includes multi-currency data
3651
- * - Uses exchange rates available at generation time
3652
- * - Warnings stored for missing exchange rates
3653
- *
3654
- * **Best Practices:**
3655
- * - Use for initial setup after account configuration
3656
- * - Run during low-traffic periods for large date ranges
3657
- * - Existing snapshots are skipped (not regenerated)
3658
- *
4003
+ * Get per-holding unrealized + realized P&L
4004
+ * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3659
4005
  * @param data The data for the request.
3660
4006
  * @param data.region Region code for tenant context
3661
- * @param data.requestBody
3662
- * @returns BackfillSnapshotsResponse Backfill completed successfully
4007
+ * @param data.asOf As-of date (ISO 8601), defaults to today
4008
+ * @param data.accountId Scope to a single account
4009
+ * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
4010
+ * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3663
4011
  * @throws ApiError
3664
4012
  */
3665
- public static reportingControllerBackfillSnapshots(
3666
- data: ReportingControllerBackfillSnapshotsData
3667
- ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
4013
+ public static holdingPnlControllerGetHoldingPnl(
4014
+ data: HoldingPnlControllerGetHoldingPnlData
4015
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3668
4016
  return __request(OpenAPI, {
3669
- method: 'POST',
3670
- url: '/api/v1/{region}/reporting/snapshots/backfill',
4017
+ method: 'GET',
4018
+ url: '/api/v1/{region}/investment/holdings/pnl',
3671
4019
  path: {
3672
4020
  region: data.region
3673
4021
  },
3674
- body: data.requestBody,
3675
- mediaType: 'application/json',
4022
+ query: {
4023
+ asOf: data.asOf,
4024
+ accountId: data.accountId,
4025
+ method: data.method
4026
+ },
3676
4027
  errors: {
3677
- 400: 'Invalid date format or range',
3678
- 401: 'User not authenticated',
3679
- 409: 'Backfill already in progress for this user'
4028
+ 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
4029
+ 401: 'User not authenticated'
3680
4030
  }
3681
4031
  });
3682
4032
  }
@@ -3705,7 +4055,7 @@ export class AuthService {
3705
4055
  * Anonymous login with access token
3706
4056
  * @param data The data for the request.
3707
4057
  * @param data.requestBody
3708
- * @returns unknown Login successful
4058
+ * @returns AnonymousLoginResponseDto Login successful
3709
4059
  * @throws ApiError
3710
4060
  */
3711
4061
  public static authControllerAccessTokenLogin(
@@ -3723,15 +4073,52 @@ export class AuthService {
3723
4073
  }
3724
4074
  }
3725
4075
 
3726
- export class DefaultService {
4076
+ export class CommunityService {
4077
+ /**
4078
+ * Relay a sanitized parser-contribution payload
4079
+ * A server-side bot re-sanitizes the payload and opens an issue on the target repository; the issue URL is returned. The payload is never persisted or logged (forward-and-drop).
4080
+ * @param data The data for the request.
4081
+ * @param data.region Region code for tenant context (routing only; the institution region rides in the payload meta)
4082
+ * @param data.requestBody
4083
+ * @returns ParserContributionRelayResponseDto Issue created by the bot
4084
+ * @throws ApiError
4085
+ */
4086
+ public static parserContributionControllerCreate(
4087
+ data: ParserContributionControllerCreateData
4088
+ ): CancelablePromise<ParserContributionControllerCreateResponse> {
4089
+ return __request(OpenAPI, {
4090
+ method: 'POST',
4091
+ url: '/api/v1/{region}/community/parser-contributions',
4092
+ path: {
4093
+ region: data.region
4094
+ },
4095
+ body: data.requestBody,
4096
+ mediaType: 'application/json',
4097
+ errors: {
4098
+ 401: 'Unauthorized',
4099
+ 422: 'Validation failed (institution slug, empty samples, row/cell size limits)',
4100
+ 429: 'Rate limited (5 submissions per user per hour)',
4101
+ 501: 'Relay not configured on this deployment — clients fall back to the clipboard flow',
4102
+ 502: 'GitHub bot failure (upstream), safe to retry'
4103
+ }
4104
+ });
4105
+ }
4106
+ }
4107
+
4108
+ export class AdminCacheService {
3727
4109
  /**
3728
- * @returns unknown
4110
+ * Flush entire cache (L1 + L2)
4111
+ * Clears ALL cache entries across ALL namespaces and users. Use only for emergency cache corruption recovery, maintenance-window refresh, or development resets.
4112
+ * @returns unknown Cache flushed successfully
3729
4113
  * @throws ApiError
3730
4114
  */
3731
4115
  public static cacheControllerFlushCache(): CancelablePromise<CacheControllerFlushCacheResponse> {
3732
4116
  return __request(OpenAPI, {
3733
4117
  method: 'POST',
3734
- url: '/api/v1/cache/flush'
4118
+ url: '/api/v1/cache/flush',
4119
+ errors: {
4120
+ 403: 'Admin access required'
4121
+ }
3735
4122
  });
3736
4123
  }
3737
4124
  }
@@ -3892,3 +4279,53 @@ export class InfoService {
3892
4279
  });
3893
4280
  }
3894
4281
  }
4282
+
4283
+ export class MarketDataService {
4284
+ /**
4285
+ * Search market symbols by name or code
4286
+ * Ranked search over the openbb catalog. Empty `q` returns [].
4287
+ * @param data The data for the request.
4288
+ * @param data.q Search term — matched against symbol and instrument name. Empty string returns [].
4289
+ * @param data.limit Maximum number of results (clamped 1..50)
4290
+ * @param data.exchange Filter by exchange code (e.g. US, HK, SS, SZ)
4291
+ * @param data.assetType Filter by OpenBB asset_type (e.g. stock, etf)
4292
+ * @returns SymbolSearchResultDto Ranked search results
4293
+ * @throws ApiError
4294
+ */
4295
+ public static symbolControllerSearch(
4296
+ data: SymbolControllerSearchData
4297
+ ): CancelablePromise<SymbolControllerSearchResponse> {
4298
+ return __request(OpenAPI, {
4299
+ method: 'GET',
4300
+ url: '/api/v1/market/symbols/search',
4301
+ query: {
4302
+ q: data.q,
4303
+ limit: data.limit,
4304
+ exchange: data.exchange,
4305
+ assetType: data.assetType
4306
+ }
4307
+ });
4308
+ }
4309
+
4310
+ /**
4311
+ * Get a market symbol quote
4312
+ * @param data The data for the request.
4313
+ * @param data.symbol
4314
+ * @returns SymbolQuoteDto Symbol quote
4315
+ * @throws ApiError
4316
+ */
4317
+ public static symbolControllerGetQuote(
4318
+ data: SymbolControllerGetQuoteData
4319
+ ): CancelablePromise<SymbolControllerGetQuoteResponse> {
4320
+ return __request(OpenAPI, {
4321
+ method: 'GET',
4322
+ url: '/api/v1/market/symbols/{symbol}/quote',
4323
+ path: {
4324
+ symbol: data.symbol
4325
+ },
4326
+ errors: {
4327
+ 404: 'Symbol not found in the openbb catalog'
4328
+ }
4329
+ });
4330
+ }
4331
+ }