Goal
Ship bin/altair openapi:import — one command that turns an existing OpenAPI 3.1 document into a directory of Altair YAML specs, and (with --scaffold) into a runnable Univeros project: Actions, Inputs, Responders, tests, entity + migration + repository (when persistence is requested), and a typed client SDK.
The forward chain today is Altair YAML → OpenAPI → SDK. This epic closes the reverse chain: OpenAPI → Altair YAML → working project.
Why
Most teams arriving at Univeros already have an OpenAPI document — generated by their current framework, hand-written, or supplied by a partner. Today the only path into Univeros is to translate every operation into an Altair YAML spec by hand. For a human that's hours of busywork. For an agent it's a token sink the framework can eliminate.
Two concrete wins:
- Adoption. "Port my existing service to Univeros" becomes a one-command operation instead of a manual translation exercise.
- Benchmark. Adds a credible variant to the
tokens-to-ship task: agents handed an OpenAPI doc up-front (a realistic porting scenario) skip spec-authoring entirely. This is exactly the kind of CRUD-with-plumbing work the framework is built for.
It also leans on infrastructure that already exists: Altair\Scaffold\Sdk\Model\OpenApiParser already parses OpenAPI 3.1 into a neutral in-memory model (OpenApiDocument, OperationModel, SchemaType) for SDK emission. Half the work is done.
CLI surface
# Library / no-scaffold
bin/altair openapi:import openapi.yaml # → ./api/, specs only
bin/altair openapi:import openapi.yaml --out=specs/
# Full pipeline
bin/altair openapi:import openapi.yaml --scaffold
bin/altair openapi:import openapi.yaml --scaffold --persistence=cycle --queue=redis
# Agent-friendly
bin/altair openapi:import openapi.yaml --dry-run # report, write nothing
bin/altair openapi:import openapi.yaml --format=json # structured receipt
bin/altair openapi:import openapi.yaml --force # clobber existing files
Sub-issues
Docs page (docs/openapi/import.md) + a benchmark task variant ("import-then-scaffold") ship as part of #162's acceptance.
Acceptance criteria
Out of scope
- OpenAPI 2.0 (Swagger). 3.1 only. Users convert first.
- Custom auth schemes beyond
bearerHttpAuthentication and API-key-in-header in v1.
- Frontend / UI generation.
- Importing from non-OpenAPI DSLs (gRPC, GraphQL) — separate epics.
- The webhook + idempotency primitives themselves. This epic only defines the extension keys that point at them.
Dependencies
Altair\Scaffold\Sdk\Model\OpenApiParser (already shipped)
Altair\Scaffold\Journal\Journal (already shipped)
Altair\Events\Contracts\RecorderInterface (already shipped)
Notes for whoever picks this up
Naming convention: openapi:* namespace (not spec:*) because OpenAPI is the source here, not the target. Keep that distinction — it's the only signal that the data flow runs the other way.
The library piece (#161) is the only non-trivial code. The CLI (#162), journal hookup, and events recording are all wiring against existing infrastructure.
Goal
Ship
bin/altair openapi:import— one command that turns an existing OpenAPI 3.1 document into a directory of Altair YAML specs, and (with--scaffold) into a runnable Univeros project: Actions, Inputs, Responders, tests, entity + migration + repository (when persistence is requested), and a typed client SDK.The forward chain today is
Altair YAML → OpenAPI → SDK. This epic closes the reverse chain:OpenAPI → Altair YAML → working project.Why
Most teams arriving at Univeros already have an OpenAPI document — generated by their current framework, hand-written, or supplied by a partner. Today the only path into Univeros is to translate every operation into an Altair YAML spec by hand. For a human that's hours of busywork. For an agent it's a token sink the framework can eliminate.
Two concrete wins:
tokens-to-shiptask: agents handed an OpenAPI doc up-front (a realistic porting scenario) skip spec-authoring entirely. This is exactly the kind of CRUD-with-plumbing work the framework is built for.It also leans on infrastructure that already exists:
Altair\Scaffold\Sdk\Model\OpenApiParseralready parses OpenAPI 3.1 into a neutral in-memory model (OpenApiDocument,OperationModel,SchemaType) for SDK emission. Half the work is done.CLI surface
Sub-issues
OpenApiDocument→ Altair YAML) [library]openapi:importCLI command + JSON receipt + events + journal hookupx-altair-*OpenAPI extensions for round-trippable persistence/queue/webhook/idempotencyopenapi → spec → openapibyte-stable)Docs page (
docs/openapi/import.md) + a benchmark task variant ("import-then-scaffold") ship as part of #162's acceptance.Acceptance criteria
bin/altair openapi:import petstore.yaml --out=api/ --scaffoldproduces a runnable Univeros project that serves every operation in the docspec:lintwithout manual editingspec:emit-openapiagainst the imported specs reproduces the original doc within documented normalization (see openapi:roundtrip \xe2\x80\x94 drift gate for openapi \xe2\x86\x92 spec \xe2\x86\x92 openapi #164)x-altair-persistence+x-altair-queueextensions imports with persistence + queue artifacts in placejournal:rewindafter an--scaffoldimport cleanly undoes the whole import.altair/events.jsonlOut of scope
bearerHttpAuthenticationand API-key-in-header in v1.Dependencies
Altair\Scaffold\Sdk\Model\OpenApiParser(already shipped)Altair\Scaffold\Journal\Journal(already shipped)Altair\Events\Contracts\RecorderInterface(already shipped)Notes for whoever picks this up
Naming convention:
openapi:*namespace (notspec:*) because OpenAPI is the source here, not the target. Keep that distinction — it's the only signal that the data flow runs the other way.The library piece (#161) is the only non-trivial code. The CLI (#162), journal hookup, and events recording are all wiring against existing infrastructure.