re #214 fix(scaffold): name RPC action paths by their noun resource (#214 Phase 5) - #222
Merged
Merged
Conversation
…214 Phase 5) Phase 5 (final) of the OpenAPI bidirectional-fidelity epic. RPC-style path leaves were treated as resources: `GET /pet/findByStatus` derived `App\FindByStatu\FindPetsByStatus` — `singularize("findByStatus")` stripped the trailing 's' to "FindByStatu", and the action became the class namespace. PathDeriver now recognises an action leaf by whether its first camelCase word is a known verb (`find`, `upload`, `login`, ...): `findByStatus` → `find` (action), `uploadImage` → `upload` (action), while a noun leaf like `userProfiles` → `user` (resource, still singularized to `UserProfile`) and `findings` → one word (resource). `resourceSegment` walks back past action leaves to the nearest noun, and `singularize` leaves action leaves intact. So: - GET /pet/findByStatus -> App\Pet\FindPetsByStatus - POST /pet/{petId}/uploadImage -> App\Pet\UploadFile - POST /user/login -> App\User\LoginUser - GET /store/inventory -> App\Inventory\GetInventory (unchanged: inventory is the resource) Two find* operations on one resource now collide on `api/pet/find.yaml` and disambiguate by operationId (`find-pets-by-status.yaml` / `find-pets-by-tags.yaml`), so no specs are lost — the real Petstore stays at 19 specs / 18 warnings / 0 unmapped, roundtrip clean. Also closes out the epic's Phase 5 scope: - Path-param declared types already import (a path param with `schema: {type: integer}` becomes `int`) — Phase 2 resolved that; the old "always string" note was stale. - Security schemes / `security` requirements are surfaced by design (Altair has no auth/middleware spec construct to generate into), documented as a deliberate non-goal in coverage.md rather than a pending gap.
This was referenced Jun 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #214 — Phase 5 (security & naming). Final phase; closes the epic.
Problem
RPC-style path leaves were treated as resources.
GET /pet/findByStatusderivedApp\FindByStatu\FindPetsByStatus—singularize("findByStatus")stripped the trailingstoFindByStatu, and the action segment became the class namespace instead of the real resource (pet).Change (
PathDeriver)An action leaf is now detected by whether its first camelCase word is a known verb (
find,upload,login, …) — which cleanly separatesfindByStatus(verbfind) from a camelCase noun likeuserProfiles(nounuser, still singularized toUserProfile) andfindings(one word, notfind).resourceSegmentwalks back past action leaves to the nearest noun;singularizeleaves action leaves intact.GET /pet/findByStatusApp\FindByStatu\FindPetsByStatusApp\Pet\FindPetsByStatusPOST /pet/{petId}/uploadImageApp\UploadImage\UploadFileApp\Pet\UploadFilePOST /user/loginApp\Login\LoginUserApp\User\LoginUserGET /store/inventoryApp\Inventory\GetInventoryTwo
find*operations on one resource now collide onapi/pet/find.yamland disambiguate by operationId (find-pets-by-status.yaml/find-pets-by-tags.yaml) — no specs lost.Also closing out Phase 5 scope
schema: {type: integer}becomesint) — Phase 2 resolved this; the old "always string" note was stale (verified on the Petstore'spetId).securityare surfaced by design — Altair has no auth/middleware spec construct to generate into, so the requirement is reported (so you wire auth yourself) rather than silently dropped. Documented as a deliberate non-goal incoverage.md, likeoneOf.Verification
filename()+resolveFilenamesdisambiguation forfind*; bare single-segment action verbs fall back to themselves.openapi:roundtrip --checkclean; the three target paths now deriveApp\Pet\…/App\User\….code-reviewer: APPROVE (0 CRITICAL/0 HIGH); the one MEDIUM (camelCase-noun misclassification) was fixed (not just documented) by the first-camel-word-verb heuristic, plus the suggested filename/collision/bare-verb tests added.Closes the #214 epic — coverage map updated to "complete".