@firela/api-types 0.0.0-canary.f2efa2bf → 0.0.0-canary.fb3ac1dd

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