This is the 11th of 12 sub-issues in the breakdown of #361. It may refer to the original consolidated PR #359 as an imperfect reference implementation (note: PR #359 did not migrate the demo apps — this slice closes that gap).
Umbrella: #361 · Series: B (runtime consumption) · Depends on: Slices 1–10 · Status: Required
Goal
Migrate demoapps/starwars (and any other demo that exercises scopes) to the new DSL block + new withScopedSchemas(schemaIds) API end-to-end. Acts as the integration test for Series A + B.
Why this is a critical PR
Series A and B can each pass their own unit/TestKit tests, but the end-to-end flow — DSL → JSON manifest written into JAR resources → runtime classloader → reader resolves IDs → working Viaduct instance — needs a real consumer to verify. The publish-to-mavenLocal demo-app cycle (per demoapps/CLAUDE.md) is the only test that exercises:
- the Gradle plugin packaging behavior for
META-INF/viaduct/schema-scoping.json,
- the runtime classloader actually finding the resource,
- a real Viaduct instance receiving valid scoped schemas,
- existing functional tests still passing.
Without this slice, no single test covers all those steps at once. Side benefit: removes the @file:Suppress("DEPRECATION") workarounds the demos carry to keep compiling against the deprecated API.
Files touched
demoapps/starwars/build.gradle.kts — add the viaductApplication { … } scope block.
demoapps/starwars/modules/{filmography,universe}/schema/*.graphqls — add @scope(to: [...]) to types where needed.
demoapps/starwars/src/main/kotlin/com/example/starwars/service/viaduct/ViaductConfiguration.kt — switch to withScopedSchemas(schemaIds = setOf(...)).
- Functional tests in
demoapps/starwars/src/test/.
- (Possibly) other demos if they exercise scopes.
Detailed changes
demoapps/starwars/build.gradle.kts
Using the single-declaration DSL settled in Slice 1:
viaductApplication {
grtPackageName.set("viaduct.api.grts")
modulePackagePrefix.set("com.example.starwars")
declaredSchemaScopes(setOf("public"))
declaredScopedSchemas(
"PUBLIC_API" to setOf("public"),
"FULL_ALIAS" to emptySet(), // demonstrate the empty-set (full-schema) alias
)
}
Schema files
Each top-level type that should appear in PUBLIC_API gets @scope(to: ["public"]). Existing @scope(to: ["*"]) decorations on framework types (Node, PageInfo, Query/Mutation roots) keep working because * is universal.
ViaductConfiguration.kt
// Before
ViaductBuilder()
.withScopedSchemas(listOf(SchemaScopeInfo("PUBLIC_API", setOf("public"))))
.build()
// After
ViaductBuilder()
.withScopedSchemas(setOf("PUBLIC_API"))
.build()
Test plan
./gradlew :starwars builds and tests pass — the canonical demo test.
META-INF/viaduct/schema-scoping.json is in the built JAR — explicit assertion in a test that loads the resource at runtime.
PUBLIC_API executes a query exercising a @scope(to: ["public"]) type — pre-existing test still passes.
FULL_ALIAS registration works — query SchemaId("FULL_ALIAS") and assert a non-public-scoped field is reachable, demonstrating the empty-set alias.
- Isolated maven-local test — per
demoapps/CLAUDE.md, run the full publish-to-maven-local + demo cycle to verify the change through the publication chain.
What NOT to migrate
demoapps/cli-starter, jetty-starter, micronaut-starter, ktor-starter, spring-starter — if they don't exercise scopes today, leave them alone (their job is KSP coverage).
- Downstream private demos/applications — out of scope.
Out of scope (deferred)
- Deprecating the old API — Slice 12.
LOC estimate
~120 LOC: ~30 build script + Viaduct config, ~80 schema annotations (likely partly present), ~10 test assertions.
Dependencies
Slices 1–10 must be merged. This slice is the end-to-end smoke test.
This is the 11th of 12 sub-issues in the breakdown of #361. It may refer to the original consolidated PR #359 as an imperfect reference implementation (note: PR #359 did not migrate the demo apps — this slice closes that gap).
Umbrella: #361 · Series: B (runtime consumption) · Depends on: Slices 1–10 · Status: Required
Goal
Migrate
demoapps/starwars(and any other demo that exercises scopes) to the new DSL block + newwithScopedSchemas(schemaIds)API end-to-end. Acts as the integration test for Series A + B.Why this is a critical PR
Series A and B can each pass their own unit/TestKit tests, but the end-to-end flow — DSL → JSON manifest written into JAR resources → runtime classloader → reader resolves IDs → working Viaduct instance — needs a real consumer to verify. The publish-to-mavenLocal demo-app cycle (per
demoapps/CLAUDE.md) is the only test that exercises:META-INF/viaduct/schema-scoping.json,Without this slice, no single test covers all those steps at once. Side benefit: removes the
@file:Suppress("DEPRECATION")workarounds the demos carry to keep compiling against the deprecated API.Files touched
demoapps/starwars/build.gradle.kts— add theviaductApplication { … }scope block.demoapps/starwars/modules/{filmography,universe}/schema/*.graphqls— add@scope(to: [...])to types where needed.demoapps/starwars/src/main/kotlin/com/example/starwars/service/viaduct/ViaductConfiguration.kt— switch towithScopedSchemas(schemaIds = setOf(...)).demoapps/starwars/src/test/.Detailed changes
demoapps/starwars/build.gradle.ktsUsing the single-declaration DSL settled in Slice 1:
viaductApplication { grtPackageName.set("viaduct.api.grts") modulePackagePrefix.set("com.example.starwars") declaredSchemaScopes(setOf("public")) declaredScopedSchemas( "PUBLIC_API" to setOf("public"), "FULL_ALIAS" to emptySet(), // demonstrate the empty-set (full-schema) alias ) }Schema files
Each top-level type that should appear in
PUBLIC_APIgets@scope(to: ["public"]). Existing@scope(to: ["*"])decorations on framework types (Node, PageInfo, Query/Mutation roots) keep working because*is universal.ViaductConfiguration.ktTest plan
./gradlew :starwarsbuilds and tests pass — the canonical demo test.META-INF/viaduct/schema-scoping.jsonis in the built JAR — explicit assertion in a test that loads the resource at runtime.PUBLIC_APIexecutes a query exercising a@scope(to: ["public"])type — pre-existing test still passes.FULL_ALIASregistration works — querySchemaId("FULL_ALIAS")and assert a non-public-scoped field is reachable, demonstrating the empty-set alias.demoapps/CLAUDE.md, run the full publish-to-maven-local + demo cycle to verify the change through the publication chain.What NOT to migrate
demoapps/cli-starter,jetty-starter,micronaut-starter,ktor-starter,spring-starter— if they don't exercise scopes today, leave them alone (their job is KSP coverage).Out of scope (deferred)
LOC estimate
~120 LOC: ~30 build script + Viaduct config, ~80 schema annotations (likely partly present), ~10 test assertions.
Dependencies
Slices 1–10 must be merged. This slice is the end-to-end smoke test.