This recipe derives read models from an owned system of record without making
an index or warehouse authoritative for order mutations. The .one syntax is
illustrative end-product syntax.
Declare projection obligations
projection OrderSearch@1
source parcelhub.orders#OrderPlaced@1
source parcelhub.orders#OrderCancelled@1
key OrderId
fields [customer_id, order_id, status, searchable_text]
freshness maximum 5s
rebuild from retained_events
deletion propagate_customer_erasure
projection OrderAnalytics@1
source parcelhub.orders#OrderFact@1
grain one_order_transition
partition day
freshness maximum 15m
retention 7y
Keep semantic and physical models separate
Orders state -> authoritative mutation and exact current value
event log -> retained transition input with causal references
search index -> lossy query projection, rebuildable
warehouse -> analytical projection, delayed by contract
vector index -> similarity projection with declared model and quality evidenceQuery with freshness evidence
let result = search.orders(query).await?;
if result.freshness.age() > requirements.maximum_age {
return ResourceState::Stale(result);
}
ResourceState::Ready(result)
Provider qualification proves declared recall/precision or consistency bounds, not the marketing label “search”, “warehouse”, or “vector database”.