# Context — EzyOrder

## Origin

A customer needed a simple — or very specific — web portal to **enter orders** and **receipt
notices** (advance notices of incoming goods) without touching the systems behind EzyFlow.
EzyOrder is that portal.

## What EzyOrder is

A web application scaffolded from the **EzyFlow web app template**
(`github.com/Ezytail/ezyflow-webapp-template`) with:

```sh
npx @ezytail/create-ezyflow-app ezyorder --activity <ACTIVITY> --env recette --add-ons webhooks,i18n -y
```

It talks to the **EzyFlow Integrator API** as one machine identity (an *API client*), for exactly
one *activity*. Three things pass between EzyOrder and EzyFlow:

1. EzyOrder **pushes** canonical events (an order was created, a procurement was created…).
2. EzyOrder **reads projections** back (lists, details, timelines of orders and procurements).
3. EzyOrder **receives deliveries** — signed HTTPS POSTs the platform makes for one event.

It ships as a Docker image with a `docker-compose.yml` (Postgres + mock OIDC for local runs) and,
optionally, a Helm chart.

## Who uses it

| Person | App role | Can |
| --- | --- | --- |
| Customer operator who reads | **viewer** | browse orders, receipt notices, timelines, deliveries |
| Customer operator who enters data | **admin** | everything a viewer can, plus push orders / receipt notices, replay deliveries |
| Integrator developer | — | builds and maintains EzyOrder, often with an AI assistant |

Roles come from one claim of the identity provider: `OIDC_ADMIN_GROUP`, `OIDC_VIEWER_GROUP`.

## Scope

In scope:

- Order entry form → `order.created` (rehearse, then push).
- Receipt notice entry form → `procurement.created` (rehearse, then push).
- Order list / detail, procurement list / detail, with timelines (projection reads).
- Delivery feed and deliveries screen (webhooks add-on).
- FR and EN UI; source code and docs in English.

Non-goals (until decided otherwise in `decisions.md`):

- No second activity per deployment — one App serves exactly one activity.
- No reimplementation of anything the SDK or Runtime already does (token cache, HMAC, inbox).
- No own copy of EzyFlow data as a source of truth — the API's projections are the truth; local
  Postgres holds the Runtime's inbox, login tables and EzyOrder-only data (drafts, preferences).
- No creation of API clients or webhook registrations — those are made in the EzyFlow portal.

## Open questions

Keep this list current; delete an item when it is decided and record the decision in `decisions.md`.

- [ ] Is `procurement.created` the right event for the customer's "receipt notice", or should
      the flow end with `receipt.confirmed`? Confirm with the activity's event catalog.
- [ ] Which order fields does the customer actually need on the form (lines, pickup point,
      channel)? The activity's composed schema may require more than the canonical one.
- [ ] Multi-line entry: free lines, or SKU picker backed by `listProductVariant`?
- [ ] Draft saving before push — needed, or push-only?
