Skip to content

[web] Orders view: the per-order honesty record — expected vs actual fill, fee as paid, provenance #700

Description

@eaitbrahim

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

  1. 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).
  2. 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
  3. 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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

featureNew capability (groups under Features)toolingDev/release tooling (Docs, CI & tooling)

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions