@robosystems/client 0.3.13 → 0.3.15

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.
Files changed (35) hide show
  1. package/artifacts/InvestorClient.d.ts +35 -20
  2. package/artifacts/InvestorClient.js +78 -71
  3. package/artifacts/InvestorClient.ts +164 -141
  4. package/artifacts/LedgerClient.d.ts +22 -1
  5. package/artifacts/LedgerClient.js +40 -0
  6. package/artifacts/LedgerClient.ts +67 -0
  7. package/artifacts/graphql/generated/graphql.d.ts +401 -6
  8. package/artifacts/graphql/generated/graphql.js +633 -4
  9. package/artifacts/graphql/generated/graphql.ts +1058 -41
  10. package/artifacts/graphql/queries/investor/portfolio_block.d.ts +10 -0
  11. package/artifacts/graphql/queries/investor/portfolio_block.js +60 -0
  12. package/artifacts/graphql/queries/investor/portfolio_block.ts +58 -0
  13. package/artifacts/graphql/queries/ledger/informationBlock.js +110 -0
  14. package/artifacts/graphql/queries/ledger/informationBlock.ts +110 -0
  15. package/artifacts/graphql/queries/ledger/reportPackage.d.ts +11 -0
  16. package/artifacts/graphql/queries/ledger/reportPackage.js +151 -0
  17. package/artifacts/graphql/queries/ledger/reportPackage.ts +149 -0
  18. package/index.ts +2 -2
  19. package/package.json +1 -1
  20. package/sdk/index.d.ts +2 -2
  21. package/sdk/index.js +8 -9
  22. package/sdk/index.ts +2 -2
  23. package/sdk/sdk.gen.d.ts +26 -34
  24. package/sdk/sdk.gen.js +51 -68
  25. package/sdk/sdk.gen.ts +47 -64
  26. package/sdk/types.gen.d.ts +409 -365
  27. package/sdk/types.gen.ts +411 -367
  28. package/sdk.gen.d.ts +26 -34
  29. package/sdk.gen.js +51 -68
  30. package/sdk.gen.ts +47 -64
  31. package/types.gen.d.ts +409 -365
  32. package/types.gen.ts +411 -367
  33. package/artifacts/graphql/queries/investor/portfolio.d.ts +0 -4
  34. package/artifacts/graphql/queries/investor/portfolio.js +0 -21
  35. package/artifacts/graphql/queries/investor/portfolio.ts +0 -19
@@ -3,14 +3,20 @@
3
3
  /**
4
4
  * Investor Client for RoboSystems API
5
5
  *
6
- * High-level facade for the RoboInvestor domain: portfolios, securities,
7
- * positions, and portfolio holdings aggregation. Follows the same
8
- * hybrid transport pattern as `LedgerClient`:
6
+ * High-level facade for the RoboInvestor domain: portfolios (via the
7
+ * Portfolio Block molecule), securities (Master Data CRUD), positions
8
+ * (folded into Portfolio Block writes), and portfolio holdings
9
+ * aggregation. Same hybrid transport pattern as `LedgerClient`:
9
10
  *
10
11
  * - **Reads** go through GraphQL at `/extensions/{graph_id}/graphql`.
11
12
  * - **Writes** go through named operations at
12
13
  * `/extensions/roboinvestor/{graph_id}/operations/{operation_name}`.
13
14
  *
15
+ * Portfolio + position writes flow through the **Portfolio Block**
16
+ * envelope ops (`create-portfolio-block`, `update-portfolio-block`,
17
+ * `delete-portfolio-block`); atom-level CRUD on portfolios/positions
18
+ * has been retired. Securities remain Master Data CRUD.
19
+ *
14
20
  * Every write returns an `OperationEnvelope`; this facade unwraps
15
21
  * `envelope.result` and returns a typed shape derived from the GraphQL
16
22
  * codegen output (which is the source of truth for read payload types).
@@ -19,37 +25,35 @@
19
25
  import type { TypedDocumentNode } from '@graphql-typed-document-node/core'
20
26
  import { ClientError } from 'graphql-request'
21
27
  import {
22
- opCreatePortfolio,
23
- opCreatePosition,
28
+ opCreatePortfolioBlock,
24
29
  opCreateSecurity,
25
- opDeletePortfolio,
26
- opDeletePosition,
30
+ opDeletePortfolioBlock,
27
31
  opDeleteSecurity,
28
- opUpdatePortfolio,
29
- opUpdatePosition,
32
+ opUpdatePortfolioBlock,
30
33
  opUpdateSecurity,
31
34
  } from '../sdk.gen'
32
35
  import type {
33
- CreatePortfolioRequest,
34
- CreatePositionRequest,
36
+ CreatePortfolioBlockRequest,
35
37
  CreateSecurityRequest,
38
+ DeletePortfolioBlockOperation,
36
39
  OperationEnvelope,
37
- UpdatePortfolioOperation,
38
- UpdatePositionOperation,
40
+ PortfolioBlockPortfolioPatch,
41
+ PortfolioBlockPositions,
42
+ UpdatePortfolioBlockOperation,
39
43
  UpdateSecurityOperation,
40
44
  } from '../types.gen'
41
45
  import type { TokenProvider } from './graphql/client'
42
46
  import { GraphQLClientCache } from './graphql/client'
43
47
  import {
44
48
  GetInvestorHoldingsDocument,
45
- GetInvestorPortfolioDocument,
49
+ GetInvestorPortfolioBlockDocument,
46
50
  GetInvestorPositionDocument,
47
51
  GetInvestorSecurityDocument,
48
52
  ListInvestorPortfoliosDocument,
49
53
  ListInvestorPositionsDocument,
50
54
  ListInvestorSecuritiesDocument,
51
55
  type GetInvestorHoldingsQuery,
52
- type GetInvestorPortfolioQuery,
56
+ type GetInvestorPortfolioBlockQuery,
53
57
  type GetInvestorPositionQuery,
54
58
  type GetInvestorSecurityQuery,
55
59
  type ListInvestorPortfoliosQuery,
@@ -61,7 +65,11 @@ import {
61
65
 
62
66
  export type InvestorPortfolioList = NonNullable<ListInvestorPortfoliosQuery['portfolios']>
63
67
  export type InvestorPortfolioSummary = InvestorPortfolioList['portfolios'][number]
64
- export type InvestorPortfolio = NonNullable<GetInvestorPortfolioQuery['portfolio']>
68
+
69
+ export type InvestorPortfolioBlock = NonNullable<GetInvestorPortfolioBlockQuery['portfolioBlock']>
70
+ export type InvestorPositionBlock = InvestorPortfolioBlock['positions'][number]
71
+ export type InvestorSecurityLite = InvestorPositionBlock['security']
72
+ export type InvestorEntityLite = InvestorPortfolioBlock['owner']
65
73
 
66
74
  export type InvestorSecurityList = NonNullable<ListInvestorSecuritiesQuery['securities']>
67
75
  export type InvestorSecuritySummary = InvestorSecurityList['securities'][number]
@@ -99,7 +107,7 @@ export class InvestorClient {
99
107
  this.gql = new GraphQLClientCache(config)
100
108
  }
101
109
 
102
- // ── Portfolios ──────────────────────────────────────────────────────
110
+ // ── Portfolios (reads) ──────────────────────────────────────────────
103
111
 
104
112
  /** List portfolios with pagination. */
105
113
  async listPortfolios(
@@ -118,56 +126,85 @@ export class InvestorClient {
118
126
  )
119
127
  }
120
128
 
121
- /** Get a single portfolio by id. Returns null if it doesn't exist. */
122
- async getPortfolio(graphId: string, portfolioId: string): Promise<InvestorPortfolio | null> {
129
+ /**
130
+ * Get the Portfolio Block molecule envelope with portfolio,
131
+ * positions, securities, and entity references in a single read.
132
+ * Returns null if the portfolio doesn't exist.
133
+ */
134
+ async getPortfolioBlock(
135
+ graphId: string,
136
+ portfolioId: string
137
+ ): Promise<InvestorPortfolioBlock | null> {
123
138
  return this.gqlQuery(
124
139
  graphId,
125
- GetInvestorPortfolioDocument,
140
+ GetInvestorPortfolioBlockDocument,
126
141
  { portfolioId },
127
- 'Get portfolio',
128
- (data) => data.portfolio
142
+ 'Get portfolio block',
143
+ (data) => data.portfolioBlock
129
144
  )
130
145
  }
131
146
 
132
- /** Create a new portfolio. Returns the created portfolio. */
133
- async createPortfolio(graphId: string, body: CreatePortfolioRequest): Promise<InvestorPortfolio> {
147
+ // ── Portfolio Block (writes) ────────────────────────────────────────
148
+
149
+ /**
150
+ * Create a portfolio (with optional initial positions) atomically.
151
+ * Each position references an existing security; this op never mints
152
+ * securities — use `createSecurity` first.
153
+ */
154
+ async createPortfolioBlock(
155
+ graphId: string,
156
+ body: CreatePortfolioBlockRequest
157
+ ): Promise<InvestorPortfolioBlock> {
134
158
  const envelope = await this.callOperation(
135
- 'Create portfolio',
136
- opCreatePortfolio({ path: { graph_id: graphId }, body })
159
+ 'Create portfolio block',
160
+ opCreatePortfolioBlock({ path: { graph_id: graphId }, body })
137
161
  )
138
- return rawToInvestorPortfolio(envelope.result as unknown as RawPortfolioResponse)
162
+ return rawToPortfolioBlock(envelope.result as unknown as RawPortfolioBlockResponse)
139
163
  }
140
164
 
141
- /** Update a portfolio's metadata. Only provided fields are applied. */
142
- async updatePortfolio(
165
+ /**
166
+ * Patch portfolio fields and apply position deltas (`add`, `update`,
167
+ * `dispose`) atomically. All deltas roll back together on failure.
168
+ * Pass only the fields/deltas you want changed — anything omitted
169
+ * is left untouched.
170
+ */
171
+ async updatePortfolioBlock(
143
172
  graphId: string,
144
173
  portfolioId: string,
145
- updates: Omit<UpdatePortfolioOperation, 'portfolio_id'>
146
- ): Promise<InvestorPortfolio> {
174
+ updates: {
175
+ portfolio?: PortfolioBlockPortfolioPatch
176
+ positions?: PortfolioBlockPositions
177
+ }
178
+ ): Promise<InvestorPortfolioBlock> {
179
+ const body: UpdatePortfolioBlockOperation = {
180
+ portfolio_id: portfolioId,
181
+ ...updates,
182
+ }
147
183
  const envelope = await this.callOperation(
148
- 'Update portfolio',
149
- opUpdatePortfolio({
150
- path: { graph_id: graphId },
151
- body: {
152
- ...updates,
153
- portfolio_id: portfolioId,
154
- } as UpdatePortfolioOperation,
155
- })
184
+ 'Update portfolio block',
185
+ opUpdatePortfolioBlock({ path: { graph_id: graphId }, body })
156
186
  )
157
- return rawToInvestorPortfolio(envelope.result as unknown as RawPortfolioResponse)
187
+ return rawToPortfolioBlock(envelope.result as unknown as RawPortfolioBlockResponse)
158
188
  }
159
189
 
160
190
  /**
161
- * Delete a portfolio. Fails with 409 if the portfolio still has active
162
- * positions dispose those first.
191
+ * Cascade-delete the portfolio plus all of its positions. When the
192
+ * portfolio still has active positions, the request must include
193
+ * `confirmActivePositions: true` — safety belt to prevent accidental
194
+ * cascade. Disposed-only portfolios delete without the flag.
163
195
  */
164
- async deletePortfolio(graphId: string, portfolioId: string): Promise<{ deleted: boolean }> {
196
+ async deletePortfolioBlock(
197
+ graphId: string,
198
+ portfolioId: string,
199
+ options?: { confirmActivePositions?: boolean }
200
+ ): Promise<{ deleted: boolean }> {
201
+ const body: DeletePortfolioBlockOperation = {
202
+ portfolio_id: portfolioId,
203
+ confirm_active_positions: options?.confirmActivePositions ?? false,
204
+ }
165
205
  const envelope = await this.callOperation(
166
- 'Delete portfolio',
167
- opDeletePortfolio({
168
- path: { graph_id: graphId },
169
- body: { portfolio_id: portfolioId },
170
- })
206
+ 'Delete portfolio block',
207
+ opDeletePortfolioBlock({ path: { graph_id: graphId }, body })
171
208
  )
172
209
  return (envelope.result ?? { deleted: true }) as { deleted: boolean }
173
210
  }
@@ -254,7 +291,7 @@ export class InvestorClient {
254
291
  return (envelope.result ?? { deleted: true }) as { deleted: boolean }
255
292
  }
256
293
 
257
- // ── Positions ───────────────────────────────────────────────────────
294
+ // ── Positions (reads only — writes folded into Portfolio Block) ─────
258
295
 
259
296
  /** List positions with pagination and filters. */
260
297
  async listPositions(
@@ -293,46 +330,6 @@ export class InvestorClient {
293
330
  )
294
331
  }
295
332
 
296
- /** Create a new position. */
297
- async createPosition(graphId: string, body: CreatePositionRequest): Promise<InvestorPosition> {
298
- const envelope = await this.callOperation(
299
- 'Create position',
300
- opCreatePosition({ path: { graph_id: graphId }, body })
301
- )
302
- return rawToInvestorPosition(envelope.result as unknown as RawPositionResponse)
303
- }
304
-
305
- /** Update a position. Only provided fields are applied. */
306
- async updatePosition(
307
- graphId: string,
308
- positionId: string,
309
- updates: Omit<UpdatePositionOperation, 'position_id'>
310
- ): Promise<InvestorPosition> {
311
- const envelope = await this.callOperation(
312
- 'Update position',
313
- opUpdatePosition({
314
- path: { graph_id: graphId },
315
- body: {
316
- ...updates,
317
- position_id: positionId,
318
- } as UpdatePositionOperation,
319
- })
320
- )
321
- return rawToInvestorPosition(envelope.result as unknown as RawPositionResponse)
322
- }
323
-
324
- /** Delete (dispose) a position. */
325
- async deletePosition(graphId: string, positionId: string): Promise<{ deleted: boolean }> {
326
- const envelope = await this.callOperation(
327
- 'Delete position',
328
- opDeletePosition({
329
- path: { graph_id: graphId },
330
- body: { position_id: positionId },
331
- })
332
- )
333
- return (envelope.result ?? { deleted: true }) as { deleted: boolean }
334
- }
335
-
336
333
  // ── Holdings (aggregation) ─────────────────────────────────────────
337
334
 
338
335
  /**
@@ -390,27 +387,13 @@ export class InvestorClient {
390
387
 
391
388
  // ── Module-private conversion helpers ─────────────────────────────────
392
389
  //
393
- // The RoboInvestor write operations (create/update portfolio, security,
394
- // position) return Pydantic-serialized envelopes where `result` is in
395
- // snake_case. The GraphQL-derived `InvestorPortfolio` / `InvestorSecurity`
396
- // / `InvestorPosition` types are in camelCase (matching the read path).
397
- //
398
- // These helpers are the single place where we bridge the two naming
399
- // conventions on the write path, mirroring the `rawFiscalCalendarToCamel`
400
- // / `rawToClosingEntry` pattern in `LedgerClient`. Keeping the unsafe
401
- // `as unknown as` cast localized to these helpers means a backend schema
402
- // drift surfaces here rather than silently at every call site.
403
-
404
- interface RawPortfolioResponse {
405
- id: string
406
- name: string
407
- description: string | null
408
- strategy: string | null
409
- inception_date: string | null
410
- base_currency: string
411
- created_at: string
412
- updated_at: string
413
- }
390
+ // The RoboInvestor write operations return Pydantic-serialized envelopes
391
+ // where `result` is in snake_case. The GraphQL-derived `Investor*` types
392
+ // are in camelCase (matching the read path). These helpers are the single
393
+ // place where we bridge the two naming conventions on the write path,
394
+ // mirroring the equivalent helpers in `LedgerClient`. Keeping the unsafe
395
+ // `as unknown as` cast localized here means a backend schema drift surfaces
396
+ // in one place rather than silently at every call site.
414
397
 
415
398
  interface RawSecurityResponse {
416
399
  id: string
@@ -428,40 +411,50 @@ interface RawSecurityResponse {
428
411
  updated_at: string
429
412
  }
430
413
 
431
- interface RawPositionResponse {
414
+ interface RawEntityLite {
415
+ id: string
416
+ name: string
417
+ source_graph_id: string | null
418
+ }
419
+
420
+ interface RawSecurityLite {
421
+ id: string
422
+ name: string
423
+ security_type: string
424
+ security_subtype: string | null
425
+ is_active: boolean
426
+ issuer: RawEntityLite | null
427
+ source_graph_id: string | null
428
+ }
429
+
430
+ interface RawPositionBlock {
432
431
  id: string
433
- portfolio_id: string
434
- security_id: string
435
- security_name: string | null
436
- entity_name: string | null
437
432
  quantity: number
438
433
  quantity_type: string
439
- cost_basis: number
440
434
  cost_basis_dollars: number
441
- currency: string
442
- current_value: number | null
443
435
  current_value_dollars: number | null
444
436
  valuation_date: string | null
445
437
  valuation_source: string | null
446
438
  acquisition_date: string | null
447
- disposition_date: string | null
448
439
  status: string
449
440
  notes: string | null
450
- created_at: string
451
- updated_at: string
441
+ security: RawSecurityLite
452
442
  }
453
443
 
454
- function rawToInvestorPortfolio(raw: RawPortfolioResponse): InvestorPortfolio {
455
- return {
456
- id: raw.id,
457
- name: raw.name,
458
- description: raw.description,
459
- strategy: raw.strategy,
460
- inceptionDate: raw.inception_date,
461
- baseCurrency: raw.base_currency,
462
- createdAt: raw.created_at,
463
- updatedAt: raw.updated_at,
464
- }
444
+ interface RawPortfolioBlockResponse {
445
+ id: string
446
+ name: string
447
+ description: string | null
448
+ strategy: string | null
449
+ inception_date: string | null
450
+ base_currency: string
451
+ owner: RawEntityLite | null
452
+ positions: RawPositionBlock[]
453
+ total_cost_basis_dollars: number
454
+ total_current_value_dollars: number | null
455
+ active_position_count: number
456
+ created_at: string
457
+ updated_at: string
465
458
  }
466
459
 
467
460
  function rawToInvestorSecurity(raw: RawSecurityResponse): InvestorSecurity {
@@ -482,26 +475,56 @@ function rawToInvestorSecurity(raw: RawSecurityResponse): InvestorSecurity {
482
475
  }
483
476
  }
484
477
 
485
- function rawToInvestorPosition(raw: RawPositionResponse): InvestorPosition {
478
+ function rawToEntityLite(raw: RawEntityLite | null): InvestorEntityLite {
479
+ if (raw === null) return null
480
+ return {
481
+ id: raw.id,
482
+ name: raw.name,
483
+ sourceGraphId: raw.source_graph_id,
484
+ }
485
+ }
486
+
487
+ function rawToSecurityLite(raw: RawSecurityLite): InvestorSecurityLite {
488
+ return {
489
+ id: raw.id,
490
+ name: raw.name,
491
+ securityType: raw.security_type,
492
+ securitySubtype: raw.security_subtype,
493
+ isActive: raw.is_active,
494
+ issuer: rawToEntityLite(raw.issuer),
495
+ sourceGraphId: raw.source_graph_id,
496
+ }
497
+ }
498
+
499
+ function rawToPositionBlock(raw: RawPositionBlock): InvestorPositionBlock {
486
500
  return {
487
501
  id: raw.id,
488
- portfolioId: raw.portfolio_id,
489
- securityId: raw.security_id,
490
- securityName: raw.security_name,
491
- entityName: raw.entity_name,
492
502
  quantity: raw.quantity,
493
503
  quantityType: raw.quantity_type,
494
- costBasis: raw.cost_basis,
495
504
  costBasisDollars: raw.cost_basis_dollars,
496
- currency: raw.currency,
497
- currentValue: raw.current_value,
498
505
  currentValueDollars: raw.current_value_dollars,
499
506
  valuationDate: raw.valuation_date,
500
507
  valuationSource: raw.valuation_source,
501
508
  acquisitionDate: raw.acquisition_date,
502
- dispositionDate: raw.disposition_date,
503
509
  status: raw.status,
504
510
  notes: raw.notes,
511
+ security: rawToSecurityLite(raw.security),
512
+ }
513
+ }
514
+
515
+ function rawToPortfolioBlock(raw: RawPortfolioBlockResponse): InvestorPortfolioBlock {
516
+ return {
517
+ id: raw.id,
518
+ name: raw.name,
519
+ description: raw.description,
520
+ strategy: raw.strategy,
521
+ inceptionDate: raw.inception_date,
522
+ baseCurrency: raw.base_currency,
523
+ owner: rawToEntityLite(raw.owner),
524
+ positions: raw.positions.map(rawToPositionBlock),
525
+ totalCostBasisDollars: raw.total_cost_basis_dollars,
526
+ totalCurrentValueDollars: raw.total_current_value_dollars,
527
+ activePositionCount: raw.active_position_count,
505
528
  createdAt: raw.created_at,
506
529
  updatedAt: raw.updated_at,
507
530
  }
@@ -1,6 +1,6 @@
1
1
  import type { AutoMapElementsOperation, CreateAgentRequest, CreateEventBlockRequest, CreateEventHandlerRequest, CreateMappingAssociationOperation, CreateTaxonomyBlockRequest, CreateViewRequest, DeleteMappingAssociationOperation, DeleteTaxonomyBlockRequest, EvaluateRulesRequest, FinancialStatementAnalysisRequest, LinkEntityTaxonomyRequest, LiveFinancialStatementRequest, OperationEnvelope, UpdateAgentRequest, UpdateEntityRequest, UpdateEventBlockRequest, UpdateEventHandlerRequest, UpdateJournalEntryRequest, UpdateTaxonomyBlockRequest } from '../types.gen';
2
2
  import type { TokenProvider } from './graphql/client';
3
- import { type GetInformationBlockQuery, type GetLedgerAccountRollupsQuery, type GetLedgerAccountTreeQuery, type GetLedgerClosingBookStructuresQuery, type GetLedgerEntityQuery, type GetLedgerFiscalCalendarQuery, type GetLedgerMappedTrialBalanceQuery, type GetLedgerMappingCoverageQuery, type GetLedgerMappingQuery, type GetLedgerPeriodCloseStatusQuery, type GetLedgerPeriodDraftsQuery, type GetLedgerPublishListQuery, type GetLedgerReportingTaxonomyQuery, type GetLedgerReportQuery, type GetLedgerStatementQuery, type GetLedgerSummaryQuery, type GetLedgerTransactionQuery, type GetLedgerTrialBalanceQuery, type ListInformationBlocksQuery, type ListLedgerAccountsQuery, type ListLedgerElementsQuery, type ListLedgerEntitiesQuery, type ListLedgerMappingsQuery, type ListLedgerPublishListsQuery, type ListLedgerReportsQuery, type ListLedgerStructuresQuery, type ListLedgerTaxonomiesQuery, type ListLedgerTransactionsQuery, type ListLedgerUnmappedElementsQuery } from './graphql/generated/graphql';
3
+ import { type GetInformationBlockQuery, type GetLedgerAccountRollupsQuery, type GetLedgerAccountTreeQuery, type GetLedgerClosingBookStructuresQuery, type GetLedgerEntityQuery, type GetLedgerFiscalCalendarQuery, type GetLedgerMappedTrialBalanceQuery, type GetLedgerMappingCoverageQuery, type GetLedgerMappingQuery, type GetLedgerPeriodCloseStatusQuery, type GetLedgerPeriodDraftsQuery, type GetLedgerPublishListQuery, type GetLedgerReportingTaxonomyQuery, type GetLedgerReportPackageQuery, type GetLedgerReportQuery, type GetLedgerStatementQuery, type GetLedgerSummaryQuery, type GetLedgerTransactionQuery, type GetLedgerTrialBalanceQuery, type ListInformationBlocksQuery, type ListLedgerAccountsQuery, type ListLedgerElementsQuery, type ListLedgerEntitiesQuery, type ListLedgerMappingsQuery, type ListLedgerPublishListsQuery, type ListLedgerReportsQuery, type ListLedgerStructuresQuery, type ListLedgerTaxonomiesQuery, type ListLedgerTransactionsQuery, type ListLedgerUnmappedElementsQuery } from './graphql/generated/graphql';
4
4
  export type LedgerEntity = NonNullable<GetLedgerEntityQuery['entity']>;
5
5
  export type LedgerEntitySummary = ListLedgerEntitiesQuery['entities'][number];
6
6
  export type LedgerSummary = NonNullable<GetLedgerSummaryQuery['summary']>;
@@ -39,6 +39,8 @@ export type LedgerClosingBookStructures = NonNullable<GetLedgerClosingBookStruct
39
39
  export type LedgerFiscalCalendar = NonNullable<GetLedgerFiscalCalendarQuery['fiscalCalendar']>;
40
40
  export type LedgerFiscalPeriod = LedgerFiscalCalendar['periods'][number];
41
41
  export type Report = NonNullable<GetLedgerReportQuery['report']>;
42
+ export type ReportPackage = NonNullable<GetLedgerReportPackageQuery['reportPackage']>;
43
+ export type ReportPackageItem = ReportPackage['items'][number];
42
44
  export type ReportListItem = NonNullable<ListLedgerReportsQuery['reports']>['reports'][number];
43
45
  export type StatementData = NonNullable<GetLedgerStatementQuery['statement']>;
44
46
  export type StatementPeriod = StatementData['periods'][number];
@@ -446,6 +448,13 @@ export declare class LedgerClient {
446
448
  listReports(graphId: string): Promise<ReportListItem[]>;
447
449
  /** Get a single report with its period list + available structures. */
448
450
  getReport(graphId: string, reportId: string): Promise<Report | null>;
451
+ /**
452
+ * Rehydrate a Report as a package — Report metadata + N
453
+ * `InformationBlock` envelopes (one per attached FactSet). Drives the
454
+ * package viewer; returns everything needed to render BS + IS (and any
455
+ * other statements the Report generated) without per-section fetches.
456
+ */
457
+ getReportPackage(graphId: string, reportId: string): Promise<ReportPackage | null>;
449
458
  /**
450
459
  * Render a financial statement — facts viewed through a structure.
451
460
  *
@@ -464,6 +473,18 @@ export declare class LedgerClient {
464
473
  * Each target graph receives a snapshot copy of the report's facts.
465
474
  */
466
475
  shareReport(graphId: string, reportId: string, publishListId: string): Promise<ReportOperationAck>;
476
+ /**
477
+ * Transition a Report's filing_status to 'filed' — locks the package.
478
+ * Allowed from 'draft' or 'under_review'. Stamps filed_at + filed_by
479
+ * from the auth context + server clock.
480
+ */
481
+ fileReport(graphId: string, reportId: string): Promise<ReportOperationAck>;
482
+ /**
483
+ * Move a Report along the non-file legs of the filing lifecycle
484
+ * (draft ↔ under_review, filed → archived). Use ``fileReport`` to
485
+ * reach 'filed' so the audit fields land cleanly.
486
+ */
487
+ transitionFilingStatus(graphId: string, reportId: string, targetStatus: string): Promise<ReportOperationAck>;
467
488
  /** Check if a report was received via sharing (vs locally created). */
468
489
  isSharedReport(report: Report): boolean;
469
490
  /** List publish lists with pagination. */
@@ -624,6 +624,15 @@ class LedgerClient {
624
624
  async getReport(graphId, reportId) {
625
625
  return this.gqlQuery(graphId, graphql_1.GetLedgerReportDocument, { reportId }, 'Get report', (data) => data.report);
626
626
  }
627
+ /**
628
+ * Rehydrate a Report as a package — Report metadata + N
629
+ * `InformationBlock` envelopes (one per attached FactSet). Drives the
630
+ * package viewer; returns everything needed to render BS + IS (and any
631
+ * other statements the Report generated) without per-section fetches.
632
+ */
633
+ async getReportPackage(graphId, reportId) {
634
+ return this.gqlQuery(graphId, graphql_1.GetLedgerReportPackageDocument, { reportId }, 'Get report package', (data) => data.reportPackage);
635
+ }
627
636
  /**
628
637
  * Render a financial statement — facts viewed through a structure.
629
638
  *
@@ -676,6 +685,37 @@ class LedgerClient {
676
685
  result: envelope.result ?? null,
677
686
  };
678
687
  }
688
+ /**
689
+ * Transition a Report's filing_status to 'filed' — locks the package.
690
+ * Allowed from 'draft' or 'under_review'. Stamps filed_at + filed_by
691
+ * from the auth context + server clock.
692
+ */
693
+ async fileReport(graphId, reportId) {
694
+ const body = { report_id: reportId };
695
+ const envelope = await this.callOperation('File report', (0, sdk_gen_1.opFileReport)({ path: { graph_id: graphId }, body }));
696
+ return {
697
+ operationId: envelope.operationId,
698
+ status: envelope.status,
699
+ result: envelope.result ?? null,
700
+ };
701
+ }
702
+ /**
703
+ * Move a Report along the non-file legs of the filing lifecycle
704
+ * (draft ↔ under_review, filed → archived). Use ``fileReport`` to
705
+ * reach 'filed' so the audit fields land cleanly.
706
+ */
707
+ async transitionFilingStatus(graphId, reportId, targetStatus) {
708
+ const body = {
709
+ report_id: reportId,
710
+ target_status: targetStatus,
711
+ };
712
+ const envelope = await this.callOperation('Transition filing status', (0, sdk_gen_1.opTransitionFilingStatus)({ path: { graph_id: graphId }, body }));
713
+ return {
714
+ operationId: envelope.operationId,
715
+ status: envelope.status,
716
+ result: envelope.result ?? null,
717
+ };
718
+ }
679
719
  /** Check if a report was received via sharing (vs locally created). */
680
720
  isSharedReport(report) {
681
721
  return report.sourceGraphId !== null;
@@ -44,6 +44,7 @@ import {
44
44
  opDeleteReport,
45
45
  opDeleteTaxonomyBlock,
46
46
  opEvaluateRules,
47
+ opFileReport,
47
48
  opFinancialStatementAnalysis,
48
49
  opInitializeLedger,
49
50
  opLinkEntityTaxonomy,
@@ -54,6 +55,7 @@ import {
54
55
  opReopenPeriod,
55
56
  opSetCloseTarget,
56
57
  opShareReport,
58
+ opTransitionFilingStatus,
57
59
  opUpdateAgent,
58
60
  opUpdateEntity,
59
61
  opUpdateEventBlock,
@@ -81,6 +83,7 @@ import type {
81
83
  DeleteMappingAssociationOperation,
82
84
  DeleteTaxonomyBlockRequest,
83
85
  EvaluateRulesRequest,
86
+ FileReportRequest,
84
87
  FinancialStatementAnalysisRequest,
85
88
  InitializeLedgerRequest,
86
89
  LinkEntityTaxonomyRequest,
@@ -88,6 +91,7 @@ import type {
88
91
  OperationEnvelope,
89
92
  ReopenPeriodOperation,
90
93
  SetCloseTargetOperation,
94
+ TransitionFilingStatusRequest,
91
95
  UpdateAgentRequest,
92
96
  UpdateEntityRequest,
93
97
  UpdateEventBlockRequest,
@@ -114,6 +118,7 @@ import {
114
118
  GetLedgerPublishListDocument,
115
119
  GetLedgerReportDocument,
116
120
  GetLedgerReportingTaxonomyDocument,
121
+ GetLedgerReportPackageDocument,
117
122
  GetLedgerStatementDocument,
118
123
  GetLedgerSummaryDocument,
119
124
  GetLedgerTransactionDocument,
@@ -142,6 +147,7 @@ import {
142
147
  type GetLedgerPeriodDraftsQuery,
143
148
  type GetLedgerPublishListQuery,
144
149
  type GetLedgerReportingTaxonomyQuery,
150
+ type GetLedgerReportPackageQuery,
145
151
  type GetLedgerReportQuery,
146
152
  type GetLedgerStatementQuery,
147
153
  type GetLedgerSummaryQuery,
@@ -227,6 +233,8 @@ export type LedgerFiscalPeriod = LedgerFiscalCalendar['periods'][number]
227
233
 
228
234
  // Reports + publish lists + statements
229
235
  export type Report = NonNullable<GetLedgerReportQuery['report']>
236
+ export type ReportPackage = NonNullable<GetLedgerReportPackageQuery['reportPackage']>
237
+ export type ReportPackageItem = ReportPackage['items'][number]
230
238
  export type ReportListItem = NonNullable<ListLedgerReportsQuery['reports']>['reports'][number]
231
239
  export type StatementData = NonNullable<GetLedgerStatementQuery['statement']>
232
240
  export type StatementPeriod = StatementData['periods'][number]
@@ -1532,6 +1540,22 @@ export class LedgerClient {
1532
1540
  )
1533
1541
  }
1534
1542
 
1543
+ /**
1544
+ * Rehydrate a Report as a package — Report metadata + N
1545
+ * `InformationBlock` envelopes (one per attached FactSet). Drives the
1546
+ * package viewer; returns everything needed to render BS + IS (and any
1547
+ * other statements the Report generated) without per-section fetches.
1548
+ */
1549
+ async getReportPackage(graphId: string, reportId: string): Promise<ReportPackage | null> {
1550
+ return this.gqlQuery(
1551
+ graphId,
1552
+ GetLedgerReportPackageDocument,
1553
+ { reportId },
1554
+ 'Get report package',
1555
+ (data) => data.reportPackage
1556
+ )
1557
+ }
1558
+
1535
1559
  /**
1536
1560
  * Render a financial statement — facts viewed through a structure.
1537
1561
  *
@@ -1616,6 +1640,49 @@ export class LedgerClient {
1616
1640
  }
1617
1641
  }
1618
1642
 
1643
+ /**
1644
+ * Transition a Report's filing_status to 'filed' — locks the package.
1645
+ * Allowed from 'draft' or 'under_review'. Stamps filed_at + filed_by
1646
+ * from the auth context + server clock.
1647
+ */
1648
+ async fileReport(graphId: string, reportId: string): Promise<ReportOperationAck> {
1649
+ const body: FileReportRequest = { report_id: reportId }
1650
+ const envelope = await this.callOperation(
1651
+ 'File report',
1652
+ opFileReport({ path: { graph_id: graphId }, body })
1653
+ )
1654
+ return {
1655
+ operationId: envelope.operationId,
1656
+ status: envelope.status,
1657
+ result: (envelope.result as Record<string, unknown> | null) ?? null,
1658
+ }
1659
+ }
1660
+
1661
+ /**
1662
+ * Move a Report along the non-file legs of the filing lifecycle
1663
+ * (draft ↔ under_review, filed → archived). Use ``fileReport`` to
1664
+ * reach 'filed' so the audit fields land cleanly.
1665
+ */
1666
+ async transitionFilingStatus(
1667
+ graphId: string,
1668
+ reportId: string,
1669
+ targetStatus: string
1670
+ ): Promise<ReportOperationAck> {
1671
+ const body: TransitionFilingStatusRequest = {
1672
+ report_id: reportId,
1673
+ target_status: targetStatus,
1674
+ }
1675
+ const envelope = await this.callOperation(
1676
+ 'Transition filing status',
1677
+ opTransitionFilingStatus({ path: { graph_id: graphId }, body })
1678
+ )
1679
+ return {
1680
+ operationId: envelope.operationId,
1681
+ status: envelope.status,
1682
+ result: (envelope.result as Record<string, unknown> | null) ?? null,
1683
+ }
1684
+ }
1685
+
1619
1686
  /** Check if a report was received via sharing (vs locally created). */
1620
1687
  isSharedReport(report: Report): boolean {
1621
1688
  return report.sourceGraphId !== null