@firela/api-types 0.0.0-canary.2fbeefe9 → 0.0.0-canary.3d558482

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.
@@ -11,7 +11,7 @@ export const $CreateAccountDto = {
11
11
  openDate: {
12
12
  format: 'date-time',
13
13
  type: 'string',
14
- description: 'Account open date',
14
+ description: 'Account open date (server defaults to today)',
15
15
  example: '2024-01-01'
16
16
  },
17
17
  currencies: {
@@ -51,9 +51,10 @@ export const $CreateAccountDto = {
51
51
  description: 'Icon identifier (overrides template)',
52
52
  example: 'bank-custom'
53
53
  },
54
- openMeta: {
54
+ openDirectiveMeta: {
55
55
  type: 'object',
56
- description: 'Additional metadata',
56
+ description:
57
+ 'Open directive metadata (NOT an opening-balance amount — use the opening-balance endpoint)',
57
58
  example: {
58
59
  branch: 'Downtown',
59
60
  accountNumber: '1234'
@@ -65,7 +66,7 @@ export const $CreateAccountDto = {
65
66
  example: 'c98e5d4a-2f71-4a5a-bb3c-92c9f231d5e2'
66
67
  }
67
68
  },
68
- required: ['path', 'openDate']
69
+ required: ['path']
69
70
  } as const;
70
71
 
71
72
  export const $AccountResponseDto = {
@@ -145,9 +146,9 @@ export const $AccountResponseDto = {
145
146
  description: 'Icon identifier',
146
147
  example: 'bank-icbc'
147
148
  },
148
- openMeta: {
149
+ openDirectiveMeta: {
149
150
  type: 'object',
150
- description: 'Account metadata',
151
+ description: 'Open directive metadata (ADR-0115 Decision 9)',
151
152
  example: {
152
153
  branch: 'Downtown'
153
154
  }
@@ -233,9 +234,10 @@ export const $UpdateAccountDto = {
233
234
  description: 'Icon identifier',
234
235
  example: 'bank-custom'
235
236
  },
236
- openMeta: {
237
+ openDirectiveMeta: {
237
238
  type: 'object',
238
- description: 'Additional metadata (merged with existing)',
239
+ description:
240
+ 'Open directive metadata (merged with existing; NOT an opening-balance amount)',
239
241
  example: {
240
242
  branch: 'Uptown'
241
243
  }
@@ -282,6 +284,40 @@ export const $ReopenAccountDto = {
282
284
  }
283
285
  } as const;
284
286
 
287
+ export const $CreateOpeningBalanceDto = {
288
+ type: 'object',
289
+ properties: {
290
+ amount: {
291
+ type: 'number',
292
+ description: 'Opening balance amount (non-negative)',
293
+ example: 1000
294
+ },
295
+ currency: {
296
+ type: 'string',
297
+ description: 'Currency code',
298
+ example: 'CNY'
299
+ },
300
+ date: {
301
+ format: 'date-time',
302
+ type: 'string',
303
+ description: 'Opening-balance date (defaults to now)',
304
+ example: '2024-01-01'
305
+ }
306
+ },
307
+ required: ['amount', 'currency']
308
+ } as const;
309
+
310
+ export const $OpeningBalanceResultDto = {
311
+ type: 'object',
312
+ properties: {
313
+ transactionId: {
314
+ type: 'string',
315
+ description: 'Created opening-balance transaction id.'
316
+ }
317
+ },
318
+ required: ['transactionId']
319
+ } as const;
320
+
285
321
  export const $AccountStandardResponseDto = {
286
322
  type: 'object',
287
323
  properties: {
@@ -4388,6 +4424,27 @@ export const $SignupDto = {
4388
4424
  }
4389
4425
  } as const;
4390
4426
 
4427
+ export const $SignupResponseDto = {
4428
+ type: 'object',
4429
+ properties: {
4430
+ authToken: {
4431
+ type: 'string',
4432
+ description: 'JWT auth token',
4433
+ example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
4434
+ },
4435
+ accessToken: {
4436
+ type: 'string',
4437
+ description: 'Auto-generated access token'
4438
+ },
4439
+ role: {
4440
+ type: 'string',
4441
+ description: 'Assigned user role',
4442
+ enum: ['USER', 'ADMIN', 'DEMO', 'INACTIVE', 'PAID', 'OPS']
4443
+ }
4444
+ },
4445
+ required: ['authToken', 'accessToken', 'role']
4446
+ } as const;
4447
+
4391
4448
  export const $UpdateUserSettingDto = {
4392
4449
  type: 'object',
4393
4450
  properties: {
@@ -4511,589 +4568,868 @@ export const $UpdatePropertyDto = {
4511
4568
  required: ['value']
4512
4569
  } as const;
4513
4570
 
4514
- export const $CreateBeanEventDto = {
4571
+ export const $CurrencyBalanceDto = {
4515
4572
  type: 'object',
4516
4573
  properties: {
4517
- date: {
4518
- type: 'string',
4519
- description: 'Life event date (ISO 8601)',
4520
- example: '2024-03-15'
4521
- },
4522
- type: {
4574
+ currency: {
4523
4575
  type: 'string',
4524
- description:
4525
- 'Life event type (e.g., "employer", "location", "marital-status") — user-defined, no enum constraint at engine layer',
4526
- example: 'employer'
4576
+ description: 'ISO 4217 currency code',
4577
+ example: 'CNY'
4527
4578
  },
4528
- description: {
4579
+ balance: {
4529
4580
  type: 'string',
4530
- description:
4531
- 'Life event description. Empty string is a VALID value (distinct from absence).',
4532
- example: 'Acme Corp'
4533
- },
4534
- meta: {
4535
- type: 'object',
4536
- description:
4537
- 'Product-side metadata (lives in BeanEvent.meta JSON, never in engine Event fields)',
4538
- example: {
4539
- note: 'Promotion'
4540
- }
4581
+ description: 'Balance amount',
4582
+ example: '500000.00'
4541
4583
  }
4542
4584
  },
4543
- required: ['date', 'type', 'description']
4585
+ required: ['currency', 'balance']
4544
4586
  } as const;
4545
4587
 
4546
- export const $EventResponseDto = {
4588
+ export const $TimeSeriesPointDto = {
4547
4589
  type: 'object',
4548
4590
  properties: {
4549
- id: {
4591
+ date: {
4550
4592
  type: 'string',
4551
- description: 'Unique identifier',
4552
- example: 'uuid-123-456'
4593
+ description: 'Date in YYYY-MM-DD format',
4594
+ example: '2024-06-15'
4553
4595
  },
4554
- userId: {
4596
+ value: {
4555
4597
  type: 'string',
4556
- description: 'User ID (owner of the life event)',
4557
- example: 'user-123'
4598
+ description: 'Value at this date (in base currency)',
4599
+ example: '500000.00'
4558
4600
  },
4559
- date: {
4560
- type: 'string',
4561
- description: 'Life event date (ISO 8601 format)',
4562
- example: '2024-03-15',
4563
- format: 'date'
4601
+ change: {
4602
+ type: 'object',
4603
+ description: 'Change from previous point',
4604
+ example: '5000.00'
4564
4605
  },
4565
- type: {
4606
+ assets: {
4566
4607
  type: 'string',
4567
- description:
4568
- 'Life event type (user-defined, e.g., "employer", "location")',
4569
- example: 'employer'
4608
+ description: 'Total assets at this date (in base currency)',
4609
+ example: '494338.00'
4570
4610
  },
4571
- description: {
4611
+ liabilities: {
4572
4612
  type: 'string',
4573
- description:
4574
- 'Life event description. May be an empty string (a valid value distinct from absence).',
4575
- example: 'Acme Corp'
4613
+ description: 'Total liabilities at this date (in base currency)',
4614
+ example: '310098.00'
4576
4615
  },
4577
- meta: {
4578
- type: 'object',
4579
- description: 'Product-side metadata (free-form JSON)',
4580
- example: {
4581
- note: 'Promotion'
4616
+ byCurrency: {
4617
+ description: 'Multi-currency breakdown for this point',
4618
+ type: 'array',
4619
+ items: {
4620
+ $ref: '#/components/schemas/CurrencyBalanceDto'
4582
4621
  }
4622
+ }
4623
+ },
4624
+ required: ['date', 'value']
4625
+ } as const;
4626
+
4627
+ export const $TrendSummaryDto = {
4628
+ type: 'object',
4629
+ properties: {
4630
+ startValue: {
4631
+ type: 'string',
4632
+ description: 'Value at start of period',
4633
+ example: '450000.00'
4583
4634
  },
4584
- createdAt: {
4585
- format: 'date-time',
4635
+ endValue: {
4586
4636
  type: 'string',
4587
- description: 'Creation timestamp',
4588
- example: '2024-03-15T10:00:00Z'
4637
+ description: 'Value at end of period',
4638
+ example: '500000.00'
4589
4639
  },
4590
- updatedAt: {
4591
- format: 'date-time',
4640
+ totalChange: {
4592
4641
  type: 'string',
4593
- description:
4594
- 'Last update timestamp. Also emitted as the ETag response header for If-Match optimistic concurrency.',
4595
- example: '2024-03-15T10:00:00Z'
4642
+ description: 'Total change over period',
4643
+ example: '50000.00'
4644
+ },
4645
+ totalChangePercentage: {
4646
+ type: 'string',
4647
+ description: 'Total change percentage',
4648
+ example: '+11.11%'
4596
4649
  }
4597
4650
  },
4598
- required: [
4599
- 'id',
4600
- 'userId',
4601
- 'date',
4602
- 'type',
4603
- 'description',
4604
- 'meta',
4605
- 'createdAt',
4606
- 'updatedAt'
4607
- ]
4651
+ required: ['startValue', 'endValue', 'totalChange', 'totalChangePercentage']
4608
4652
  } as const;
4609
4653
 
4610
- export const $EventListResponseDto = {
4654
+ export const $MultiCurrencyPointDto = {
4611
4655
  type: 'object',
4612
4656
  properties: {
4613
- items: {
4614
- description: 'List of life events',
4657
+ date: {
4658
+ type: 'string',
4659
+ description: 'Date in YYYY-MM-DD format',
4660
+ example: '2024-06-15'
4661
+ },
4662
+ byCurrency: {
4663
+ description: 'Balances by currency',
4615
4664
  type: 'array',
4616
4665
  items: {
4617
- $ref: '#/components/schemas/EventResponseDto'
4666
+ $ref: '#/components/schemas/CurrencyBalanceDto'
4618
4667
  }
4619
- },
4620
- total: {
4621
- type: 'number',
4622
- description: 'Total number of life events matching the query',
4623
- example: 42
4624
4668
  }
4625
4669
  },
4626
- required: ['items', 'total']
4670
+ required: ['date', 'byCurrency']
4627
4671
  } as const;
4628
4672
 
4629
- export const $UpdateBeanEventDto = {
4673
+ export const $PortfolioTrendsResponseDto = {
4630
4674
  type: 'object',
4631
4675
  properties: {
4632
- date: {
4676
+ series: {
4677
+ description: 'Time series data points',
4678
+ type: 'array',
4679
+ items: {
4680
+ $ref: '#/components/schemas/TimeSeriesPointDto'
4681
+ }
4682
+ },
4683
+ summary: {
4684
+ description: 'Period summary',
4685
+ allOf: [
4686
+ {
4687
+ $ref: '#/components/schemas/TrendSummaryDto'
4688
+ }
4689
+ ]
4690
+ },
4691
+ period: {
4633
4692
  type: 'string',
4634
- description: 'Life event date (ISO 8601)'
4693
+ description: 'Period requested',
4694
+ example: '6m'
4635
4695
  },
4636
- type: {
4696
+ granularity: {
4637
4697
  type: 'string',
4638
- description: 'Life event type (user-defined)'
4698
+ description: 'Data granularity',
4699
+ example: 'month'
4639
4700
  },
4640
- description: {
4701
+ currency: {
4641
4702
  type: 'string',
4703
+ description: 'Base currency for converted values',
4704
+ example: 'CNY'
4705
+ },
4706
+ byCurrency: {
4642
4707
  description:
4643
- 'Life event description. Empty string is a VALID value (distinct from absence).'
4708
+ 'Multi-currency time series (each point has currency breakdown)',
4709
+ type: 'array',
4710
+ items: {
4711
+ $ref: '#/components/schemas/MultiCurrencyPointDto'
4712
+ }
4644
4713
  },
4645
- meta: {
4646
- type: 'object',
4647
- description: 'Product-side metadata (free-form JSON)'
4714
+ warnings: {
4715
+ description: 'Exchange rate warnings',
4716
+ type: 'array',
4717
+ items: {
4718
+ $ref: '#/components/schemas/ExchangeRateWarningDto'
4719
+ }
4648
4720
  }
4649
- }
4721
+ },
4722
+ required: ['series', 'summary', 'period', 'granularity', 'currency']
4650
4723
  } as const;
4651
4724
 
4652
- export const $OnboardingAccountDto = {
4725
+ export const $CashFlowPointDto = {
4653
4726
  type: 'object',
4654
4727
  properties: {
4655
- path: {
4728
+ month: {
4656
4729
  type: 'string',
4657
- description:
4658
- 'Account path (Assets/Liabilities only; format validated by the account service)',
4659
- example: 'Assets:Checking'
4730
+ description: 'Month key (YYYY-MM)',
4731
+ example: '2024-03'
4660
4732
  },
4661
- currency: {
4733
+ income: {
4662
4734
  type: 'string',
4663
- description: 'ISO 4217 currency code (3 letters)',
4664
- example: 'USD'
4735
+ description: 'Income in base currency (absolute, converted)',
4736
+ example: '10000.00'
4665
4737
  },
4666
- openingBalance: {
4738
+ expense: {
4667
4739
  type: 'string',
4668
- description:
4669
- 'Opening balance as a non-negative Decimal string (e.g. "1000.00")',
4670
- example: '1000.00'
4740
+ description: 'Expense in base currency (absolute, converted)',
4741
+ example: '5000.00'
4671
4742
  },
4672
- platformId: {
4743
+ netSavings: {
4673
4744
  type: 'string',
4674
- description:
4675
- 'Platform ID to bind the account to (references Platform.id); omit for unbound',
4676
- example: 'c98e5d4a-2f71-4a5a-bb3c-92c9f231d5e2'
4745
+ description: 'netSavings = income − expense (savings positive)',
4746
+ example: '5000.00'
4677
4747
  }
4678
4748
  },
4679
- required: ['path', 'currency']
4749
+ required: ['month', 'income', 'expense', 'netSavings']
4680
4750
  } as const;
4681
4751
 
4682
- export const $OnboardingDto = {
4752
+ export const $CashFlowTrendSummaryDto = {
4683
4753
  type: 'object',
4684
4754
  properties: {
4685
- accounts: {
4686
- description: 'Asset/Liability accounts to register with opening balances',
4687
- type: 'array',
4688
- items: {
4689
- $ref: '#/components/schemas/OnboardingAccountDto'
4690
- }
4755
+ totalIncome: {
4756
+ type: 'string',
4757
+ description: 'Total income across the period',
4758
+ example: '60000.00'
4691
4759
  },
4692
- skipAssetRegistration: {
4693
- type: 'boolean',
4694
- description:
4695
- 'Skip asset registration; only bootstrap the core account set',
4696
- default: false
4697
- }
4698
- }
4699
- } as const;
4700
-
4701
- export const $ActualBalanceDto = {
4702
- type: 'object',
4703
- properties: {
4704
- amount: {
4760
+ totalExpense: {
4705
4761
  type: 'string',
4706
- description:
4707
- 'Actual balance amount as a decimal string (preserves precision for tolerance inference).',
4708
- example: '1234.56'
4762
+ description: 'Total expense across the period',
4763
+ example: '30000.00'
4709
4764
  },
4710
- ccy: {
4765
+ totalNetSavings: {
4711
4766
  type: 'string',
4712
- description: 'Currency code (ISO 4217 or commodity ticker).',
4713
- example: 'CNY'
4767
+ description: 'income − expense across the period',
4768
+ example: '30000.00'
4769
+ },
4770
+ averageMonthlyNetSavings: {
4771
+ type: 'string',
4772
+ description:
4773
+ 'totalNetSavings divided by the window length (N months, incl. zero-filled)',
4774
+ example: '5000.00'
4714
4775
  }
4715
4776
  },
4716
- required: ['amount', 'ccy']
4777
+ required: [
4778
+ 'totalIncome',
4779
+ 'totalExpense',
4780
+ 'totalNetSavings',
4781
+ 'averageMonthlyNetSavings'
4782
+ ]
4717
4783
  } as const;
4718
4784
 
4719
- export const $ComputeReconciliationDto = {
4785
+ export const $CashFlowTrendsResponseDto = {
4720
4786
  type: 'object',
4721
4787
  properties: {
4722
- accountId: {
4723
- type: 'string',
4724
- description: 'BeanAccount id to reconcile.'
4725
- },
4726
- asOfDate: {
4727
- type: 'string',
4728
- description: 'Assertion date (ISO 8601, e.g. "2026-07-24").',
4729
- example: '2026-07-24'
4788
+ series: {
4789
+ description:
4790
+ 'Monthly cash-flow series (fixed N-month window, zero-filled)',
4791
+ type: 'array',
4792
+ items: {
4793
+ $ref: '#/components/schemas/CashFlowPointDto'
4794
+ }
4730
4795
  },
4731
- actualBalance: {
4732
- description: 'Actual balance from the external statement.',
4796
+ summary: {
4797
+ description: 'Period totals',
4733
4798
  allOf: [
4734
4799
  {
4735
- $ref: '#/components/schemas/ActualBalanceDto'
4800
+ $ref: '#/components/schemas/CashFlowTrendSummaryDto'
4736
4801
  }
4737
4802
  ]
4738
- }
4739
- },
4740
- required: ['accountId', 'asOfDate', 'actualBalance']
4741
- } as const;
4742
-
4743
- export const $ReconciliationComputeResultDto = {
4744
- type: 'object',
4745
- properties: {
4746
- accountId: {
4747
- type: 'string'
4748
- },
4749
- asOfDate: {
4750
- type: 'string'
4751
4803
  },
4752
- bookBalance: {
4804
+ period: {
4753
4805
  type: 'string',
4754
- description: 'System-computed book balance (decimal string).'
4806
+ description: 'Period requested',
4807
+ example: '6m'
4755
4808
  },
4756
- actualBalance: {
4809
+ granularity: {
4757
4810
  type: 'string',
4758
- description: 'User-entered actual balance (decimal string).'
4811
+ description: 'Data granularity (v1 returns month buckets)',
4812
+ example: 'month'
4759
4813
  },
4760
4814
  currency: {
4761
- type: 'string'
4762
- },
4763
- diff: {
4764
- type: 'string',
4765
- description: 'Diff = book − actual (decimal string).'
4766
- },
4767
- tolerance: {
4768
4815
  type: 'string',
4769
- description: 'Applied tolerance (decimal string).'
4770
- },
4771
- withinTolerance: {
4772
- type: 'boolean',
4773
- description: 'true when |diff| ≤ tolerance.'
4816
+ description: 'Base currency for converted values',
4817
+ example: 'CNY'
4774
4818
  },
4775
- suggestedAction: {
4776
- type: 'string',
4777
- enum: ['assert', 'pad'],
4778
- description:
4779
- 'Suggested next action: assert when within tolerance, pad otherwise.'
4819
+ warnings: {
4820
+ description: 'Exchange rate warnings (e.g. missing rate for a currency)',
4821
+ type: 'array',
4822
+ items: {
4823
+ $ref: '#/components/schemas/ExchangeRateWarningDto'
4824
+ }
4780
4825
  }
4781
4826
  },
4782
- required: [
4783
- 'accountId',
4784
- 'asOfDate',
4785
- 'bookBalance',
4786
- 'actualBalance',
4787
- 'currency',
4788
- 'diff',
4789
- 'tolerance',
4790
- 'withinTolerance',
4791
- 'suggestedAction'
4792
- ]
4827
+ required: ['series', 'summary', 'period', 'granularity', 'currency']
4793
4828
  } as const;
4794
4829
 
4795
- export const $AssertReconciliationDto = {
4830
+ export const $GenerateSnapshotBody = {
4831
+ type: 'object',
4832
+ properties: {}
4833
+ } as const;
4834
+
4835
+ export const $GenerateSnapshotResponse = {
4836
+ type: 'object',
4837
+ properties: {}
4838
+ } as const;
4839
+
4840
+ export const $BackfillSnapshotsBody = {
4841
+ type: 'object',
4842
+ properties: {}
4843
+ } as const;
4844
+
4845
+ export const $BackfillSnapshotsResponse = {
4846
+ type: 'object',
4847
+ properties: {}
4848
+ } as const;
4849
+
4850
+ export const $CreateBeanEventDto = {
4796
4851
  type: 'object',
4797
4852
  properties: {
4798
- accountId: {
4853
+ date: {
4799
4854
  type: 'string',
4800
- description: 'BeanAccount id to reconcile.'
4855
+ description: 'Life event date (ISO 8601)',
4856
+ example: '2024-03-15'
4801
4857
  },
4802
- asOfDate: {
4858
+ type: {
4803
4859
  type: 'string',
4804
- description: 'Assertion date (ISO 8601, e.g. "2026-07-24").',
4805
- example: '2026-07-24'
4806
- },
4807
- actualBalance: {
4808
- description: 'Actual balance from the external statement.',
4809
- allOf: [
4810
- {
4811
- $ref: '#/components/schemas/ActualBalanceDto'
4812
- }
4813
- ]
4860
+ description:
4861
+ 'Life event type (e.g., "employer", "location", "marital-status") — user-defined, no enum constraint at engine layer',
4862
+ example: 'employer'
4814
4863
  },
4815
- tolerance: {
4864
+ description: {
4816
4865
  type: 'string',
4817
4866
  description:
4818
- 'Optional explicit tolerance override. Omit to infer from amount precision (Beancount default).',
4819
- example: '0.01'
4867
+ 'Life event description. Empty string is a VALID value (distinct from absence).',
4868
+ example: 'Acme Corp'
4869
+ },
4870
+ meta: {
4871
+ type: 'object',
4872
+ description:
4873
+ 'Product-side metadata (lives in BeanEvent.meta JSON, never in engine Event fields)',
4874
+ example: {
4875
+ note: 'Promotion'
4876
+ }
4820
4877
  }
4821
4878
  },
4822
- required: ['accountId', 'asOfDate', 'actualBalance']
4879
+ required: ['date', 'type', 'description']
4823
4880
  } as const;
4824
4881
 
4825
- export const $ReconciliationRecordDto = {
4882
+ export const $EventResponseDto = {
4826
4883
  type: 'object',
4827
4884
  properties: {
4828
4885
  id: {
4829
- type: 'string'
4886
+ type: 'string',
4887
+ description: 'Unique identifier',
4888
+ example: 'uuid-123-456'
4830
4889
  },
4831
- accountId: {
4832
- type: 'string'
4890
+ userId: {
4891
+ type: 'string',
4892
+ description: 'User ID (owner of the life event)',
4893
+ example: 'user-123'
4833
4894
  },
4834
4895
  date: {
4835
- type: 'string'
4836
- },
4837
- amount: {
4838
4896
  type: 'string',
4839
- description: 'Asserted (actual) amount.'
4840
- },
4841
- currency: {
4842
- type: 'string'
4897
+ description: 'Life event date (ISO 8601 format)',
4898
+ example: '2024-03-15',
4899
+ format: 'date'
4843
4900
  },
4844
- tolerance: {
4845
- type: 'string'
4901
+ type: {
4902
+ type: 'string',
4903
+ description:
4904
+ 'Life event type (user-defined, e.g., "employer", "location")',
4905
+ example: 'employer'
4846
4906
  },
4847
- diffAmount: {
4907
+ description: {
4848
4908
  type: 'string',
4849
- description: 'book − actual.'
4909
+ description:
4910
+ 'Life event description. May be an empty string (a valid value distinct from absence).',
4911
+ example: 'Acme Corp'
4850
4912
  },
4851
- diffCurrency: {
4852
- type: 'string'
4913
+ meta: {
4914
+ type: 'object',
4915
+ description: 'Product-side metadata (free-form JSON)',
4916
+ example: {
4917
+ note: 'Promotion'
4918
+ }
4853
4919
  },
4854
4920
  createdAt: {
4855
- type: 'string'
4856
- }
4857
- },
4858
- required: ['id', 'accountId', 'date', 'amount', 'currency', 'createdAt']
4859
- } as const;
4860
-
4861
- export const $PadReconciliationDto = {
4862
- type: 'object',
4863
- properties: {
4864
- accountId: {
4921
+ format: 'date-time',
4865
4922
  type: 'string',
4866
- description: 'BeanAccount id to reconcile.'
4867
- },
4868
- asOfDate: {
4869
- type: 'string',
4870
- description: 'Assertion date (ISO 8601, e.g. "2026-07-24").',
4871
- example: '2026-07-24'
4872
- },
4873
- actualBalance: {
4874
- description: 'Actual balance from the external statement.',
4875
- allOf: [
4876
- {
4877
- $ref: '#/components/schemas/ActualBalanceDto'
4878
- }
4879
- ]
4923
+ description: 'Creation timestamp',
4924
+ example: '2024-03-15T10:00:00Z'
4880
4925
  },
4881
- sourceAccount: {
4926
+ updatedAt: {
4927
+ format: 'date-time',
4882
4928
  type: 'string',
4883
4929
  description:
4884
- 'Pad source account. Defaults to Equity:Opening-Balances (official Beancount convention).',
4885
- example: 'Equity:Opening-Balances',
4886
- default: 'Equity:Opening-Balances'
4930
+ 'Last update timestamp. Also emitted as the ETag response header for If-Match optimistic concurrency.',
4931
+ example: '2024-03-15T10:00:00Z'
4887
4932
  }
4888
4933
  },
4889
- required: ['accountId', 'asOfDate', 'actualBalance']
4934
+ required: [
4935
+ 'id',
4936
+ 'userId',
4937
+ 'date',
4938
+ 'type',
4939
+ 'description',
4940
+ 'meta',
4941
+ 'createdAt',
4942
+ 'updatedAt'
4943
+ ]
4890
4944
  } as const;
4891
4945
 
4892
- export const $PadResultDto = {
4946
+ export const $EventListResponseDto = {
4893
4947
  type: 'object',
4894
4948
  properties: {
4895
- transactionId: {
4896
- type: 'string',
4897
- description: 'Created pad adjusting transaction id.'
4949
+ items: {
4950
+ description: 'List of life events',
4951
+ type: 'array',
4952
+ items: {
4953
+ $ref: '#/components/schemas/EventResponseDto'
4954
+ }
4955
+ },
4956
+ total: {
4957
+ type: 'number',
4958
+ description: 'Total number of life events matching the query',
4959
+ example: 42
4898
4960
  }
4899
4961
  },
4900
- required: ['transactionId']
4962
+ required: ['items', 'total']
4901
4963
  } as const;
4902
4964
 
4903
- export const $FileImportDto = {
4965
+ export const $UpdateBeanEventDto = {
4904
4966
  type: 'object',
4905
4967
  properties: {
4906
- file: {
4968
+ date: {
4907
4969
  type: 'string',
4908
- format: 'binary',
4909
- description: 'Bill file to import (CSV, PDF, OFX, etc.)',
4910
- example: 'alipay.csv'
4911
- }
4912
- },
4913
- required: ['file']
4914
- } as const;
4915
-
4916
- export const $ImportErrorDto = {
4917
- type: 'object',
4918
- properties: {
4919
- index: {
4920
- type: 'number',
4921
- description: 'Index of failed transaction in the file',
4922
- example: 5
4970
+ description: 'Life event date (ISO 8601)'
4923
4971
  },
4924
- error: {
4972
+ type: {
4925
4973
  type: 'string',
4926
- description: 'Error message',
4927
- example: 'Transaction does not balance: -100 USD != 0'
4974
+ description: 'Life event type (user-defined)'
4975
+ },
4976
+ description: {
4977
+ type: 'string',
4978
+ description:
4979
+ 'Life event description. Empty string is a VALID value (distinct from absence).'
4980
+ },
4981
+ meta: {
4982
+ type: 'object',
4983
+ description: 'Product-side metadata (free-form JSON)'
4928
4984
  }
4929
- },
4930
- required: ['index', 'error']
4985
+ }
4931
4986
  } as const;
4932
4987
 
4933
- export const $ReviewItemPreviewDto = {
4988
+ export const $OnboardingAccountDto = {
4934
4989
  type: 'object',
4935
4990
  properties: {
4936
- index: {
4937
- type: 'number',
4938
- description: 'Index in the import batch (for tracking)',
4939
- example: 0
4940
- },
4941
- date: {
4991
+ path: {
4942
4992
  type: 'string',
4943
- description: 'Transaction date (ISO format)',
4944
- example: '2026-03-05'
4945
- },
4946
- amount: {
4947
- type: 'number',
4948
- description: 'Transaction amount (absolute value)',
4949
- example: 99
4993
+ description:
4994
+ 'Account path (Assets/Liabilities only; format validated by the account service)',
4995
+ example: 'Assets:Checking'
4950
4996
  },
4951
4997
  currency: {
4952
4998
  type: 'string',
4953
- description: 'Currency code',
4954
- example: 'CNY'
4955
- },
4956
- narration: {
4957
- type: 'string',
4958
- description: 'Transaction narration/description',
4959
- example: 'Restaurant expense'
4960
- },
4961
- payee: {
4962
- type: 'string',
4963
- description: 'Payee name',
4964
- example: 'Restaurant ABC'
4999
+ description: 'ISO 4217 currency code (3 letters)',
5000
+ example: 'USD'
4965
5001
  },
4966
- category: {
5002
+ openingBalance: {
4967
5003
  type: 'string',
4968
- description: 'Inferred category from rule matching',
4969
- example: 'food'
4970
- },
4971
- confidence: {
4972
- type: 'number',
4973
- description: 'Confidence score for the match (0-1)',
4974
- example: 0.85
5004
+ description:
5005
+ 'Opening balance as a non-negative Decimal string (e.g. "1000.00")',
5006
+ example: '1000.00'
4975
5007
  },
4976
- branchType: {
5008
+ platformId: {
4977
5009
  type: 'string',
4978
- description: 'Type of branch requiring review',
4979
- enum: [
4980
- 'DUPLICATE',
4981
- 'PAYEE_MATCH',
4982
- 'RULE_MATCH',
4983
- 'ACCOUNT_VALIDATION',
4984
- 'PIPELINE_ERROR'
4985
- ],
4986
- example: 'RULE_MATCH'
4987
- },
4988
- reasons: {
4989
- description: 'Human-readable reasons for requiring review',
4990
- example: ['Moderate confidence rule match', 'Multiple rules matched'],
4991
- type: 'array',
4992
- items: {
4993
- type: 'string'
4994
- }
5010
+ description:
5011
+ 'Platform ID to bind the account to (references Platform.id); omit for unbound',
5012
+ example: 'c98e5d4a-2f71-4a5a-bb3c-92c9f231d5e2'
4995
5013
  }
4996
5014
  },
4997
- required: ['index', 'date', 'narration']
5015
+ required: ['path', 'currency']
4998
5016
  } as const;
4999
5017
 
5000
- export const $ImportResultDto = {
5018
+ export const $OnboardingDto = {
5001
5019
  type: 'object',
5002
5020
  properties: {
5003
- imported: {
5004
- type: 'number',
5005
- description: 'Number of successfully imported transactions',
5006
- example: 45
5007
- },
5008
- failed: {
5009
- type: 'number',
5010
- description: 'Number of failed transactions',
5011
- example: 2
5012
- },
5013
- skipped: {
5014
- type: 'number',
5015
- description:
5016
- 'Number of skipped transactions (high confidence duplicates, auto-skipped)',
5017
- example: 3
5018
- },
5019
- pendingReview: {
5020
- type: 'number',
5021
- description:
5022
- 'Number of transactions pending review (medium confidence duplicates)',
5023
- example: 2
5024
- },
5025
- errors: {
5026
- description: 'Array of error details for failed transactions',
5021
+ accounts: {
5022
+ description: 'Asset/Liability accounts to register with opening balances',
5027
5023
  type: 'array',
5028
5024
  items: {
5029
- $ref: '#/components/schemas/ImportErrorDto'
5025
+ $ref: '#/components/schemas/OnboardingAccountDto'
5030
5026
  }
5031
5027
  },
5032
- reviewItems: {
5028
+ skipAssetRegistration: {
5029
+ type: 'boolean',
5033
5030
  description:
5034
- 'Array of transactions pending review with preview data. Contains essential information for displaying in the import preview UI.',
5035
- type: 'array',
5036
- items: {
5037
- $ref: '#/components/schemas/ReviewItemPreviewDto'
5038
- }
5039
- },
5040
- transactions: {
5041
- type: 'object',
5042
- description: 'Array of imported transactions (optional, for debugging)'
5031
+ 'Skip asset registration; only bootstrap the core account set',
5032
+ default: false
5043
5033
  }
5044
- },
5045
- required: ['imported', 'failed', 'skipped', 'pendingReview', 'errors']
5034
+ }
5046
5035
  } as const;
5047
5036
 
5048
- export const $IdentifyResultDto = {
5037
+ export const $ActualBalanceDto = {
5049
5038
  type: 'object',
5050
5039
  properties: {
5051
- identified: {
5052
- type: 'boolean',
5053
- description: 'Whether the file was successfully identified',
5054
- example: true
5055
- },
5056
- importerName: {
5057
- type: 'string',
5058
- description: 'Name of the importer that can handle this file',
5059
- example: 'AlipayImporter'
5060
- },
5061
- importerId: {
5062
- type: 'string',
5063
- description: 'Unique identifier of the importer',
5064
- example: 'alipay'
5065
- },
5066
- account: {
5040
+ amount: {
5067
5041
  type: 'string',
5068
- description: 'Default account used by this importer',
5069
- example: 'Assets:CN:Alipay:Balance'
5042
+ description:
5043
+ 'Actual balance amount as a decimal string (preserves precision for tolerance inference).',
5044
+ example: '1234.56'
5070
5045
  },
5071
- message: {
5046
+ ccy: {
5072
5047
  type: 'string',
5073
- description: 'Message when file cannot be identified',
5074
- example: 'No matching importer found'
5048
+ description: 'Currency code (ISO 4217 or commodity ticker).',
5049
+ example: 'CNY'
5075
5050
  }
5076
5051
  },
5077
- required: ['identified']
5052
+ required: ['amount', 'ccy']
5078
5053
  } as const;
5079
5054
 
5080
- export const $MapperDefaultsDto = {
5055
+ export const $ComputeReconciliationDto = {
5081
5056
  type: 'object',
5082
5057
  properties: {
5083
- sourceAccount: {
5084
- type: 'string',
5085
- description: 'Source account for transactions (Beancount format)',
5086
- example: 'Assets:CN:Alipay:Balance'
5087
- },
5088
- currency: {
5058
+ accountId: {
5089
5059
  type: 'string',
5090
- description: 'Default currency (ISO 4217 code)',
5091
- example: 'CNY'
5060
+ description: 'BeanAccount id to reconcile.'
5092
5061
  },
5093
- expenseAccount: {
5062
+ asOfDate: {
5094
5063
  type: 'string',
5095
- description: 'Default expense account',
5096
- example: 'Expenses:Unknown'
5064
+ description: 'Assertion date (ISO 8601, e.g. "2026-07-24").',
5065
+ example: '2026-07-24'
5066
+ },
5067
+ actualBalance: {
5068
+ description: 'Actual balance from the external statement.',
5069
+ allOf: [
5070
+ {
5071
+ $ref: '#/components/schemas/ActualBalanceDto'
5072
+ }
5073
+ ]
5074
+ }
5075
+ },
5076
+ required: ['accountId', 'asOfDate', 'actualBalance']
5077
+ } as const;
5078
+
5079
+ export const $ReconciliationComputeResultDto = {
5080
+ type: 'object',
5081
+ properties: {
5082
+ accountId: {
5083
+ type: 'string'
5084
+ },
5085
+ asOfDate: {
5086
+ type: 'string'
5087
+ },
5088
+ bookBalance: {
5089
+ type: 'string',
5090
+ description: 'System-computed book balance (decimal string).'
5091
+ },
5092
+ actualBalance: {
5093
+ type: 'string',
5094
+ description: 'User-entered actual balance (decimal string).'
5095
+ },
5096
+ currency: {
5097
+ type: 'string'
5098
+ },
5099
+ diff: {
5100
+ type: 'string',
5101
+ description: 'Diff = book − actual (decimal string).'
5102
+ },
5103
+ tolerance: {
5104
+ type: 'string',
5105
+ description: 'Applied tolerance (decimal string).'
5106
+ },
5107
+ withinTolerance: {
5108
+ type: 'boolean',
5109
+ description: 'true when |diff| ≤ tolerance.'
5110
+ },
5111
+ suggestedAction: {
5112
+ type: 'string',
5113
+ enum: ['assert', 'pad'],
5114
+ description:
5115
+ 'Suggested next action: assert when within tolerance, pad otherwise.'
5116
+ }
5117
+ },
5118
+ required: [
5119
+ 'accountId',
5120
+ 'asOfDate',
5121
+ 'bookBalance',
5122
+ 'actualBalance',
5123
+ 'currency',
5124
+ 'diff',
5125
+ 'tolerance',
5126
+ 'withinTolerance',
5127
+ 'suggestedAction'
5128
+ ]
5129
+ } as const;
5130
+
5131
+ export const $AssertReconciliationDto = {
5132
+ type: 'object',
5133
+ properties: {
5134
+ accountId: {
5135
+ type: 'string',
5136
+ description: 'BeanAccount id to reconcile.'
5137
+ },
5138
+ asOfDate: {
5139
+ type: 'string',
5140
+ description: 'Assertion date (ISO 8601, e.g. "2026-07-24").',
5141
+ example: '2026-07-24'
5142
+ },
5143
+ actualBalance: {
5144
+ description: 'Actual balance from the external statement.',
5145
+ allOf: [
5146
+ {
5147
+ $ref: '#/components/schemas/ActualBalanceDto'
5148
+ }
5149
+ ]
5150
+ },
5151
+ tolerance: {
5152
+ type: 'string',
5153
+ description:
5154
+ 'Optional explicit tolerance override. Omit to infer from amount precision (Beancount default).',
5155
+ example: '0.01'
5156
+ }
5157
+ },
5158
+ required: ['accountId', 'asOfDate', 'actualBalance']
5159
+ } as const;
5160
+
5161
+ export const $ReconciliationRecordDto = {
5162
+ type: 'object',
5163
+ properties: {
5164
+ id: {
5165
+ type: 'string'
5166
+ },
5167
+ accountId: {
5168
+ type: 'string'
5169
+ },
5170
+ date: {
5171
+ type: 'string'
5172
+ },
5173
+ amount: {
5174
+ type: 'string',
5175
+ description: 'Asserted (actual) amount.'
5176
+ },
5177
+ currency: {
5178
+ type: 'string'
5179
+ },
5180
+ tolerance: {
5181
+ type: 'string'
5182
+ },
5183
+ diffAmount: {
5184
+ type: 'string',
5185
+ description: 'book − actual.'
5186
+ },
5187
+ diffCurrency: {
5188
+ type: 'string'
5189
+ },
5190
+ createdAt: {
5191
+ type: 'string'
5192
+ }
5193
+ },
5194
+ required: ['id', 'accountId', 'date', 'amount', 'currency', 'createdAt']
5195
+ } as const;
5196
+
5197
+ export const $PadReconciliationDto = {
5198
+ type: 'object',
5199
+ properties: {
5200
+ accountId: {
5201
+ type: 'string',
5202
+ description: 'BeanAccount id to reconcile.'
5203
+ },
5204
+ asOfDate: {
5205
+ type: 'string',
5206
+ description: 'Assertion date (ISO 8601, e.g. "2026-07-24").',
5207
+ example: '2026-07-24'
5208
+ },
5209
+ actualBalance: {
5210
+ description: 'Actual balance from the external statement.',
5211
+ allOf: [
5212
+ {
5213
+ $ref: '#/components/schemas/ActualBalanceDto'
5214
+ }
5215
+ ]
5216
+ },
5217
+ sourceAccount: {
5218
+ type: 'string',
5219
+ description:
5220
+ 'Pad source account. Defaults to Equity:Opening-Balances (official Beancount convention).',
5221
+ example: 'Equity:Opening-Balances',
5222
+ default: 'Equity:Opening-Balances'
5223
+ }
5224
+ },
5225
+ required: ['accountId', 'asOfDate', 'actualBalance']
5226
+ } as const;
5227
+
5228
+ export const $PadResultDto = {
5229
+ type: 'object',
5230
+ properties: {
5231
+ transactionId: {
5232
+ type: 'string',
5233
+ description: 'Created pad adjusting transaction id.'
5234
+ }
5235
+ },
5236
+ required: ['transactionId']
5237
+ } as const;
5238
+
5239
+ export const $FileImportDto = {
5240
+ type: 'object',
5241
+ properties: {
5242
+ file: {
5243
+ type: 'string',
5244
+ format: 'binary',
5245
+ description: 'Bill file to import (CSV, PDF, OFX, etc.)',
5246
+ example: 'alipay.csv'
5247
+ }
5248
+ },
5249
+ required: ['file']
5250
+ } as const;
5251
+
5252
+ export const $ImportErrorDto = {
5253
+ type: 'object',
5254
+ properties: {
5255
+ index: {
5256
+ type: 'number',
5257
+ description: 'Index of failed transaction in the file',
5258
+ example: 5
5259
+ },
5260
+ error: {
5261
+ type: 'string',
5262
+ description: 'Error message',
5263
+ example: 'Transaction does not balance: -100 USD != 0'
5264
+ }
5265
+ },
5266
+ required: ['index', 'error']
5267
+ } as const;
5268
+
5269
+ export const $ReviewItemPreviewDto = {
5270
+ type: 'object',
5271
+ properties: {
5272
+ index: {
5273
+ type: 'number',
5274
+ description: 'Index in the import batch (for tracking)',
5275
+ example: 0
5276
+ },
5277
+ date: {
5278
+ type: 'string',
5279
+ description: 'Transaction date (ISO format)',
5280
+ example: '2026-03-05'
5281
+ },
5282
+ amount: {
5283
+ type: 'number',
5284
+ description: 'Transaction amount (absolute value)',
5285
+ example: 99
5286
+ },
5287
+ currency: {
5288
+ type: 'string',
5289
+ description: 'Currency code',
5290
+ example: 'CNY'
5291
+ },
5292
+ narration: {
5293
+ type: 'string',
5294
+ description: 'Transaction narration/description',
5295
+ example: 'Restaurant expense'
5296
+ },
5297
+ payee: {
5298
+ type: 'string',
5299
+ description: 'Payee name',
5300
+ example: 'Restaurant ABC'
5301
+ },
5302
+ category: {
5303
+ type: 'string',
5304
+ description: 'Inferred category from rule matching',
5305
+ example: 'food'
5306
+ },
5307
+ confidence: {
5308
+ type: 'number',
5309
+ description: 'Confidence score for the match (0-1)',
5310
+ example: 0.85
5311
+ },
5312
+ branchType: {
5313
+ type: 'string',
5314
+ description: 'Type of branch requiring review',
5315
+ enum: [
5316
+ 'DUPLICATE',
5317
+ 'PAYEE_MATCH',
5318
+ 'RULE_MATCH',
5319
+ 'ACCOUNT_VALIDATION',
5320
+ 'PIPELINE_ERROR'
5321
+ ],
5322
+ example: 'RULE_MATCH'
5323
+ },
5324
+ reasons: {
5325
+ description: 'Human-readable reasons for requiring review',
5326
+ example: ['Moderate confidence rule match', 'Multiple rules matched'],
5327
+ type: 'array',
5328
+ items: {
5329
+ type: 'string'
5330
+ }
5331
+ }
5332
+ },
5333
+ required: ['index', 'date', 'narration']
5334
+ } as const;
5335
+
5336
+ export const $ImportResultDto = {
5337
+ type: 'object',
5338
+ properties: {
5339
+ imported: {
5340
+ type: 'number',
5341
+ description: 'Number of successfully imported transactions',
5342
+ example: 45
5343
+ },
5344
+ failed: {
5345
+ type: 'number',
5346
+ description: 'Number of failed transactions',
5347
+ example: 2
5348
+ },
5349
+ skipped: {
5350
+ type: 'number',
5351
+ description:
5352
+ 'Number of skipped transactions (high confidence duplicates, auto-skipped)',
5353
+ example: 3
5354
+ },
5355
+ pendingReview: {
5356
+ type: 'number',
5357
+ description:
5358
+ 'Number of transactions pending review (medium confidence duplicates)',
5359
+ example: 2
5360
+ },
5361
+ errors: {
5362
+ description: 'Array of error details for failed transactions',
5363
+ type: 'array',
5364
+ items: {
5365
+ $ref: '#/components/schemas/ImportErrorDto'
5366
+ }
5367
+ },
5368
+ reviewItems: {
5369
+ description:
5370
+ 'Array of transactions pending review with preview data. Contains essential information for displaying in the import preview UI.',
5371
+ type: 'array',
5372
+ items: {
5373
+ $ref: '#/components/schemas/ReviewItemPreviewDto'
5374
+ }
5375
+ },
5376
+ transactions: {
5377
+ type: 'object',
5378
+ description: 'Array of imported transactions (optional, for debugging)'
5379
+ }
5380
+ },
5381
+ required: ['imported', 'failed', 'skipped', 'pendingReview', 'errors']
5382
+ } as const;
5383
+
5384
+ export const $IdentifyResultDto = {
5385
+ type: 'object',
5386
+ properties: {
5387
+ identified: {
5388
+ type: 'boolean',
5389
+ description: 'Whether the file was successfully identified',
5390
+ example: true
5391
+ },
5392
+ importerName: {
5393
+ type: 'string',
5394
+ description: 'Name of the importer that can handle this file',
5395
+ example: 'AlipayImporter'
5396
+ },
5397
+ importerId: {
5398
+ type: 'string',
5399
+ description: 'Unique identifier of the importer',
5400
+ example: 'alipay'
5401
+ },
5402
+ account: {
5403
+ type: 'string',
5404
+ description: 'Default account used by this importer',
5405
+ example: 'Assets:CN:Alipay:Balance'
5406
+ },
5407
+ message: {
5408
+ type: 'string',
5409
+ description: 'Message when file cannot be identified',
5410
+ example: 'No matching importer found'
5411
+ }
5412
+ },
5413
+ required: ['identified']
5414
+ } as const;
5415
+
5416
+ export const $MapperDefaultsDto = {
5417
+ type: 'object',
5418
+ properties: {
5419
+ sourceAccount: {
5420
+ type: 'string',
5421
+ description: 'Source account for transactions (Beancount format)',
5422
+ example: 'Assets:CN:Alipay:Balance'
5423
+ },
5424
+ currency: {
5425
+ type: 'string',
5426
+ description: 'Default currency (ISO 4217 code)',
5427
+ example: 'CNY'
5428
+ },
5429
+ expenseAccount: {
5430
+ type: 'string',
5431
+ description: 'Default expense account',
5432
+ example: 'Expenses:Unknown'
5097
5433
  },
5098
5434
  incomeAccount: {
5099
5435
  type: 'string',
@@ -6356,15 +6692,157 @@ export const $NlpResponseDto = {
6356
6692
  },
6357
6693
  defaultAccounts: {
6358
6694
  description:
6359
- 'Default accounts for the user/region. These are fallback accounts used when no specific suggestion is available.',
6360
- allOf: [
6361
- {
6362
- $ref: '#/components/schemas/NlpDefaultAccountsDto'
6363
- }
6364
- ]
6695
+ 'Default accounts for the user/region. These are fallback accounts used when no specific suggestion is available.',
6696
+ allOf: [
6697
+ {
6698
+ $ref: '#/components/schemas/NlpDefaultAccountsDto'
6699
+ }
6700
+ ]
6701
+ }
6702
+ },
6703
+ required: ['status', 'action']
6704
+ } as const;
6705
+
6706
+ export const $PlatformListItemDto = {
6707
+ type: 'object',
6708
+ properties: {
6709
+ id: {
6710
+ type: 'string',
6711
+ description: 'Global platform ID'
6712
+ },
6713
+ name: {
6714
+ type: 'string',
6715
+ description: 'Platform name'
6716
+ },
6717
+ url: {
6718
+ type: 'string',
6719
+ description: 'Platform URL'
6720
+ },
6721
+ type: {
6722
+ type: 'string',
6723
+ description: 'Platform type',
6724
+ enum: [
6725
+ 'BANK',
6726
+ 'BROKERAGE',
6727
+ 'CRYPTO_EXCHANGE',
6728
+ 'PAYMENT',
6729
+ 'INVESTMENT',
6730
+ 'INSURANCE',
6731
+ 'OTHER'
6732
+ ]
6733
+ },
6734
+ canonical: {
6735
+ type: 'string',
6736
+ description: 'Canonical identifier in ACCOUNT_RE format (e.g., "icbc")'
6737
+ },
6738
+ suggestedSegment: {
6739
+ type: 'string',
6740
+ description:
6741
+ 'Suggested path segment — canonical with first char uppercased (ACC_COMP_NAME_RE)'
6742
+ },
6743
+ logoUrl: {
6744
+ type: 'string',
6745
+ description: 'Logo URL',
6746
+ nullable: true
6747
+ },
6748
+ isBound: {
6749
+ type: 'boolean',
6750
+ description: 'Whether user has accounts using this platform'
6751
+ }
6752
+ },
6753
+ required: [
6754
+ 'id',
6755
+ 'name',
6756
+ 'url',
6757
+ 'type',
6758
+ 'canonical',
6759
+ 'suggestedSegment',
6760
+ 'logoUrl',
6761
+ 'isBound'
6762
+ ]
6763
+ } as const;
6764
+
6765
+ export const $PlatformMatchResultDto = {
6766
+ type: 'object',
6767
+ properties: {
6768
+ id: {
6769
+ type: 'string',
6770
+ description: 'Global platform ID'
6771
+ },
6772
+ name: {
6773
+ type: 'string',
6774
+ description: 'Platform name (e.g., "ICBC")'
6775
+ },
6776
+ canonical: {
6777
+ type: 'string',
6778
+ description: 'Canonical identifier in ACCOUNT_RE format (e.g., "icbc")'
6779
+ },
6780
+ type: {
6781
+ type: 'string',
6782
+ description: 'Platform type',
6783
+ enum: [
6784
+ 'BANK',
6785
+ 'BROKERAGE',
6786
+ 'CRYPTO_EXCHANGE',
6787
+ 'PAYMENT',
6788
+ 'INVESTMENT',
6789
+ 'INSURANCE',
6790
+ 'OTHER'
6791
+ ]
6792
+ },
6793
+ suggestedSegment: {
6794
+ type: 'string',
6795
+ description:
6796
+ 'Suggested path segment — canonical, already in ACCOUNT_RE format'
6797
+ },
6798
+ logoUrl: {
6799
+ type: 'string',
6800
+ description: 'Logo URL',
6801
+ nullable: true
6802
+ },
6803
+ matchType: {
6804
+ type: 'string',
6805
+ description: "How this row matched: 'exact' > 'prefix' > 'substring'",
6806
+ enum: ['exact', 'prefix', 'substring']
6807
+ }
6808
+ },
6809
+ required: [
6810
+ 'id',
6811
+ 'name',
6812
+ 'canonical',
6813
+ 'type',
6814
+ 'suggestedSegment',
6815
+ 'logoUrl',
6816
+ 'matchType'
6817
+ ]
6818
+ } as const;
6819
+
6820
+ export const $PlatformMatchResponseDto = {
6821
+ type: 'object',
6822
+ properties: {
6823
+ platforms: {
6824
+ description: 'Ranked matches, best tier first (at most 10 rows)',
6825
+ type: 'array',
6826
+ items: {
6827
+ $ref: '#/components/schemas/PlatformMatchResultDto'
6828
+ }
6829
+ },
6830
+ matchType: {
6831
+ type: 'string',
6832
+ description:
6833
+ "Overall match quality — top row's tier, or 'none' when no hits",
6834
+ enum: ['none', 'exact', 'prefix', 'substring']
6835
+ },
6836
+ total: {
6837
+ type: 'number',
6838
+ description: 'Total matches before LIMIT (truncation transparency)'
6839
+ },
6840
+ hasMore: {
6841
+ type: 'boolean',
6842
+ description: 'true when total > platforms.length (more matches exist)'
6365
6843
  }
6366
6844
  },
6367
- required: ['status', 'action']
6845
+ required: ['platforms', 'matchType', 'total', 'hasMore']
6368
6846
  } as const;
6369
6847
 
6370
6848
  export const $CreatePlatformDto = {
@@ -7409,435 +7887,156 @@ export const $HoldingPnlRowDto = {
7409
7887
  ]
7410
7888
  },
7411
7889
  costBasis: {
7412
- description: 'Cost basis of held units',
7413
- nullable: true,
7414
- allOf: [
7415
- {
7416
- $ref: '#/components/schemas/MonetaryDto'
7417
- }
7418
- ]
7419
- },
7420
- marketValue: {
7421
- description: 'Market value at asOf price',
7422
- nullable: true,
7423
- allOf: [
7424
- {
7425
- $ref: '#/components/schemas/MonetaryDto'
7426
- }
7427
- ]
7428
- },
7429
- currentPrice: {
7430
- description: 'Price used for market value',
7431
- nullable: true,
7432
- allOf: [
7433
- {
7434
- $ref: '#/components/schemas/CurrentPriceDto'
7435
- }
7436
- ]
7437
- },
7438
- unrealizedPnlBase: {
7439
- type: 'object',
7440
- description:
7441
- 'Unrealized P&L in base currency (Decimal string); null when any FX/price missing',
7442
- nullable: true,
7443
- example: '6000'
7444
- },
7445
- unrealizedPnlPct: {
7446
- type: 'object',
7447
- description: 'Unrealized P&L % (Decimal string)',
7448
- nullable: true,
7449
- example: '25'
7450
- },
7451
- costFxRate: {
7452
- description: 'Historical FX rate applied to cost basis',
7453
- nullable: true,
7454
- allOf: [
7455
- {
7456
- $ref: '#/components/schemas/FxRateDto'
7457
- }
7458
- ]
7459
- },
7460
- marketFxRate: {
7461
- description: 'FX rate applied to market value',
7462
- nullable: true,
7463
- allOf: [
7464
- {
7465
- $ref: '#/components/schemas/FxRateDto'
7466
- }
7467
- ]
7468
- },
7469
- pctOfInvestedAssets: {
7470
- type: 'object',
7471
- description:
7472
- 'Share of invested assets % (Decimal string); only for invested chartTokens',
7473
- nullable: true,
7474
- example: '40'
7475
- },
7476
- realizedPnl: {
7477
- description:
7478
- 'Cumulative realized P&L on sold lots (asOf-date cutoff); null when the method has no applicable sells, a sell lacks a price, or any required FX rate is missing (never-mix). When a sell spans multiple currencies (cross-currency sale), amount and currency reflect the base currency; baseCcyEquivalent is always the authoritative dual-FX figure',
7479
- nullable: true,
7480
- allOf: [
7481
- {
7482
- $ref: '#/components/schemas/MonetaryDto'
7483
- }
7484
- ]
7485
- }
7486
- },
7487
- required: [
7488
- 'accountId',
7489
- 'accountPath',
7490
- 'symbol',
7491
- 'chartToken',
7492
- 'assetClass',
7493
- 'units'
7494
- ]
7495
- } as const;
7496
-
7497
- export const $HoldingPnlWarningDto = {
7498
- type: 'object',
7499
- properties: {
7500
- type: {
7501
- type: 'string',
7502
- description: 'Warning type',
7503
- example: 'MISSING_COST_FX_RATE',
7504
- enum: [
7505
- 'MISSING_COST_FX_RATE',
7506
- 'MISSING_MARKET_FX_RATE',
7507
- 'MISSING_SALE_PRICE',
7508
- 'MISSING_REALIZED_FX_RATE',
7509
- 'OVERSOLD_LOTS',
7510
- 'NO_PRICE',
7511
- 'MIXED_COST_CURRENCY'
7512
- ]
7513
- },
7514
- symbol: {
7515
- type: 'object',
7516
- nullable: true
7517
- },
7518
- accountId: {
7519
- type: 'object',
7520
- nullable: true
7521
- },
7522
- currency: {
7523
- type: 'object',
7524
- nullable: true
7525
- }
7526
- },
7527
- required: ['type']
7528
- } as const;
7529
-
7530
- export const $HoldingPnlResponseDto = {
7531
- type: 'object',
7532
- properties: {
7533
- asOfDate: {
7534
- type: 'string',
7535
- example: '2026-07-08'
7536
- },
7537
- baseCurrency: {
7538
- type: 'string',
7539
- example: 'CNY'
7540
- },
7541
- method: {
7542
- type: 'string',
7543
- description:
7544
- 'Realized-P&L lot-matching method (FIFO or average). Unrealized cost basis remains average regardless of this value (#473).',
7545
- enum: ['average', 'FIFO'],
7546
- example: 'average'
7547
- },
7548
- rows: {
7549
- type: 'array',
7550
- items: {
7551
- $ref: '#/components/schemas/HoldingPnlRowDto'
7552
- }
7553
- },
7554
- warnings: {
7555
- type: 'array',
7556
- items: {
7557
- $ref: '#/components/schemas/HoldingPnlWarningDto'
7558
- }
7559
- }
7560
- },
7561
- required: ['asOfDate', 'baseCurrency', 'method', 'rows', 'warnings']
7562
- } as const;
7563
-
7564
- export const $CurrencyBalanceDto = {
7565
- type: 'object',
7566
- properties: {
7567
- currency: {
7568
- type: 'string',
7569
- description: 'ISO 4217 currency code',
7570
- example: 'CNY'
7571
- },
7572
- balance: {
7573
- type: 'string',
7574
- description: 'Balance amount',
7575
- example: '500000.00'
7576
- }
7577
- },
7578
- required: ['currency', 'balance']
7579
- } as const;
7580
-
7581
- export const $TimeSeriesPointDto = {
7582
- type: 'object',
7583
- properties: {
7584
- date: {
7585
- type: 'string',
7586
- description: 'Date in YYYY-MM-DD format',
7587
- example: '2024-06-15'
7588
- },
7589
- value: {
7590
- type: 'string',
7591
- description: 'Value at this date (in base currency)',
7592
- example: '500000.00'
7593
- },
7594
- change: {
7595
- type: 'object',
7596
- description: 'Change from previous point',
7597
- example: '5000.00'
7598
- },
7599
- assets: {
7600
- type: 'string',
7601
- description: 'Total assets at this date (in base currency)',
7602
- example: '494338.00'
7603
- },
7604
- liabilities: {
7605
- type: 'string',
7606
- description: 'Total liabilities at this date (in base currency)',
7607
- example: '310098.00'
7608
- },
7609
- byCurrency: {
7610
- description: 'Multi-currency breakdown for this point',
7611
- type: 'array',
7612
- items: {
7613
- $ref: '#/components/schemas/CurrencyBalanceDto'
7614
- }
7615
- }
7616
- },
7617
- required: ['date', 'value']
7618
- } as const;
7619
-
7620
- export const $TrendSummaryDto = {
7621
- type: 'object',
7622
- properties: {
7623
- startValue: {
7624
- type: 'string',
7625
- description: 'Value at start of period',
7626
- example: '450000.00'
7627
- },
7628
- endValue: {
7629
- type: 'string',
7630
- description: 'Value at end of period',
7631
- example: '500000.00'
7632
- },
7633
- totalChange: {
7634
- type: 'string',
7635
- description: 'Total change over period',
7636
- example: '50000.00'
7637
- },
7638
- totalChangePercentage: {
7639
- type: 'string',
7640
- description: 'Total change percentage',
7641
- example: '+11.11%'
7642
- }
7643
- },
7644
- required: ['startValue', 'endValue', 'totalChange', 'totalChangePercentage']
7645
- } as const;
7646
-
7647
- export const $MultiCurrencyPointDto = {
7648
- type: 'object',
7649
- properties: {
7650
- date: {
7651
- type: 'string',
7652
- description: 'Date in YYYY-MM-DD format',
7653
- example: '2024-06-15'
7890
+ description: 'Cost basis of held units',
7891
+ nullable: true,
7892
+ allOf: [
7893
+ {
7894
+ $ref: '#/components/schemas/MonetaryDto'
7895
+ }
7896
+ ]
7654
7897
  },
7655
- byCurrency: {
7656
- description: 'Balances by currency',
7657
- type: 'array',
7658
- items: {
7659
- $ref: '#/components/schemas/CurrencyBalanceDto'
7660
- }
7661
- }
7662
- },
7663
- required: ['date', 'byCurrency']
7664
- } as const;
7665
-
7666
- export const $PortfolioTrendsResponseDto = {
7667
- type: 'object',
7668
- properties: {
7669
- series: {
7670
- description: 'Time series data points',
7671
- type: 'array',
7672
- items: {
7673
- $ref: '#/components/schemas/TimeSeriesPointDto'
7674
- }
7898
+ marketValue: {
7899
+ description: 'Market value at asOf price',
7900
+ nullable: true,
7901
+ allOf: [
7902
+ {
7903
+ $ref: '#/components/schemas/MonetaryDto'
7904
+ }
7905
+ ]
7675
7906
  },
7676
- summary: {
7677
- description: 'Period summary',
7907
+ currentPrice: {
7908
+ description: 'Price used for market value',
7909
+ nullable: true,
7678
7910
  allOf: [
7679
7911
  {
7680
- $ref: '#/components/schemas/TrendSummaryDto'
7912
+ $ref: '#/components/schemas/CurrentPriceDto'
7681
7913
  }
7682
7914
  ]
7683
7915
  },
7684
- period: {
7685
- type: 'string',
7686
- description: 'Period requested',
7687
- example: '6m'
7916
+ unrealizedPnlBase: {
7917
+ type: 'object',
7918
+ description:
7919
+ 'Unrealized P&L in base currency (Decimal string); null when any FX/price missing',
7920
+ nullable: true,
7921
+ example: '6000'
7688
7922
  },
7689
- granularity: {
7690
- type: 'string',
7691
- description: 'Data granularity',
7692
- example: 'month'
7923
+ unrealizedPnlPct: {
7924
+ type: 'object',
7925
+ description: 'Unrealized P&L % (Decimal string)',
7926
+ nullable: true,
7927
+ example: '25'
7693
7928
  },
7694
- currency: {
7695
- type: 'string',
7696
- description: 'Base currency for converted values',
7697
- example: 'CNY'
7929
+ costFxRate: {
7930
+ description: 'Historical FX rate applied to cost basis',
7931
+ nullable: true,
7932
+ allOf: [
7933
+ {
7934
+ $ref: '#/components/schemas/FxRateDto'
7935
+ }
7936
+ ]
7698
7937
  },
7699
- byCurrency: {
7938
+ marketFxRate: {
7939
+ description: 'FX rate applied to market value',
7940
+ nullable: true,
7941
+ allOf: [
7942
+ {
7943
+ $ref: '#/components/schemas/FxRateDto'
7944
+ }
7945
+ ]
7946
+ },
7947
+ pctOfInvestedAssets: {
7948
+ type: 'object',
7700
7949
  description:
7701
- 'Multi-currency time series (each point has currency breakdown)',
7702
- type: 'array',
7703
- items: {
7704
- $ref: '#/components/schemas/MultiCurrencyPointDto'
7705
- }
7950
+ 'Share of invested assets % (Decimal string); only for invested chartTokens',
7951
+ nullable: true,
7952
+ example: '40'
7706
7953
  },
7707
- warnings: {
7708
- description: 'Exchange rate warnings',
7709
- type: 'array',
7710
- items: {
7711
- $ref: '#/components/schemas/ExchangeRateWarningDto'
7712
- }
7954
+ realizedPnl: {
7955
+ description:
7956
+ 'Cumulative realized P&L on sold lots (asOf-date cutoff); null when the method has no applicable sells, a sell lacks a price, or any required FX rate is missing (never-mix). When a sell spans multiple currencies (cross-currency sale), amount and currency reflect the base currency; baseCcyEquivalent is always the authoritative dual-FX figure',
7957
+ nullable: true,
7958
+ allOf: [
7959
+ {
7960
+ $ref: '#/components/schemas/MonetaryDto'
7961
+ }
7962
+ ]
7713
7963
  }
7714
7964
  },
7715
- required: ['series', 'summary', 'period', 'granularity', 'currency']
7965
+ required: [
7966
+ 'accountId',
7967
+ 'accountPath',
7968
+ 'symbol',
7969
+ 'chartToken',
7970
+ 'assetClass',
7971
+ 'units'
7972
+ ]
7716
7973
  } as const;
7717
7974
 
7718
- export const $CashFlowPointDto = {
7975
+ export const $HoldingPnlWarningDto = {
7719
7976
  type: 'object',
7720
7977
  properties: {
7721
- month: {
7978
+ type: {
7722
7979
  type: 'string',
7723
- description: 'Month key (YYYY-MM)',
7724
- example: '2024-03'
7980
+ description: 'Warning type',
7981
+ example: 'MISSING_COST_FX_RATE',
7982
+ enum: [
7983
+ 'MISSING_COST_FX_RATE',
7984
+ 'MISSING_MARKET_FX_RATE',
7985
+ 'MISSING_SALE_PRICE',
7986
+ 'MISSING_REALIZED_FX_RATE',
7987
+ 'OVERSOLD_LOTS',
7988
+ 'NO_PRICE',
7989
+ 'MIXED_COST_CURRENCY'
7990
+ ]
7725
7991
  },
7726
- income: {
7727
- type: 'string',
7728
- description: 'Income in base currency (absolute, converted)',
7729
- example: '10000.00'
7992
+ symbol: {
7993
+ type: 'object',
7994
+ nullable: true
7730
7995
  },
7731
- expense: {
7732
- type: 'string',
7733
- description: 'Expense in base currency (absolute, converted)',
7734
- example: '5000.00'
7996
+ accountId: {
7997
+ type: 'object',
7998
+ nullable: true
7735
7999
  },
7736
- netSavings: {
7737
- type: 'string',
7738
- description: 'netSavings = income − expense (savings positive)',
7739
- example: '5000.00'
8000
+ currency: {
8001
+ type: 'object',
8002
+ nullable: true
7740
8003
  }
7741
8004
  },
7742
- required: ['month', 'income', 'expense', 'netSavings']
8005
+ required: ['type']
7743
8006
  } as const;
7744
8007
 
7745
- export const $CashFlowTrendSummaryDto = {
8008
+ export const $HoldingPnlResponseDto = {
7746
8009
  type: 'object',
7747
8010
  properties: {
7748
- totalIncome: {
7749
- type: 'string',
7750
- description: 'Total income across the period',
7751
- example: '60000.00'
7752
- },
7753
- totalExpense: {
8011
+ asOfDate: {
7754
8012
  type: 'string',
7755
- description: 'Total expense across the period',
7756
- example: '30000.00'
8013
+ example: '2026-07-08'
7757
8014
  },
7758
- totalNetSavings: {
8015
+ baseCurrency: {
7759
8016
  type: 'string',
7760
- description: 'income − expense across the period',
7761
- example: '30000.00'
8017
+ example: 'CNY'
7762
8018
  },
7763
- averageMonthlyNetSavings: {
8019
+ method: {
7764
8020
  type: 'string',
7765
8021
  description:
7766
- 'totalNetSavings divided by the window length (N months, incl. zero-filled)',
7767
- example: '5000.00'
7768
- }
7769
- },
7770
- required: [
7771
- 'totalIncome',
7772
- 'totalExpense',
7773
- 'totalNetSavings',
7774
- 'averageMonthlyNetSavings'
7775
- ]
7776
- } as const;
7777
-
7778
- export const $CashFlowTrendsResponseDto = {
7779
- type: 'object',
7780
- properties: {
7781
- series: {
7782
- description:
7783
- 'Monthly cash-flow series (fixed N-month window, zero-filled)',
8022
+ 'Realized-P&L lot-matching method (FIFO or average). Unrealized cost basis remains average regardless of this value (#473).',
8023
+ enum: ['average', 'FIFO'],
8024
+ example: 'average'
8025
+ },
8026
+ rows: {
7784
8027
  type: 'array',
7785
8028
  items: {
7786
- $ref: '#/components/schemas/CashFlowPointDto'
8029
+ $ref: '#/components/schemas/HoldingPnlRowDto'
7787
8030
  }
7788
8031
  },
7789
- summary: {
7790
- description: 'Period totals',
7791
- allOf: [
7792
- {
7793
- $ref: '#/components/schemas/CashFlowTrendSummaryDto'
7794
- }
7795
- ]
7796
- },
7797
- period: {
7798
- type: 'string',
7799
- description: 'Period requested',
7800
- example: '6m'
7801
- },
7802
- granularity: {
7803
- type: 'string',
7804
- description: 'Data granularity (v1 returns month buckets)',
7805
- example: 'month'
7806
- },
7807
- currency: {
7808
- type: 'string',
7809
- description: 'Base currency for converted values',
7810
- example: 'CNY'
7811
- },
7812
8032
  warnings: {
7813
- description: 'Exchange rate warnings (e.g. missing rate for a currency)',
7814
8033
  type: 'array',
7815
8034
  items: {
7816
- $ref: '#/components/schemas/ExchangeRateWarningDto'
8035
+ $ref: '#/components/schemas/HoldingPnlWarningDto'
7817
8036
  }
7818
8037
  }
7819
8038
  },
7820
- required: ['series', 'summary', 'period', 'granularity', 'currency']
7821
- } as const;
7822
-
7823
- export const $GenerateSnapshotBody = {
7824
- type: 'object',
7825
- properties: {}
7826
- } as const;
7827
-
7828
- export const $GenerateSnapshotResponse = {
7829
- type: 'object',
7830
- properties: {}
7831
- } as const;
7832
-
7833
- export const $BackfillSnapshotsBody = {
7834
- type: 'object',
7835
- properties: {}
7836
- } as const;
7837
-
7838
- export const $BackfillSnapshotsResponse = {
7839
- type: 'object',
7840
- properties: {}
8039
+ required: ['asOfDate', 'baseCurrency', 'method', 'rows', 'warnings']
7841
8040
  } as const;
7842
8041
 
7843
8042
  export const $AnonymousLoginDto = {
@@ -7850,3 +8049,15 @@ export const $AnonymousLoginDto = {
7850
8049
  },
7851
8050
  required: ['accessToken']
7852
8051
  } as const;
8052
+
8053
+ export const $AnonymousLoginResponseDto = {
8054
+ type: 'object',
8055
+ properties: {
8056
+ authToken: {
8057
+ type: 'string',
8058
+ description: 'JWT auth token',
8059
+ example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
8060
+ }
8061
+ },
8062
+ required: ['authToken']
8063
+ } as const;