/**
* Analytical Table — input and output schemas (Std 2 + Std 11).
*
* Input: Pillar 1 Resolution's payload (resolved records).
* Output: AnalyticalTable — entities × metrics × periods with
* cell-level lineage back to Pillar 1.
*/
import { z } from 'zod';
import { resolvedRecordSchema } from '../../baseline/resolution/schema.js';
export const analyticalTableInputSchema = z.object({
records: z.array(resolvedRecordSchema),
});
export type AnalyticalTableInput = z.infer<typeof analyticalTableInputSchema>;
/** A single cell in the analytical table — one (entity, metric, period). */
export const analyticalCellSchema = z.object({
entity: z.string(),
metric: z.string(),
period: z.string(),
value: z.number().nullable(),
unit: z.string(),
/** Why this cell ended up as it did — e.g. "unit:identity:USD", "period:fy=2024 fp=FY". */
derivations: z.array(z.string()),
/** Lineage back to one or more Pillar 1 source URLs. */
sourceLineage: z.array(z.string()),
/** Per-cell confidence inherited from the upstream record. */
confidence: z.number().min(0).max(1),
/** Any conditions noted on this cell (missing, mixed-unit, etc.). */
flags: z.array(z.string()),
});
export type AnalyticalCell = z.infer<typeof analyticalCellSchema>;
export const analyticalTableOutputSchema = z.object({
entities: z.array(z.string()),
metrics: z.array(z.string()),
periods: z.array(z.string()),
cells: z.array(analyticalCellSchema),
/** Missing-cell notes — entities × metrics × periods that produced no record. */
missingCells: z.array(
z.object({
entity: z.string(),
metric: z.string(),
period: z.string(),
reason: z.string(),
}),
),
/** Methodology IDs the agent invoked while building the table. */
appliedMethodologies: z.array(z.string()),
/** Free-form notes from the agent (e.g. mixed units flagged for downstream). */
notes: z.array(z.string()),
});
export type AnalyticalTableOutput = z.infer<typeof analyticalTableOutputSchema>;