View contracts
Publish versioned replayable logical shapes without prescribing a physical read store, GraphQL resolver, or SDUI runtime.
A ViewContract makes a projection's identity and portable output contract first-class:
const summaryView = {
name: "orders/summary",
version: "1",
shape: {
type: "object",
required: ["openCount"],
properties: { openCount: { type: "integer" } },
},
parameterSchema: {
type: "object",
required: ["region"],
properties: { region: { type: "string", minLength: 1 } },
additionalProperties: false,
},
consumes: [{ eventType: "OrderSubmitted", schemaVersions: [1, 2] }],
scope: "tenant-space",
snapshotVersion: 2,
compatibleSnapshotVersions: [1],
upgradeSnapshot: (data, fromVersion) => ({ openCount: readLegacyCount(data, fromVersion) }),
initialState: { openCount: 0 },
applyEvent: (state, event) => ({ /* deterministic fold */ }),
} satisfies ViewContract;replayView applies only declared event types and schema versions, preserves tenant/space replay
scoping, upgrades declared-compatible snapshots through the required upgradeSnapshot function,
and rejects incompatible versions or old snapshots without an upgrader.
parameterSchema is optional. When present, ProjectionHost requires query parameters, validates
them with the portable JSON Schema profile, and includes their canonical SHA-256 identity in the
snapshot key. It also supplies the validated parameters to authorization and event-source adapters.
Parameter values themselves are not persisted in snapshots or query audit records.
The manifest serializes identity, version, shape, event-version consumption, scope, and snapshot
metadata. It never serializes initialState, applyEvent, or upgradeSnapshot. Database tables, hydration workers,
GraphQL resolvers, and SDUI bindings belong to generator or Host adapters.