Skip to content

api(loop): /v1/loop/request-apr-transfer publishes a 200 it never returns #9711

Description

@JSONbored

⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.

Context

POST /v1/loop/request-apr-transfer (src/api/routes.ts:4004-4013) has exactly four exits: a 400 for a failed parse; 409 when result.status === "rejected"; 502 when result.status === "failed"; and 202 otherwise.

The route's own comment (:3999-4003) states the design: "Rejected gate -> 409 without touching GitHub; initiation is still pending-acceptance (202), never 'transfer done'."

Its spec entry (src/openapi/internal-and-public-route-specs.ts:326-334) declares 200: "Transfer requested", 400, 401. So the published contract advertises the one status the handler can never return, labels it with the semantics the comment explicitly rejects ("never 'transfer done'"), and omits all three statuses the handler actually produces on the non-400 paths. A generated client checking response.status === 200 treats every real outcome — including a hard 502 — as a non-success it cannot classify.

Requirements

  • Replace the 200 in the requestAprTransfer spec entry with 202, described as the pending-acceptance initiation the handler returns.
  • Add 409 (the transfer gate rejected the request; GitHub was not touched) and 502 (the transfer attempt failed downstream).
  • Keep 400 and 401.
  • Do not change the handler's statuses.
  • Regenerate and commit apps/loopover-ui/public/openapi.json.

⚠️ Required pattern: mirror the description style of the neighbouring MISC_ROUTES entries in src/openapi/internal-and-public-route-specs.ts:268-344, which name the concrete outcome per status ("Batch accepted", "Notification queued"). It does NOT satisfy this issue to keep 200 alongside 202; to change the handler to return 200 (202/409/502 are the shipped, deliberately-chosen statuses); or to declare 409/502 without correcting the success status.

Deliverables

  • The requestAprTransfer entry declares exactly 202, 400, 401, 409, 502 — and no 200.
  • A new test asserts the route answers 202 for a request whose requestAprRepoTransfer result status is neither rejected nor failed.
  • A new test asserts it answers 409 when the result status is rejected, and 502 when it is failed.
  • A new assertion that the set of statuses buildOpenApiSpec() declares for POST /v1/loop/request-apr-transfer is exactly {202, 400, 401, 409, 502}.
  • apps/loopover-ui/public/openapi.json regenerated and committed.

All Deliverables above are required in a single PR. A PR that satisfies only some of them — for example correcting the spec without the handler-status tests, or adding the tests while leaving 200 declared — does not resolve this issue.

Test Coverage Requirements

src/api/** and src/openapi/** are inside Codecov's src/** include; the 99% branch-counted patch gate applies. All three arms of the status ladder (rejected -> 409, failed -> 502, otherwise -> 202) plus the 400 parse failure must be covered. Extend test/unit/routes-request-apr-transfer.test.ts rather than creating a parallel file. The exact-status-set assertion is the named regression test for this fix.

Expected Outcome

The published operation for the APR transfer request states the three real outcomes, so a client can tell a pending-acceptance initiation from a gate rejection from a downstream failure — instead of matching on a 200 that never arrives.

Links & Resources

src/api/routes.ts:3999-4013; src/openapi/internal-and-public-route-specs.ts:317-334; test/unit/routes-request-apr-transfer.test.ts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:bugGittensor-scored bug fix — scores a 0.05x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions