fix(openapi): document /v1/opportunities/find + /v1/issue-rag/retrieve - #9423
fix(openapi): document /v1/opportunities/find + /v1/issue-rag/retrieve#9423hurryup52 wants to merge 1 commit into
Conversation
Both routes were fully implemented and gated correctly but never wired
into the OpenAPI generator, so they were invisible in GET /openapi.json
and the committed apps/loopover-ui/public/openapi.json even though their
MCP tool counterparts (loopover_find_opportunities,
loopover_retrieve_issue_context) already validate full Zod shapes.
Adds FindOpportunitiesRequestSchema/ResponseSchema and
IssueRagRetrieveRequestSchema/ResponseSchema to src/openapi/schemas.ts,
mirroring the MCP tools' own shapes field-for-field
(findOpportunitiesShape/findOpportunitiesOutputSchema and
issueRagShape/issueRagOutputSchema in src/mcp/server.ts) so the contract
can't silently drift from what the tools actually validate. Registers
both response schemas as OpenAPI components and both routes as POST
paths in src/openapi/spec.ts, following the same pattern used for
GET /v1/repos/{owner}/{repo}/gate-config/effective.
Regenerates apps/loopover-ui/public/openapi.json via `npm run
ui:openapi` and extends test/unit/openapi.test.ts with assertions that
both paths are defined and that the response schemas' fields match the
MCP output shapes.
Closes JSONbored#9310
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-27 18:04:28 UTC
Review summary Nits — 5 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Visual preview
Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy. Scroll preview
A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
LoopOver is closing this pull request on the maintainer's behalf (conflicts with the base branch — resolve and open a fresh PR). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed. |
#9452) * fix(openapi): document /v1/opportunities/find + /v1/issue-rag/retrieve (#9310) Both discovery routes were live (and MCP-backed) but absent from OpenAPI. Add request/response schemas mirroring the MCP tool shapes, register the POST paths, regenerate openapi.json, and add regression assertions. Replaces conflict-closed #9423 on current main. Co-authored-by: Cursor <cursoragent@cursor.com> * recheck --------- Co-authored-by: Andriy Polanski <andriy.polanski@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>

Closes #9310
What
/v1/opportunities/find(OPPORTUNITIES_FIND_PATH, backing theloopover_find_opportunitiesMCP tool) and/v1/issue-rag/retrieve(ISSUE_RAG_RETRIEVE_PATH, backingloopover_retrieve_issue_context) are fully implemented and access-gated insrc/api/routes.ts, but were never registered with the OpenAPI generator — grep foropportunities/find/issue-raginsrc/openapi/spec.tspreviously returned nothing, so neither route appeared inGET /openapi.jsonor the committedapps/loopover-ui/public/openapi.json.Changes
src/openapi/schemas.ts: addedFindOpportunitiesRequestSchema/FindOpportunitiesResponseSchemaandIssueRagRetrieveRequestSchema/IssueRagRetrieveResponseSchema. Field shapes mirror the MCP tools' own Zod shapes verbatim (findOpportunitiesShape/findOpportunitiesOutputSchemaandissueRagShape/issueRagOutputSchemainsrc/mcp/server.ts) so the contract can't silently drift from what the tools actually validate — reused the sameMAX_FIND_OPPORTUNITIES_*/MAX_ISSUE_RAG_*/PREFLIGHT_LIMITSconstants those shapes already use.src/openapi/spec.ts: registered both response schemas as named components (FindOpportunitiesResponse,IssueRagRetrieveResponse) and added tworegisterPathPOST entries, following the same pattern used forGET /v1/repos/{owner}/{repo}/gate-config/effective(OpenAPI spec is missing GET /v1/repos/{owner}/{repo}/gate-config/effective (documented sibling: live-gate-thresholds) #6611) and the existing POST-with-body routes (e.g. the incident-reports pair). Response codes (400/401/403) are matched to each route handler's actual behavior inroutes.ts.apps/loopover-ui/public/openapi.json: regenerated vianpm run ui:openapiand committed.npm run ui:openapi:checkpasses.test/unit/openapi.test.ts: added assertions that both paths are defined, that both response schema components are registered, and that their fields (aiPolicyAllowed,retrievedPathCount) match the MCP output shapes — a regression guard against future drift between the two.Verification
npx vitest run test/unit/openapi.test.ts— 3/3 pass.npm run ui:openapi:check— passes.npm run typecheck— clean.test/unit/openapi.test.ts:src/openapi/spec.tsat 100% statements/functions/lines, 95.65% branches (the one uncovered branch,spec.ts:1468, is pre-existing code inapplySecurityMetadatauntouched by this diff).npm run test:coverage: no failures related to this change. The run does show ~69 pre-existing failing test files, all inpackages/loopover-miner/**(worktree-allocator, purge-cli, rejection-signal, etc.) — unrelated tosrc/openapi/**, reproducible on a cleanupstream/maincheckout with none of this diff applied.