Skip to content

JSON API over the existing reports, with server-side sort and /api/config #534

Description

@eaitbrahim

Spec: docs/superpowers/specs/2026-08-23-web-ui-rewrite-design.md § Server, § The data contract.

Depends on #533 (the serialisation contract).

What ships

GET /api/* endpoints covering the data behind the eight routes keel/web/server.py serves today — /, /setup, /activity, /insights, /rules, /venues, /gates, /glossary(*) — using #533's serialiser.

(*) /glossary has no API counterpart. It becomes an outbound link (#539) and its renderer is deleted.

The API is a further consumer of the same frozen report dataclasses the console already builds. It never computes.

Server-side sort

Tables sort by query parameter; Python orders with Decimal. Sub-millisecond on loopback, zero client arithmetic to audit.

GET /api/config

Exposes the running version. Consumed by:

Engine-not-running is a first-class state

The payload carries "engine": "running" | "stopped" and an as_of timestamp. The client must be able to say "keel isn't running" rather than render an empty view or, worse, a stale figure. This is the same requirement the service worker enforces from the other side.

Writes stay exactly as gated as they are

POST continues to route only through keel.commands.setup.ACTIONS, and the existing test asserting that set is disjoint from the eleven capability-increasing actions in keel/capabilities.py must keep passing unchanged. Nothing in this issue widens what the browser may do.

Acceptance

  • Every read the current HTML routes perform is available as JSON.
  • All monetary fields are strings; The serialisation contract: money as strings, values presentation-ready #533's test covers the new endpoints.
  • Sorting is a query parameter, ordered with Decimal, with a test on a case where float ordering would differ.
  • GET /api/config returns the running version.
  • A stopped engine produces a payload that says so, not an empty one.
  • The ACTIONS-disjointness test is untouched and green.
  • test_console_thinness.py pins the API layer.

Metadata

Metadata

Assignees

Labels

featureNew capability (groups under Features)

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions