Skip to content

docs(fr-044): Plan 3 — generated read routes, typed rows and docs pages for reports - #400

Merged
dmealing merged 1 commit into
mainfrom
fm/fr044-plan3-write
Oct 4, 2026
Merged

dmealing merged 1 commit into
mainfrom
fm/fr044-plan3-write

Conversation

@dmealing

@dmealing dmealing commented Oct 4, 2026

Copy link
Copy Markdown
Member

What this is

The implementation plan for FR-044 Plan 3, the plan after Plan 2 (report view lowering and reads in every port, #399). One file, no code:

docs/superpowers/plans/2026-10-04-fr-044-plan-3-report-read-routes.md

What Plan 3 covers

  • A generated list route for every view-backed object.report, in five ports: GET with filter, sort and paging on the derived fields, 405 on POST, no /{id} route.
  • A new api-contract report/ sub-corpus (model, seed, twelve scenarios, given in full), run on the generated lane of every port.
  • The TypeScript, Java and Python generators stop skipping reports. C# and Kotlin already generate a report's typed row.
  • Model and API pages for reports in meta docs.

The approach: a report is served the way a keyless read-only projection is served today. Each port hands the read model it already has (Plan 2) to its existing read-only generators. The lowering is not edited.

How it was verified

  • Every cited path, function and test file was read in the tree at e2456aa23. What could not be confirmed is marked UNVERIFIED and listed in one section.
  • The corpus model was loaded with the real TypeScript loader. Its three views, and every query behind an expected row, were run on PostgreSQL 16.15.
  • Two throwaway spikes (reverted) fed the read model through every TypeScript and Python generator. What they emitted, and what broke, is what the tasks are written from.
  • Not executed: the HTTP bodies. No port serves a report yet, so they are the SQL rows written in the documented wire encodings.

Found while verifying

These are folded into the tasks and raised as open questions, because each reaches beyond reports:

  • TypeScript and Python mount /{id} routes for a keyless projection, against the documented contract. C#, Java and Kotlin follow it.
  • TypeScript types a decimal in a view read schema as number, while the value is a string.
  • A report declares no fields, so its derived fields carry no @filterable and the allowlists come out empty unless the read model marks them.

Open questions for the maintainer

Seven, at the end of the plan, each with the plan's assumed default: what may be filtered and sorted, the route segment, the /{id} answer, keyless projections in TypeScript and Python, decimals, the typed client, and two small asymmetries.

Not in this plan

Plan 4 (Cube exporter), Plan 5 (reporting library), #395, #222, #8, #393.

…es for reports

The implementation plan after Plan 2 (report view lowering and reads in
every port). It covers a generated list route for a view-backed
object.report in five ports, the api-contract report/ sub-corpus, the
TypeScript, Java and Python generators no longer skipping reports, and
model and API pages for reports in meta docs.

A report is served as a keyless read-only projection is served today:
each port hands the read model it already has to its existing read-only
generators. The contract is stated as tables the ports copy: which
reports are served, the REST surface, what may be filtered and sorted,
the wire encoding of each derived subtype, what each port generates, the
corpus (model, seed, twelve scenarios in full) and the docs pages.

The corpus model was loaded with the real loader and its three views and
every query behind an expected row were run on Postgres 16. Two
throwaway spikes fed the read model through every TypeScript and Python
generator, and what they emitted and what broke is what the tasks are
written from. HTTP bodies were not executed: no port serves a report
yet. Cited paths and names were read in the tree; what could not be
confirmed is marked UNVERIFIED and listed. Seven questions for the
maintainer are at the end.

Found while verifying, and folded into the tasks: TypeScript and Python
mount item routes for a keyless projection against the documented
contract, and TypeScript types a decimal in a view read schema as a
number while the value is a string.
@dmealing
dmealing merged commit b5d4d59 into main Oct 4, 2026
1 check passed
@dmealing
dmealing deleted the fm/fr044-plan3-write branch October 4, 2026 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant