Skip to content

improvement(api): retire route contracts that no route serves - #7206

Merged
icecrasher321 merged 2 commits into
stagingfrom
fix/retire-orphaned-route-contracts
Aug 28, 2026
Merged

improvement(api): retire route contracts that no route serves#7206
icecrasher321 merged 2 commits into
stagingfrom
fix/retire-orphaned-route-contracts

Conversation

@icecrasher321

Copy link
Copy Markdown
Collaborator

Summary

The staging integ-failure alarm fired because integ-session-kb-document-lifecycle/create-document-from-inline-content got HTTP 405 instead of 200.

Root cause: #7179 moved tool operations in process and deleted the routes that only existed to serve them, but createKnowledgeDocumentsContract kept declaring POST /api/knowledge/[id]/documents. The surviving GET/PATCH on that path make Next.js answer POST with 405 rather than an honest 404 — which reads as "wrong verb, endpoint is fine" and sends the caller looking in the wrong place.

Nothing in the repo called that endpoint: the KB UI creates documents through the presigned upload flow, and no SDK, desktop, docs, or client fetch references it. The capability is unaffected either way — knowledge_create_document is a shipped tool that reaches the same use case in process. So this retires the declaration rather than restoring the route.

Audit

Checked all 1125 contracts for the same drift. The knowledge one was the only contract whose path resolves to a live route missing its declared method. 259 others declare paths of routes deleted outright — those 404 honestly and are left alone.

Changes

  • Knowledge create-documents — replaced the route contract with plain params/body schemas plus a named response schema, so nothing declares an endpoint we don't serve. Schemas stay in the contracts tree beside the siblings they share (documentDataSchema is used by the v2 contracts; createKnowledgeDocumentsBodySchema already backed the in-process operation).
  • Deleted 4 contracts with no consumer at all — both TTS contracts, docusign, mistral. Their handlers own strictly better schemas: TTS dispatches by toolId across 8 per-provider schemas instead of one .passthrough() superset covering 7 providers, and mistral bounds pages by the OCR request policy. This removes duplication rather than creating it.
  • Kept crowdstrike and windchill. They look identical from the outside but are load-bearing — crowdstrikeQueryBodySchema is parsed by lib/internal/crowdstrike/execute-tool.ts, windchillOperationResponseSchema by tools/windchill/utils.ts, plus derived types across both.
  • New audit check:api-contract-routes, auto-discovered by run-audits. Also documents the two contract consumption modes on ApiRouteContract, with membership derived (--list-in-process) rather than annotated per file.

Why the new audit isn't redundant with check:route-verbs

check-route-verbs scans routes → contracts, so a contract whose route method was deleted is invisible to it. Verified against the exact regression state: check:route-verbs passes clean (359 handlers) while the new check fails with the precise diagnosis.

Not in scope

The repo is split on where in-process schemas live — 54 lib/internal domains declare them inline, 36 import from contracts, 18 are mixed. Converging on the contracts tree is worth doing but is a 54-domain migration, not this PR. Nothing here makes that split worse: the four deletions each removed a dead duplicate, leaving one source of truth.

Testing

  • bunx turbo run type-check — clean
  • bun run lint:check — clean
  • bun run check:audits — 38/38 pass, including the new audit
  • 1019 tests across 82 files in the touched areas (knowledge, table, tool-operations, contracts, crowdstrike, windchill, mistral, tts)
  • Negative-tested the new audit: reproduces the staging failure at lint time, passes once resolved

🤖 Generated with Claude Code

@icecrasher321
icecrasher321 requested a review from a team as a code owner August 28, 2026 07:32
@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 28, 2026 7:53am

Request Review

@icecrasher321 icecrasher321 changed the title fix(api): retire route contracts that no route serves improvement(api): retire route contracts that no route serves Aug 28, 2026
@greptile-apps

greptile-apps Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Retires route metadata for operations that now execute in process while preserving their validation schemas, and adds an audit comparing declared contract methods with live route handlers.

  • Replaces retired knowledge and Confluence route contracts with directly consumed schemas.
  • Removes unused DocuSign, Mistral, and text-to-speech contract declarations.
  • Adds contract discovery and route-method auditing to the repository audit suite.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
scripts/check-api-contract-routes.ts Adds runtime contract discovery and route-method comparison, including exact and catch-all route resolution.
apps/sim/lib/api/contracts/knowledge/documents.ts Replaces the retired document-creation route contract with standalone request and response schemas.
apps/sim/lib/internal/knowledge/execute-tool.ts Updates in-process knowledge document creation to validate directly against standalone schemas.
apps/sim/lib/internal/confluence/execute-tool.ts Generalizes schema-based input parsing for retired Confluence update and delete routes.
apps/sim/lib/internal/tool-operations/parse-contract-input.ts Adds a schema-bundle parsing entry point while retaining contract-specific type inference.
apps/sim/lib/api/contracts/types.ts Documents boundary and in-process contract consumption modes.
package.json Registers the new API contract route audit.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Contract modules] --> B[Import exported contract objects]
  B --> C[Resolve exact or catch-all route]
  C --> D[Read exported HTTP methods]
  D --> E{Declared method served?}
  E -->|Yes| F[Audit passes entry]
  E -->|No| G[Report stale route declaration]
  H[Retired in-process operation] --> I[Plain Zod schemas]
  I --> J[Internal tool executor]
Loading

Reviews (2): Last reviewed commit: "fix(api): read contracts by import, and ..." | Re-trigger Greptile

Comment thread scripts/check-api-contract-routes.ts
Comment thread scripts/check-api-contract-routes.ts Outdated
icecrasher321 and others added 2 commits August 28, 2026 00:46
The staging integ alarm fired because the session knowledge-document
inline-create check got a 405. #7179 moved tool operations in process and
deleted the routes that only existed to serve them, but
`createKnowledgeDocumentsContract` kept declaring
`POST /api/knowledge/[id]/documents` — a path whose surviving GET/PATCH make
Next.js answer POST with 405 rather than an honest 404. Nothing in the repo
called it: the KB UI creates documents through the presigned upload flow, and
the capability itself is unaffected because `knowledge_create_document` reaches
the same use case in process.

Audited all 1125 contracts for the same drift. It was the only one whose path
resolves to a live route missing the declared method; 259 others declare paths
of routes that were deleted outright, which 404 honestly and are left alone.

- Drop the create-documents route contract for plain `params`/`body` schemas
  plus a named response schema, so nothing declares an endpoint we do not
  serve. The schemas stay in the contracts tree next to the siblings they share
  (`documentDataSchema` is used by the v2 contracts, and
  `createKnowledgeDocumentsBodySchema` already backed the in-process operation).
- Delete four contracts with no consumer at all — both TTS contracts, docusign,
  and mistral. Their handlers own better schemas: TTS dispatches by `toolId`
  with eight per-provider schemas instead of one passthrough superset, and
  mistral bounds `pages` by the OCR request policy. crowdstrike and windchill
  look similar but are load-bearing (schema and derived types are imported by
  live code), so they stay.
- Add `check:api-contract-routes`, picked up automatically by `run-audits`.
  `check:route-verbs` scans routes to contracts, so a contract whose route
  method was deleted is invisible to it — verified it passes clean against the
  exact regression this catches.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…tions

Greptile flagged the audit's brace counter as blind to braces inside strings,
template literals, regexes and comments. It was, but the bigger problem was that
a text scan can only see contracts whose `method`/`path` are inline literals —
the 70-plus built through `definePostSelector(path, …)` and friends were never
checked at all. Comparing raw `defineRouteContract(` occurrences against parsed
ones showed the scanner silently skipping declarations.

Read the contracts by importing each contract module and inspecting its exported
objects instead, the way `check-route-verbs.ts` already resolves the contract
behind a route. Contract modules are pure Zod so importing them is safe; route
files stay a static scan because importing one drags in `@sim/db`, auth and
`next/server`. Barrels re-export the same object, so entries are keyed by
identity. Coverage goes from 1125 contracts to 1283.

That immediately surfaced two more instances of exactly what this PR retires.
`/api/tools/confluence/page` kept its `PUT` and `DELETE` contracts after #7179
reduced the route to the selector `POST`, so both declared verbs the live route
answers with 405. Neither is fetched — `lib/internal/confluence/execute-tool.ts`
is the only consumer — so they become plain schemas like the knowledge one, and
`executeOperation` now delegates to a schema form rather than growing a second
pattern beside it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@icecrasher321
icecrasher321 force-pushed the fix/retire-orphaned-route-contracts branch from a5b06c6 to 1bf6017 Compare August 28, 2026 07:47
@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@greptile

@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@cubic review

@cubic-dev-ai

cubic-dev-ai Bot commented Aug 28, 2026

Copy link
Copy Markdown

@cubic review

@icecrasher321 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 13 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@icecrasher321
icecrasher321 merged commit 498cdb6 into staging Aug 28, 2026
33 checks passed
@icecrasher321
icecrasher321 deleted the fix/retire-orphaned-route-contracts branch August 28, 2026 07:57
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