feat(scaffold): x-altair-* OpenAPI extensions for round-trippable spec fields (#163)#169
Merged
Merged
Conversation
…c fields (#163) Defines the x-altair-* extension family so framework-specific spec fields survive a round trip through OpenAPI 3.1: - x-altair-domain spec.domain (class, invocation) - x-altair-persistence spec.persistence (entity + repository + fields) - x-altair-queue spec.queue (dispatches as a list) - x-altair-idempotency reserved; key + schema only this release - x-altair-webhook reserved; key + schema only this release - x-altair-input-location reserved; needs parameters[] parser support Forward (spec:emit-openapi) - OpenApiEmitter writes x-altair-domain on every operation and x-altair-persistence / x-altair-queue when the spec carries those blocks. Reverse (openapi:import) - OperationModel grew an extensions: array<string, mixed> field. - OpenApiParser extracts every x-altair-* key on each operation onto that field so unknown keys ride along verbatim (forward compat). - OperationMapper reads x-altair-domain / x-altair-persistence / x-altair-queue when building the spec structure, so an imported endpoint keeps the original domain FQCN, persistence block, and queue map instead of falling back to path-derived defaults. - The runner surfaces a warning entry in ImportReceipt.warnings for any x-altair-* key outside the v1 known set. Documentation - docs/openapi/extensions.md walks through the v1 key set, forward/reverse semantics, round-trip example, and what does not round-trip yet. - docs/openapi/extensions/*.schema.json — Draft 2020-12 JSON Schemas for each key. Tests - 16 new tests across emitter, parser, mapper, and runner extension coverage. Existing OpenApiEmitterTest golden snapshot regenerated to include the new x-altair-domain block. Part of #160. Closes #163.
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.
Closes #163. Part of #160.
Summary
Defines the
x-altair-*OpenAPI 3.1 extension family so the framework-specific spec fields the base spec cannot express survive a round trip through OpenAPI.spec:emit-openapiwrites them on the forward path;openapi:importreads them on the reverse path. Closes the loop opened by #161 (emitter) and #162 (CLI).V1 key set
x-altair-domainspec.domain.{class, invocation}docs/openapi/extensions/x-altair-domain.schema.jsonx-altair-persistencespec.persistencedocs/openapi/extensions/x-altair-persistence.schema.jsonx-altair-queuespec.queuedocs/openapi/extensions/x-altair-queue.schema.jsonx-altair-idempotencydocs/openapi/extensions/x-altair-idempotency.schema.jsonx-altair-webhookdocs/openapi/extensions/x-altair-webhook.schema.jsonx-altair-input-locationparameters[]parser supportdocs/openapi/extensions/x-altair-input-location.schema.json"Carried through" means the parser preserves the key on
OperationModel::$extensionsand the receipt warns when the runner sees it but doesn't yet act on it. The schema is published so authoring tooling can validate.Forward (spec:emit-openapi)
OpenApiEmitternow writes:x-altair-domainon every operation (the domain class is always set on a spec)x-altair-persistencewhenspec.persistenceis non-nullx-altair-queue(list form) whenspec.queueis non-emptyThe Petstore-class golden snapshot was regenerated to include the new
x-altair-domainblock.Reverse (openapi:import)
OperationModelgrew anextensions: array<string, mixed>field. Backwards-compatible default[].OpenApiParserextracts every key starting withx-altair-from each operation onto that field. Unknown keys ride along verbatim (forward compat).OperationMapperreadsx-altair-domain/x-altair-persistence/x-altair-queuewhen building the spec structure, preferring them over the path-derived defaults fromPathDeriver.OpenApiImportRunnercollects anyx-altair-*key outside the v1 known set intoImportReceipt::$warningsso v1 imports never silently drop a key a future release will rely on.Round-trip example (from docs/openapi/extensions.md)
emits:
which
openapi:importrecovers back intospec.persistencebyte-for-byte (not the inferred persistence block the--persistence=cycleflag synthesises).Tests
OpenApiEmitterExtensionsTest(4) \xe2\x80\x94 forwardOpenApiParserExtensionsTest(2) \xe2\x80\x94 parser captures known + unknownx-altair-*OperationMapperExtensionsTest(5) \xe2\x80\x94 reverse mapping per extensionOpenApiImportExtensionsTest(5) \xe2\x80\x94 end-to-end round trip + unknown-key warning + no-false-positive warnings on known keysTest plan
composer cs\xe2\x80\x94 greencomposer stan\xe2\x80\x94 greencomposer rector(full tree, no cache) \xe2\x80\x94 greencomposer test\xe2\x80\x94 6220 tests (+16 new), 0 new failures (5 pre-existing environmental errors unchanged)bin/altair manifest:generate\xe2\x80\x94 cleanopenapi:importon the Posts benchmark fixture \xe2\x80\x94 ok=true, warnings=[]Out of scope (per #160)