diff --git a/clients/LedgerClient.test.ts b/clients/LedgerClient.test.ts index 46466c4..a6882ef 100644 --- a/clients/LedgerClient.test.ts +++ b/clients/LedgerClient.test.ts @@ -686,6 +686,73 @@ describe('LedgerClient', () => { mockFetch.mockResolvedValueOnce(gqlResponse({ mappings: null })) expect(await client.listMappings('graph_1')).toEqual([]) }) + + it('names whose chart each mapping maps, and keeps one entity on request', async () => { + mockFetch.mockResolvedValueOnce( + gqlResponse({ + mappings: { + structures: [ + { + id: 'map_sub', + name: 'CoA → GAAP', + description: null, + blockType: 'coa_mapping', + taxonomyId: 'tax_map_sub', + isActive: true, + framework: 'rs-gaap', + entityId: 'ent_sub', + }, + ], + }, + }) + ) + const mappings = await client.listMappings('graph_1', { entityId: 'ent_sub' }) + expect(mappings[0].entityId).toBe('ent_sub') + const body = JSON.parse((mockFetch.mock.calls[0][1] as RequestInit).body as string) + expect(body.variables.entityId).toBe('ent_sub') + }) + + it('sends a null entity to list every entity mapping', async () => { + mockFetch.mockResolvedValueOnce(gqlResponse({ mappings: { structures: [] } })) + await client.listMappings('graph_1') + const body = JSON.parse((mockFetch.mock.calls[0][1] as RequestInit).body as string) + expect(body.variables.entityId).toBeNull() + }) + }) + + describe('getMappingCandidates', () => { + it('narrows by the named entity', async () => { + mockFetch.mockResolvedValueOnce(gqlResponse({ mappingCandidates: [] })) + await client.getMappingCandidates('graph_1', 'asset', { entityId: 'ent_sub' }) + const body = JSON.parse((mockFetch.mock.calls[0][1] as RequestInit).body as string) + expect(body.variables).toEqual({ classification: 'asset', entityId: 'ent_sub' }) + }) + }) + + describe('information blocks', () => { + const variablesOf = (call: number) => + JSON.parse((mockFetch.mock.calls[call][1] as RequestInit).body as string).variables + + it('getInformationBlock sends the entity, windowed or not', async () => { + mockFetch.mockResolvedValue(gqlResponse({ informationBlock: null })) + await client.getInformationBlock('graph_1', 'struct_bs', { entityId: 'ent_sub' }) + await client.getInformationBlock('graph_1', 'struct_bs', { + entityId: 'ent_sub', + series: true, + seriesHistory: 12, + }) + await client.getInformationBlock('graph_1', 'struct_bs') + expect(variablesOf(0).entityId).toBe('ent_sub') + expect(variablesOf(1).entityId).toBe('ent_sub') + expect(variablesOf(1).seriesHistory).toBe(12) + expect(variablesOf(2).entityId).toBeNull() + }) + + it('listInformationBlocks sends the entity', async () => { + mockFetch.mockResolvedValueOnce(gqlResponse({ informationBlocks: [] })) + await client.listInformationBlocks('graph_1', { blockType: 'forecast', entityId: 'ent_sub' }) + expect(variablesOf(0)).toMatchObject({ blockType: 'forecast', entityId: 'ent_sub' }) + }) }) describe('getMappingCoverage', () => { @@ -1653,6 +1720,24 @@ describe('LedgerClient', () => { }) describe('createSchedule', () => { + it('books the schedule to a named entity', async () => { + mockFetch.mockResolvedValueOnce( + envelopeResponse('create-schedule', { id: 'str_1', block_type: 'schedule', name: 'Rent' }) + ) + await client.createSchedule('graph_1', { + name: 'Rent', + elementIds: ['elem_1'], + periodStart: '2026-01-01', + periodEnd: '2026-12-31', + monthlyAmount: 1000, + entryTemplate: { debitElementId: 'elem_rent', creditElementId: 'elem_prepaid' }, + entityId: 'ent_sub', + }) + const req = mockFetch.mock.calls[0][0] as Request + const body = JSON.parse(await req.text()) + expect(body.payload.entity_id).toBe('ent_sub') + }) + it('serializes options into snake_case body and converts the result', async () => { // `create-information-block` returns an InformationBlockEnvelope. The // previous mock invented a ScheduleCreatedResponse-shaped body that the @@ -1806,6 +1891,21 @@ describe('LedgerClient', () => { expect(body.mapping_id).toBe('map_1') expect(body.period_start).toBe('2025-01-01') expect(body.period_end).toBe('2025-12-31') + expect(body).not.toHaveProperty('entity_id') + }) + + it('passes the entity the report is for', async () => { + mockFetch.mockResolvedValueOnce(envelopeResponse('create-report', { id: 'rpt_1' })) + await client.createReport('graph_42', { + name: 'FY25', + mappingId: 'map_sub', + periodStart: '2025-01-01', + periodEnd: '2025-12-31', + entityId: 'ent_sub', + }) + const req = mockFetch.mock.calls[0][0] as Request + const body = JSON.parse(await req.text()) + expect(body.entity_id).toBe('ent_sub') }) it('throws when the envelope carries no result', async () => { diff --git a/clients/LedgerClient.ts b/clients/LedgerClient.ts index a2684d2..4c66bac 100644 --- a/clients/LedgerClient.ts +++ b/clients/LedgerClient.ts @@ -412,6 +412,12 @@ export interface CreateReportOptions { periodType?: string comparative?: boolean periods?: PeriodSpecInput[] + /** + * The entity the report is for. Omit for the entity whose chart + * `mappingId` maps from; named alongside another entity's mapping, the + * server refuses it. + */ + entityId?: string | null } // ── Write result shapes (envelope.result payloads) ───────────────────── @@ -733,6 +739,8 @@ export interface CreateScheduleOptions { */ bookedOn?: string } + /** The entity whose books the schedule belongs to. Omit for the group parent. */ + entityId?: string | null } export interface JournalEntryLineItem { @@ -1338,18 +1346,20 @@ export class LedgerClient { /** * rs-gaap concepts a CoA element of the given EFS `classification` * (asset / liability / equity / revenue / expense) may map to — limited - * to concepts that render under the graph's active Reporting Style, with - * statement-level subtotals excluded. Use this to populate the mapping - * picker so it never offers an unreachable target. + * to concepts that render under the Reporting Style of the entity whose + * chart is being mapped (`options.entityId`, default the group parent), + * with statement-level subtotals excluded. Use this to populate the + * mapping picker so it never offers an unreachable target. */ async getMappingCandidates( graphId: string, - classification: string + classification: string, + options?: { entityId?: string | null } ): Promise { return this.gqlQuery( graphId, MappingCandidatesDocument, - { classification }, + { classification, entityId: options?.entityId ?? null }, 'Mapping candidates', (data) => data.mappingCandidates ) @@ -1393,13 +1403,18 @@ export class LedgerClient { /** * List active CoA→reporting mapping structures, the book mapping first. - * Each carries `framework`: the reporting framework it maps the chart into. + * Each carries `framework`: the reporting framework it maps the chart into, + * and `entityId`: the entity whose chart it maps from, so whose reports it + * can produce. `options.entityId` keeps that entity's mappings only. */ - async listMappings(graphId: string): Promise { + async listMappings( + graphId: string, + options?: { entityId?: string | null } + ): Promise { const list = await this.gqlQuery( graphId, ListLedgerMappingsDocument, - undefined, + { entityId: options?.entityId ?? null }, 'List mappings', (data) => data.mappings ) @@ -1493,6 +1508,12 @@ export class LedgerClient { * window arguments — a pre-window server rejects it. Callers that * never pass a window keep the un-windowed document and stay * compatible with older backends. + * + * `options.entityId` picks whose books a block shared by the group + * reads (statements, metrics, disclosures); omitted, the scenario's + * entity, else the group parent. A schedule, reconciliation or forecast + * always reads its own entity's. The envelope's `entityId` names the + * entity it read. */ async getInformationBlock( graphId: string, @@ -1502,6 +1523,7 @@ export class LedgerClient { series?: boolean seriesHistory?: number seriesForecast?: number + entityId?: string | null } ): Promise { const windowed = options?.seriesHistory !== undefined || options?.seriesForecast !== undefined @@ -1515,6 +1537,7 @@ export class LedgerClient { series: options?.series ?? false, seriesHistory: options?.seriesHistory ?? null, seriesForecast: options?.seriesForecast ?? null, + entityId: options?.entityId ?? null, }, 'Get information block', (data) => data.informationBlock ?? null @@ -1526,6 +1549,7 @@ export class LedgerClient { id, scenarioId: options?.scenarioId ?? null, series: options?.series ?? false, + entityId: options?.entityId ?? null, }, 'Get information block', (data) => data.informationBlock ?? null @@ -1539,6 +1563,11 @@ export class LedgerClient { * `{blockType: 'schedule'}` to get the same set of blocks. * `options.scenarioId` threads into each envelope's FactSet binding * (the block list itself is scenario-independent). + * + * `options.entityId` (omitted: the scenario's entity, else the group + * parent) lists the blocks shared by the group plus that entity's own + * schedules, reconciliations and forecasts, never another entity's; + * shared blocks read its books. */ async listInformationBlocks( graphId: string, @@ -1548,6 +1577,7 @@ export class LedgerClient { limit?: number offset?: number scenarioId?: string + entityId?: string | null } ): Promise { const blocks = await this.gqlQuery( @@ -1559,6 +1589,7 @@ export class LedgerClient { limit: options?.limit ?? null, offset: options?.offset ?? null, scenarioId: options?.scenarioId ?? null, + entityId: options?.entityId ?? null, }, 'List information blocks', (data) => data.informationBlocks @@ -1642,6 +1673,7 @@ export class LedgerClient { memo_template: options.entryTemplate.memoTemplate, }, taxonomy_id: options.taxonomyId, + ...(options.entityId ? { entity_id: options.entityId } : {}), schedule_metadata: options.scheduleMetadata ? { method: options.scheduleMetadata.method, @@ -2565,6 +2597,9 @@ export class LedgerClient { if (options.periods && options.periods.length > 0) { body.periods = options.periods } + if (options.entityId) { + body.entity_id = options.entityId + } const envelope = await this.callOperation('Create report', (o) => createReport({ ...o, path: { graph_id: graphId }, body }) ) diff --git a/clients/graphql/generated/graphql.ts b/clients/graphql/generated/graphql.ts index c05b4fd..10fad54 100644 --- a/clients/graphql/generated/graphql.ts +++ b/clients/graphql/generated/graphql.ts @@ -697,6 +697,7 @@ export type GetInformationBlockQueryVariables = Exact<{ id: string | number scenarioId: string | null | undefined series?: boolean + entityId: string | null | undefined }> export type GetInformationBlockQuery = { @@ -708,6 +709,7 @@ export type GetInformationBlockQuery = { category: string taxonomyId: string | null taxonomyName: string | null + entityId: string | null informationModel: { conceptArrangement: string | null; memberArrangement: string | null } artifact: { topic: string | null @@ -844,6 +846,7 @@ export type GetInformationBlockWindowedQueryVariables = Exact<{ series?: boolean seriesHistory: number | null | undefined seriesForecast: number | null | undefined + entityId: string | null | undefined }> export type GetInformationBlockWindowedQuery = { @@ -855,6 +858,7 @@ export type GetInformationBlockWindowedQuery = { category: string taxonomyId: string | null taxonomyName: string | null + entityId: string | null informationModel: { conceptArrangement: string | null; memberArrangement: string | null } artifact: { topic: string | null @@ -991,6 +995,7 @@ export type ListInformationBlocksQueryVariables = Exact<{ limit: number | null | undefined offset: number | null | undefined scenarioId: string | null | undefined + entityId: string | null | undefined }> export type ListInformationBlocksQuery = { @@ -1002,6 +1007,7 @@ export type ListInformationBlocksQuery = { category: string taxonomyId: string | null taxonomyName: string | null + entityId: string | null informationModel: { conceptArrangement: string | null; memberArrangement: string | null } artifact: { topic: string | null @@ -1232,6 +1238,7 @@ export type GetLedgerMappingQuery = { export type MappingCandidatesQueryVariables = Exact<{ classification: string + entityId: string | null | undefined }> export type MappingCandidatesQuery = { @@ -1255,7 +1262,9 @@ export type GetLedgerMappingCoverageQuery = { } | null } -export type ListLedgerMappingsQueryVariables = Exact<{ [key: string]: never }> +export type ListLedgerMappingsQueryVariables = Exact<{ + entityId: string | null | undefined +}> export type ListLedgerMappingsQuery = { mappings: { @@ -1267,6 +1276,7 @@ export type ListLedgerMappingsQuery = { taxonomyId: string isActive: boolean framework: string | null + entityId: string | null }> } | null } @@ -4162,6 +4172,11 @@ export const GetInformationBlockDocument = { }, defaultValue: { kind: 'BooleanValue', value: false }, }, + { + kind: 'VariableDefinition', + variable: { kind: 'Variable', name: { kind: 'Name', value: 'entityId' } }, + type: { kind: 'NamedType', name: { kind: 'Name', value: 'String' } }, + }, ], selectionSet: { kind: 'SelectionSet', @@ -4185,6 +4200,11 @@ export const GetInformationBlockDocument = { name: { kind: 'Name', value: 'series' }, value: { kind: 'Variable', name: { kind: 'Name', value: 'series' } }, }, + { + kind: 'Argument', + name: { kind: 'Name', value: 'entityId' }, + value: { kind: 'Variable', name: { kind: 'Name', value: 'entityId' } }, + }, ], selectionSet: { kind: 'SelectionSet', @@ -4196,6 +4216,7 @@ export const GetInformationBlockDocument = { { kind: 'Field', name: { kind: 'Name', value: 'category' } }, { kind: 'Field', name: { kind: 'Name', value: 'taxonomyId' } }, { kind: 'Field', name: { kind: 'Name', value: 'taxonomyName' } }, + { kind: 'Field', name: { kind: 'Name', value: 'entityId' } }, { kind: 'Field', name: { kind: 'Name', value: 'informationModel' }, @@ -4530,6 +4551,11 @@ export const GetInformationBlockWindowedDocument = { variable: { kind: 'Variable', name: { kind: 'Name', value: 'seriesForecast' } }, type: { kind: 'NamedType', name: { kind: 'Name', value: 'Int' } }, }, + { + kind: 'VariableDefinition', + variable: { kind: 'Variable', name: { kind: 'Name', value: 'entityId' } }, + type: { kind: 'NamedType', name: { kind: 'Name', value: 'String' } }, + }, ], selectionSet: { kind: 'SelectionSet', @@ -4563,6 +4589,11 @@ export const GetInformationBlockWindowedDocument = { name: { kind: 'Name', value: 'seriesForecast' }, value: { kind: 'Variable', name: { kind: 'Name', value: 'seriesForecast' } }, }, + { + kind: 'Argument', + name: { kind: 'Name', value: 'entityId' }, + value: { kind: 'Variable', name: { kind: 'Name', value: 'entityId' } }, + }, ], selectionSet: { kind: 'SelectionSet', @@ -4574,6 +4605,7 @@ export const GetInformationBlockWindowedDocument = { { kind: 'Field', name: { kind: 'Name', value: 'category' } }, { kind: 'Field', name: { kind: 'Name', value: 'taxonomyId' } }, { kind: 'Field', name: { kind: 'Name', value: 'taxonomyName' } }, + { kind: 'Field', name: { kind: 'Name', value: 'entityId' } }, { kind: 'Field', name: { kind: 'Name', value: 'informationModel' }, @@ -4904,6 +4936,11 @@ export const ListInformationBlocksDocument = { variable: { kind: 'Variable', name: { kind: 'Name', value: 'scenarioId' } }, type: { kind: 'NamedType', name: { kind: 'Name', value: 'String' } }, }, + { + kind: 'VariableDefinition', + variable: { kind: 'Variable', name: { kind: 'Name', value: 'entityId' } }, + type: { kind: 'NamedType', name: { kind: 'Name', value: 'String' } }, + }, ], selectionSet: { kind: 'SelectionSet', @@ -4937,6 +4974,11 @@ export const ListInformationBlocksDocument = { name: { kind: 'Name', value: 'scenarioId' }, value: { kind: 'Variable', name: { kind: 'Name', value: 'scenarioId' } }, }, + { + kind: 'Argument', + name: { kind: 'Name', value: 'entityId' }, + value: { kind: 'Variable', name: { kind: 'Name', value: 'entityId' } }, + }, ], selectionSet: { kind: 'SelectionSet', @@ -4948,6 +4990,7 @@ export const ListInformationBlocksDocument = { { kind: 'Field', name: { kind: 'Name', value: 'category' } }, { kind: 'Field', name: { kind: 'Name', value: 'taxonomyId' } }, { kind: 'Field', name: { kind: 'Name', value: 'taxonomyName' } }, + { kind: 'Field', name: { kind: 'Name', value: 'entityId' } }, { kind: 'Field', name: { kind: 'Name', value: 'informationModel' }, @@ -5590,6 +5633,11 @@ export const MappingCandidatesDocument = { type: { kind: 'NamedType', name: { kind: 'Name', value: 'String' } }, }, }, + { + kind: 'VariableDefinition', + variable: { kind: 'Variable', name: { kind: 'Name', value: 'entityId' } }, + type: { kind: 'NamedType', name: { kind: 'Name', value: 'String' } }, + }, ], selectionSet: { kind: 'SelectionSet', @@ -5603,6 +5651,11 @@ export const MappingCandidatesDocument = { name: { kind: 'Name', value: 'classification' }, value: { kind: 'Variable', name: { kind: 'Name', value: 'classification' } }, }, + { + kind: 'Argument', + name: { kind: 'Name', value: 'entityId' }, + value: { kind: 'Variable', name: { kind: 'Name', value: 'entityId' } }, + }, ], selectionSet: { kind: 'SelectionSet', @@ -5675,12 +5728,26 @@ export const ListLedgerMappingsDocument = { kind: 'OperationDefinition', operation: 'query', name: { kind: 'Name', value: 'ListLedgerMappings' }, + variableDefinitions: [ + { + kind: 'VariableDefinition', + variable: { kind: 'Variable', name: { kind: 'Name', value: 'entityId' } }, + type: { kind: 'NamedType', name: { kind: 'Name', value: 'String' } }, + }, + ], selectionSet: { kind: 'SelectionSet', selections: [ { kind: 'Field', name: { kind: 'Name', value: 'mappings' }, + arguments: [ + { + kind: 'Argument', + name: { kind: 'Name', value: 'entityId' }, + value: { kind: 'Variable', name: { kind: 'Name', value: 'entityId' } }, + }, + ], selectionSet: { kind: 'SelectionSet', selections: [ @@ -5697,6 +5764,7 @@ export const ListLedgerMappingsDocument = { { kind: 'Field', name: { kind: 'Name', value: 'taxonomyId' } }, { kind: 'Field', name: { kind: 'Name', value: 'isActive' } }, { kind: 'Field', name: { kind: 'Name', value: 'framework' } }, + { kind: 'Field', name: { kind: 'Name', value: 'entityId' } }, ], }, }, diff --git a/clients/graphql/queries/ledger/informationBlock.ts b/clients/graphql/queries/ledger/informationBlock.ts index 7438b7d..f55528b 100644 --- a/clients/graphql/queries/ledger/informationBlock.ts +++ b/clients/graphql/queries/ledger/informationBlock.ts @@ -8,8 +8,13 @@ import { gql } from 'graphql-request' * branch. See `local/docs/specs/information-block.md` §2. */ export const GET_INFORMATION_BLOCK = gql` - query GetInformationBlock($id: ID!, $scenarioId: String, $series: Boolean! = false) { - informationBlock(id: $id, scenarioId: $scenarioId, series: $series) { + query GetInformationBlock( + $id: ID! + $scenarioId: String + $series: Boolean! = false + $entityId: String + ) { + informationBlock(id: $id, scenarioId: $scenarioId, series: $series, entityId: $entityId) { id blockType name @@ -17,6 +22,7 @@ export const GET_INFORMATION_BLOCK = gql` category taxonomyId taxonomyName + entityId informationModel { conceptArrangement memberArrangement @@ -179,6 +185,7 @@ export const GET_INFORMATION_BLOCK_WINDOWED = gql` $series: Boolean! = false $seriesHistory: Int $seriesForecast: Int + $entityId: String ) { informationBlock( id: $id @@ -186,6 +193,7 @@ export const GET_INFORMATION_BLOCK_WINDOWED = gql` series: $series seriesHistory: $seriesHistory seriesForecast: $seriesForecast + entityId: $entityId ) { id blockType @@ -194,6 +202,7 @@ export const GET_INFORMATION_BLOCK_WINDOWED = gql` category taxonomyId taxonomyName + entityId informationModel { conceptArrangement memberArrangement @@ -351,6 +360,7 @@ export const LIST_INFORMATION_BLOCKS = gql` $limit: Int $offset: Int $scenarioId: String + $entityId: String ) { informationBlocks( blockType: $blockType @@ -358,6 +368,7 @@ export const LIST_INFORMATION_BLOCKS = gql` limit: $limit offset: $offset scenarioId: $scenarioId + entityId: $entityId ) { id blockType @@ -366,6 +377,7 @@ export const LIST_INFORMATION_BLOCKS = gql` category taxonomyId taxonomyName + entityId informationModel { conceptArrangement memberArrangement diff --git a/clients/graphql/queries/ledger/mappingCandidates.ts b/clients/graphql/queries/ledger/mappingCandidates.ts index f290859..04201c2 100644 --- a/clients/graphql/queries/ledger/mappingCandidates.ts +++ b/clients/graphql/queries/ledger/mappingCandidates.ts @@ -2,14 +2,15 @@ import { gql } from 'graphql-request' /** * rs-gaap concepts a CoA element of a given EFS classification may map to, - * limited to concepts that render under the graph's active Reporting Style - * (statement-level subtotals excluded). This is the candidate set the mapping + * limited to concepts that render under the Reporting Style of the entity whose + * chart is being mapped (`$entityId`, default the group parent; statement-level + * subtotals excluded). This is the candidate set the mapping * picker should offer — mapping to anything outside it would land a fact on an * unreachable branch that never renders. */ export const MAPPING_CANDIDATES = gql` - query MappingCandidates($classification: String!) { - mappingCandidates(classification: $classification) { + query MappingCandidates($classification: String!, $entityId: String) { + mappingCandidates(classification: $classification, entityId: $entityId) { id name qname diff --git a/clients/graphql/queries/ledger/mappings.ts b/clients/graphql/queries/ledger/mappings.ts index 5d14761..0470427 100644 --- a/clients/graphql/queries/ledger/mappings.ts +++ b/clients/graphql/queries/ledger/mappings.ts @@ -5,10 +5,12 @@ import { gql } from 'graphql-request' * StructureList (same wire shape as `structures`, just filtered server-side * to `block_type = 'coa_mapping'`). `framework` is the reporting framework * each maps the chart into; a chart holds one mapping per framework. + * `entityId` is the entity whose chart it maps from, and `$entityId` + * keeps one entity's mappings. */ export const LIST_MAPPINGS = gql` - query ListLedgerMappings { - mappings { + query ListLedgerMappings($entityId: String) { + mappings(entityId: $entityId) { structures { id name @@ -17,6 +19,7 @@ export const LIST_MAPPINGS = gql` taxonomyId isActive framework + entityId } } } diff --git a/sdk/types.gen.ts b/sdk/types.gen.ts index c64add9..91206bc 100644 --- a/sdk/types.gen.ts +++ b/sdk/types.gen.ts @@ -273,7 +273,7 @@ export type AssertMetricsRequest = { /** * Entity Id * - * Entity to assert for. Defaults to the graph's earliest-created entity (the primary entity for single-entity graphs). + * The entity the asserted values belong to, by id. Omit for the group parent. */ entity_id?: string | null; /** @@ -1172,7 +1172,7 @@ export type BindTextBlockRequest = { /** * Entity Id * - * Entity the fact belongs to; defaults to the primary entity. + * Entity the fact belongs to, by id; omit for the group parent. */ entity_id?: string | null; }; @@ -1404,7 +1404,7 @@ export type ChangeReportingStyleRequest = { /** * Entity Id * - * Target entity. Omit to target the graph's primary (earliest-created) entity — the single-entity default. + * The entity whose style to change, by id. Omit for the group parent. */ entity_id?: string | null; }; @@ -1965,7 +1965,7 @@ export type ComputeMetricsRequest = { /** * Entity Id * - * Entity to compute for. Defaults to the graph's earliest-created entity (the primary entity for single-entity graphs). + * The entity whose metrics to compute, by id. Omit for the group parent. */ entity_id?: string | null; /** @@ -2985,7 +2985,7 @@ export type CreateForecastRequest = { /** * Entity Id * - * Entity the scenario belongs to. Defaults to the graph's earliest-created entity (single-entity convention). + * The entity the scenario belongs to, by id: its history and its computed months are that entity's books. Omit for the group parent. */ entity_id?: string | null; }; @@ -3324,6 +3324,12 @@ export type CreateScheduleRequest = { * Schedule name */ name: string; + /** + * Entity Id + * + * The entity whose books the schedule belongs to, by id. Omit for the group parent. Its facts, obligations and closing entries land in that entity's books, against that entity's own accounts. + */ + entity_id?: string | null; /** * Taxonomy Id * @@ -7722,6 +7728,12 @@ export type InformationBlockEnvelope = { * Qname of the named Disclosure this block corresponds to (e.g., 'disclosures:BalanceSheet'), when an inbound reportedDisclosure-requiresDisclosure arc identifies one. Null for tenant-authored blocks without a Disclosure mapping. */ disclosure_id?: string | null; + /** + * Entity Id + * + * The entity whose books the envelope reads. A schedule, reconciliation or forecast is one entity's own and always reads its owner's; a block shared by the group (statements, metrics) reads the entity asked for, else the group parent. Null on the library and on a graph with no entity yet. + */ + entity_id?: string | null; information_model: InformationModelResponse; artifact: ArtifactResponse; /**