docs(api): fill 10 empty op descriptions + mark disabled endpoints deprecated (#4599 C+D)#4667
Conversation
…precated (#4599 C+D) Adversarial-audit follow-ups on the merged OpenAPI docs (#4657): C — 10 RPCs (GetForecasts, GetSimulationOutcome, GetSimulationPackage, GetOilInventories, SearchImagery, GetResilienceRuntimeManifest, GetCriticalMinerals, GetShippingRates, GetWebcamImage, ListWebcams) lacked a leading proto comment, so the generator emitted `description: null` and they rendered description-less on the docs site. Add an accurate one-line comment (sourced from each RPC's real response payload) above each; the generator now emits the operation description. D — GetCompanyEnrichment and ListCompanySignals are DISABLED empty stubs whose routes are preserved for contract stability, but they carried only prose "DISABLED" and rendered as normal, usable endpoints. Add `option deprecated = true;` (proto source of truth) and a new post-generation injector (openapi-inject-deprecated.mjs) that propagates it to OpenAPI `deprecated: true` — sebuf v0.11.1 does not. The injector is proto-sourced, so any future RPC gaining the option is covered automatically. Wired into `make generate` + `npm run gen:openapi:deprecated`. Regenerated with the pinned sebuf v0.11.1 plugin (verified reproducible: make generate on clean main is byte-identical). All 34 JSON + 34 YAML + bundle updated with full parity; make generate idempotent; new guard asserts every op has a description and deprecated ⟺ DISABLED; 383 contract tests pass; src/generated unchanged. Answers #4657 review D ("why document disabled endpoints"): exactly 2 exist; they stay documented (routes still serve 200) but are now machine-readable deprecated. Claude-Session: https://claude.ai/code/session_01EsjtheWqt8GxEZfd3DyTMu
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
Greptile SummaryThis PR fills missing operation descriptions for 10 proto RPCs (C) and propagates
Confidence Score: 4/5Safe to merge; all changes are documentation and test artifacts with no runtime code path impact. The core injector logic and proto changes are correct and idempotent. The contract test's deprecated/DISABLED case never reads YAML files, so a regression in the YAML injection path would go undetected. GetRouteImpact was also missed from the 10-operation description fix. tests/openapi-deprecated-contract.test.mjs (YAML files never read in the deprecation test) and proto/worldmonitor/supply_chain/v1/service.proto (GetRouteImpact missing a functional comment). Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[make generate] --> B[buf generate\nproto to OpenAPI JSON/YAML]
B --> C[openapi-inject-required.mjs]
C --> D[openapi-inject-examples.mjs]
D --> E[openapi-inject-servers.mjs]
E --> F[openapi-inject-deprecated.mjs]
F --> G{Walk proto/worldmonitor\nfor option deprecated = true}
G --> H[Extract HTTP path suffix]
H --> I[DEPRECATED_SUFFIXES Set]
I --> J[Patch per-service JSON]
I --> K[Patch per-service YAML]
I --> L[Patch bundle YAML]
J & K & L --> M[Mintlify renders deprecated badge]
subgraph Test Guard
N[openapi-deprecated-contract.test.mjs]
N --> O[C: every op has non-empty description]
N --> P[D: deprecated=true iff DISABLED in description]
P -.->|only checks JSON not YAML| Q[YAML coverage gap]
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[make generate] --> B[buf generate\nproto to OpenAPI JSON/YAML]
B --> C[openapi-inject-required.mjs]
C --> D[openapi-inject-examples.mjs]
D --> E[openapi-inject-servers.mjs]
E --> F[openapi-inject-deprecated.mjs]
F --> G{Walk proto/worldmonitor\nfor option deprecated = true}
G --> H[Extract HTTP path suffix]
H --> I[DEPRECATED_SUFFIXES Set]
I --> J[Patch per-service JSON]
I --> K[Patch per-service YAML]
I --> L[Patch bundle YAML]
J & K & L --> M[Mintlify renders deprecated badge]
subgraph Test Guard
N[openapi-deprecated-contract.test.mjs]
N --> O[C: every op has non-empty description]
N --> P[D: deprecated=true iff DISABLED in description]
P -.->|only checks JSON not YAML| Q[YAML coverage gap]
end
|
| const yamlFiles = readdirSync(apiDir) | ||
| .filter((f) => /Service\.openapi\.json$/.test(f)) | ||
| .sort(); |
There was a problem hiding this comment.
YAML artifacts never validated despite "every artifact" label
The variable is named yamlFiles but is filtered with /Service\.openapi\.json$/, so the test reads exactly the same JSON files as the outer serviceSpecs variable and never touches any YAML files. The injectYaml() code path — which inserts deprecated: true into *Service.openapi.yaml and worldmonitor.openapi.yaml — is therefore not exercised by this test at all. A bug in YAML indentation detection or the "already present" idempotency check would go silently undetected here.
| const yamlFiles = readdirSync(apiDir) | |
| .filter((f) => /Service\.openapi\.json$/.test(f)) | |
| .sort(); | |
| const jsonServiceSpecs = readdirSync(apiDir) | |
| .filter((f) => /Service\.openapi\.json$/.test(f)) | |
| .sort(); | |
| let deprecatedCount = 0; | |
| for (const file of jsonServiceSpecs) { |
| function isDeprecatedPath(path) { | ||
| for (const suffix of DEPRECATED_SUFFIXES) { | ||
| if (path === suffix || path.endsWith(suffix)) return true; | ||
| } | ||
| return false; |
There was a problem hiding this comment.
endsWith suffix matching is broader than exact path equality
path.endsWith(suffix) will match any OpenAPI path that ends with a deprecated suffix string. Today's suffixes (/get-company-enrichment, /list-company-signals) are unique, but if a future RPC path happened to share a trailing segment with a deprecated one, it would incorrectly receive deprecated: true. Building the full path from base_path + path at parse time and matching with exact equality would eliminate the ambiguity without much extra complexity.
What & why
Second follow-up PR from the adversarial re-audit of the merged OpenAPI docs (#4657, umbrella #4599). These are the plugin-gated items (proto changes + a real regen with the pinned sebuf v0.11.1). Companion to #4666 (items A+B, version-independent).
C — 10 operations shipped empty descriptions
GetForecasts,GetSimulationOutcome,GetSimulationPackage,GetOilInventories,SearchImagery,GetResilienceRuntimeManifest,GetCriticalMinerals,GetShippingRates,GetWebcamImage,ListWebcamshad no leading proto comment, so the sebuf generator emitteddescription: nulland they rendered description-less on the docs site (#4624 filled param descriptions, not operation ones).Fix: an accurate one-line
//comment above each RPC, each sourced from the RPC's real response payload (e.g.GetOilInventories→ "US crude weeks, the SPR snapshot, natural-gas weeks, EU gas storage, and IEA stocks"). The generator now emits the operation description.D — disabled endpoints rendered as active
GetCompanyEnrichmentandListCompanySignalsare DISABLED empty stubs whose routes are kept "for contract stability" — but they carried only prose "DISABLED" and no machine-readable flag, so Mintlify rendered them as normal, usable endpoints. (Confirmed these are the only 2 disabled endpoints — every other empty-ish handler returns real data or degrades gracefully.)Fix:
option deprecated = true;on the 2 proto RPCs (source of truth) + a new post-generation injectorscripts/openapi-inject-deprecated.mjsthat propagates it to OpenAPIdeprecated: true— sebuf v0.11.1 does not emit it. The injector is proto-sourced, so any future RPC that gains the option is covered automatically. The routes stay documented (they still serve200) but now carry the deprecated badge.Regen safety
Verified the pinned v0.11.1 plugin reproduces the committed docs byte-for-byte (
make generateon cleanmain= 0 diff) before any proto change, so the regenerated diff is exactly these changes.make generateidempotent; JSON + YAML + bundle parity;src/generatedunchanged.Tests
New
openapi-deprecated-contractguard: every operation has a non-empty description (C), anddeprecated: true⟺ description marks DISABLED (D — an independent cross-check against the injector's proto-option source). 383 contract tests pass; all 5 injectors--checkidempotent; biome clean.Wired:
make generatechain +npm run gen:openapi:deprecated. Follow-up: #4658.