Intent: a harness that reads OpenAPI can run an app on the forge without a hand-written wrapper. Today src/contract/openapi.ts describes only /app/production/open among the app routes.
Done:
[ ] the Route method type gains "put"
[ ] rows for GET/POST/PATCH/DELETE {REPO}/app, GET/PUT {REPO}/app/members, GET/POST {REPO}/app/domains, DELETE {REPO}/app/domains/{host}, POST {REPO}/app/domains/{host}/check, GET {REPO}/app/env, PUT/DELETE {REPO}/app/env/{var}, and POST {REPO}/app/{env}/redeploy and /stop, placed right after the existing {REPO}/app/production/open row
[ ] the env rows say that a value is written and never read back
Each row says what the route answers (its shape in the summary), whether it needs a token (auth), its body fields, query and refusals, as the existing rows do. test/openapi.test.ts must still pass (every described route is registered). Add a test asserting each new path and method is in the served document. Another issue adds rows in parallel, so put these exactly where named.
Intent: a harness that reads OpenAPI can run an app on the forge without a hand-written wrapper. Today src/contract/openapi.ts describes only
/app/production/openamong the app routes.Done:
Routemethod type gains"put"{REPO}/app, GET/PUT{REPO}/app/members, GET/POST{REPO}/app/domains, DELETE{REPO}/app/domains/{host}, POST{REPO}/app/domains/{host}/check, GET{REPO}/app/env, PUT/DELETE{REPO}/app/env/{var}, and POST{REPO}/app/{env}/redeployand/stop, placed right after the existing{REPO}/app/production/openrowEach row says what the route answers (its shape in the summary), whether it needs a token (
auth), its body fields, query and refusals, as the existing rows do.test/openapi.test.tsmust still pass (every described route is registered). Add a test asserting each new path and method is in the served document. Another issue adds rows in parallel, so put these exactly where named.