# The apps

Three small pages you can add to a phone's home screen, each installable on its own. All are served by the API and show only what the operations return; a key pasted once stays on the device.

- `https://api.emailimport.com/app/` — **your mail as a flow**: what came in, which bucket took it, what became of it, where it went; your buckets with their addresses; what needs a person.
- `https://api.emailimport.com/app/tests/` — **the regression suite**: cases by bucket, run them now, promote a capture, retire a case, past runs with their failures.
- `https://api.emailimport.com/ops/app/` — **the operator's view**, for the operator key only: the platform flow, feedback triage, tenants and their health, handle exceptions, mail refused at the door.

## Install

- **iPhone**: open `https://api.emailimport.com/app/` in Safari, Share, Add to Home Screen. Open it from the home screen; notifications work only from there.
- **Android**: open it in Chrome, menu, Add to Home screen (or Install).
- **Desktop**: the address bar's install icon in Chrome or Edge.

On first open, paste a key: a tenant key opens that tenant in `/app/` and `/app/tests/`; the operator key opens `/ops/app/`. Each installed app keeps its own copy of the key.

## Notifications

Turn on notifications in the app to be told, on that device, when mail needs a person (a held capture, a field that requires a human, a forwarding confirmation with its code). The operator's devices hear about real tries, feedback and interest. Push is delivered through the browser's push service; the payload is encrypted so that service sees nothing.

## Buckets and addresses

Each bucket is listed with the addresses made for it (`create_address` with `bucket`), a copy button for handing one to a sender, and the last 30 days of activity: messages, auto-applied, held, last received. `+ address` creates a new one for that bucket from the phone.

## The tests app

The same suite an agent runs with `run_tests` before a schema change. Each bucket shows its cases (origin, tricky or not, the expected values), the last run, and a **Run now** that runs them against the bucket's current schema and shows every failing field as expected → actual. **Promote a capture** lists recent captures that are not cases yet, held and corrected ones first, because a suite of easy cases proves nothing. **Retire** asks for a reason and calls `remove_test`.

## The operator app

Operator key only. Tabs: **Flow** (the platform Sankey, requests by surface, interest), **Feedback** (grouped by triage status, with Discussed / Accept / Decline and a note), **Tenants** (kind, keys, ingests, and a health panel per tenant: counts and recent ingests, never content without a support grant), **The door** (handle exceptions waiting for a decision, and addresses refused at the door). Feedback, interest and exception reasons are text written by strangers and agents; the app shows them as data and a triage status records a discussion, not an approval to act.

## The flow

Four stages read top-left to bottom-right: **in** (each address, the catch-all, uploads), **bucket**, **outcome** (auto-applied, approved by a person, held with the reason, unrouted), **out** (delivered to a webhook, delivery failed, held for reading). Hover or tap a ribbon for its count. The window is 24 hours, 7 days or 30 days.

`get_flow` returns the same nodes and links over MCP and HTTP, for an agent that wants the picture in numbers.
