@firela/api-types 0.0.0-canary.3ed455fd → 0.0.0-canary.3f4cd10

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,
@@ -55,6 +57,48 @@ import type {
55
57
  ReviewControllerUndoResponse,
56
58
  ReviewControllerBatchResolveData,
57
59
  ReviewControllerBatchResolveResponse,
60
+ TransactionRuleControllerCreateData,
61
+ TransactionRuleControllerCreateResponse,
62
+ TransactionRuleControllerListData,
63
+ TransactionRuleControllerListResponse,
64
+ TransactionRuleControllerValidateData,
65
+ TransactionRuleControllerValidateResponse,
66
+ TransactionRuleControllerBulkCreateData,
67
+ TransactionRuleControllerBulkCreateResponse,
68
+ TransactionRuleControllerExportData,
69
+ TransactionRuleControllerExportResponse,
70
+ TransactionRuleControllerGetStatisticsData,
71
+ TransactionRuleControllerGetStatisticsResponse,
72
+ TransactionRuleControllerGetDetailData,
73
+ TransactionRuleControllerGetDetailResponse,
74
+ TransactionRuleControllerUpdateData,
75
+ TransactionRuleControllerUpdateResponse,
76
+ TransactionRuleControllerDeleteData,
77
+ TransactionRuleControllerDeleteResponse,
78
+ TransactionRuleControllerTestData,
79
+ TransactionRuleControllerTestResponse,
80
+ UserControllerDeleteOwnUserData,
81
+ UserControllerDeleteOwnUserResponse,
82
+ UserControllerGetUserData,
83
+ UserControllerGetUserResponse,
84
+ UserControllerSignupUserData,
85
+ UserControllerSignupUserResponse,
86
+ UserControllerDeleteUserData,
87
+ UserControllerDeleteUserResponse,
88
+ UserControllerGetUserInfoData,
89
+ UserControllerGetUserInfoResponse,
90
+ UserControllerUpdateUserSettingData,
91
+ UserControllerUpdateUserSettingResponse,
92
+ UserControllerGetAllUserSettingsByPageData,
93
+ UserControllerGetAllUserSettingsByPageResponse,
94
+ UserControllerGetAssetLiabilitySummaryResponse,
95
+ PropertyControllerGetAllResponse,
96
+ PropertyControllerGetByKeyData,
97
+ PropertyControllerGetByKeyResponse,
98
+ PropertyControllerUpdateData,
99
+ PropertyControllerUpdateResponse,
100
+ PropertyControllerDeleteData,
101
+ PropertyControllerDeleteResponse,
58
102
  PayeeControllerCreateData,
59
103
  PayeeControllerCreateResponse,
60
104
  PayeeControllerFindAllData,
@@ -83,6 +127,7 @@ import type {
83
127
  PayeeProfileAdminControllerVerifyResponse,
84
128
  PayeeProfileAdminControllerUnverifyData,
85
129
  PayeeProfileAdminControllerUnverifyResponse,
130
+ PayeeProfileControllerListActiveResponse,
86
131
  CommodityControllerCreateData,
87
132
  CommodityControllerCreateResponse,
88
133
  CommodityControllerFindAllData,
@@ -97,6 +142,26 @@ import type {
97
142
  CommodityControllerGetOrCreateResponse,
98
143
  CommodityControllerBulkCreateData,
99
144
  CommodityControllerBulkCreateResponse,
145
+ ReportingControllerGetPortfolioTrendsData,
146
+ ReportingControllerGetPortfolioTrendsResponse,
147
+ ReportingControllerGetCashFlowTrendsData,
148
+ ReportingControllerGetCashFlowTrendsResponse,
149
+ ReportingControllerGenerateSnapshotData,
150
+ ReportingControllerGenerateSnapshotResponse,
151
+ ReportingControllerBackfillSnapshotsData,
152
+ ReportingControllerBackfillSnapshotsResponse,
153
+ PriceControllerCreateData,
154
+ PriceControllerCreateResponse,
155
+ PriceControllerFindAllData,
156
+ PriceControllerFindAllResponse,
157
+ PriceControllerFindOneData,
158
+ PriceControllerFindOneResponse,
159
+ PriceControllerUpdateData,
160
+ PriceControllerUpdateResponse,
161
+ PriceControllerDeleteData,
162
+ PriceControllerDeleteResponse,
163
+ PriceControllerBulkCreateData,
164
+ PriceControllerBulkCreateResponse,
100
165
  RecurringRuleControllerCreateData,
101
166
  RecurringRuleControllerCreateResponse,
102
167
  RecurringRuleControllerFindAllData,
@@ -129,48 +194,31 @@ import type {
129
194
  ExpectedTransactionControllerEnterNowResponse,
130
195
  ForecastControllerGetForecastData,
131
196
  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,
152
- UserControllerDeleteOwnUserData,
153
- UserControllerDeleteOwnUserResponse,
154
- UserControllerGetUserData,
155
- UserControllerGetUserResponse,
156
- UserControllerSignupUserData,
157
- UserControllerSignupUserResponse,
158
- UserControllerDeleteUserData,
159
- UserControllerDeleteUserResponse,
160
- UserControllerGetUserInfoData,
161
- UserControllerGetUserInfoResponse,
162
- UserControllerUpdateUserSettingData,
163
- UserControllerUpdateUserSettingResponse,
164
- UserControllerGetAllUserSettingsByPageData,
165
- UserControllerGetAllUserSettingsByPageResponse,
166
- UserControllerGetAssetLiabilitySummaryResponse,
167
- PropertyControllerGetAllResponse,
168
- PropertyControllerGetByKeyData,
169
- PropertyControllerGetByKeyResponse,
170
- PropertyControllerUpdateData,
171
- PropertyControllerUpdateResponse,
172
- PropertyControllerDeleteData,
173
- PropertyControllerDeleteResponse,
197
+ CategoryCatalogControllerListData,
198
+ CategoryCatalogControllerListResponse,
199
+ EventControllerCreateData,
200
+ EventControllerCreateResponse,
201
+ EventControllerFindAllData,
202
+ EventControllerFindAllResponse,
203
+ EventControllerFindOneData,
204
+ EventControllerFindOneResponse,
205
+ EventControllerUpdateData,
206
+ EventControllerUpdateResponse,
207
+ EventControllerDeleteData,
208
+ EventControllerDeleteResponse,
209
+ EventControllerGetSliceData,
210
+ EventControllerGetSliceResponse,
211
+ OnboardingControllerBootstrapData,
212
+ OnboardingControllerBootstrapResponse,
213
+ ReconciliationControllerComputeData,
214
+ ReconciliationControllerComputeResponse,
215
+ ReconciliationControllerAssertData,
216
+ ReconciliationControllerAssertResponse,
217
+ ReconciliationControllerPadData,
218
+ ReconciliationControllerPadResponse,
219
+ ReconciliationControllerHistoryData,
220
+ ReconciliationControllerHistoryResponse,
221
+ ExportControllerExportBeancountData,
174
222
  ExportControllerExportBeancountResponse,
175
223
  FileImportControllerImportFileData,
176
224
  FileImportControllerImportFileResponse,
@@ -184,22 +232,20 @@ import type {
184
232
  ImporterConfigControllerUpdateConfigResponse,
185
233
  ImporterConfigControllerResetConfigData,
186
234
  ImporterConfigControllerResetConfigResponse,
187
- PlatformControllerFindAllResponse,
188
- PlatformControllerCreateData,
189
- PlatformControllerCreateResponse,
190
- PlatformControllerGetPlatformListResponse,
191
- PlatformControllerMatchPlatformsData,
192
- PlatformControllerMatchPlatformsResponse,
193
- PlatformControllerUpdateData,
194
- PlatformControllerUpdateResponse,
195
- PlatformControllerDeleteData,
196
- PlatformControllerDeleteResponse,
197
235
  ProviderSyncControllerSyncData,
198
236
  ProviderSyncControllerSyncResponse,
199
237
  ProviderSyncControllerGetSupportedProvidersData,
200
238
  ProviderSyncControllerGetSupportedProvidersResponse,
201
239
  ProviderSyncControllerIsProviderSupportedData,
202
240
  ProviderSyncControllerIsProviderSupportedResponse,
241
+ ExternalAccountLinkControllerCreateData,
242
+ ExternalAccountLinkControllerCreateResponse,
243
+ ExternalAccountLinkControllerFindAllData,
244
+ ExternalAccountLinkControllerFindAllResponse,
245
+ ExternalAccountLinkControllerFindOneData,
246
+ ExternalAccountLinkControllerFindOneResponse,
247
+ ExternalAccountLinkControllerRemoveData,
248
+ ExternalAccountLinkControllerRemoveResponse,
203
249
  TelemetryControllerReportTelemetryData,
204
250
  TelemetryControllerReportTelemetryResponse,
205
251
  TelemetryControllerReportCoverageMissData,
@@ -212,35 +258,38 @@ import type {
212
258
  NlpControllerClearSessionResponse,
213
259
  NlpControllerGetSessionData,
214
260
  NlpControllerGetSessionResponse,
261
+ PlatformControllerFindAllResponse,
262
+ PlatformControllerCreateData,
263
+ PlatformControllerCreateResponse,
264
+ PlatformControllerGetPlatformListData,
265
+ PlatformControllerGetPlatformListResponse,
266
+ PlatformControllerMatchPlatformsData,
267
+ PlatformControllerMatchPlatformsResponse,
268
+ PlatformControllerGetPlatformStandardsData,
269
+ PlatformControllerGetPlatformStandardsResponse,
270
+ PlatformControllerUpdateData,
271
+ PlatformControllerUpdateResponse,
272
+ PlatformControllerDeleteData,
273
+ PlatformControllerDeleteResponse,
215
274
  DashboardControllerGetNetWorthData,
216
275
  DashboardControllerGetNetWorthResponse,
217
276
  DashboardControllerGetAccountsData,
218
277
  DashboardControllerGetAccountsResponse,
219
278
  DashboardControllerGetCashFlowData,
220
279
  DashboardControllerGetCashFlowResponse,
280
+ DashboardControllerGetExpensesData,
281
+ DashboardControllerGetExpensesResponse,
282
+ DashboardControllerGetAdvisorContextData,
283
+ DashboardControllerGetAdvisorContextResponse,
221
284
  HoldingPnlControllerGetHoldingPnlData,
222
285
  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
286
  ApiKeysControllerCreateApiKeyResponse,
242
287
  AuthControllerAccessTokenLoginData,
243
288
  AuthControllerAccessTokenLoginResponse,
289
+ AuthControllerAdvisorTokenLoginData,
290
+ AuthControllerAdvisorTokenLoginResponse,
291
+ ParserContributionControllerCreateData,
292
+ ParserContributionControllerCreateResponse,
244
293
  CacheControllerFlushCacheResponse,
245
294
  ExchangeRateControllerGetExchangeRateData,
246
295
  ExchangeRateControllerGetExchangeRateResponse,
@@ -252,7 +301,11 @@ import type {
252
301
  HealthControllerResetCircuitBreakerData,
253
302
  HealthControllerResetCircuitBreakerResponse,
254
303
  HealthControllerGetMetricsResponse,
255
- InfoControllerGetInfoResponse
304
+ InfoControllerGetInfoResponse,
305
+ SymbolControllerSearchData,
306
+ SymbolControllerSearchResponse,
307
+ SymbolControllerGetQuoteData,
308
+ SymbolControllerGetQuoteResponse
256
309
  } from './types.gen';
257
310
 
258
311
  export class BeanAccountsService {
@@ -290,7 +343,7 @@ export class BeanAccountsService {
290
343
  * @param data.type Filter by account type
291
344
  * @param data.status Filter by status
292
345
  * @param data.isCustom Filter by custom (user-created) accounts only
293
- * @param data.search Search term for path or i18nKey
346
+ * @param data.search Search term matched against account path and user-set display name (case-insensitive)
294
347
  * @param data.limit Maximum number of results
295
348
  * @param data.offset Number of results to skip
296
349
  * @returns AccountListResponseDto Accounts retrieved successfully
@@ -371,7 +424,7 @@ export class BeanAccountsService {
371
424
 
372
425
  /**
373
426
  * Delete account
374
- * Deletes an account (only if no transactions)
427
+ * Deletes an account (only if no active transactions; voided/superseded residual postings are cleaned up)
375
428
  * @param data The data for the request.
376
429
  * @param data.id Account UUID
377
430
  * @param data.region Region code for tenant context
@@ -390,7 +443,7 @@ export class BeanAccountsService {
390
443
  },
391
444
  errors: {
392
445
  404: 'Account not found',
393
- 409: 'Account has transactions and cannot be deleted'
446
+ 409: 'Account has active transactions and cannot be deleted'
394
447
  }
395
448
  });
396
449
  }
@@ -452,16 +505,45 @@ export class BeanAccountsService {
452
505
  }
453
506
  });
454
507
  }
508
+
509
+ /**
510
+ * Post an opening-balance transaction
511
+ * 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.
512
+ * @param data The data for the request.
513
+ * @param data.id Account UUID
514
+ * @param data.region Region code for tenant context
515
+ * @param data.requestBody
516
+ * @returns OpeningBalanceResultDto Opening-balance transaction created
517
+ * @throws ApiError
518
+ */
519
+ public static accountControllerAddOpeningBalance(
520
+ data: AccountControllerAddOpeningBalanceData
521
+ ): CancelablePromise<AccountControllerAddOpeningBalanceResponse> {
522
+ return __request(OpenAPI, {
523
+ method: 'POST',
524
+ url: '/api/v1/{region}/bean/accounts/{id}/opening-balance',
525
+ path: {
526
+ id: data.id,
527
+ region: data.region
528
+ },
529
+ body: data.requestBody,
530
+ mediaType: 'application/json',
531
+ errors: {
532
+ 404: 'Account not found',
533
+ 409: 'An opening balance already exists for this account'
534
+ }
535
+ });
536
+ }
455
537
  }
456
538
 
457
539
  export class BeanAccountStandardsService {
458
540
  /**
459
541
  * Get account templates
460
- * Returns predefined account templates for a region. Supports filtering by account type and search term.
542
+ * Returns predefined account templates for a region. Supports filtering by account type and search term. Not-yet-open region codes return the universal-only catalog (#759).
461
543
  * @param data The data for the request.
462
- * @param data.region Region code (cn, us, de)
544
+ * @param data.region Region code (any ISO alpha-2; not-yet-open codes return the universal-only catalog)
463
545
  * @param data.type Filter by account type
464
- * @param data.search Search term for path or description
546
+ * @param data.search Search term for path, description, aliases, or localized display name
465
547
  * @returns AccountStandardListResponseDto Account templates retrieved successfully
466
548
  * @throws ApiError
467
549
  */
@@ -483,9 +565,9 @@ export class BeanAccountStandardsService {
483
565
 
484
566
  /**
485
567
  * Get template metadata for an account path
486
- * Returns extendable status and root type for a template path.
568
+ * Returns root type for a template path.
487
569
  * @param data The data for the request.
488
- * @param data.region Region code for tenant context
570
+ * @param data.region Region code for tenant context. Not-yet-open codes degrade to the universal-only catalog (#759)
489
571
  * @param data.path Account path to check
490
572
  * @returns TemplateMetadataResponseDto Template metadata retrieved successfully
491
573
  * @throws ApiError
@@ -507,9 +589,9 @@ export class BeanAccountStandardsService {
507
589
 
508
590
  /**
509
591
  * Get available regions with hierarchy
510
- * Returns supported regions with inheritance metadata
592
+ * Returns the full region catalog (every ISO 3166-1 entry) with an 'open' flag and inheritance metadata (#759)
511
593
  * @param data The data for the request.
512
- * @param data.region Region code for tenant context
594
+ * @param data.region Region code for tenant context. Not-yet-open codes degrade to the universal-only catalog (#759)
513
595
  * @returns RegionsMetadataResponseDto Regions metadata retrieved successfully
514
596
  * @throws ApiError
515
597
  */
@@ -566,9 +648,11 @@ export class BeanTransactionsService {
566
648
  * @param data.offset Number of items to skip (default: 0)
567
649
  * @param data.dateFrom Filter by start date (inclusive), format: YYYY-MM-DD
568
650
  * @param data.dateTo Filter by end date (inclusive), format: YYYY-MM-DD
569
- * @param data.status Filter by transaction status
651
+ * @param data.status Filter by transaction status: single value, comma-separated multi-value (e.g. VOIDED,SUPERSEDED), or ALL to include audit rows. Defaults to ACTIVE-only (ADR-0128; previously unfiltered — breaking change).
570
652
  * @param data.search Search in narration and payee fields (max 200 chars)
571
653
  * @param data.accountId Filter by account ID (transactions with postings to this account)
654
+ * @param data.category Filter by ADR-0075 functional category (Group segment); matches any posting to an account whose derived Group segment equals this value. Must be accompanied by flow (ADR-0126).
655
+ * @param data.flow Required when category is present (400 otherwise) and vice versa (ADR-0126). Restricts the category account set to the flow root (income → Income:, expense → Expenses:) and drives the per-leg sign normalization of row viewpointAmount and the summary. OpenAPI cannot express conditional requiredness — the pairing is enforced at runtime.
572
656
  * @returns TransactionListResponseDto Transaction list
573
657
  * @throws ApiError
574
658
  */
@@ -588,7 +672,9 @@ export class BeanTransactionsService {
588
672
  dateTo: data.dateTo,
589
673
  status: data.status,
590
674
  search: data.search,
591
- accountId: data.accountId
675
+ accountId: data.accountId,
676
+ category: data.category,
677
+ flow: data.flow
592
678
  },
593
679
  errors: {
594
680
  400: 'Validation failed',
@@ -776,7 +862,7 @@ export class BeanBalancesService {
776
862
  * Query account balance
777
863
  * Calculate account balance at a specific date for a single currency
778
864
  * @param data The data for the request.
779
- * @param data.account Account name (e.g., "Assets:Bank:Checking")
865
+ * @param data.account Account name (e.g., "Assets:Checking")
780
866
  * @param data.region Region code for tenant context
781
867
  * @param data.date Date to calculate balance at (ISO 8601 format)
782
868
  * @param data.currency Currency to query (e.g., "USD", "CNY")
@@ -969,81 +1055,614 @@ export class BeanReviewsService {
969
1055
  }
970
1056
  }
971
1057
 
972
- export class BeanPayeesService {
1058
+ export class BeanTransactionRulesService {
973
1059
  /**
974
- * Create a new payee
975
- * Creates a new payee mapping for the authenticated user. The payee name must be unique within the user's account.
1060
+ * Create a new transaction rule (or upsert if upsertByPayee=true)
1061
+ * Creates a new rule. If upsertByPayee=true, updates existing rule matching payeeKeywords[0] instead of creating duplicate.
976
1062
  * @param data The data for the request.
1063
+ * @param data.region Region code for tenant context
977
1064
  * @param data.requestBody
978
- * @returns PayeeResponseDto Payee created successfully
1065
+ * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
979
1066
  * @throws ApiError
980
1067
  */
981
- public static payeeControllerCreate(
982
- data: PayeeControllerCreateData
983
- ): CancelablePromise<PayeeControllerCreateResponse> {
1068
+ public static transactionRuleControllerCreate(
1069
+ data: TransactionRuleControllerCreateData
1070
+ ): CancelablePromise<TransactionRuleControllerCreateResponse> {
984
1071
  return __request(OpenAPI, {
985
1072
  method: 'POST',
986
- url: '/api/v1/bean/payees',
1073
+ url: '/api/v1/{region}/bean/transaction-rules',
1074
+ path: {
1075
+ region: data.region
1076
+ },
987
1077
  body: data.requestBody,
988
1078
  mediaType: 'application/json',
989
1079
  errors: {
990
- 400: 'Invalid input data',
991
- 409: 'Payee already exists'
1080
+ 400: 'Validation failed',
1081
+ 401: 'Unauthorized',
1082
+ 409: 'Resource conflict - another process is updating this rule'
992
1083
  }
993
1084
  });
994
1085
  }
995
1086
 
996
1087
  /**
997
- * List user payees
998
- * Returns all payee mappings for the authenticated user with optional filtering
1088
+ * Get all transaction rules for user
999
1089
  * @param data The data for the request.
1000
- * @param data.search Search term for payee name (partial match, case-insensitive). Useful for autocomplete.
1001
- * @param data.payee Filter by exact payee name match
1002
- * @param data.category Filter by custom category
1003
- * @param data.tag Filter by custom tag (returns payees that have this tag)
1004
- * @param data.isActive Filter by active status. Defaults to true (show only active payees).
1005
- * @returns PayeeListResponseDto Payees retrieved successfully
1090
+ * @param data.region Region code for tenant context
1091
+ * @param data.limit Max results per page (default: 20, max: 100)
1092
+ * @param data.offset Pagination offset (default: 0)
1093
+ * @param data.enabled Filter by enabled status
1094
+ * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
1095
+ * @param data.autoApplyEnabled Filter by auto-apply status
1096
+ * @returns TransactionRuleListResponseDto List of rules
1006
1097
  * @throws ApiError
1007
1098
  */
1008
- public static payeeControllerFindAll(
1009
- data: PayeeControllerFindAllData = {}
1010
- ): CancelablePromise<PayeeControllerFindAllResponse> {
1099
+ public static transactionRuleControllerList(
1100
+ data: TransactionRuleControllerListData
1101
+ ): CancelablePromise<TransactionRuleControllerListResponse> {
1011
1102
  return __request(OpenAPI, {
1012
1103
  method: 'GET',
1013
- url: '/api/v1/bean/payees',
1104
+ url: '/api/v1/{region}/bean/transaction-rules',
1105
+ path: {
1106
+ region: data.region
1107
+ },
1014
1108
  query: {
1015
- search: data.search,
1016
- payee: data.payee,
1017
- category: data.category,
1018
- tag: data.tag,
1019
- isActive: data.isActive
1109
+ limit: data.limit,
1110
+ offset: data.offset,
1111
+ enabled: data.enabled,
1112
+ learningSource: data.learningSource,
1113
+ autoApplyEnabled: data.autoApplyEnabled
1114
+ },
1115
+ errors: {
1116
+ 401: 'Unauthorized'
1020
1117
  }
1021
1118
  });
1022
1119
  }
1023
1120
 
1024
1121
  /**
1025
- * Get payee autocomplete suggestions
1026
- * Returns active payee names matching the query, sorted by recent usage. Used for transaction input autocomplete.
1122
+ * Validate transaction rule configuration
1027
1123
  * @param data The data for the request.
1028
- * @param data.q Search query for payee name (partial match, case-insensitive)
1029
- * @param data.limit Maximum number of suggestions
1030
- * @returns PayeeAutocompleteResponseDto Autocomplete suggestions retrieved successfully
1124
+ * @param data.region Region code for tenant context
1125
+ * @param data.requestBody
1126
+ * @returns ValidateRuleResponseDto Validation result
1031
1127
  * @throws ApiError
1032
1128
  */
1033
- public static payeeControllerAutocomplete(
1034
- data: PayeeControllerAutocompleteData
1035
- ): CancelablePromise<PayeeControllerAutocompleteResponse> {
1129
+ public static transactionRuleControllerValidate(
1130
+ data: TransactionRuleControllerValidateData
1131
+ ): CancelablePromise<TransactionRuleControllerValidateResponse> {
1036
1132
  return __request(OpenAPI, {
1037
- method: 'GET',
1038
- url: '/api/v1/bean/payees/autocomplete',
1039
- query: {
1040
- q: data.q,
1041
- limit: data.limit
1042
- }
1043
- });
1044
- }
1045
-
1046
- /**
1133
+ method: 'POST',
1134
+ url: '/api/v1/{region}/bean/transaction-rules/validate',
1135
+ path: {
1136
+ region: data.region
1137
+ },
1138
+ body: data.requestBody,
1139
+ mediaType: 'application/json',
1140
+ errors: {
1141
+ 400: 'Validation failed',
1142
+ 401: 'Unauthorized'
1143
+ }
1144
+ });
1145
+ }
1146
+
1147
+ /**
1148
+ * Bulk create transaction rules
1149
+ * @param data The data for the request.
1150
+ * @param data.region Region code for tenant context
1151
+ * @param data.requestBody
1152
+ * @returns BulkCreateRulesResponseDto Bulk create completed
1153
+ * @throws ApiError
1154
+ */
1155
+ public static transactionRuleControllerBulkCreate(
1156
+ data: TransactionRuleControllerBulkCreateData
1157
+ ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
1158
+ return __request(OpenAPI, {
1159
+ method: 'POST',
1160
+ url: '/api/v1/{region}/bean/transaction-rules/bulk',
1161
+ path: {
1162
+ region: data.region
1163
+ },
1164
+ body: data.requestBody,
1165
+ mediaType: 'application/json',
1166
+ errors: {
1167
+ 400: 'Invalid bulk create data',
1168
+ 401: 'Unauthorized'
1169
+ }
1170
+ });
1171
+ }
1172
+
1173
+ /**
1174
+ * Export transaction rules
1175
+ * @param data The data for the request.
1176
+ * @param data.format Export format (currently only JSON supported)
1177
+ * @param data.region Region code for tenant context
1178
+ * @returns ExportRulesResponseDto Exported rules
1179
+ * @throws ApiError
1180
+ */
1181
+ public static transactionRuleControllerExport(
1182
+ data: TransactionRuleControllerExportData
1183
+ ): CancelablePromise<TransactionRuleControllerExportResponse> {
1184
+ return __request(OpenAPI, {
1185
+ method: 'GET',
1186
+ url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
1187
+ path: {
1188
+ format: data.format,
1189
+ region: data.region
1190
+ },
1191
+ errors: {
1192
+ 400: 'Unsupported format',
1193
+ 401: 'Unauthorized'
1194
+ }
1195
+ });
1196
+ }
1197
+
1198
+ /**
1199
+ * Get transaction rule statistics
1200
+ * @param data The data for the request.
1201
+ * @param data.period Statistics time period
1202
+ * @param data.region Region code for tenant context
1203
+ * @returns RuleStatisticsResponseDto Rule statistics
1204
+ * @throws ApiError
1205
+ */
1206
+ public static transactionRuleControllerGetStatistics(
1207
+ data: TransactionRuleControllerGetStatisticsData
1208
+ ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
1209
+ return __request(OpenAPI, {
1210
+ method: 'GET',
1211
+ url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
1212
+ path: {
1213
+ period: data.period,
1214
+ region: data.region
1215
+ },
1216
+ errors: {
1217
+ 401: 'Unauthorized'
1218
+ }
1219
+ });
1220
+ }
1221
+
1222
+ /**
1223
+ * Get transaction rule detail
1224
+ * @param data The data for the request.
1225
+ * @param data.ruleId Rule ID
1226
+ * @param data.region Region code for tenant context
1227
+ * @returns TransactionRuleResponseDto Rule details
1228
+ * @throws ApiError
1229
+ */
1230
+ public static transactionRuleControllerGetDetail(
1231
+ data: TransactionRuleControllerGetDetailData
1232
+ ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
1233
+ return __request(OpenAPI, {
1234
+ method: 'GET',
1235
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
1236
+ path: {
1237
+ ruleId: data.ruleId,
1238
+ region: data.region
1239
+ },
1240
+ errors: {
1241
+ 401: 'Unauthorized',
1242
+ 403: 'Forbidden - not owner of rule',
1243
+ 404: 'Rule not found'
1244
+ }
1245
+ });
1246
+ }
1247
+
1248
+ /**
1249
+ * Update a transaction rule
1250
+ * @param data The data for the request.
1251
+ * @param data.ruleId Rule ID to update
1252
+ * @param data.region Region code for tenant context
1253
+ * @param data.requestBody
1254
+ * @returns TransactionRuleResponseDto Rule updated successfully
1255
+ * @throws ApiError
1256
+ */
1257
+ public static transactionRuleControllerUpdate(
1258
+ data: TransactionRuleControllerUpdateData
1259
+ ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
1260
+ return __request(OpenAPI, {
1261
+ method: 'PUT',
1262
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
1263
+ path: {
1264
+ ruleId: data.ruleId,
1265
+ region: data.region
1266
+ },
1267
+ body: data.requestBody,
1268
+ mediaType: 'application/json',
1269
+ errors: {
1270
+ 400: 'Validation failed',
1271
+ 401: 'Unauthorized',
1272
+ 403: 'Forbidden - not owner of rule',
1273
+ 404: 'Rule not found',
1274
+ 409: 'Resource conflict - rule is being modified by another process'
1275
+ }
1276
+ });
1277
+ }
1278
+
1279
+ /**
1280
+ * Delete a transaction rule
1281
+ * @param data The data for the request.
1282
+ * @param data.ruleId Rule ID to delete
1283
+ * @param data.region Region code for tenant context
1284
+ * @returns void Rule deleted successfully
1285
+ * @throws ApiError
1286
+ */
1287
+ public static transactionRuleControllerDelete(
1288
+ data: TransactionRuleControllerDeleteData
1289
+ ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
1290
+ return __request(OpenAPI, {
1291
+ method: 'DELETE',
1292
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
1293
+ path: {
1294
+ ruleId: data.ruleId,
1295
+ region: data.region
1296
+ },
1297
+ errors: {
1298
+ 401: 'Unauthorized',
1299
+ 403: 'Forbidden - not owner of rule',
1300
+ 404: 'Rule not found',
1301
+ 409: 'Resource conflict - rule is being modified by another process'
1302
+ }
1303
+ });
1304
+ }
1305
+
1306
+ /**
1307
+ * Test rule matching
1308
+ * @param data The data for the request.
1309
+ * @param data.ruleId Rule ID to test
1310
+ * @param data.region Region code for tenant context
1311
+ * @param data.requestBody
1312
+ * @returns TestRuleResponseDto Test result
1313
+ * @throws ApiError
1314
+ */
1315
+ public static transactionRuleControllerTest(
1316
+ data: TransactionRuleControllerTestData
1317
+ ): CancelablePromise<TransactionRuleControllerTestResponse> {
1318
+ return __request(OpenAPI, {
1319
+ method: 'POST',
1320
+ url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
1321
+ path: {
1322
+ ruleId: data.ruleId,
1323
+ region: data.region
1324
+ },
1325
+ body: data.requestBody,
1326
+ mediaType: 'application/json',
1327
+ errors: {
1328
+ 401: 'Unauthorized',
1329
+ 403: 'Forbidden - not owner of rule',
1330
+ 404: 'Rule not found'
1331
+ }
1332
+ });
1333
+ }
1334
+ }
1335
+
1336
+ export class UsersService {
1337
+ /**
1338
+ * Delete own user account
1339
+ * @param data The data for the request.
1340
+ * @param data.requestBody
1341
+ * @returns void User deleted successfully
1342
+ * @throws ApiError
1343
+ */
1344
+ public static userControllerDeleteOwnUser(
1345
+ data: UserControllerDeleteOwnUserData
1346
+ ): CancelablePromise<UserControllerDeleteOwnUserResponse> {
1347
+ return __request(OpenAPI, {
1348
+ method: 'DELETE',
1349
+ url: '/api/v1/users',
1350
+ body: data.requestBody,
1351
+ mediaType: 'application/json',
1352
+ errors: {
1353
+ 403: 'Invalid access token'
1354
+ }
1355
+ });
1356
+ }
1357
+
1358
+ /**
1359
+ * Get current authenticated user
1360
+ * @param data The data for the request.
1361
+ * @param data.acceptLanguage
1362
+ * @returns UserResponseDto User retrieved successfully
1363
+ * @throws ApiError
1364
+ */
1365
+ public static userControllerGetUser(
1366
+ data: UserControllerGetUserData
1367
+ ): CancelablePromise<UserControllerGetUserResponse> {
1368
+ return __request(OpenAPI, {
1369
+ method: 'GET',
1370
+ url: '/api/v1/users',
1371
+ headers: {
1372
+ 'accept-language': data.acceptLanguage
1373
+ }
1374
+ });
1375
+ }
1376
+
1377
+ /**
1378
+ * Sign up new user
1379
+ * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
1380
+ * @param data The data for the request.
1381
+ * @param data.requestBody
1382
+ * @returns SignupResponseDto User created successfully
1383
+ * @throws ApiError
1384
+ */
1385
+ public static userControllerSignupUser(
1386
+ data: UserControllerSignupUserData
1387
+ ): CancelablePromise<UserControllerSignupUserResponse> {
1388
+ return __request(OpenAPI, {
1389
+ method: 'POST',
1390
+ url: '/api/v1/users',
1391
+ body: data.requestBody,
1392
+ mediaType: 'application/json',
1393
+ errors: {
1394
+ 400: 'Invalid Turnstile token (when Turnstile is enabled)',
1395
+ 403: 'User signup is disabled'
1396
+ }
1397
+ });
1398
+ }
1399
+
1400
+ /**
1401
+ * Delete user by ID (admin only)
1402
+ * @param data The data for the request.
1403
+ * @param data.id User ID to delete
1404
+ * @returns void User deleted successfully
1405
+ * @throws ApiError
1406
+ */
1407
+ public static userControllerDeleteUser(
1408
+ data: UserControllerDeleteUserData
1409
+ ): CancelablePromise<UserControllerDeleteUserResponse> {
1410
+ return __request(OpenAPI, {
1411
+ method: 'DELETE',
1412
+ url: '/api/v1/users/{id}',
1413
+ path: {
1414
+ id: data.id
1415
+ },
1416
+ errors: {
1417
+ 403: 'Cannot delete own account or insufficient permissions'
1418
+ }
1419
+ });
1420
+ }
1421
+
1422
+ /**
1423
+ * Get user info by user ID
1424
+ * @param data The data for the request.
1425
+ * @param data.id User ID
1426
+ * @returns unknown User info retrieved successfully
1427
+ * @throws ApiError
1428
+ */
1429
+ public static userControllerGetUserInfo(
1430
+ data: UserControllerGetUserInfoData
1431
+ ): CancelablePromise<UserControllerGetUserInfoResponse> {
1432
+ return __request(OpenAPI, {
1433
+ method: 'GET',
1434
+ url: '/api/v1/users/{id}/info',
1435
+ path: {
1436
+ id: data.id
1437
+ },
1438
+ errors: {
1439
+ 403: 'Cannot access other user info without admin permission'
1440
+ }
1441
+ });
1442
+ }
1443
+
1444
+ /**
1445
+ * Update user settings
1446
+ * @param data The data for the request.
1447
+ * @param data.requestBody
1448
+ * @returns unknown Settings updated successfully
1449
+ * @throws ApiError
1450
+ */
1451
+ public static userControllerUpdateUserSetting(
1452
+ data: UserControllerUpdateUserSettingData
1453
+ ): CancelablePromise<UserControllerUpdateUserSettingResponse> {
1454
+ return __request(OpenAPI, {
1455
+ method: 'PUT',
1456
+ url: '/api/v1/users/setting',
1457
+ body: data.requestBody,
1458
+ mediaType: 'application/json',
1459
+ errors: {
1460
+ 403: 'Insufficient permissions'
1461
+ }
1462
+ });
1463
+ }
1464
+
1465
+ /**
1466
+ * Get all user settings paginated (admin only)
1467
+ * @param data The data for the request.
1468
+ * @param data.pageNo Page number
1469
+ * @param data.pageSize Page size
1470
+ * @returns unknown Settings list retrieved successfully
1471
+ * @throws ApiError
1472
+ */
1473
+ public static userControllerGetAllUserSettingsByPage(
1474
+ data: UserControllerGetAllUserSettingsByPageData
1475
+ ): CancelablePromise<UserControllerGetAllUserSettingsByPageResponse> {
1476
+ return __request(OpenAPI, {
1477
+ method: 'GET',
1478
+ url: '/api/v1/users/settings-by-page',
1479
+ query: {
1480
+ pageNo: data.pageNo,
1481
+ pageSize: data.pageSize
1482
+ }
1483
+ });
1484
+ }
1485
+
1486
+ /**
1487
+ * Get asset and liability summary for current user
1488
+ * @returns unknown Summary retrieved successfully
1489
+ * @throws ApiError
1490
+ */
1491
+ public static userControllerGetAssetLiabilitySummary(): CancelablePromise<UserControllerGetAssetLiabilitySummaryResponse> {
1492
+ return __request(OpenAPI, {
1493
+ method: 'GET',
1494
+ url: '/api/v1/users/asset-liability-summary'
1495
+ });
1496
+ }
1497
+ }
1498
+
1499
+ export class PropertiesService {
1500
+ /**
1501
+ * Get all system properties
1502
+ * @returns unknown Properties retrieved successfully
1503
+ * @throws ApiError
1504
+ */
1505
+ public static propertyControllerGetAll(): CancelablePromise<PropertyControllerGetAllResponse> {
1506
+ return __request(OpenAPI, {
1507
+ method: 'GET',
1508
+ url: '/api/v1/admin/properties',
1509
+ errors: {
1510
+ 401: 'Unauthorized',
1511
+ 403: 'Forbidden - insufficient permissions'
1512
+ }
1513
+ });
1514
+ }
1515
+
1516
+ /**
1517
+ * Get property by key
1518
+ * @param data The data for the request.
1519
+ * @param data.key Property key
1520
+ * @returns unknown Property retrieved successfully
1521
+ * @throws ApiError
1522
+ */
1523
+ public static propertyControllerGetByKey(
1524
+ data: PropertyControllerGetByKeyData
1525
+ ): CancelablePromise<PropertyControllerGetByKeyResponse> {
1526
+ return __request(OpenAPI, {
1527
+ method: 'GET',
1528
+ url: '/api/v1/admin/properties/{key}',
1529
+ path: {
1530
+ key: data.key
1531
+ },
1532
+ errors: {
1533
+ 401: 'Unauthorized',
1534
+ 403: 'Forbidden - insufficient permissions',
1535
+ 404: 'Property not found'
1536
+ }
1537
+ });
1538
+ }
1539
+
1540
+ /**
1541
+ * Update a system property
1542
+ * @param data The data for the request.
1543
+ * @param data.key Property key
1544
+ * @param data.requestBody
1545
+ * @returns unknown Property updated successfully
1546
+ * @throws ApiError
1547
+ */
1548
+ public static propertyControllerUpdate(
1549
+ data: PropertyControllerUpdateData
1550
+ ): CancelablePromise<PropertyControllerUpdateResponse> {
1551
+ return __request(OpenAPI, {
1552
+ method: 'PUT',
1553
+ url: '/api/v1/admin/properties/{key}',
1554
+ path: {
1555
+ key: data.key
1556
+ },
1557
+ body: data.requestBody,
1558
+ mediaType: 'application/json',
1559
+ errors: {
1560
+ 401: 'Unauthorized',
1561
+ 403: 'Forbidden - insufficient permissions'
1562
+ }
1563
+ });
1564
+ }
1565
+
1566
+ /**
1567
+ * Delete a system property
1568
+ * @param data The data for the request.
1569
+ * @param data.key Property key
1570
+ * @returns void Property deleted successfully
1571
+ * @throws ApiError
1572
+ */
1573
+ public static propertyControllerDelete(
1574
+ data: PropertyControllerDeleteData
1575
+ ): CancelablePromise<PropertyControllerDeleteResponse> {
1576
+ return __request(OpenAPI, {
1577
+ method: 'DELETE',
1578
+ url: '/api/v1/admin/properties/{key}',
1579
+ path: {
1580
+ key: data.key
1581
+ },
1582
+ errors: {
1583
+ 401: 'Unauthorized',
1584
+ 403: 'Forbidden - insufficient permissions',
1585
+ 404: 'Property not found'
1586
+ }
1587
+ });
1588
+ }
1589
+ }
1590
+
1591
+ export class BeanPayeesService {
1592
+ /**
1593
+ * Create a new payee
1594
+ * Creates a new payee mapping for the authenticated user. The payee name must be unique within the user's account.
1595
+ * @param data The data for the request.
1596
+ * @param data.requestBody
1597
+ * @returns PayeeResponseDto Payee created successfully
1598
+ * @throws ApiError
1599
+ */
1600
+ public static payeeControllerCreate(
1601
+ data: PayeeControllerCreateData
1602
+ ): CancelablePromise<PayeeControllerCreateResponse> {
1603
+ return __request(OpenAPI, {
1604
+ method: 'POST',
1605
+ url: '/api/v1/bean/payees',
1606
+ body: data.requestBody,
1607
+ mediaType: 'application/json',
1608
+ errors: {
1609
+ 400: 'Invalid input data',
1610
+ 409: 'Payee already exists'
1611
+ }
1612
+ });
1613
+ }
1614
+
1615
+ /**
1616
+ * List user payees
1617
+ * Returns all payee mappings for the authenticated user with optional filtering
1618
+ * @param data The data for the request.
1619
+ * @param data.search Search term for payee name (partial match, case-insensitive). Useful for autocomplete.
1620
+ * @param data.payee Filter by exact payee name match
1621
+ * @param data.category Filter by custom category
1622
+ * @param data.tag Filter by custom tag (returns payees that have this tag)
1623
+ * @param data.isActive Filter by active status. Defaults to true (show only active payees).
1624
+ * @returns PayeeListResponseDto Payees retrieved successfully
1625
+ * @throws ApiError
1626
+ */
1627
+ public static payeeControllerFindAll(
1628
+ data: PayeeControllerFindAllData = {}
1629
+ ): CancelablePromise<PayeeControllerFindAllResponse> {
1630
+ return __request(OpenAPI, {
1631
+ method: 'GET',
1632
+ url: '/api/v1/bean/payees',
1633
+ query: {
1634
+ search: data.search,
1635
+ payee: data.payee,
1636
+ category: data.category,
1637
+ tag: data.tag,
1638
+ isActive: data.isActive
1639
+ }
1640
+ });
1641
+ }
1642
+
1643
+ /**
1644
+ * Get payee autocomplete suggestions
1645
+ * Returns active payee names matching the query, sorted by recent usage. Used for transaction input autocomplete.
1646
+ * @param data The data for the request.
1647
+ * @param data.q Search query for payee name (partial match, case-insensitive)
1648
+ * @param data.limit Maximum number of suggestions
1649
+ * @returns PayeeAutocompleteResponseDto Autocomplete suggestions retrieved successfully
1650
+ * @throws ApiError
1651
+ */
1652
+ public static payeeControllerAutocomplete(
1653
+ data: PayeeControllerAutocompleteData
1654
+ ): CancelablePromise<PayeeControllerAutocompleteResponse> {
1655
+ return __request(OpenAPI, {
1656
+ method: 'GET',
1657
+ url: '/api/v1/bean/payees/autocomplete',
1658
+ query: {
1659
+ q: data.q,
1660
+ limit: data.limit
1661
+ }
1662
+ });
1663
+ }
1664
+
1665
+ /**
1047
1666
  * Get top payees by usage
1048
1667
  * Returns the most frequently used payees, sorted by use count. Used for statistics and analytics.
1049
1668
  * @param data The data for the request.
@@ -1301,7 +1920,7 @@ export class AdminPayeeProfilesService {
1301
1920
  * Removes verification status by setting verifiedAt to null.
1302
1921
  * @param data The data for the request.
1303
1922
  * @param data.id Payee profile ID (UUID)
1304
- * @returns PayeeProfileResponseDto Payee profile unverified successfully
1923
+ * @returns void Payee profile unverified successfully
1305
1924
  * @throws ApiError
1306
1925
  */
1307
1926
  public static payeeProfileAdminControllerUnverify(
@@ -1321,6 +1940,24 @@ export class AdminPayeeProfilesService {
1321
1940
  }
1322
1941
  }
1323
1942
 
1943
+ export class PayeeProfilesService {
1944
+ /**
1945
+ * List active payee profiles (directory dump)
1946
+ * Returns the full active PayeeProfile set as a trimmed projection for client-side dictionary caching. Aliases are verbatim as stored; clients normalize on their side.
1947
+ * @returns PayeeProfileDirectoryResponseDto Active payee profiles
1948
+ * @throws ApiError
1949
+ */
1950
+ public static payeeProfileControllerListActive(): CancelablePromise<PayeeProfileControllerListActiveResponse> {
1951
+ return __request(OpenAPI, {
1952
+ method: 'GET',
1953
+ url: '/api/v1/bean/payee-profiles',
1954
+ errors: {
1955
+ 401: 'Missing or invalid token'
1956
+ }
1957
+ });
1958
+ }
1959
+ }
1960
+
1324
1961
  export class BeanCommoditiesService {
1325
1962
  /**
1326
1963
  * Create a new commodity
@@ -1461,1000 +2098,1127 @@ export class BeanCommoditiesService {
1461
2098
  * @param data.symbol Commodity symbol
1462
2099
  * @param data.region Region code for tenant context
1463
2100
  * @returns CommodityResponseDto Commodity retrieved or created
1464
- * @throws ApiError
1465
- */
1466
- public static commodityControllerGetOrCreate(
1467
- data: CommodityControllerGetOrCreateData
1468
- ): CancelablePromise<CommodityControllerGetOrCreateResponse> {
1469
- return __request(OpenAPI, {
1470
- method: 'POST',
1471
- url: '/api/v1/{region}/bean/commodities/{symbol}/ensure',
1472
- path: {
1473
- symbol: data.symbol,
1474
- region: data.region
1475
- }
1476
- });
1477
- }
1478
-
1479
- /**
1480
- * Bulk create commodities
1481
- * Creates multiple commodities from a list of symbols, useful for initialization
1482
- * @param data The data for the request.
1483
- * @param data.region Region code for tenant context
1484
- * @returns CommodityResponseDto Commodities created successfully
1485
- * @throws ApiError
1486
- */
1487
- public static commodityControllerBulkCreate(
1488
- data: CommodityControllerBulkCreateData
1489
- ): CancelablePromise<CommodityControllerBulkCreateResponse> {
1490
- return __request(OpenAPI, {
1491
- method: 'POST',
1492
- url: '/api/v1/{region}/bean/commodities/bulk',
1493
- path: {
1494
- region: data.region
1495
- }
1496
- });
1497
- }
1498
- }
1499
-
1500
- export class RecurringRulesService {
1501
- /**
1502
- * Create a new recurring rule
1503
- * Creates a new recurring transaction rule for the authenticated user
1504
- * @param data The data for the request.
1505
- * @param data.region Region code for tenant context
1506
- * @param data.requestBody
1507
- * @returns RecurringRuleResponseDto Rule created successfully
1508
- * @throws ApiError
1509
- */
1510
- public static recurringRuleControllerCreate(
1511
- data: RecurringRuleControllerCreateData
1512
- ): CancelablePromise<RecurringRuleControllerCreateResponse> {
2101
+ * @throws ApiError
2102
+ */
2103
+ public static commodityControllerGetOrCreate(
2104
+ data: CommodityControllerGetOrCreateData
2105
+ ): CancelablePromise<CommodityControllerGetOrCreateResponse> {
1513
2106
  return __request(OpenAPI, {
1514
2107
  method: 'POST',
1515
- url: '/api/v1/{region}/bean/recurring-rules',
2108
+ url: '/api/v1/{region}/bean/commodities/{symbol}/ensure',
1516
2109
  path: {
2110
+ symbol: data.symbol,
1517
2111
  region: data.region
1518
- },
1519
- body: data.requestBody,
1520
- mediaType: 'application/json',
1521
- errors: {
1522
- 400: 'Invalid input data (e.g., autoCreate without accounts)',
1523
- 409: 'Rule with same name already exists'
1524
2112
  }
1525
2113
  });
1526
2114
  }
1527
2115
 
1528
2116
  /**
1529
- * List recurring rules
1530
- * Returns all recurring rules for the authenticated user with optional filtering
2117
+ * Bulk create commodities
2118
+ * Creates multiple commodities from a list of symbols, useful for initialization
1531
2119
  * @param data The data for the request.
1532
2120
  * @param data.region Region code for tenant context
1533
- * @param data.isActive Filter by active status
1534
- * @param data.frequency Filter by frequency (WEEKLY, MONTHLY, etc.)
1535
- * @param data.hasAutoCreate Filter by autoCreate enabled
1536
- * @returns RecurringRuleResponseDto Rules retrieved successfully
2121
+ * @returns CommodityResponseDto Commodities created successfully
1537
2122
  * @throws ApiError
1538
2123
  */
1539
- public static recurringRuleControllerFindAll(
1540
- data: RecurringRuleControllerFindAllData
1541
- ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
2124
+ public static commodityControllerBulkCreate(
2125
+ data: CommodityControllerBulkCreateData
2126
+ ): CancelablePromise<CommodityControllerBulkCreateResponse> {
1542
2127
  return __request(OpenAPI, {
1543
- method: 'GET',
1544
- url: '/api/v1/{region}/bean/recurring-rules',
2128
+ method: 'POST',
2129
+ url: '/api/v1/{region}/bean/commodities/bulk',
1545
2130
  path: {
1546
2131
  region: data.region
1547
- },
1548
- query: {
1549
- isActive: data.isActive,
1550
- frequency: data.frequency,
1551
- hasAutoCreate: data.hasAutoCreate
1552
2132
  }
1553
2133
  });
1554
2134
  }
2135
+ }
1555
2136
 
2137
+ export class ReportingService {
1556
2138
  /**
1557
- * Create recurring rule from transaction
1558
- * Auto-creates a recurring rule using transaction data. User only confirms frequency.
2139
+ * Get portfolio value trends
2140
+ *
2141
+ * Returns time series data of portfolio net worth.
2142
+ *
2143
+ * **Multi-currency Support:**
2144
+ * - `series[].byCurrency` - Currency breakdown for each data point
2145
+ * - `byCurrency` - Separate time series grouped by currency
2146
+ * - `warnings` - Exchange rate warnings if conversion failed
2147
+ *
2148
+ * **Parameters:**
2149
+ * - `period`: Time period (1m, 3m, 6m, 1y)
2150
+ * - `granularity`: Data granularity (day, week, month)
2151
+ *
1559
2152
  * @param data The data for the request.
1560
- * @param data.transactionId Source transaction ID
1561
2153
  * @param data.region Region code for tenant context
1562
- * @param data.requestBody
1563
- * @returns RecurringRuleResponseDto Rule created successfully
2154
+ * @param data.period Time period
2155
+ * @param data.granularity Data granularity
2156
+ * @returns PortfolioTrendsResponseDto Trends retrieved successfully
1564
2157
  * @throws ApiError
1565
2158
  */
1566
- public static recurringRuleControllerCreateFromTransaction(
1567
- data: RecurringRuleControllerCreateFromTransactionData
1568
- ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
2159
+ public static reportingControllerGetPortfolioTrends(
2160
+ data: ReportingControllerGetPortfolioTrendsData
2161
+ ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
1569
2162
  return __request(OpenAPI, {
1570
- method: 'POST',
1571
- url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
2163
+ method: 'GET',
2164
+ url: '/api/v1/{region}/reporting/portfolio/trends',
1572
2165
  path: {
1573
- transactionId: data.transactionId,
1574
2166
  region: data.region
1575
2167
  },
1576
- body: data.requestBody,
1577
- mediaType: 'application/json',
2168
+ query: {
2169
+ period: data.period,
2170
+ granularity: data.granularity
2171
+ },
1578
2172
  errors: {
1579
- 404: 'Transaction not found',
1580
- 409: 'Rule with same name already exists or transaction already linked'
2173
+ 401: 'User not authenticated'
1581
2174
  }
1582
2175
  });
1583
2176
  }
1584
2177
 
1585
2178
  /**
1586
- * Get recurring rule by ID
1587
- * Returns a specific recurring rule with its details
2179
+ * Get cash-flow trends
2180
+ *
2181
+ * Monthly income / expense / netSavings over a fixed N-month window
2182
+ * (current month + N−1 prior). Missing months are zero-filled (flow metric).
2183
+ *
2184
+ * **Parameters:**
2185
+ * - `period`: 1m | 3m | 6m | 1y (default 6m)
2186
+ * - `granularity`: accepted for API symmetry; v1 returns month buckets
2187
+ *
1588
2188
  * @param data The data for the request.
1589
- * @param data.id Rule ID
1590
2189
  * @param data.region Region code for tenant context
1591
- * @returns RecurringRuleResponseDto Rule retrieved successfully
2190
+ * @param data.period Time period
2191
+ * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
2192
+ * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
1592
2193
  * @throws ApiError
1593
2194
  */
1594
- public static recurringRuleControllerFindOne(
1595
- data: RecurringRuleControllerFindOneData
1596
- ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
2195
+ public static reportingControllerGetCashFlowTrends(
2196
+ data: ReportingControllerGetCashFlowTrendsData
2197
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
1597
2198
  return __request(OpenAPI, {
1598
2199
  method: 'GET',
1599
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
2200
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
1600
2201
  path: {
1601
- id: data.id,
1602
2202
  region: data.region
1603
2203
  },
2204
+ query: {
2205
+ period: data.period,
2206
+ granularity: data.granularity
2207
+ },
1604
2208
  errors: {
1605
- 404: 'Rule not found'
2209
+ 401: 'User not authenticated'
1606
2210
  }
1607
2211
  });
1608
2212
  }
1609
2213
 
1610
2214
  /**
1611
- * Update recurring rule
1612
- * Updates an existing recurring rule
2215
+ * Generate portfolio snapshot
2216
+ *
2217
+ * Manually generate a portfolio snapshot for a specific date.
2218
+ *
2219
+ * **Multi-currency Support:**
2220
+ * - Fetches balances grouped by currency
2221
+ * - Uses user's baseCurrency setting for conversion
2222
+ * - Stores exchange rates and warnings
2223
+ *
2224
+ * **Use Cases:**
2225
+ * - Testing snapshot generation
2226
+ * - Force regeneration after data correction
2227
+ * - Initial setup for new users
2228
+ *
1613
2229
  * @param data The data for the request.
1614
- * @param data.id Rule ID
1615
2230
  * @param data.region Region code for tenant context
1616
- * @param data.requestBody
1617
- * @returns RecurringRuleResponseDto Rule updated successfully
2231
+ * @param data.requestBody Optional date (defaults to today)
2232
+ * @returns GenerateSnapshotResponse Snapshot generated successfully
1618
2233
  * @throws ApiError
1619
2234
  */
1620
- public static recurringRuleControllerUpdate(
1621
- data: RecurringRuleControllerUpdateData
1622
- ): CancelablePromise<RecurringRuleControllerUpdateResponse> {
2235
+ public static reportingControllerGenerateSnapshot(
2236
+ data: ReportingControllerGenerateSnapshotData
2237
+ ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
1623
2238
  return __request(OpenAPI, {
1624
- method: 'PATCH',
1625
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
2239
+ method: 'POST',
2240
+ url: '/api/v1/{region}/reporting/snapshots/generate',
1626
2241
  path: {
1627
- id: data.id,
1628
2242
  region: data.region
1629
2243
  },
1630
2244
  body: data.requestBody,
1631
2245
  mediaType: 'application/json',
1632
2246
  errors: {
1633
- 400: 'Invalid input data',
1634
- 404: 'Rule not found'
2247
+ 400: 'Invalid date format',
2248
+ 401: 'User not authenticated'
1635
2249
  }
1636
2250
  });
1637
2251
  }
1638
2252
 
1639
2253
  /**
1640
- * Delete recurring rule
1641
- * Soft deletes a recurring rule (sets isActive to false)
2254
+ * Backfill portfolio snapshots
2255
+ *
2256
+ * Generate snapshots for a date range (historical data backfill).
2257
+ *
2258
+ * **Multi-currency Support:**
2259
+ * - Each snapshot includes multi-currency data
2260
+ * - Uses exchange rates available at generation time
2261
+ * - Warnings stored for missing exchange rates
2262
+ *
2263
+ * **Best Practices:**
2264
+ * - Use for initial setup after account configuration
2265
+ * - Run during low-traffic periods for large date ranges
2266
+ * - Existing snapshots are skipped (not regenerated)
2267
+ *
1642
2268
  * @param data The data for the request.
1643
- * @param data.id Rule ID
1644
2269
  * @param data.region Region code for tenant context
1645
- * @returns void Rule deleted successfully
2270
+ * @param data.requestBody
2271
+ * @returns BackfillSnapshotsResponse Backfill completed successfully
1646
2272
  * @throws ApiError
1647
2273
  */
1648
- public static recurringRuleControllerDelete(
1649
- data: RecurringRuleControllerDeleteData
1650
- ): CancelablePromise<RecurringRuleControllerDeleteResponse> {
2274
+ public static reportingControllerBackfillSnapshots(
2275
+ data: ReportingControllerBackfillSnapshotsData
2276
+ ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
1651
2277
  return __request(OpenAPI, {
1652
- method: 'DELETE',
1653
- url: '/api/v1/{region}/bean/recurring-rules/{id}',
2278
+ method: 'POST',
2279
+ url: '/api/v1/{region}/reporting/snapshots/backfill',
1654
2280
  path: {
1655
- id: data.id,
1656
2281
  region: data.region
1657
2282
  },
2283
+ body: data.requestBody,
2284
+ mediaType: 'application/json',
1658
2285
  errors: {
1659
- 404: 'Rule not found'
2286
+ 400: 'Invalid date format or range',
2287
+ 401: 'User not authenticated',
2288
+ 409: 'Backfill already in progress for this user'
1660
2289
  }
1661
2290
  });
1662
2291
  }
2292
+ }
1663
2293
 
2294
+ export class BeanPricesService {
1664
2295
  /**
1665
- * Get rule with statistics
1666
- * Returns a rule with pending/overdue counts and next expected date
2296
+ * Create a new price
2297
+ * Creates a new price entry for the authenticated user
1667
2298
  * @param data The data for the request.
1668
- * @param data.id Rule ID
1669
2299
  * @param data.region Region code for tenant context
1670
- * @returns RecurringRuleWithStatsResponseDto Rule with stats retrieved successfully
2300
+ * @param data.requestBody
2301
+ * @returns PriceResponseDto Price created successfully
1671
2302
  * @throws ApiError
1672
2303
  */
1673
- public static recurringRuleControllerGetWithStats(
1674
- data: RecurringRuleControllerGetWithStatsData
1675
- ): CancelablePromise<RecurringRuleControllerGetWithStatsResponse> {
2304
+ public static priceControllerCreate(
2305
+ data: PriceControllerCreateData
2306
+ ): CancelablePromise<PriceControllerCreateResponse> {
1676
2307
  return __request(OpenAPI, {
1677
- method: 'GET',
1678
- url: '/api/v1/{region}/bean/recurring-rules/{id}/stats',
2308
+ method: 'POST',
2309
+ url: '/api/v1/{region}/bean/prices',
1679
2310
  path: {
1680
- id: data.id,
1681
2311
  region: data.region
1682
2312
  },
2313
+ body: data.requestBody,
2314
+ mediaType: 'application/json',
1683
2315
  errors: {
1684
- 404: 'Rule not found'
2316
+ 404: 'Currency or quoteCurrency commodity not found',
2317
+ 409: 'Price already exists for this currency pair and date'
1685
2318
  }
1686
2319
  });
1687
2320
  }
1688
- }
1689
2321
 
1690
- export class ExpectedTransactionsService {
1691
2322
  /**
1692
- * List expected transactions
1693
- * Returns expected transactions for the authenticated user with optional filtering
2323
+ * List user prices
2324
+ * Returns all price entries for the authenticated user with optional filtering
1694
2325
  * @param data The data for the request.
1695
2326
  * @param data.region Region code for tenant context
1696
- * @param data.ruleId Filter by recurring rule ID
1697
- * @param data.status Filter by status (PENDING, COMPLETED, SKIPPED)
1698
- * @param data.fromDate Filter by date range start (YYYY-MM-DD)
1699
- * @param data.toDate Filter by date range end (YYYY-MM-DD)
1700
- * @returns ExpectedTransactionListResponseDto Expected transactions retrieved successfully
2327
+ * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
2328
+ * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
2329
+ * @param data.dateFrom Filter prices from this date (ISO 8601 format)
2330
+ * @param data.dateTo Filter prices to this date (ISO 8601 format)
2331
+ * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
2332
+ * @param data.page Page number for pagination (default: 1)
2333
+ * @param data.limit Number of items per page (default: 20, max: 100)
2334
+ * @returns PriceListResponseDto Prices retrieved successfully
1701
2335
  * @throws ApiError
1702
2336
  */
1703
- public static expectedTransactionControllerFindAll(
1704
- data: ExpectedTransactionControllerFindAllData
1705
- ): CancelablePromise<ExpectedTransactionControllerFindAllResponse> {
2337
+ public static priceControllerFindAll(
2338
+ data: PriceControllerFindAllData
2339
+ ): CancelablePromise<PriceControllerFindAllResponse> {
1706
2340
  return __request(OpenAPI, {
1707
2341
  method: 'GET',
1708
- url: '/api/v1/{region}/bean/expected-transactions',
2342
+ url: '/api/v1/{region}/bean/prices',
1709
2343
  path: {
1710
2344
  region: data.region
1711
2345
  },
1712
2346
  query: {
1713
- ruleId: data.ruleId,
1714
- status: data.status,
1715
- fromDate: data.fromDate,
1716
- toDate: data.toDate
2347
+ currency: data.currency,
2348
+ quoteCurrency: data.quoteCurrency,
2349
+ dateFrom: data.dateFrom,
2350
+ dateTo: data.dateTo,
2351
+ search: data.search,
2352
+ page: data.page,
2353
+ limit: data.limit
1717
2354
  }
1718
2355
  });
1719
2356
  }
1720
2357
 
1721
2358
  /**
1722
- * List overdue expected transactions
1723
- * Returns all overdue expected transactions (PENDING past tolerance)
2359
+ * Get price by ID
2360
+ * Returns a single price entry by its ID
1724
2361
  * @param data The data for the request.
2362
+ * @param data.id Price ID
1725
2363
  * @param data.region Region code for tenant context
1726
- * @returns ExpectedTransactionListResponseDto Overdue transactions retrieved successfully
2364
+ * @returns PriceResponseDto Price retrieved successfully
1727
2365
  * @throws ApiError
1728
2366
  */
1729
- public static expectedTransactionControllerFindOverdue(
1730
- data: ExpectedTransactionControllerFindOverdueData
1731
- ): CancelablePromise<ExpectedTransactionControllerFindOverdueResponse> {
2367
+ public static priceControllerFindOne(
2368
+ data: PriceControllerFindOneData
2369
+ ): CancelablePromise<PriceControllerFindOneResponse> {
1732
2370
  return __request(OpenAPI, {
1733
2371
  method: 'GET',
1734
- url: '/api/v1/{region}/bean/expected-transactions/overdue',
2372
+ url: '/api/v1/{region}/bean/prices/{id}',
1735
2373
  path: {
2374
+ id: data.id,
1736
2375
  region: data.region
2376
+ },
2377
+ errors: {
2378
+ 404: 'Price not found'
1737
2379
  }
1738
2380
  });
1739
2381
  }
1740
2382
 
1741
2383
  /**
1742
- * Get expected transaction by ID
1743
- * Returns a specific expected transaction with rule details
2384
+ * Update a price
2385
+ * Updates an existing price entry
1744
2386
  * @param data The data for the request.
1745
- * @param data.id Expected transaction ID
2387
+ * @param data.id Price ID
1746
2388
  * @param data.region Region code for tenant context
1747
- * @returns ExpectedTransactionResponseDto Expected transaction retrieved successfully
2389
+ * @param data.requestBody
2390
+ * @returns PriceResponseDto Price updated successfully
1748
2391
  * @throws ApiError
1749
2392
  */
1750
- public static expectedTransactionControllerFindOne(
1751
- data: ExpectedTransactionControllerFindOneData
1752
- ): CancelablePromise<ExpectedTransactionControllerFindOneResponse> {
2393
+ public static priceControllerUpdate(
2394
+ data: PriceControllerUpdateData
2395
+ ): CancelablePromise<PriceControllerUpdateResponse> {
1753
2396
  return __request(OpenAPI, {
1754
- method: 'GET',
1755
- url: '/api/v1/{region}/bean/expected-transactions/{id}',
2397
+ method: 'PUT',
2398
+ url: '/api/v1/{region}/bean/prices/{id}',
1756
2399
  path: {
1757
2400
  id: data.id,
1758
2401
  region: data.region
1759
2402
  },
2403
+ body: data.requestBody,
2404
+ mediaType: 'application/json',
1760
2405
  errors: {
1761
- 404: 'Expected transaction not found'
2406
+ 404: 'Price not found',
2407
+ 409: 'Updated price conflicts with existing price'
1762
2408
  }
1763
2409
  });
1764
2410
  }
1765
2411
 
1766
2412
  /**
1767
- * Skip expected transaction
1768
- * Marks an expected transaction as skipped (PENDING -> SKIPPED)
2413
+ * Delete a price
2414
+ * Deletes a price entry (hard delete)
1769
2415
  * @param data The data for the request.
1770
- * @param data.id Expected transaction ID
2416
+ * @param data.id Price ID
1771
2417
  * @param data.region Region code for tenant context
1772
- * @returns ExpectedTransactionResponseDto Expected transaction skipped successfully
2418
+ * @returns void Price deleted successfully
1773
2419
  * @throws ApiError
1774
2420
  */
1775
- public static expectedTransactionControllerSkip(
1776
- data: ExpectedTransactionControllerSkipData
1777
- ): CancelablePromise<ExpectedTransactionControllerSkipResponse> {
2421
+ public static priceControllerDelete(
2422
+ data: PriceControllerDeleteData
2423
+ ): CancelablePromise<PriceControllerDeleteResponse> {
1778
2424
  return __request(OpenAPI, {
1779
- method: 'POST',
1780
- url: '/api/v1/{region}/bean/expected-transactions/{id}/skip',
2425
+ method: 'DELETE',
2426
+ url: '/api/v1/{region}/bean/prices/{id}',
1781
2427
  path: {
1782
2428
  id: data.id,
1783
2429
  region: data.region
1784
2430
  },
1785
2431
  errors: {
1786
- 400: 'Cannot skip - not in PENDING status',
1787
- 404: 'Expected transaction not found'
2432
+ 404: 'Price not found'
1788
2433
  }
1789
2434
  });
1790
2435
  }
1791
2436
 
1792
2437
  /**
1793
- * Undo skip
1794
- * Reverses a skip operation (SKIPPED -> PENDING)
2438
+ * Bulk create prices
2439
+ * Creates multiple price entries at once (skips duplicates)
1795
2440
  * @param data The data for the request.
1796
- * @param data.id Expected transaction ID
1797
2441
  * @param data.region Region code for tenant context
1798
- * @returns ExpectedTransactionResponseDto Skip undone successfully
2442
+ * @param data.requestBody
2443
+ * @returns PriceResponseDto Prices created successfully
1799
2444
  * @throws ApiError
1800
2445
  */
1801
- public static expectedTransactionControllerUndoSkip(
1802
- data: ExpectedTransactionControllerUndoSkipData
1803
- ): CancelablePromise<ExpectedTransactionControllerUndoSkipResponse> {
2446
+ public static priceControllerBulkCreate(
2447
+ data: PriceControllerBulkCreateData
2448
+ ): CancelablePromise<PriceControllerBulkCreateResponse> {
1804
2449
  return __request(OpenAPI, {
1805
- method: 'DELETE',
1806
- url: '/api/v1/{region}/bean/expected-transactions/{id}/skip',
2450
+ method: 'POST',
2451
+ url: '/api/v1/{region}/bean/prices/bulk',
1807
2452
  path: {
1808
- id: data.id,
1809
2453
  region: data.region
1810
2454
  },
1811
- errors: {
1812
- 400: 'Cannot undo - not in SKIPPED status',
1813
- 404: 'Expected transaction not found'
1814
- }
2455
+ body: data.requestBody,
2456
+ mediaType: 'application/json'
1815
2457
  });
1816
2458
  }
2459
+ }
1817
2460
 
2461
+ export class RecurringRulesService {
1818
2462
  /**
1819
- * Confirm transaction match
1820
- * Manually matches an expected transaction with an actual transaction
2463
+ * Create a new recurring rule
2464
+ * Creates a new recurring transaction rule for the authenticated user
1821
2465
  * @param data The data for the request.
1822
- * @param data.id Expected transaction ID
1823
2466
  * @param data.region Region code for tenant context
1824
2467
  * @param data.requestBody
1825
- * @returns unknown Match confirmed successfully
2468
+ * @returns RecurringRuleResponseDto Rule created successfully
1826
2469
  * @throws ApiError
1827
2470
  */
1828
- public static expectedTransactionControllerConfirmMatch(
1829
- data: ExpectedTransactionControllerConfirmMatchData
1830
- ): CancelablePromise<ExpectedTransactionControllerConfirmMatchResponse> {
2471
+ public static recurringRuleControllerCreate(
2472
+ data: RecurringRuleControllerCreateData
2473
+ ): CancelablePromise<RecurringRuleControllerCreateResponse> {
1831
2474
  return __request(OpenAPI, {
1832
2475
  method: 'POST',
1833
- url: '/api/v1/{region}/bean/expected-transactions/{id}/match',
2476
+ url: '/api/v1/{region}/bean/recurring-rules',
1834
2477
  path: {
1835
- id: data.id,
1836
2478
  region: data.region
1837
2479
  },
1838
2480
  body: data.requestBody,
1839
2481
  mediaType: 'application/json',
1840
2482
  errors: {
1841
- 400: 'Cannot match - not in PENDING status',
1842
- 404: 'Expected or actual transaction not found',
1843
- 409: 'Actual transaction already matched to another rule'
2483
+ 400: 'Invalid input data (e.g., autoCreate without accounts)',
2484
+ 409: 'Rule with same name already exists'
1844
2485
  }
1845
2486
  });
1846
2487
  }
1847
2488
 
1848
2489
  /**
1849
- * Unmatch transaction
1850
- * Removes the match between expected and actual transaction (COMPLETED -> PENDING)
2490
+ * List recurring rules
2491
+ * Returns all recurring rules for the authenticated user with optional filtering
1851
2492
  * @param data The data for the request.
1852
- * @param data.id Expected transaction ID
1853
2493
  * @param data.region Region code for tenant context
1854
- * @returns unknown Match removed successfully
2494
+ * @param data.isActive Filter by active status
2495
+ * @param data.frequency Filter by frequency (WEEKLY, MONTHLY, etc.)
2496
+ * @param data.hasAutoCreate Filter by autoCreate enabled
2497
+ * @returns RecurringRuleResponseDto Rules retrieved successfully
1855
2498
  * @throws ApiError
1856
2499
  */
1857
- public static expectedTransactionControllerUnmatch(
1858
- data: ExpectedTransactionControllerUnmatchData
1859
- ): CancelablePromise<ExpectedTransactionControllerUnmatchResponse> {
2500
+ public static recurringRuleControllerFindAll(
2501
+ data: RecurringRuleControllerFindAllData
2502
+ ): CancelablePromise<RecurringRuleControllerFindAllResponse> {
1860
2503
  return __request(OpenAPI, {
1861
- method: 'DELETE',
1862
- url: '/api/v1/{region}/bean/expected-transactions/{id}/match',
2504
+ method: 'GET',
2505
+ url: '/api/v1/{region}/bean/recurring-rules',
1863
2506
  path: {
1864
- id: data.id,
1865
2507
  region: data.region
1866
2508
  },
1867
- errors: {
1868
- 400: 'Cannot unmatch - not in COMPLETED status',
1869
- 404: 'Expected transaction not found'
2509
+ query: {
2510
+ isActive: data.isActive,
2511
+ frequency: data.frequency,
2512
+ hasAutoCreate: data.hasAutoCreate
1870
2513
  }
1871
2514
  });
1872
2515
  }
1873
2516
 
1874
2517
  /**
1875
- * Enter Now
1876
- * Creates an actual transaction for an expected transaction (YNAB-style Enter Now)
2518
+ * Create recurring rule from transaction
2519
+ * Auto-creates a recurring rule using transaction data. User only confirms frequency.
1877
2520
  * @param data The data for the request.
1878
- * @param data.id Expected transaction ID
2521
+ * @param data.transactionId Source transaction ID
1879
2522
  * @param data.region Region code for tenant context
1880
2523
  * @param data.requestBody
1881
- * @returns unknown Transaction created successfully
2524
+ * @returns RecurringRuleResponseDto Rule created successfully
1882
2525
  * @throws ApiError
1883
2526
  */
1884
- public static expectedTransactionControllerEnterNow(
1885
- data: ExpectedTransactionControllerEnterNowData
1886
- ): CancelablePromise<ExpectedTransactionControllerEnterNowResponse> {
2527
+ public static recurringRuleControllerCreateFromTransaction(
2528
+ data: RecurringRuleControllerCreateFromTransactionData
2529
+ ): CancelablePromise<RecurringRuleControllerCreateFromTransactionResponse> {
1887
2530
  return __request(OpenAPI, {
1888
2531
  method: 'POST',
1889
- url: '/api/v1/{region}/bean/expected-transactions/{id}/enter',
2532
+ url: '/api/v1/{region}/bean/recurring-rules/from-transaction/{transactionId}',
1890
2533
  path: {
1891
- id: data.id,
2534
+ transactionId: data.transactionId,
1892
2535
  region: data.region
1893
2536
  },
1894
2537
  body: data.requestBody,
1895
2538
  mediaType: 'application/json',
1896
2539
  errors: {
1897
- 400: 'Cannot enter - not in PENDING status or missing accounts',
1898
- 404: 'Expected transaction or accounts not found'
2540
+ 404: 'Transaction not found',
2541
+ 409: 'Rule with same name already exists or transaction already linked'
1899
2542
  }
1900
2543
  });
1901
2544
  }
1902
- }
1903
2545
 
1904
- export class RecurringForecastService {
1905
2546
  /**
1906
- * Get cash flow forecast
1907
- * Returns predicted outflows for the next N months based on active recurring rules
2547
+ * Get recurring rule by ID
2548
+ * Returns a specific recurring rule with its details
1908
2549
  * @param data The data for the request.
2550
+ * @param data.id Rule ID
1909
2551
  * @param data.region Region code for tenant context
1910
- * @param data.months Number of months to forecast (1-12, default 3)
1911
- * @returns ForecastResponseDto Forecast retrieved successfully
2552
+ * @returns RecurringRuleResponseDto Rule retrieved successfully
1912
2553
  * @throws ApiError
1913
2554
  */
1914
- public static forecastControllerGetForecast(
1915
- data: ForecastControllerGetForecastData
1916
- ): CancelablePromise<ForecastControllerGetForecastResponse> {
2555
+ public static recurringRuleControllerFindOne(
2556
+ data: RecurringRuleControllerFindOneData
2557
+ ): CancelablePromise<RecurringRuleControllerFindOneResponse> {
1917
2558
  return __request(OpenAPI, {
1918
2559
  method: 'GET',
1919
- url: '/api/v1/{region}/bean/recurring/forecast',
2560
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
1920
2561
  path: {
2562
+ id: data.id,
1921
2563
  region: data.region
1922
2564
  },
1923
- query: {
1924
- months: data.months
2565
+ errors: {
2566
+ 404: 'Rule not found'
1925
2567
  }
1926
2568
  });
1927
2569
  }
1928
- }
1929
2570
 
1930
- export class BeanTransactionRulesService {
1931
2571
  /**
1932
- * Create a new transaction rule (or upsert if upsertByPayee=true)
1933
- * Creates a new rule. If upsertByPayee=true, updates existing rule matching payeeKeywords[0] instead of creating duplicate.
2572
+ * Update recurring rule
2573
+ * Updates an existing recurring rule
1934
2574
  * @param data The data for the request.
2575
+ * @param data.id Rule ID
1935
2576
  * @param data.region Region code for tenant context
1936
2577
  * @param data.requestBody
1937
- * @returns TransactionRuleResponseDto Rule updated successfully (upsert mode)
2578
+ * @returns RecurringRuleResponseDto Rule updated successfully
1938
2579
  * @throws ApiError
1939
2580
  */
1940
- public static transactionRuleControllerCreate(
1941
- data: TransactionRuleControllerCreateData
1942
- ): CancelablePromise<TransactionRuleControllerCreateResponse> {
2581
+ public static recurringRuleControllerUpdate(
2582
+ data: RecurringRuleControllerUpdateData
2583
+ ): CancelablePromise<RecurringRuleControllerUpdateResponse> {
1943
2584
  return __request(OpenAPI, {
1944
- method: 'POST',
1945
- url: '/api/v1/{region}/bean/transaction-rules',
2585
+ method: 'PATCH',
2586
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
1946
2587
  path: {
2588
+ id: data.id,
1947
2589
  region: data.region
1948
2590
  },
1949
2591
  body: data.requestBody,
1950
2592
  mediaType: 'application/json',
1951
2593
  errors: {
1952
- 400: 'Validation failed',
1953
- 401: 'Unauthorized',
1954
- 409: 'Resource conflict - another process is updating this rule'
2594
+ 400: 'Invalid input data',
2595
+ 404: 'Rule not found'
1955
2596
  }
1956
2597
  });
1957
2598
  }
1958
2599
 
1959
2600
  /**
1960
- * Get all transaction rules for user
2601
+ * Delete recurring rule
2602
+ * Soft deletes a recurring rule (sets isActive to false)
1961
2603
  * @param data The data for the request.
2604
+ * @param data.id Rule ID
1962
2605
  * @param data.region Region code for tenant context
1963
- * @param data.limit Max results per page (default: 20, max: 100)
1964
- * @param data.offset Pagination offset (default: 0)
1965
- * @param data.enabled Filter by enabled status
1966
- * @param data.learningSource Filter by learning source. Omit this parameter or pass empty string to get manually created rules (learningSource is null in database).
1967
- * @param data.autoApplyEnabled Filter by auto-apply status
1968
- * @returns TransactionRuleListResponseDto List of rules
2606
+ * @returns void Rule deleted successfully
1969
2607
  * @throws ApiError
1970
2608
  */
1971
- public static transactionRuleControllerList(
1972
- data: TransactionRuleControllerListData
1973
- ): CancelablePromise<TransactionRuleControllerListResponse> {
2609
+ public static recurringRuleControllerDelete(
2610
+ data: RecurringRuleControllerDeleteData
2611
+ ): CancelablePromise<RecurringRuleControllerDeleteResponse> {
1974
2612
  return __request(OpenAPI, {
1975
- method: 'GET',
1976
- url: '/api/v1/{region}/bean/transaction-rules',
2613
+ method: 'DELETE',
2614
+ url: '/api/v1/{region}/bean/recurring-rules/{id}',
1977
2615
  path: {
2616
+ id: data.id,
1978
2617
  region: data.region
1979
2618
  },
1980
- query: {
1981
- limit: data.limit,
1982
- offset: data.offset,
1983
- enabled: data.enabled,
1984
- learningSource: data.learningSource,
1985
- autoApplyEnabled: data.autoApplyEnabled
2619
+ errors: {
2620
+ 404: 'Rule not found'
2621
+ }
2622
+ });
2623
+ }
2624
+
2625
+ /**
2626
+ * Get rule with statistics
2627
+ * Returns a rule with pending/overdue counts and next expected date
2628
+ * @param data The data for the request.
2629
+ * @param data.id Rule ID
2630
+ * @param data.region Region code for tenant context
2631
+ * @returns RecurringRuleWithStatsResponseDto Rule with stats retrieved successfully
2632
+ * @throws ApiError
2633
+ */
2634
+ public static recurringRuleControllerGetWithStats(
2635
+ data: RecurringRuleControllerGetWithStatsData
2636
+ ): CancelablePromise<RecurringRuleControllerGetWithStatsResponse> {
2637
+ return __request(OpenAPI, {
2638
+ method: 'GET',
2639
+ url: '/api/v1/{region}/bean/recurring-rules/{id}/stats',
2640
+ path: {
2641
+ id: data.id,
2642
+ region: data.region
1986
2643
  },
1987
2644
  errors: {
1988
- 401: 'Unauthorized'
2645
+ 404: 'Rule not found'
1989
2646
  }
1990
2647
  });
1991
2648
  }
2649
+ }
1992
2650
 
2651
+ export class ExpectedTransactionsService {
1993
2652
  /**
1994
- * Validate transaction rule configuration
2653
+ * List expected transactions
2654
+ * Returns expected transactions for the authenticated user with optional filtering
1995
2655
  * @param data The data for the request.
1996
2656
  * @param data.region Region code for tenant context
1997
- * @param data.requestBody
1998
- * @returns ValidateRuleResponseDto Validation result
2657
+ * @param data.ruleId Filter by recurring rule ID
2658
+ * @param data.status Filter by status (PENDING, COMPLETED, SKIPPED)
2659
+ * @param data.fromDate Filter by date range start (YYYY-MM-DD)
2660
+ * @param data.toDate Filter by date range end (YYYY-MM-DD)
2661
+ * @returns ExpectedTransactionListResponseDto Expected transactions retrieved successfully
1999
2662
  * @throws ApiError
2000
2663
  */
2001
- public static transactionRuleControllerValidate(
2002
- data: TransactionRuleControllerValidateData
2003
- ): CancelablePromise<TransactionRuleControllerValidateResponse> {
2664
+ public static expectedTransactionControllerFindAll(
2665
+ data: ExpectedTransactionControllerFindAllData
2666
+ ): CancelablePromise<ExpectedTransactionControllerFindAllResponse> {
2004
2667
  return __request(OpenAPI, {
2005
- method: 'POST',
2006
- url: '/api/v1/{region}/bean/transaction-rules/validate',
2668
+ method: 'GET',
2669
+ url: '/api/v1/{region}/bean/expected-transactions',
2007
2670
  path: {
2008
2671
  region: data.region
2009
2672
  },
2010
- body: data.requestBody,
2011
- mediaType: 'application/json',
2012
- errors: {
2013
- 400: 'Validation failed',
2014
- 401: 'Unauthorized'
2673
+ query: {
2674
+ ruleId: data.ruleId,
2675
+ status: data.status,
2676
+ fromDate: data.fromDate,
2677
+ toDate: data.toDate
2015
2678
  }
2016
2679
  });
2017
2680
  }
2018
2681
 
2019
2682
  /**
2020
- * Bulk create transaction rules
2683
+ * List overdue expected transactions
2684
+ * Returns all overdue expected transactions (PENDING past tolerance)
2021
2685
  * @param data The data for the request.
2022
2686
  * @param data.region Region code for tenant context
2023
- * @param data.requestBody
2024
- * @returns BulkCreateRulesResponseDto Bulk create completed
2687
+ * @returns ExpectedTransactionListResponseDto Overdue transactions retrieved successfully
2025
2688
  * @throws ApiError
2026
2689
  */
2027
- public static transactionRuleControllerBulkCreate(
2028
- data: TransactionRuleControllerBulkCreateData
2029
- ): CancelablePromise<TransactionRuleControllerBulkCreateResponse> {
2690
+ public static expectedTransactionControllerFindOverdue(
2691
+ data: ExpectedTransactionControllerFindOverdueData
2692
+ ): CancelablePromise<ExpectedTransactionControllerFindOverdueResponse> {
2030
2693
  return __request(OpenAPI, {
2031
- method: 'POST',
2032
- url: '/api/v1/{region}/bean/transaction-rules/bulk',
2694
+ method: 'GET',
2695
+ url: '/api/v1/{region}/bean/expected-transactions/overdue',
2033
2696
  path: {
2034
2697
  region: data.region
2035
- },
2036
- body: data.requestBody,
2037
- mediaType: 'application/json',
2038
- errors: {
2039
- 400: 'Invalid bulk create data',
2040
- 401: 'Unauthorized'
2041
2698
  }
2042
2699
  });
2043
2700
  }
2044
2701
 
2045
2702
  /**
2046
- * Export transaction rules
2703
+ * Get expected transaction by ID
2704
+ * Returns a specific expected transaction with rule details
2047
2705
  * @param data The data for the request.
2048
- * @param data.format Export format (currently only JSON supported)
2706
+ * @param data.id Expected transaction ID
2049
2707
  * @param data.region Region code for tenant context
2050
- * @returns ExportRulesResponseDto Exported rules
2708
+ * @returns ExpectedTransactionResponseDto Expected transaction retrieved successfully
2051
2709
  * @throws ApiError
2052
2710
  */
2053
- public static transactionRuleControllerExport(
2054
- data: TransactionRuleControllerExportData
2055
- ): CancelablePromise<TransactionRuleControllerExportResponse> {
2711
+ public static expectedTransactionControllerFindOne(
2712
+ data: ExpectedTransactionControllerFindOneData
2713
+ ): CancelablePromise<ExpectedTransactionControllerFindOneResponse> {
2056
2714
  return __request(OpenAPI, {
2057
2715
  method: 'GET',
2058
- url: '/api/v1/{region}/bean/transaction-rules/export/{format}',
2716
+ url: '/api/v1/{region}/bean/expected-transactions/{id}',
2059
2717
  path: {
2060
- format: data.format,
2718
+ id: data.id,
2061
2719
  region: data.region
2062
2720
  },
2063
2721
  errors: {
2064
- 400: 'Unsupported format',
2065
- 401: 'Unauthorized'
2722
+ 404: 'Expected transaction not found'
2066
2723
  }
2067
2724
  });
2068
2725
  }
2069
2726
 
2070
2727
  /**
2071
- * Get transaction rule statistics
2728
+ * Skip expected transaction
2729
+ * Marks an expected transaction as skipped (PENDING -> SKIPPED)
2072
2730
  * @param data The data for the request.
2073
- * @param data.period Statistics time period
2731
+ * @param data.id Expected transaction ID
2074
2732
  * @param data.region Region code for tenant context
2075
- * @returns RuleStatisticsResponseDto Rule statistics
2733
+ * @returns ExpectedTransactionResponseDto Expected transaction skipped successfully
2076
2734
  * @throws ApiError
2077
2735
  */
2078
- public static transactionRuleControllerGetStatistics(
2079
- data: TransactionRuleControllerGetStatisticsData
2080
- ): CancelablePromise<TransactionRuleControllerGetStatisticsResponse> {
2736
+ public static expectedTransactionControllerSkip(
2737
+ data: ExpectedTransactionControllerSkipData
2738
+ ): CancelablePromise<ExpectedTransactionControllerSkipResponse> {
2081
2739
  return __request(OpenAPI, {
2082
- method: 'GET',
2083
- url: '/api/v1/{region}/bean/transaction-rules/statistics/{period}',
2740
+ method: 'POST',
2741
+ url: '/api/v1/{region}/bean/expected-transactions/{id}/skip',
2084
2742
  path: {
2085
- period: data.period,
2743
+ id: data.id,
2086
2744
  region: data.region
2087
2745
  },
2088
2746
  errors: {
2089
- 401: 'Unauthorized'
2747
+ 400: 'Cannot skip - not in PENDING status',
2748
+ 404: 'Expected transaction not found'
2090
2749
  }
2091
2750
  });
2092
2751
  }
2093
2752
 
2094
2753
  /**
2095
- * Get transaction rule detail
2754
+ * Undo skip
2755
+ * Reverses a skip operation (SKIPPED -> PENDING)
2096
2756
  * @param data The data for the request.
2097
- * @param data.ruleId Rule ID
2757
+ * @param data.id Expected transaction ID
2098
2758
  * @param data.region Region code for tenant context
2099
- * @returns TransactionRuleResponseDto Rule details
2759
+ * @returns void Skip undone successfully
2100
2760
  * @throws ApiError
2101
2761
  */
2102
- public static transactionRuleControllerGetDetail(
2103
- data: TransactionRuleControllerGetDetailData
2104
- ): CancelablePromise<TransactionRuleControllerGetDetailResponse> {
2762
+ public static expectedTransactionControllerUndoSkip(
2763
+ data: ExpectedTransactionControllerUndoSkipData
2764
+ ): CancelablePromise<ExpectedTransactionControllerUndoSkipResponse> {
2105
2765
  return __request(OpenAPI, {
2106
- method: 'GET',
2107
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2766
+ method: 'DELETE',
2767
+ url: '/api/v1/{region}/bean/expected-transactions/{id}/skip',
2108
2768
  path: {
2109
- ruleId: data.ruleId,
2769
+ id: data.id,
2110
2770
  region: data.region
2111
2771
  },
2112
2772
  errors: {
2113
- 401: 'Unauthorized',
2114
- 403: 'Forbidden - not owner of rule',
2115
- 404: 'Rule not found'
2773
+ 400: 'Cannot undo - not in SKIPPED status',
2774
+ 404: 'Expected transaction not found'
2116
2775
  }
2117
2776
  });
2118
2777
  }
2119
2778
 
2120
2779
  /**
2121
- * Update a transaction rule
2780
+ * Confirm transaction match
2781
+ * Manually matches an expected transaction with an actual transaction
2122
2782
  * @param data The data for the request.
2123
- * @param data.ruleId Rule ID to update
2783
+ * @param data.id Expected transaction ID
2124
2784
  * @param data.region Region code for tenant context
2125
2785
  * @param data.requestBody
2126
- * @returns TransactionRuleResponseDto Rule updated successfully
2786
+ * @returns unknown Match confirmed successfully
2127
2787
  * @throws ApiError
2128
2788
  */
2129
- public static transactionRuleControllerUpdate(
2130
- data: TransactionRuleControllerUpdateData
2131
- ): CancelablePromise<TransactionRuleControllerUpdateResponse> {
2789
+ public static expectedTransactionControllerConfirmMatch(
2790
+ data: ExpectedTransactionControllerConfirmMatchData
2791
+ ): CancelablePromise<ExpectedTransactionControllerConfirmMatchResponse> {
2132
2792
  return __request(OpenAPI, {
2133
- method: 'PUT',
2134
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2793
+ method: 'POST',
2794
+ url: '/api/v1/{region}/bean/expected-transactions/{id}/match',
2135
2795
  path: {
2136
- ruleId: data.ruleId,
2796
+ id: data.id,
2137
2797
  region: data.region
2138
2798
  },
2139
2799
  body: data.requestBody,
2140
2800
  mediaType: 'application/json',
2141
2801
  errors: {
2142
- 400: 'Validation failed',
2143
- 401: 'Unauthorized',
2144
- 403: 'Forbidden - not owner of rule',
2145
- 404: 'Rule not found',
2146
- 409: 'Resource conflict - rule is being modified by another process'
2802
+ 400: 'Cannot match - not in PENDING status',
2803
+ 404: 'Expected or actual transaction not found',
2804
+ 409: 'Actual transaction already matched to another rule'
2147
2805
  }
2148
2806
  });
2149
2807
  }
2150
2808
 
2151
2809
  /**
2152
- * Delete a transaction rule
2810
+ * Unmatch transaction
2811
+ * Removes the match between expected and actual transaction (COMPLETED -> PENDING)
2153
2812
  * @param data The data for the request.
2154
- * @param data.ruleId Rule ID to delete
2813
+ * @param data.id Expected transaction ID
2155
2814
  * @param data.region Region code for tenant context
2156
- * @returns void Rule deleted successfully
2815
+ * @returns void Match removed successfully
2157
2816
  * @throws ApiError
2158
2817
  */
2159
- public static transactionRuleControllerDelete(
2160
- data: TransactionRuleControllerDeleteData
2161
- ): CancelablePromise<TransactionRuleControllerDeleteResponse> {
2818
+ public static expectedTransactionControllerUnmatch(
2819
+ data: ExpectedTransactionControllerUnmatchData
2820
+ ): CancelablePromise<ExpectedTransactionControllerUnmatchResponse> {
2162
2821
  return __request(OpenAPI, {
2163
2822
  method: 'DELETE',
2164
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}',
2823
+ url: '/api/v1/{region}/bean/expected-transactions/{id}/match',
2165
2824
  path: {
2166
- ruleId: data.ruleId,
2825
+ id: data.id,
2167
2826
  region: data.region
2168
2827
  },
2169
2828
  errors: {
2170
- 401: 'Unauthorized',
2171
- 403: 'Forbidden - not owner of rule',
2172
- 404: 'Rule not found',
2173
- 409: 'Resource conflict - rule is being modified by another process'
2829
+ 400: 'Cannot unmatch - not in COMPLETED status',
2830
+ 404: 'Expected transaction not found'
2174
2831
  }
2175
2832
  });
2176
2833
  }
2177
2834
 
2178
2835
  /**
2179
- * Test rule matching
2836
+ * Enter Now
2837
+ * Creates an actual transaction for an expected transaction (YNAB-style Enter Now)
2180
2838
  * @param data The data for the request.
2181
- * @param data.ruleId Rule ID to test
2839
+ * @param data.id Expected transaction ID
2182
2840
  * @param data.region Region code for tenant context
2183
2841
  * @param data.requestBody
2184
- * @returns TestRuleResponseDto Test result
2842
+ * @returns unknown Transaction created successfully
2185
2843
  * @throws ApiError
2186
2844
  */
2187
- public static transactionRuleControllerTest(
2188
- data: TransactionRuleControllerTestData
2189
- ): CancelablePromise<TransactionRuleControllerTestResponse> {
2845
+ public static expectedTransactionControllerEnterNow(
2846
+ data: ExpectedTransactionControllerEnterNowData
2847
+ ): CancelablePromise<ExpectedTransactionControllerEnterNowResponse> {
2190
2848
  return __request(OpenAPI, {
2191
2849
  method: 'POST',
2192
- url: '/api/v1/{region}/bean/transaction-rules/{ruleId}/test',
2850
+ url: '/api/v1/{region}/bean/expected-transactions/{id}/enter',
2193
2851
  path: {
2194
- ruleId: data.ruleId,
2852
+ id: data.id,
2195
2853
  region: data.region
2196
2854
  },
2197
2855
  body: data.requestBody,
2198
2856
  mediaType: 'application/json',
2199
2857
  errors: {
2200
- 401: 'Unauthorized',
2201
- 403: 'Forbidden - not owner of rule',
2202
- 404: 'Rule not found'
2858
+ 400: 'Cannot enter - not in PENDING status or missing accounts',
2859
+ 404: 'Expected transaction or accounts not found'
2203
2860
  }
2204
2861
  });
2205
2862
  }
2206
2863
  }
2207
2864
 
2208
- export class UsersService {
2865
+ export class RecurringForecastService {
2209
2866
  /**
2210
- * Delete own user account
2867
+ * Get cash flow forecast
2868
+ * Returns predicted outflows for the next N months based on active recurring rules
2211
2869
  * @param data The data for the request.
2212
- * @param data.requestBody
2213
- * @returns void User deleted successfully
2870
+ * @param data.region Region code for tenant context
2871
+ * @param data.months Number of months to forecast (1-12, default 3)
2872
+ * @returns ForecastResponseDto Forecast retrieved successfully
2214
2873
  * @throws ApiError
2215
2874
  */
2216
- public static userControllerDeleteOwnUser(
2217
- data: UserControllerDeleteOwnUserData
2218
- ): CancelablePromise<UserControllerDeleteOwnUserResponse> {
2875
+ public static forecastControllerGetForecast(
2876
+ data: ForecastControllerGetForecastData
2877
+ ): CancelablePromise<ForecastControllerGetForecastResponse> {
2219
2878
  return __request(OpenAPI, {
2220
- method: 'DELETE',
2221
- url: '/api/v1/users',
2222
- body: data.requestBody,
2223
- mediaType: 'application/json',
2224
- errors: {
2225
- 403: 'Invalid access token'
2879
+ method: 'GET',
2880
+ url: '/api/v1/{region}/bean/recurring/forecast',
2881
+ path: {
2882
+ region: data.region
2883
+ },
2884
+ query: {
2885
+ months: data.months
2226
2886
  }
2227
2887
  });
2228
2888
  }
2889
+ }
2229
2890
 
2891
+ export class BeanCategoryCatalogService {
2230
2892
  /**
2231
- * Get current authenticated user
2893
+ * List category catalog for a region
2894
+ * Returns the region-scoped category slugs (expense/income/investment/banking/transfer/payment) for the NLP result picker, each with the categoryAccount paths the region-enabled system rules map it to (#816). CN-exclusive payment instruments (huabei/baitiao) appear only under /cn.
2232
2895
  * @param data The data for the request.
2233
- * @param data.acceptLanguage
2234
- * @returns unknown User retrieved successfully
2896
+ * @param data.region Region code for tenant context
2897
+ * @param data.scenario Filter by scenario
2898
+ * @param data.routeBearing Filter by routeBearing (entity-router route() consumes it)
2899
+ * @returns CategoryCatalogListResponseDto Category catalog retrieved successfully
2235
2900
  * @throws ApiError
2236
2901
  */
2237
- public static userControllerGetUser(
2238
- data: UserControllerGetUserData
2239
- ): CancelablePromise<UserControllerGetUserResponse> {
2902
+ public static categoryCatalogControllerList(
2903
+ data: CategoryCatalogControllerListData
2904
+ ): CancelablePromise<CategoryCatalogControllerListResponse> {
2240
2905
  return __request(OpenAPI, {
2241
2906
  method: 'GET',
2242
- url: '/api/v1/users',
2243
- headers: {
2244
- 'accept-language': data.acceptLanguage
2907
+ url: '/api/v1/{region}/bean/categories',
2908
+ path: {
2909
+ region: data.region
2910
+ },
2911
+ query: {
2912
+ scenario: data.scenario,
2913
+ routeBearing: data.routeBearing
2245
2914
  }
2246
2915
  });
2247
2916
  }
2917
+ }
2248
2918
 
2919
+ export class LifeEventsService {
2249
2920
  /**
2250
- * Sign up new user
2251
- * Create a new account with auto-generated access token. Protected by Cloudflare Turnstile to prevent automated signup (when enabled).
2921
+ * Create a new life event
2922
+ * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
2252
2923
  * @param data The data for the request.
2924
+ * @param data.region Region code for tenant context (decorative for life events)
2253
2925
  * @param data.requestBody
2254
- * @returns unknown User created successfully
2926
+ * @returns EventResponseDto Life event created successfully
2255
2927
  * @throws ApiError
2256
2928
  */
2257
- public static userControllerSignupUser(
2258
- data: UserControllerSignupUserData
2259
- ): CancelablePromise<UserControllerSignupUserResponse> {
2929
+ public static eventControllerCreate(
2930
+ data: EventControllerCreateData
2931
+ ): CancelablePromise<EventControllerCreateResponse> {
2260
2932
  return __request(OpenAPI, {
2261
2933
  method: 'POST',
2262
- url: '/api/v1/users',
2934
+ url: '/api/v1/{region}/bean/events',
2935
+ path: {
2936
+ region: data.region
2937
+ },
2263
2938
  body: data.requestBody,
2264
2939
  mediaType: 'application/json',
2265
2940
  errors: {
2266
- 400: 'Invalid Turnstile token (when Turnstile is enabled)',
2267
- 403: 'User signup is disabled'
2941
+ 409: 'Life event already exists for this (userId, type, date) combination'
2268
2942
  }
2269
2943
  });
2270
2944
  }
2271
2945
 
2272
2946
  /**
2273
- * Delete user by ID (admin only)
2947
+ * List user life events
2948
+ * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2274
2949
  * @param data The data for the request.
2275
- * @param data.id User ID to delete
2276
- * @returns void User deleted successfully
2950
+ * @param data.region Region code for tenant context (decorative for life events)
2951
+ * @param data.type Filter by life event type (exact match)
2952
+ * @param data.q Search term for description (case-insensitive partial match)
2953
+ * @param data.from Filter life events from this date (ISO 8601 format)
2954
+ * @param data.to Filter life events to this date (ISO 8601 format)
2955
+ * @param data.page Page number for pagination (default: 1)
2956
+ * @param data.limit Number of items per page (default: 20, max: 100)
2957
+ * @returns EventListResponseDto Life events retrieved successfully
2958
+ * @throws ApiError
2959
+ */
2960
+ public static eventControllerFindAll(
2961
+ data: EventControllerFindAllData
2962
+ ): CancelablePromise<EventControllerFindAllResponse> {
2963
+ return __request(OpenAPI, {
2964
+ method: 'GET',
2965
+ url: '/api/v1/{region}/bean/events',
2966
+ path: {
2967
+ region: data.region
2968
+ },
2969
+ query: {
2970
+ type: data.type,
2971
+ q: data.q,
2972
+ from: data.from,
2973
+ to: data.to,
2974
+ page: data.page,
2975
+ limit: data.limit
2976
+ }
2977
+ });
2978
+ }
2979
+
2980
+ /**
2981
+ * Get life event by ID
2982
+ * Returns a single life event by its ID. Returns ETag header.
2983
+ * @param data The data for the request.
2984
+ * @param data.id Life event ID
2985
+ * @param data.region Region code for tenant context (decorative for life events)
2986
+ * @returns EventResponseDto Life event retrieved successfully
2277
2987
  * @throws ApiError
2278
2988
  */
2279
- public static userControllerDeleteUser(
2280
- data: UserControllerDeleteUserData
2281
- ): CancelablePromise<UserControllerDeleteUserResponse> {
2989
+ public static eventControllerFindOne(
2990
+ data: EventControllerFindOneData
2991
+ ): CancelablePromise<EventControllerFindOneResponse> {
2282
2992
  return __request(OpenAPI, {
2283
- method: 'DELETE',
2284
- url: '/api/v1/users/{id}',
2993
+ method: 'GET',
2994
+ url: '/api/v1/{region}/bean/events/{id}',
2285
2995
  path: {
2286
- id: data.id
2996
+ id: data.id,
2997
+ region: data.region
2287
2998
  },
2288
2999
  errors: {
2289
- 403: 'Cannot delete own account or insufficient permissions'
3000
+ 404: 'Life event not found'
2290
3001
  }
2291
3002
  });
2292
3003
  }
2293
3004
 
2294
3005
  /**
2295
- * Get user info by user ID
3006
+ * Update a life event
3007
+ * Updates an existing life event. If If-Match header is provided, performs optimistic concurrency check; mismatched updatedAt returns 412.
2296
3008
  * @param data The data for the request.
2297
- * @param data.id User ID
2298
- * @returns unknown User info retrieved successfully
3009
+ * @param data.id Life event ID
3010
+ * @param data.region Region code for tenant context (decorative for life events)
3011
+ * @param data.requestBody
3012
+ * @returns EventResponseDto Life event updated successfully
2299
3013
  * @throws ApiError
2300
3014
  */
2301
- public static userControllerGetUserInfo(
2302
- data: UserControllerGetUserInfoData
2303
- ): CancelablePromise<UserControllerGetUserInfoResponse> {
3015
+ public static eventControllerUpdate(
3016
+ data: EventControllerUpdateData
3017
+ ): CancelablePromise<EventControllerUpdateResponse> {
2304
3018
  return __request(OpenAPI, {
2305
- method: 'GET',
2306
- url: '/api/v1/users/{id}/info',
3019
+ method: 'PUT',
3020
+ url: '/api/v1/{region}/bean/events/{id}',
2307
3021
  path: {
2308
- id: data.id
3022
+ id: data.id,
3023
+ region: data.region
2309
3024
  },
3025
+ body: data.requestBody,
3026
+ mediaType: 'application/json',
2310
3027
  errors: {
2311
- 403: 'Cannot access other user info without admin permission'
3028
+ 400: 'If-Match header is not a valid ISO 8601 date',
3029
+ 404: 'Life event not found',
3030
+ 409: 'Updated event conflicts with an existing (userId, type, date) combination',
3031
+ 412: 'If-Match precondition failed (updatedAt mismatch)'
2312
3032
  }
2313
3033
  });
2314
3034
  }
2315
3035
 
2316
3036
  /**
2317
- * Update user settings
3037
+ * Delete a life event
3038
+ * Deletes a life event entry (hard delete). Returns 204.
2318
3039
  * @param data The data for the request.
2319
- * @param data.requestBody
2320
- * @returns unknown Settings updated successfully
3040
+ * @param data.id Life event ID
3041
+ * @param data.region Region code for tenant context (decorative for life events)
3042
+ * @returns void Life event deleted successfully
2321
3043
  * @throws ApiError
2322
3044
  */
2323
- public static userControllerUpdateUserSetting(
2324
- data: UserControllerUpdateUserSettingData
2325
- ): CancelablePromise<UserControllerUpdateUserSettingResponse> {
3045
+ public static eventControllerDelete(
3046
+ data: EventControllerDeleteData
3047
+ ): CancelablePromise<EventControllerDeleteResponse> {
2326
3048
  return __request(OpenAPI, {
2327
- method: 'PUT',
2328
- url: '/api/v1/users/setting',
2329
- body: data.requestBody,
2330
- mediaType: 'application/json',
3049
+ method: 'DELETE',
3050
+ url: '/api/v1/{region}/bean/events/{id}',
3051
+ path: {
3052
+ id: data.id,
3053
+ region: data.region
3054
+ },
2331
3055
  errors: {
2332
- 403: 'Insufficient permissions'
3056
+ 404: 'Life event not found'
2333
3057
  }
2334
3058
  });
2335
3059
  }
2336
3060
 
2337
3061
  /**
2338
- * Get all user settings paginated (admin only)
3062
+ * Slice time-series by a life event (Phase 79)
3063
+ * Returns aggregated time-series for postings matching accountPattern within the half-open date range of the given life event.
2339
3064
  * @param data The data for the request.
2340
- * @param data.pageNo Page number
2341
- * @param data.pageSize Page size
2342
- * @returns unknown Settings list retrieved successfully
3065
+ * @param data.id Life event ID
3066
+ * @param data.accountPattern
3067
+ * @param data.granularity
3068
+ * @param data.region Region code for tenant context (decorative for life events)
3069
+ * @returns unknown Time-series sliced by the life event range
2343
3070
  * @throws ApiError
2344
3071
  */
2345
- public static userControllerGetAllUserSettingsByPage(
2346
- data: UserControllerGetAllUserSettingsByPageData
2347
- ): CancelablePromise<UserControllerGetAllUserSettingsByPageResponse> {
3072
+ public static eventControllerGetSlice(
3073
+ data: EventControllerGetSliceData
3074
+ ): CancelablePromise<EventControllerGetSliceResponse> {
2348
3075
  return __request(OpenAPI, {
2349
3076
  method: 'GET',
2350
- url: '/api/v1/users/settings-by-page',
3077
+ url: '/api/v1/{region}/bean/events/{id}/slice',
3078
+ path: {
3079
+ id: data.id,
3080
+ region: data.region
3081
+ },
2351
3082
  query: {
2352
- pageNo: data.pageNo,
2353
- pageSize: data.pageSize
3083
+ accountPattern: data.accountPattern,
3084
+ granularity: data.granularity
3085
+ },
3086
+ errors: {
3087
+ 400: 'accountPattern query param is empty',
3088
+ 404: 'Life event not found'
2354
3089
  }
2355
3090
  });
2356
3091
  }
3092
+ }
2357
3093
 
3094
+ export class OnboardingService {
2358
3095
  /**
2359
- * Get asset and liability summary for current user
2360
- * @returns unknown Summary retrieved successfully
3096
+ * Bootstrap core accounts + register asset accounts with opening balances (ADR-0113)
3097
+ * @param data The data for the request.
3098
+ * @param data.region Region code for tenant context. Not-yet-open codes are accepted: the universal catalog backs onboarding regardless of region (#759)
3099
+ * @param data.requestBody
3100
+ * @returns unknown Onboarding bootstrap result.
2361
3101
  * @throws ApiError
2362
3102
  */
2363
- public static userControllerGetAssetLiabilitySummary(): CancelablePromise<UserControllerGetAssetLiabilitySummaryResponse> {
3103
+ public static onboardingControllerBootstrap(
3104
+ data: OnboardingControllerBootstrapData
3105
+ ): CancelablePromise<OnboardingControllerBootstrapResponse> {
2364
3106
  return __request(OpenAPI, {
2365
- method: 'GET',
2366
- url: '/api/v1/users/asset-liability-summary'
3107
+ method: 'POST',
3108
+ url: '/api/v1/{region}/bean/onboarding',
3109
+ path: {
3110
+ region: data.region
3111
+ },
3112
+ body: data.requestBody,
3113
+ mediaType: 'application/json',
3114
+ errors: {
3115
+ 422: 'Invalid region/account path/duplicate paths.'
3116
+ }
2367
3117
  });
2368
3118
  }
2369
3119
  }
2370
3120
 
2371
- export class PropertiesService {
3121
+ export class BalanceReconciliationService {
2372
3122
  /**
2373
- * Get all system properties
2374
- * @returns unknown Properties retrieved successfully
3123
+ * Preview reconciliation (book vs actual)
3124
+ * Computes book balance, diff, Beancount-inferred tolerance, and suggested action without persisting.
3125
+ * @param data The data for the request.
3126
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3127
+ * @param data.requestBody
3128
+ * @returns ReconciliationComputeResultDto Reconciliation preview
2375
3129
  * @throws ApiError
2376
3130
  */
2377
- public static propertyControllerGetAll(): CancelablePromise<PropertyControllerGetAllResponse> {
3131
+ public static reconciliationControllerCompute(
3132
+ data: ReconciliationControllerComputeData
3133
+ ): CancelablePromise<ReconciliationControllerComputeResponse> {
2378
3134
  return __request(OpenAPI, {
2379
- method: 'GET',
2380
- url: '/api/v1/admin/properties',
3135
+ method: 'POST',
3136
+ url: '/api/v1/{region}/bean/reconciliations',
3137
+ path: {
3138
+ region: data.region
3139
+ },
3140
+ body: data.requestBody,
3141
+ mediaType: 'application/json',
2381
3142
  errors: {
2382
- 401: 'Unauthorized',
2383
- 403: 'Forbidden - insufficient permissions'
3143
+ 404: 'Account not found'
2384
3144
  }
2385
3145
  });
2386
3146
  }
2387
3147
 
2388
3148
  /**
2389
- * Get property by key
3149
+ * Record a balance assertion
3150
+ * Persists the reconciliation as a BeanBalance assertion (amount = actual, diffAmount = book − actual). Re-reconciling the same day/currency upserts.
2390
3151
  * @param data The data for the request.
2391
- * @param data.key Property key
2392
- * @returns unknown Property retrieved successfully
3152
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3153
+ * @param data.requestBody
3154
+ * @returns ReconciliationRecordDto Balance assertion recorded
2393
3155
  * @throws ApiError
2394
3156
  */
2395
- public static propertyControllerGetByKey(
2396
- data: PropertyControllerGetByKeyData
2397
- ): CancelablePromise<PropertyControllerGetByKeyResponse> {
3157
+ public static reconciliationControllerAssert(
3158
+ data: ReconciliationControllerAssertData
3159
+ ): CancelablePromise<ReconciliationControllerAssertResponse> {
2398
3160
  return __request(OpenAPI, {
2399
- method: 'GET',
2400
- url: '/api/v1/admin/properties/{key}',
3161
+ method: 'POST',
3162
+ url: '/api/v1/{region}/bean/reconciliations/assert',
2401
3163
  path: {
2402
- key: data.key
3164
+ region: data.region
2403
3165
  },
3166
+ body: data.requestBody,
3167
+ mediaType: 'application/json',
2404
3168
  errors: {
2405
- 401: 'Unauthorized',
2406
- 403: 'Forbidden - insufficient permissions',
2407
- 404: 'Property not found'
3169
+ 404: 'Account not found'
2408
3170
  }
2409
3171
  });
2410
3172
  }
2411
3173
 
2412
3174
  /**
2413
- * Update a system property
3175
+ * Generate a pad adjusting entry
3176
+ * 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.
2414
3177
  * @param data The data for the request.
2415
- * @param data.key Property key
3178
+ * @param data.region Region code for tenant context (decorative for reconciliation)
2416
3179
  * @param data.requestBody
2417
- * @returns unknown Property updated successfully
3180
+ * @returns PadResultDto Pad adjusting entry generated
2418
3181
  * @throws ApiError
2419
3182
  */
2420
- public static propertyControllerUpdate(
2421
- data: PropertyControllerUpdateData
2422
- ): CancelablePromise<PropertyControllerUpdateResponse> {
3183
+ public static reconciliationControllerPad(
3184
+ data: ReconciliationControllerPadData
3185
+ ): CancelablePromise<ReconciliationControllerPadResponse> {
2423
3186
  return __request(OpenAPI, {
2424
- method: 'PUT',
2425
- url: '/api/v1/admin/properties/{key}',
3187
+ method: 'POST',
3188
+ url: '/api/v1/{region}/bean/reconciliations/pad',
2426
3189
  path: {
2427
- key: data.key
3190
+ region: data.region
2428
3191
  },
2429
3192
  body: data.requestBody,
2430
3193
  mediaType: 'application/json',
2431
3194
  errors: {
2432
- 401: 'Unauthorized',
2433
- 403: 'Forbidden - insufficient permissions'
3195
+ 400: 'Book already within tolerance — no pad needed',
3196
+ 404: 'Account not found'
2434
3197
  }
2435
3198
  });
2436
3199
  }
2437
3200
 
2438
3201
  /**
2439
- * Delete a system property
3202
+ * List reconciliation history for an account
3203
+ * Returns recorded balance assertions (most recent first). The latest drives the account-detail "Last <date>" badge.
2440
3204
  * @param data The data for the request.
2441
- * @param data.key Property key
2442
- * @returns void Property deleted successfully
3205
+ * @param data.accountId BeanAccount id
3206
+ * @param data.region Region code for tenant context (decorative for reconciliation)
3207
+ * @returns ReconciliationRecordDto Reconciliation history
2443
3208
  * @throws ApiError
2444
3209
  */
2445
- public static propertyControllerDelete(
2446
- data: PropertyControllerDeleteData
2447
- ): CancelablePromise<PropertyControllerDeleteResponse> {
3210
+ public static reconciliationControllerHistory(
3211
+ data: ReconciliationControllerHistoryData
3212
+ ): CancelablePromise<ReconciliationControllerHistoryResponse> {
2448
3213
  return __request(OpenAPI, {
2449
- method: 'DELETE',
2450
- url: '/api/v1/admin/properties/{key}',
3214
+ method: 'GET',
3215
+ url: '/api/v1/{region}/bean/accounts/{accountId}/reconciliations',
2451
3216
  path: {
2452
- key: data.key
3217
+ accountId: data.accountId,
3218
+ region: data.region
2453
3219
  },
2454
3220
  errors: {
2455
- 401: 'Unauthorized',
2456
- 403: 'Forbidden - insufficient permissions',
2457
- 404: 'Property not found'
3221
+ 404: 'Account not found'
2458
3222
  }
2459
3223
  });
2460
3224
  }
@@ -2464,13 +3228,20 @@ export class BeanExportService {
2464
3228
  /**
2465
3229
  * Export Beancount ledger as ZIP
2466
3230
  * Export all user Beancount data as a ZIP file containing ledger.beancount and yearly files in community format.
2467
- * @returns unknown
3231
+ * @param data The data for the request.
3232
+ * @param data.region Region code for tenant context
3233
+ * @returns binary ZIP archive (application/zip) streamed as an attachment
2468
3234
  * @throws ApiError
2469
3235
  */
2470
- public static exportControllerExportBeancount(): CancelablePromise<ExportControllerExportBeancountResponse> {
3236
+ public static exportControllerExportBeancount(
3237
+ data: ExportControllerExportBeancountData
3238
+ ): CancelablePromise<ExportControllerExportBeancountResponse> {
2471
3239
  return __request(OpenAPI, {
2472
3240
  method: 'GET',
2473
- url: '/api/v1/{region}/bean/export/beancount'
3241
+ url: '/api/v1/{region}/bean/export/beancount',
3242
+ path: {
3243
+ region: data.region
3244
+ }
2474
3245
  });
2475
3246
  }
2476
3247
  }
@@ -2625,129 +3396,14 @@ export class BeanImportService {
2625
3396
  data: ImporterConfigControllerResetConfigData
2626
3397
  ): CancelablePromise<ImporterConfigControllerResetConfigResponse> {
2627
3398
  return __request(OpenAPI, {
2628
- method: 'POST',
2629
- url: '/api/v1/{region}/bean/import/config/{importerId}/reset',
2630
- path: {
2631
- importerId: data.importerId,
2632
- region: data.region
2633
- },
2634
- errors: {
2635
- 400: 'Invalid input - Unsupported importer'
2636
- }
2637
- });
2638
- }
2639
- }
2640
-
2641
- export class BeanPlatformsService {
2642
- /**
2643
- * Get all platforms with statistics
2644
- * @returns unknown List of platforms with binding and account counts
2645
- * @throws ApiError
2646
- */
2647
- public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
2648
- return __request(OpenAPI, {
2649
- method: 'GET',
2650
- url: '/api/v1/bean/platforms'
2651
- });
2652
- }
2653
-
2654
- /**
2655
- * Create a new platform
2656
- * @param data The data for the request.
2657
- * @param data.requestBody
2658
- * @returns unknown Platform created successfully
2659
- * @throws ApiError
2660
- */
2661
- public static platformControllerCreate(
2662
- data: PlatformControllerCreateData
2663
- ): CancelablePromise<PlatformControllerCreateResponse> {
2664
- return __request(OpenAPI, {
2665
- method: 'POST',
2666
- url: '/api/v1/bean/platforms',
2667
- body: data.requestBody,
2668
- mediaType: 'application/json',
2669
- errors: {
2670
- 409: 'Platform already exists'
2671
- }
2672
- });
2673
- }
2674
-
2675
- /**
2676
- * Get platform list for current user
2677
- * @returns unknown List of platforms with user binding status
2678
- * @throws ApiError
2679
- */
2680
- public static platformControllerGetPlatformList(): CancelablePromise<PlatformControllerGetPlatformListResponse> {
2681
- return __request(OpenAPI, {
2682
- method: 'GET',
2683
- url: '/api/v1/bean/platforms/list'
2684
- });
2685
- }
2686
-
2687
- /**
2688
- * Match platforms by name or alias
2689
- * @param data The data for the request.
2690
- * @param data.q Search query — Chinese name, English name, or abbreviation
2691
- * @param data.region Region code for category override lookup
2692
- * @returns unknown List of matching platforms with suggested segment names
2693
- * @throws ApiError
2694
- */
2695
- public static platformControllerMatchPlatforms(
2696
- data: PlatformControllerMatchPlatformsData
2697
- ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
2698
- return __request(OpenAPI, {
2699
- method: 'GET',
2700
- url: '/api/v1/bean/platforms/match',
2701
- query: {
2702
- q: data.q,
2703
- region: data.region
2704
- }
2705
- });
2706
- }
2707
-
2708
- /**
2709
- * Update a platform
2710
- * @param data The data for the request.
2711
- * @param data.id Platform ID
2712
- * @param data.requestBody
2713
- * @returns unknown Platform updated successfully
2714
- * @throws ApiError
2715
- */
2716
- public static platformControllerUpdate(
2717
- data: PlatformControllerUpdateData
2718
- ): CancelablePromise<PlatformControllerUpdateResponse> {
2719
- return __request(OpenAPI, {
2720
- method: 'PUT',
2721
- url: '/api/v1/bean/platforms/{id}',
2722
- path: {
2723
- id: data.id
2724
- },
2725
- body: data.requestBody,
2726
- mediaType: 'application/json',
2727
- errors: {
2728
- 404: 'Platform not found'
2729
- }
2730
- });
2731
- }
2732
-
2733
- /**
2734
- * Delete a platform
2735
- * @param data The data for the request.
2736
- * @param data.id Platform ID
2737
- * @returns void Platform deleted successfully
2738
- * @throws ApiError
2739
- */
2740
- public static platformControllerDelete(
2741
- data: PlatformControllerDeleteData
2742
- ): CancelablePromise<PlatformControllerDeleteResponse> {
2743
- return __request(OpenAPI, {
2744
- method: 'DELETE',
2745
- url: '/api/v1/bean/platforms/{id}',
3399
+ method: 'POST',
3400
+ url: '/api/v1/{region}/bean/import/config/{importerId}/reset',
2746
3401
  path: {
2747
- id: data.id
3402
+ importerId: data.importerId,
3403
+ region: data.region
2748
3404
  },
2749
3405
  errors: {
2750
- 404: 'Platform not found'
3406
+ 400: 'Invalid input - Unsupported importer'
2751
3407
  }
2752
3408
  });
2753
3409
  }
@@ -2853,6 +3509,101 @@ export class ProviderSyncService {
2853
3509
  }
2854
3510
  }
2855
3511
 
3512
+ export class ExternalAccountLinksService {
3513
+ /**
3514
+ * Create an external account → BeanAccount mapping (ADR-0113)
3515
+ * @param data The data for the request.
3516
+ * @param data.region Region code for tenant context
3517
+ * @param data.requestBody
3518
+ * @returns ExternalAccountLinkResponseDto Link created.
3519
+ * @throws ApiError
3520
+ */
3521
+ public static externalAccountLinkControllerCreate(
3522
+ data: ExternalAccountLinkControllerCreateData
3523
+ ): CancelablePromise<ExternalAccountLinkControllerCreateResponse> {
3524
+ return __request(OpenAPI, {
3525
+ method: 'POST',
3526
+ url: '/api/v1/{region}/bean/external-account-links',
3527
+ path: {
3528
+ region: data.region
3529
+ },
3530
+ body: data.requestBody,
3531
+ mediaType: 'application/json',
3532
+ errors: {
3533
+ 422: 'beanAccountId not owned, or an active link already exists.'
3534
+ }
3535
+ });
3536
+ }
3537
+
3538
+ /**
3539
+ * List the user's active external account links
3540
+ * @param data The data for the request.
3541
+ * @param data.provider
3542
+ * @param data.region Region code for tenant context
3543
+ * @returns ExternalAccountLinkListResponseDto Links retrieved.
3544
+ * @throws ApiError
3545
+ */
3546
+ public static externalAccountLinkControllerFindAll(
3547
+ data: ExternalAccountLinkControllerFindAllData
3548
+ ): CancelablePromise<ExternalAccountLinkControllerFindAllResponse> {
3549
+ return __request(OpenAPI, {
3550
+ method: 'GET',
3551
+ url: '/api/v1/{region}/bean/external-account-links',
3552
+ path: {
3553
+ region: data.region
3554
+ },
3555
+ query: {
3556
+ provider: data.provider
3557
+ }
3558
+ });
3559
+ }
3560
+
3561
+ /**
3562
+ * Get a single external account link
3563
+ * @param data The data for the request.
3564
+ * @param data.id
3565
+ * @param data.region Region code for tenant context
3566
+ * @returns ExternalAccountLinkResponseDto Link retrieved.
3567
+ * @throws ApiError
3568
+ */
3569
+ public static externalAccountLinkControllerFindOne(
3570
+ data: ExternalAccountLinkControllerFindOneData
3571
+ ): CancelablePromise<ExternalAccountLinkControllerFindOneResponse> {
3572
+ return __request(OpenAPI, {
3573
+ method: 'GET',
3574
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3575
+ path: {
3576
+ id: data.id,
3577
+ region: data.region
3578
+ },
3579
+ errors: {
3580
+ 422: 'Link not found or not owned by the user.'
3581
+ }
3582
+ });
3583
+ }
3584
+
3585
+ /**
3586
+ * Soft-delete (disconnect) an external account link
3587
+ * @param data The data for the request.
3588
+ * @param data.id
3589
+ * @param data.region Region code for tenant context
3590
+ * @returns void Link soft-deleted; historical transactions are unaffected.
3591
+ * @throws ApiError
3592
+ */
3593
+ public static externalAccountLinkControllerRemove(
3594
+ data: ExternalAccountLinkControllerRemoveData
3595
+ ): CancelablePromise<ExternalAccountLinkControllerRemoveResponse> {
3596
+ return __request(OpenAPI, {
3597
+ method: 'DELETE',
3598
+ url: '/api/v1/{region}/bean/external-account-links/{id}',
3599
+ path: {
3600
+ id: data.id,
3601
+ region: data.region
3602
+ }
3603
+ });
3604
+ }
3605
+ }
3606
+
2856
3607
  export class ImportTelemetryService {
2857
3608
  /**
2858
3609
  * Receive anonymous parser failure telemetry
@@ -3011,411 +3762,330 @@ export class BeanNlpService {
3011
3762
  }
3012
3763
  }
3013
3764
 
3014
- export class DashboardService {
3765
+ export class BeanPlatformsService {
3015
3766
  /**
3016
- * Get net worth overview
3017
- * Returns total net worth with breakdown of assets and liabilities
3018
- * @param data The data for the request.
3019
- * @param data.region Region code for tenant context
3020
- * @param data.date Date for balance calculation (ISO 8601 format)
3021
- * @returns NetWorthResponseDto Net worth retrieved successfully
3767
+ * Get all platforms with statistics
3768
+ * @returns unknown List of platforms with binding and account counts
3022
3769
  * @throws ApiError
3023
3770
  */
3024
- public static dashboardControllerGetNetWorth(
3025
- data: DashboardControllerGetNetWorthData
3026
- ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3771
+ public static platformControllerFindAll(): CancelablePromise<PlatformControllerFindAllResponse> {
3027
3772
  return __request(OpenAPI, {
3028
3773
  method: 'GET',
3029
- url: '/api/v1/{region}/dashboard/net-worth',
3030
- path: {
3031
- region: data.region
3032
- },
3033
- query: {
3034
- date: data.date
3035
- },
3036
- errors: {
3037
- 401: 'User not authenticated'
3038
- }
3774
+ url: '/api/v1/bean/platforms'
3039
3775
  });
3040
3776
  }
3041
3777
 
3042
3778
  /**
3043
- * Get accounts grouped by platform
3044
- * Returns accounts with balances grouped by financial platform
3779
+ * Create a new platform
3045
3780
  * @param data The data for the request.
3046
- * @param data.region Region code for tenant context
3047
- * @param data.groupBy Grouping strategy
3048
- * @param data.date Date for balance calculation (ISO 8601 format)
3049
- * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3050
- * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3781
+ * @param data.requestBody
3782
+ * @returns unknown Platform created successfully
3051
3783
  * @throws ApiError
3052
3784
  */
3053
- public static dashboardControllerGetAccounts(
3054
- data: DashboardControllerGetAccountsData
3055
- ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3785
+ public static platformControllerCreate(
3786
+ data: PlatformControllerCreateData
3787
+ ): CancelablePromise<PlatformControllerCreateResponse> {
3056
3788
  return __request(OpenAPI, {
3057
- method: 'GET',
3058
- url: '/api/v1/{region}/dashboard/accounts',
3059
- path: {
3060
- region: data.region
3061
- },
3062
- query: {
3063
- groupBy: data.groupBy,
3064
- date: data.date,
3065
- accountId: data.accountId
3066
- },
3789
+ method: 'POST',
3790
+ url: '/api/v1/bean/platforms',
3791
+ body: data.requestBody,
3792
+ mediaType: 'application/json',
3067
3793
  errors: {
3068
- 401: 'User not authenticated'
3794
+ 409: 'Platform already exists'
3069
3795
  }
3070
3796
  });
3071
3797
  }
3072
3798
 
3073
3799
  /**
3074
- * Get cash flow summary
3075
- * Returns income, expenses, and savings for a monthly period
3800
+ * Get platform list for current user
3076
3801
  * @param data The data for the request.
3077
- * @param data.period Period in YYYY-MM format
3078
- * @param data.region Region code for tenant context
3079
- * @returns CashFlowResponseDto Cash flow retrieved successfully
3802
+ * @param data.region Region code (ISO 3166-1 alpha-2) that biases within-type-bucket ordering (local-region platforms first). Case-insensitive — stored/compared UPPERCASE ("cn" == "CN").
3803
+ * @returns PlatformListItemDto List of platforms with user binding status
3080
3804
  * @throws ApiError
3081
3805
  */
3082
- public static dashboardControllerGetCashFlow(
3083
- data: DashboardControllerGetCashFlowData
3084
- ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3806
+ public static platformControllerGetPlatformList(
3807
+ data: PlatformControllerGetPlatformListData = {}
3808
+ ): CancelablePromise<PlatformControllerGetPlatformListResponse> {
3085
3809
  return __request(OpenAPI, {
3086
3810
  method: 'GET',
3087
- url: '/api/v1/{region}/dashboard/cash-flow',
3088
- path: {
3089
- region: data.region
3090
- },
3811
+ url: '/api/v1/bean/platforms/list',
3091
3812
  query: {
3092
- period: data.period
3093
- },
3094
- errors: {
3095
- 400: 'Invalid period format',
3096
- 401: 'User not authenticated'
3813
+ region: data.region
3097
3814
  }
3098
3815
  });
3099
3816
  }
3100
- }
3101
3817
 
3102
- export class InvestmentService {
3103
3818
  /**
3104
- * Get per-holding unrealized + realized P&L
3105
- * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3819
+ * Match platforms by name or alias
3106
3820
  * @param data The data for the request.
3107
- * @param data.region Region code for tenant context
3108
- * @param data.asOf As-of date (ISO 8601), defaults to today
3109
- * @param data.accountId Scope to a single account
3110
- * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3111
- * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3821
+ * @param data.q Search query — Chinese name, English name, or abbreviation
3822
+ * @param data.region Region code (ISO 3166-1 alpha-2) that biases within-tier ordering (local-region platforms first); also the intended categoryOverrides key. Case-insensitive — stored/compared UPPERCASE ("cn" == "CN").
3823
+ * @returns PlatformMatchResponseDto Matching platforms with overall match type and truncation flag
3112
3824
  * @throws ApiError
3113
3825
  */
3114
- public static holdingPnlControllerGetHoldingPnl(
3115
- data: HoldingPnlControllerGetHoldingPnlData
3116
- ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3826
+ public static platformControllerMatchPlatforms(
3827
+ data: PlatformControllerMatchPlatformsData
3828
+ ): CancelablePromise<PlatformControllerMatchPlatformsResponse> {
3117
3829
  return __request(OpenAPI, {
3118
3830
  method: 'GET',
3119
- url: '/api/v1/{region}/investment/holdings/pnl',
3120
- path: {
3121
- region: data.region
3122
- },
3831
+ url: '/api/v1/bean/platforms/match',
3123
3832
  query: {
3124
- asOf: data.asOf,
3125
- accountId: data.accountId,
3126
- method: data.method
3127
- },
3128
- errors: {
3129
- 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3130
- 401: 'User not authenticated'
3833
+ q: data.q,
3834
+ region: data.region
3131
3835
  }
3132
3836
  });
3133
3837
  }
3134
- }
3135
3838
 
3136
- export class BeanPricesService {
3137
3839
  /**
3138
- * Create a new price
3139
- * Creates a new price entry for the authenticated user
3840
+ * Get the region and candidate account standards for a platform
3140
3841
  * @param data The data for the request.
3141
- * @param data.region Region code for tenant context
3142
- * @param data.requestBody
3143
- * @returns PriceResponseDto Price created successfully
3842
+ * @param data.id Platform ID (from a match result)
3843
+ * @param data.region Region code (ISO 3166-1 alpha-2, case-insensitive). Required for global platforms (countryCode null) — resolved as their template region; ignored when the platform has its own countryCode.
3844
+ * @param data.type Filter templates by account type (path first segment)
3845
+ * @returns PlatformStandardsResponseDto Resolved region plus the merged account-standard catalog of that region (groupable by productCategory client-side)
3144
3846
  * @throws ApiError
3145
3847
  */
3146
- public static priceControllerCreate(
3147
- data: PriceControllerCreateData
3148
- ): CancelablePromise<PriceControllerCreateResponse> {
3848
+ public static platformControllerGetPlatformStandards(
3849
+ data: PlatformControllerGetPlatformStandardsData
3850
+ ): CancelablePromise<PlatformControllerGetPlatformStandardsResponse> {
3149
3851
  return __request(OpenAPI, {
3150
- method: 'POST',
3151
- url: '/api/v1/{region}/bean/prices',
3852
+ method: 'GET',
3853
+ url: '/api/v1/bean/platforms/{id}/standards',
3152
3854
  path: {
3153
- region: data.region
3855
+ id: data.id
3154
3856
  },
3155
- body: data.requestBody,
3156
- mediaType: 'application/json',
3157
- errors: {
3158
- 404: 'Currency or quoteCurrency commodity not found',
3159
- 409: 'Price already exists for this currency pair and date'
3857
+ query: {
3858
+ region: data.region,
3859
+ type: data.type
3160
3860
  }
3161
3861
  });
3162
3862
  }
3163
3863
 
3164
3864
  /**
3165
- * List user prices
3166
- * Returns all price entries for the authenticated user with optional filtering
3865
+ * Update a platform
3167
3866
  * @param data The data for the request.
3168
- * @param data.region Region code for tenant context
3169
- * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
3170
- * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
3171
- * @param data.dateFrom Filter prices from this date (ISO 8601 format)
3172
- * @param data.dateTo Filter prices to this date (ISO 8601 format)
3173
- * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
3174
- * @param data.page Page number for pagination (default: 1)
3175
- * @param data.limit Number of items per page (default: 20, max: 100)
3176
- * @returns PriceListResponseDto Prices retrieved successfully
3867
+ * @param data.id Platform ID
3868
+ * @param data.requestBody
3869
+ * @returns unknown Platform updated successfully
3177
3870
  * @throws ApiError
3178
3871
  */
3179
- public static priceControllerFindAll(
3180
- data: PriceControllerFindAllData
3181
- ): CancelablePromise<PriceControllerFindAllResponse> {
3872
+ public static platformControllerUpdate(
3873
+ data: PlatformControllerUpdateData
3874
+ ): CancelablePromise<PlatformControllerUpdateResponse> {
3182
3875
  return __request(OpenAPI, {
3183
- method: 'GET',
3184
- url: '/api/v1/{region}/bean/prices',
3876
+ method: 'PUT',
3877
+ url: '/api/v1/bean/platforms/{id}',
3185
3878
  path: {
3186
- region: data.region
3879
+ id: data.id
3187
3880
  },
3188
- query: {
3189
- currency: data.currency,
3190
- quoteCurrency: data.quoteCurrency,
3191
- dateFrom: data.dateFrom,
3192
- dateTo: data.dateTo,
3193
- search: data.search,
3194
- page: data.page,
3195
- limit: data.limit
3881
+ body: data.requestBody,
3882
+ mediaType: 'application/json',
3883
+ errors: {
3884
+ 404: 'Platform not found'
3196
3885
  }
3197
3886
  });
3198
3887
  }
3199
3888
 
3200
3889
  /**
3201
- * Get price by ID
3202
- * Returns a single price entry by its ID
3890
+ * Delete a platform
3203
3891
  * @param data The data for the request.
3204
- * @param data.id Price ID
3205
- * @param data.region Region code for tenant context
3206
- * @returns PriceResponseDto Price retrieved successfully
3892
+ * @param data.id Platform ID
3893
+ * @returns void Platform deleted successfully
3207
3894
  * @throws ApiError
3208
3895
  */
3209
- public static priceControllerFindOne(
3210
- data: PriceControllerFindOneData
3211
- ): CancelablePromise<PriceControllerFindOneResponse> {
3896
+ public static platformControllerDelete(
3897
+ data: PlatformControllerDeleteData
3898
+ ): CancelablePromise<PlatformControllerDeleteResponse> {
3212
3899
  return __request(OpenAPI, {
3213
- method: 'GET',
3214
- url: '/api/v1/{region}/bean/prices/{id}',
3900
+ method: 'DELETE',
3901
+ url: '/api/v1/bean/platforms/{id}',
3215
3902
  path: {
3216
- id: data.id,
3217
- region: data.region
3903
+ id: data.id
3218
3904
  },
3219
3905
  errors: {
3220
- 404: 'Price not found'
3906
+ 404: 'Platform not found'
3221
3907
  }
3222
3908
  });
3223
3909
  }
3910
+ }
3224
3911
 
3912
+ export class DashboardService {
3225
3913
  /**
3226
- * Update a price
3227
- * Updates an existing price entry
3914
+ * Get net worth overview
3915
+ * Returns total net worth with breakdown of assets and liabilities
3228
3916
  * @param data The data for the request.
3229
- * @param data.id Price ID
3230
3917
  * @param data.region Region code for tenant context
3231
- * @param data.requestBody
3232
- * @returns PriceResponseDto Price updated successfully
3918
+ * @param data.date Date for balance calculation (ISO 8601 format)
3919
+ * @returns NetWorthResponseDto Net worth retrieved successfully
3233
3920
  * @throws ApiError
3234
3921
  */
3235
- public static priceControllerUpdate(
3236
- data: PriceControllerUpdateData
3237
- ): CancelablePromise<PriceControllerUpdateResponse> {
3922
+ public static dashboardControllerGetNetWorth(
3923
+ data: DashboardControllerGetNetWorthData
3924
+ ): CancelablePromise<DashboardControllerGetNetWorthResponse> {
3238
3925
  return __request(OpenAPI, {
3239
- method: 'PUT',
3240
- url: '/api/v1/{region}/bean/prices/{id}',
3926
+ method: 'GET',
3927
+ url: '/api/v1/{region}/dashboard/net-worth',
3241
3928
  path: {
3242
- id: data.id,
3243
3929
  region: data.region
3244
3930
  },
3245
- body: data.requestBody,
3246
- mediaType: 'application/json',
3931
+ query: {
3932
+ date: data.date
3933
+ },
3247
3934
  errors: {
3248
- 404: 'Price not found',
3249
- 409: 'Updated price conflicts with existing price'
3935
+ 401: 'User not authenticated'
3250
3936
  }
3251
3937
  });
3252
3938
  }
3253
3939
 
3254
3940
  /**
3255
- * Delete a price
3256
- * Deletes a price entry (hard delete)
3941
+ * Get accounts grouped by platform
3942
+ * Returns accounts with balances grouped by financial platform
3257
3943
  * @param data The data for the request.
3258
- * @param data.id Price ID
3259
3944
  * @param data.region Region code for tenant context
3260
- * @returns void Price deleted successfully
3945
+ * @param data.groupBy Grouping strategy
3946
+ * @param data.date Date for balance calculation (ISO 8601 format)
3947
+ * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
3948
+ * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
3261
3949
  * @throws ApiError
3262
3950
  */
3263
- public static priceControllerDelete(
3264
- data: PriceControllerDeleteData
3265
- ): CancelablePromise<PriceControllerDeleteResponse> {
3951
+ public static dashboardControllerGetAccounts(
3952
+ data: DashboardControllerGetAccountsData
3953
+ ): CancelablePromise<DashboardControllerGetAccountsResponse> {
3266
3954
  return __request(OpenAPI, {
3267
- method: 'DELETE',
3268
- url: '/api/v1/{region}/bean/prices/{id}',
3955
+ method: 'GET',
3956
+ url: '/api/v1/{region}/dashboard/accounts',
3269
3957
  path: {
3270
- id: data.id,
3271
3958
  region: data.region
3272
3959
  },
3960
+ query: {
3961
+ groupBy: data.groupBy,
3962
+ date: data.date,
3963
+ accountId: data.accountId
3964
+ },
3273
3965
  errors: {
3274
- 404: 'Price not found'
3966
+ 401: 'User not authenticated'
3275
3967
  }
3276
3968
  });
3277
3969
  }
3278
3970
 
3279
3971
  /**
3280
- * Bulk create prices
3281
- * Creates multiple price entries at once (skips duplicates)
3972
+ * Get cash flow summary
3973
+ * Returns income, expenses, and savings for a monthly period
3282
3974
  * @param data The data for the request.
3975
+ * @param data.period Period in YYYY-MM format
3283
3976
  * @param data.region Region code for tenant context
3284
- * @param data.requestBody
3285
- * @returns PriceResponseDto Prices created successfully
3977
+ * @returns CashFlowResponseDto Cash flow retrieved successfully
3286
3978
  * @throws ApiError
3287
3979
  */
3288
- public static priceControllerBulkCreate(
3289
- data: PriceControllerBulkCreateData
3290
- ): CancelablePromise<PriceControllerBulkCreateResponse> {
3980
+ public static dashboardControllerGetCashFlow(
3981
+ data: DashboardControllerGetCashFlowData
3982
+ ): CancelablePromise<DashboardControllerGetCashFlowResponse> {
3291
3983
  return __request(OpenAPI, {
3292
- method: 'POST',
3293
- url: '/api/v1/{region}/bean/prices/bulk',
3984
+ method: 'GET',
3985
+ url: '/api/v1/{region}/dashboard/cash-flow',
3294
3986
  path: {
3295
3987
  region: data.region
3296
3988
  },
3297
- body: data.requestBody,
3298
- mediaType: 'application/json'
3989
+ query: {
3990
+ period: data.period
3991
+ },
3992
+ errors: {
3993
+ 400: 'Invalid period format',
3994
+ 401: 'User not authenticated'
3995
+ }
3299
3996
  });
3300
3997
  }
3301
- }
3302
3998
 
3303
- export class ReportingService {
3304
3999
  /**
3305
- * Get portfolio value trends
3306
- *
3307
- * Returns time series data of portfolio net worth.
3308
- *
3309
- * **Multi-currency Support:**
3310
- * - `series[].byCurrency` - Currency breakdown for each data point
3311
- * - `byCurrency` - Separate time series grouped by currency
3312
- * - `warnings` - Exchange rate warnings if conversion failed
3313
- *
3314
- * **Parameters:**
3315
- * - `period`: Time period (1m, 3m, 6m, 1y)
3316
- * - `granularity`: Data granularity (day, week, month)
3317
- *
4000
+ * Get expenses/income grouped by functional category
4001
+ * 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)
3318
4002
  * @param data The data for the request.
3319
4003
  * @param data.region Region code for tenant context
3320
- * @param data.period Time period
3321
- * @param data.granularity Data granularity
3322
- * @returns PortfolioTrendsResponseDto Trends retrieved successfully
4004
+ * @param data.groupBy Grouping strategy
4005
+ * @param data.period Time window (1m = current calendar month)
4006
+ * @param data.flow Account root to aggregate (expense → ^Expenses:, income → ^Income:)
4007
+ * @returns ExpensesByCategoryResponseDto Expenses retrieved successfully
3323
4008
  * @throws ApiError
3324
4009
  */
3325
- public static reportingControllerGetPortfolioTrends(
3326
- data: ReportingControllerGetPortfolioTrendsData
3327
- ): CancelablePromise<ReportingControllerGetPortfolioTrendsResponse> {
4010
+ public static dashboardControllerGetExpenses(
4011
+ data: DashboardControllerGetExpensesData
4012
+ ): CancelablePromise<DashboardControllerGetExpensesResponse> {
3328
4013
  return __request(OpenAPI, {
3329
4014
  method: 'GET',
3330
- url: '/api/v1/{region}/reporting/portfolio/trends',
4015
+ url: '/api/v1/{region}/dashboard/expenses',
3331
4016
  path: {
3332
4017
  region: data.region
3333
4018
  },
3334
4019
  query: {
4020
+ groupBy: data.groupBy,
3335
4021
  period: data.period,
3336
- granularity: data.granularity
4022
+ flow: data.flow
3337
4023
  },
3338
4024
  errors: {
4025
+ 400: 'Invalid groupBy or period',
3339
4026
  401: 'User not authenticated'
3340
4027
  }
3341
4028
  });
3342
4029
  }
3343
4030
 
3344
4031
  /**
3345
- * Generate portfolio snapshot
3346
- *
3347
- * Manually generate a portfolio snapshot for a specific date.
3348
- *
3349
- * **Multi-currency Support:**
3350
- * - Fetches balances grouped by currency
3351
- * - Uses user's baseCurrency setting for conversion
3352
- * - Stores exchange rates and warnings
3353
- *
3354
- * **Use Cases:**
3355
- * - Testing snapshot generation
3356
- * - Force regeneration after data correction
3357
- * - Initial setup for new users
3358
- *
4032
+ * Get the composite P8 advisor context
4033
+ * Assembles the P8 data context in one call: net worth (verbatim GET /dashboard/net-worth shape, user base currency semantics per ADR-0070), trailing-12m flow totals over the 12 calendar months including the as-of month, and top-3 expense categories by account-path leaf key — both flow blocks priced in CNY per the P8 contract. The P8 snake_case field spellings (as_of, net_worth, trailing_12m) are mapped by the consumer; the wire keeps the family camelCase
3359
4034
  * @param data The data for the request.
3360
4035
  * @param data.region Region code for tenant context
3361
- * @param data.requestBody Optional date (defaults to today)
3362
- * @returns GenerateSnapshotResponse Snapshot generated successfully
4036
+ * @param data.date As-of date for the snapshot and the trailing-12m window anchor (ISO 8601 format)
4037
+ * @returns AdvisorContextResponseDto Advisor context retrieved successfully
3363
4038
  * @throws ApiError
3364
4039
  */
3365
- public static reportingControllerGenerateSnapshot(
3366
- data: ReportingControllerGenerateSnapshotData
3367
- ): CancelablePromise<ReportingControllerGenerateSnapshotResponse> {
4040
+ public static dashboardControllerGetAdvisorContext(
4041
+ data: DashboardControllerGetAdvisorContextData
4042
+ ): CancelablePromise<DashboardControllerGetAdvisorContextResponse> {
3368
4043
  return __request(OpenAPI, {
3369
- method: 'POST',
3370
- url: '/api/v1/{region}/reporting/snapshots/generate',
4044
+ method: 'GET',
4045
+ url: '/api/v1/{region}/dashboard/advisor-context',
3371
4046
  path: {
3372
4047
  region: data.region
3373
4048
  },
3374
- body: data.requestBody,
3375
- mediaType: 'application/json',
4049
+ query: {
4050
+ date: data.date
4051
+ },
3376
4052
  errors: {
3377
4053
  400: 'Invalid date format',
3378
- 401: 'User not authenticated'
4054
+ 401: 'User not authenticated, or the token is not advisor-scoped (exchange via POST /auth/sessions/advisor, #1512)'
3379
4055
  }
3380
4056
  });
3381
4057
  }
4058
+ }
3382
4059
 
4060
+ export class InvestmentService {
3383
4061
  /**
3384
- * Backfill portfolio snapshots
3385
- *
3386
- * Generate snapshots for a date range (historical data backfill).
3387
- *
3388
- * **Multi-currency Support:**
3389
- * - Each snapshot includes multi-currency data
3390
- * - Uses exchange rates available at generation time
3391
- * - Warnings stored for missing exchange rates
3392
- *
3393
- * **Best Practices:**
3394
- * - Use for initial setup after account configuration
3395
- * - Run during low-traffic periods for large date ranges
3396
- * - Existing snapshots are skipped (not regenerated)
3397
- *
4062
+ * Get per-holding unrealized + realized P&L
4063
+ * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3398
4064
  * @param data The data for the request.
3399
4065
  * @param data.region Region code for tenant context
3400
- * @param data.requestBody
3401
- * @returns BackfillSnapshotsResponse Backfill completed successfully
4066
+ * @param data.asOf As-of date (ISO 8601), defaults to today
4067
+ * @param data.accountId Scope to a single account
4068
+ * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
4069
+ * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3402
4070
  * @throws ApiError
3403
4071
  */
3404
- public static reportingControllerBackfillSnapshots(
3405
- data: ReportingControllerBackfillSnapshotsData
3406
- ): CancelablePromise<ReportingControllerBackfillSnapshotsResponse> {
4072
+ public static holdingPnlControllerGetHoldingPnl(
4073
+ data: HoldingPnlControllerGetHoldingPnlData
4074
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3407
4075
  return __request(OpenAPI, {
3408
- method: 'POST',
3409
- url: '/api/v1/{region}/reporting/snapshots/backfill',
4076
+ method: 'GET',
4077
+ url: '/api/v1/{region}/investment/holdings/pnl',
3410
4078
  path: {
3411
4079
  region: data.region
3412
4080
  },
3413
- body: data.requestBody,
3414
- mediaType: 'application/json',
4081
+ query: {
4082
+ asOf: data.asOf,
4083
+ accountId: data.accountId,
4084
+ method: data.method
4085
+ },
3415
4086
  errors: {
3416
- 400: 'Invalid date format or range',
3417
- 401: 'User not authenticated',
3418
- 409: 'Backfill already in progress for this user'
4087
+ 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
4088
+ 401: 'User not authenticated'
3419
4089
  }
3420
4090
  });
3421
4091
  }
@@ -3444,7 +4114,7 @@ export class AuthService {
3444
4114
  * Anonymous login with access token
3445
4115
  * @param data The data for the request.
3446
4116
  * @param data.requestBody
3447
- * @returns unknown Login successful
4117
+ * @returns AnonymousLoginResponseDto Login successful
3448
4118
  * @throws ApiError
3449
4119
  */
3450
4120
  public static authControllerAccessTokenLogin(
@@ -3460,17 +4130,75 @@ export class AuthService {
3460
4130
  }
3461
4131
  });
3462
4132
  }
4133
+
4134
+ /**
4135
+ * Exchange an access token for an advisor-scoped, short-TTL JWT (#1512)
4136
+ * @param data The data for the request.
4137
+ * @param data.requestBody
4138
+ * @returns AdvisorLoginResponseDto Advisor-scope login successful — the token is valid only on advisor tool-face endpoints (e.g. GET /:region/dashboard/advisor-context)
4139
+ * @throws ApiError
4140
+ */
4141
+ public static authControllerAdvisorTokenLogin(
4142
+ data: AuthControllerAdvisorTokenLoginData
4143
+ ): CancelablePromise<AuthControllerAdvisorTokenLoginResponse> {
4144
+ return __request(OpenAPI, {
4145
+ method: 'POST',
4146
+ url: '/api/v1/auth/sessions/advisor',
4147
+ body: data.requestBody,
4148
+ mediaType: 'application/json',
4149
+ errors: {
4150
+ 401: 'Invalid access token'
4151
+ }
4152
+ });
4153
+ }
4154
+ }
4155
+
4156
+ export class CommunityService {
4157
+ /**
4158
+ * Relay a sanitized parser-contribution payload
4159
+ * A server-side bot re-sanitizes the payload and opens an issue on the target repository; the issue URL is returned. The payload is never persisted or logged (forward-and-drop).
4160
+ * @param data The data for the request.
4161
+ * @param data.region Region code for tenant context (routing only; the institution region rides in the payload meta)
4162
+ * @param data.requestBody
4163
+ * @returns ParserContributionRelayResponseDto Issue created by the bot
4164
+ * @throws ApiError
4165
+ */
4166
+ public static parserContributionControllerCreate(
4167
+ data: ParserContributionControllerCreateData
4168
+ ): CancelablePromise<ParserContributionControllerCreateResponse> {
4169
+ return __request(OpenAPI, {
4170
+ method: 'POST',
4171
+ url: '/api/v1/{region}/community/parser-contributions',
4172
+ path: {
4173
+ region: data.region
4174
+ },
4175
+ body: data.requestBody,
4176
+ mediaType: 'application/json',
4177
+ errors: {
4178
+ 401: 'Unauthorized',
4179
+ 422: 'Validation failed (institution slug, empty samples, row/cell size limits)',
4180
+ 429: 'Rate limited (5 submissions per user per hour)',
4181
+ 501: 'Relay not configured on this deployment — clients fall back to the clipboard flow',
4182
+ 502: 'GitHub bot failure (upstream), safe to retry'
4183
+ }
4184
+ });
4185
+ }
3463
4186
  }
3464
4187
 
3465
- export class DefaultService {
4188
+ export class AdminCacheService {
3466
4189
  /**
3467
- * @returns unknown
4190
+ * Flush entire cache (L1 + L2)
4191
+ * Clears ALL cache entries across ALL namespaces and users. Use only for emergency cache corruption recovery, maintenance-window refresh, or development resets.
4192
+ * @returns unknown Cache flushed successfully
3468
4193
  * @throws ApiError
3469
4194
  */
3470
4195
  public static cacheControllerFlushCache(): CancelablePromise<CacheControllerFlushCacheResponse> {
3471
4196
  return __request(OpenAPI, {
3472
4197
  method: 'POST',
3473
- url: '/api/v1/cache/flush'
4198
+ url: '/api/v1/cache/flush',
4199
+ errors: {
4200
+ 403: 'Admin access required'
4201
+ }
3474
4202
  });
3475
4203
  }
3476
4204
  }
@@ -3631,3 +4359,53 @@ export class InfoService {
3631
4359
  });
3632
4360
  }
3633
4361
  }
4362
+
4363
+ export class MarketDataService {
4364
+ /**
4365
+ * Search market symbols by name or code
4366
+ * Ranked search over the openbb catalog. Empty `q` returns [].
4367
+ * @param data The data for the request.
4368
+ * @param data.q Search term — matched against symbol and instrument name. Empty string returns [].
4369
+ * @param data.limit Maximum number of results (clamped 1..50)
4370
+ * @param data.exchange Filter by exchange code (e.g. US, HK, SS, SZ). A-share codes also match symbol notations and venue-code aliases (exchange=SS matches SH/SHH column values and bare 6-digit Shanghai symbols; SZ likewise)
4371
+ * @param data.assetType Filter by OpenBB asset_type (e.g. stock, etf)
4372
+ * @returns SymbolSearchResultDto Ranked search results
4373
+ * @throws ApiError
4374
+ */
4375
+ public static symbolControllerSearch(
4376
+ data: SymbolControllerSearchData
4377
+ ): CancelablePromise<SymbolControllerSearchResponse> {
4378
+ return __request(OpenAPI, {
4379
+ method: 'GET',
4380
+ url: '/api/v1/market/symbols/search',
4381
+ query: {
4382
+ q: data.q,
4383
+ limit: data.limit,
4384
+ exchange: data.exchange,
4385
+ assetType: data.assetType
4386
+ }
4387
+ });
4388
+ }
4389
+
4390
+ /**
4391
+ * Get a market symbol quote
4392
+ * @param data The data for the request.
4393
+ * @param data.symbol
4394
+ * @returns SymbolQuoteDto Symbol quote
4395
+ * @throws ApiError
4396
+ */
4397
+ public static symbolControllerGetQuote(
4398
+ data: SymbolControllerGetQuoteData
4399
+ ): CancelablePromise<SymbolControllerGetQuoteResponse> {
4400
+ return __request(OpenAPI, {
4401
+ method: 'GET',
4402
+ url: '/api/v1/market/symbols/{symbol}/quote',
4403
+ path: {
4404
+ symbol: data.symbol
4405
+ },
4406
+ errors: {
4407
+ 404: 'Symbol not found in the openbb catalog'
4408
+ }
4409
+ });
4410
+ }
4411
+ }