camunda / camunda/api-test-generator
Support operation-scoped x-semantic-provider for a shared response schema
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 3
- Avg merge
- 13h 41m
- Merged PRs (30d)
- 23
Description
Summary
Allow a producing operation to mark a scoped provider for an identifier that is carried by a shared response schema — without forcing a dedicated per-operation result DTO.
Today the only supported way to make an operation an authoritative producer of a server-minted identifier is x-semantic-provider on a schema where the identifier is a direct property. When a CRUD entity reuses one result schema across create/get/update/search, there is no supported way to say "only the create response is the canonical producer of the key".
Context / motivation: camunda/camunda-hub#25042 (annotating File/Folder/Project public-API ops). File is a server-minted-key entity (fileKey is allocated by the server and returned in the response) whose create/get/update/search operations all share a single FileResult schema. We do not want to duplicate FileResult into a FileCreateResult just to host the provider annotation.
Why the current options don't fit
OCA's convention is a dedicated *CreateResult DTO per producer (TenantCreateResult vs TenantResult, CreateProcessInstanceResult, DeploymentResult, …), so the shared-schema case has no precedent and no consumer support. The two documented escape hatches both fail here:
-
Array-form
x-semantic-provider: [fileKey]on anallOfwrapper (wrapperallOf: [$ref FileResult], scoped to the create 200 only) is silently a no-op:providerProps(the array form) is consumed only for direct properties of the annotated object —semantic-graph-extractor/schema-analyzer.ts:676-693.fileKeyarrives viaallOf$ref, so it is never a direct property of the wrapper.- The
allOfbranch re-propagates provider only for the booleantrueform, not the array form —schema-analyzer.ts:724-742. - The boolean-form-through-
allOffallback only resolves a top-levelx-semantic-typeon the$ref'd schema —schema-analyzer.ts:628-643— which an object likeFileResult(whose key is a nested property) does not have. - Net:
FileKeyis extracted withprovider: false, so it never entersproviderMap/produces(gated atpath-analyser/src/graphLoader.ts:747-760).createFileis not registered inproducersByType[FileKey], andgetFile/updateFile/deleteFile(which requireFileKeyvia the path param) become orphaned in base chains.
-
Array-form
x-semantic-provider: [fileKey]on the sharedFileResultwould work mechanically (direct property) but implicitly claims provider semantics for every operation that$refs it — includingsearchFiles(returns pre-existingitems[].fileKey) — which is exactly the anti-pattern called out in the endpoint guidelines (and tracked upstream by camunda/camunda#52414).
Proposed enhancement
Add an operation-scoped provider declaration so a producer can name which identifier(s) of its (possibly shared) response schema it authoritatively produces. Sketch of options (open to design):
-
Option A — operation-level
x-semantic-provideron the operation (or itsresponses.<2xx>.content), e.g.responses: "200": x-semantic-provider: [fileKey] # scoped to THIS operation's response only content: application/json: schema: { $ref: '#/components/schemas/FileResult' }The extractor would resolve the named props against the (allOf/$ref-composed) response schema for that operation only, and set
provider: trueon those leaves for that op'sresponseSemanticTypes— independent of other operations sharing the schema. -
Option B — thread array-form
providerPropsthroughallOf/$refso theallOf-wrapper-scoped pattern in (1) above works as authored. i.e. when an object carriesx-semantic-provider: [name]andnameresolves to a property reachable throughallOf/$refcomposition (not only ownproperties), mark it. This keeps the annotation on a thin per-operation wrapper while reusing the shared schema.
Either way the goal is: provider scope = the producing operation, not the schema, with no duplicated DTO.
Acceptance criteria
- A producer that
$refs a shared result schema can mark a scoped provider for one or more identifiers without a dedicated result DTO. - The same shared schema referenced by non-producing ops (
get/update/search) does not become an authoritative producer. createFileends up inproducersByType[FileKey]; base chains forgetFile/updateFile/deleteFileresolvecreateFileas theFileKeyproducer.- Regression coverage in
tests/fixtures/extractor(provider extraction) and a graph-loader test assertingproducersByTypemembership for the scoped case. - Endpoint-guidelines doc updated to describe the supported shared-schema pattern (currently it only offers "split the schema" or "omit provider").
Related
- camunda-hub PR: camunda/camunda-hub#25042
- Shared-schema provider caveat / structural lint guard: camunda/camunda#52414
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with semantic-graph-extractor/schema-analyzer.ts, especially the provider and allOf handling around the cited sections, then trace provider registration in path-analyser/src/graphLoader.ts. Add regression coverage in tests/fixtures/extractor and a graph-loader test for producersByType, and update the endpoint-guidelines documentation. Done means createFile is registered for FileKey while non-producing shared-schema operations are not.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- openapi, typescript
- Domain
- testing, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100