> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.cessy.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.cessy.ai/_mcp/server.

# DomainConfig

> Learn how DomainConfig drives commands, events, projections, policies, permissions, agents, triggers, adapters, and pages.

DomainConfig is the app model. It is the contract the Builder UI edits, the Design MCP inspects, and the runtime materializes after publish.

## Draft and published config

| State     | Meaning                                                                                      |
| --------- | -------------------------------------------------------------------------------------------- |
| Draft     | Design-time state under active work. It can live in the main draft or an isolated workspace. |
| Changeset | A reviewable set of workspace changes with validation results.                               |
| Published | The model currently used by runtime APIs, agents, webhooks, subscriptions, and pages.        |

Keep draft exploration separate from published runtime behavior. Publish only after validation and a concrete smoke test plan.

## Commands

Commands are business requests. They should read like a user or system asking the app to decide something:

* `PlaceOrder`
* `ApproveInvoice`
* `AssignCaseOwner`

A command schema defines the input fields and refined types. At runtime, Cessy validates current state and records events when the decision succeeds. Keep orchestration, dedupe, lookup-before-create, and cross-app coordination explicit in the surrounding workflow.

## Events

Events are durable facts. They should use past-tense names and carry the data needed by projections, policies, audit, and future decisions:

* `OrderPlaced`
* `InvoiceApproved`
* `CaseOwnerAssigned`

Events are append-only business history. If a later workflow needs different read data, add or rebuild projections instead of editing historical facts.

## Projections

Projections answer runtime questions. Model them around actual user and integration needs:

* list current orders
* show open cases by priority
* export billing activity for one account

Projection query behavior is documented in [Projection Queries](/build-a-backend/projection-queries).

When projection mapping targets can legitimately be absent, declare those target names in the event mapping's `optionalFields`. Cessy still writes the evaluated `null` or `undefined` value, but does not raise a `projection_null_value` warning for those explicitly optional targets.

For read models where one event should create or update multiple documents, use projection fan-out with an `upsertMany` event mapping. The mapping evaluates an `itemsExpression`, derives each document id from the current `item`, and applies create/update mappings per item during normal processing and projection rebuilds. Fan-out items must be objects; map primitive arrays first, for example `event.monthOffsets|map('offset', { offset: offset })`.

Workspace ChangeSet validation also checks each projection's live collection and rebuild shadow against the canonical runtime ownership catalog. An ownership-conflict diagnostic identifies both owners. Create a fresh Workspace from the latest published graph and reapply the changes; if the conflict persists, ask an operator to reconcile the catalog instead of retrying preview or rebuild.

## Policies

Policies react to events. Use them for automation, external side effects, command dispatch, agent wakeups, adapter calls, and webhook-driven workflows.

Keep policy intent explicit. If the automation is business-critical, make the triggering event and resulting command visible in the model.

## Permissions

Permissions define who can execute commands and read projections. Model roles and attributes in the app instead of hiding checks in custom frontend code.

See [Permissions](/build-a-backend/permissions) for the runtime implications.

## Agents and pages

Agents and custom pages are not separate products bolted onto the app. They should use the generated runtime surfaces and stay aligned with DomainConfig:

* Runtime MCP exposes command and projection tools to app agents.
* Custom pages call runtime commands and projections.
* Design MCP helps builder agents inspect and change the design model.