# Build a data-backed service

This recipe adds transactional order state without putting a database product,
table layout, or connection string into the service contract.

The `.one` and Rust APIs below are illustrative end-product syntax.

## 1. Declare state obligations

```one
one 1

semantic parcelhub.order_state
    domain one.data@1
    state Orders@1
        key (CustomerId, OrderId)
        value Order

        consistency read_your_writes
        transaction atomic_per_key
        durability acknowledged
        retention 7y
        encryption at_rest
        tenancy customer_id
        erasure by_customer
```

This declaration owns what callers may rely on. It does not mention
PostgreSQL, SQLite, DynamoDB, a table name, an index, or a region.

## 2. Declare the write effect

```one
semantic parcelhub.orders
    domain one.contracts@1
    struct PlaceOrder@1
        customer_id: CustomerId
        order_id: OrderId
        items: List<OrderItem>(1..=100)
        idempotency_key: IdempotencyKey

    operation Place@1
        input PlaceOrder
        output Order
        faults [DuplicateOrder, InvalidOrder]
        effect create(order)
        idempotency caller_key(input.idempotency_key)
        outcome query Orders.Get
        authority customer_order:place
```

The idempotency and outcome-query contracts make retry and reconciliation
behavior explicit. They do not grant a caller permission to place an order.

## 3. Use a capability, not a database handle

```rust,ignore
pub async fn place(ctx: Place, input: PlaceOrder)
    -> Result<Order, PlaceOrderFault>
{
    let order = Order::construct(input)?;

    ctx.orders()
        .insert_if_absent(
            (order.customer_id, order.id),
            &order,
            input.idempotency_key,
        )
        .await?;

    Ok(order)
}
```

The generated `orders()` capability exposes only the selected state contract.
The implementation cannot issue arbitrary SQL, enumerate other tenants, or
open a second connection unless another exact capability is declared.

## 4. Let Planning select the realization

```console
one plan --root OrdersApi
```

An eligible local plan may select an embedded transactional store. A production
plan may select a managed relational provider. Each candidate must prove the
declared consistency, transaction, durability, encryption, tenancy, retention,
erasure, observation, and recovery requirements.

Installing either provider does nothing by itself. The accepted P-IR names one
exact realization and configuration revision for this root.

## 5. Test the owned behavior

```rust,ignore
#[one::test(root = claims::OrdersApi)]
async fn duplicate_delivery_is_idempotent(app: TestApp) {
    let request = fixtures::place_order("order-7391", "attempt-7");

    let first = app.orders().place(request.clone()).await.unwrap();
    let second = app.orders().place(request).await.unwrap();

    assert_eq!(first.id, second.id);
    app.state().assert_single_order(first.id).await;
}
```

Run the same contract suite against every claimed state provider. Add
provider-specific tests only for behavior unique to that realization.

## Executable evidence

ParcelHub's
[current Contracts source](https://github.com/muijf/one/blob/main/systems/system-idl/examples/parcelhub/one/contracts.one)
uses `struct` declarations and attaches bounded `one.data#KeyValue@1` lanes
directly to Get, Place, and Cancel. Its
[reactive Orders test](https://github.com/muijf/one/blob/main/systems/system-idl/examples/parcelhub/tests/reactive_orders.rs)
proves SQLite-backed exact-key reads, cache reuse, unrelated-key suppression,
updates, bounded replay, and explicit resnapshot:

```console
cargo test -p parcelhub --all-targets
```

See [data and state](/one/model/data) and
[data-intensive systems](/one/guides/data-systems).
