Context (verified)
The orders table already records a per-order honesty ledger no broker dashboard publishes (keel/data/db.py): status, fee, expected_fill, actual_fill, filled_quantity, raw_response, confirmation, rule_id, mode. There is no /api/orders endpoint and no Orders view — the data exists, the surface doesn't.
Alpaca's Orders page (status tabs: All/Open/Filled/Canceled/Expired/Rejected) is the one pattern worth taking. Keel's version shows what Alpaca hides: execution drag per order.
Scope
GET /api/orders — read-only, following the standing wire contract exactly:
- Money through the
Field machinery ({"value", "display", "state"}; keel/web/payload.py Rule 1 — the guard test fails on any JSON number). No integer-cents companions; that was deliberately rejected in the Web UI Rewrite design (integer sorting is server-side via Decimal re-parse in payload.order_rows).
?sort=/?dir= server-side on declared columns; unknown column → 400 naming valid columns (existing api.py behaviour).
- Orders view (Portfolio section) — status tabs mirroring the statuses keel actually records, columns:
- time submitted / product / side / kind / qty
- expected fill vs actual fill side by side
- fee as actually charged (not estimated)
- quote provenance: BROKER QUOTE / SYNTHETIC ESTIMATE / UNPRICED / UNREADABLE — the same banners the CLI confirm gate renders (
keel/commands/confirm.py)
- idempotency
client_order_id, and the rule that placed it
- Detail disclosure per row (
<details> pattern as in Activity) exposing the raw exchange response.
Explicitly out of scope
- No cancel action here. Cancellation is the cancel-asymmetry issue (typed friction for exits, entry-side web action only, its own security pass). This issue is purely read.
Acceptance
- Payload guard test green; every monetary field a
Field; sorting numeric server-side.
- Status tabs filter server-side; empty states honest ("no orders recorded yet" — the engine may simply be fresh).
- No POST route exists on this endpoint.
Depends on the payload/nav patterns from #698 (Sprint 1, second).
Context (verified)
The
orderstable already records a per-order honesty ledger no broker dashboard publishes (keel/data/db.py):status,fee,expected_fill,actual_fill,filled_quantity,raw_response,confirmation,rule_id,mode. There is no/api/ordersendpoint and no Orders view — the data exists, the surface doesn't.Alpaca's Orders page (status tabs: All/Open/Filled/Canceled/Expired/Rejected) is the one pattern worth taking. Keel's version shows what Alpaca hides: execution drag per order.
Scope
GET /api/orders— read-only, following the standing wire contract exactly:Fieldmachinery ({"value", "display", "state"};keel/web/payload.pyRule 1 — the guard test fails on any JSON number). No integer-cents companions; that was deliberately rejected in the Web UI Rewrite design (integer sorting is server-side viaDecimalre-parse inpayload.order_rows).?sort=/?dir=server-side on declared columns; unknown column → 400 naming valid columns (existingapi.pybehaviour).keel/commands/confirm.py)client_order_id, and the rule that placed it<details>pattern as in Activity) exposing the raw exchange response.Explicitly out of scope
Acceptance
Field; sorting numeric server-side.Depends on the payload/nav patterns from #698 (Sprint 1, second).