Multi-domain openrpc.json: aggregate + per-domain (#82) #84

Merged
timur merged 1 commit from issue-82-multidomain-openrpc into development 2026-05-20 07:48:17 +00:00
Owner

Closes #82.

Summary

  • Generator now writes per-domain <workspace>/docs/<domain>/openrpc.json in addition to the aggregate <workspace>/docs/openrpc.json (kept from #73).
  • Multi-domain builder reads every per-domain file back after the per-domain loop and writes the union as the aggregate via write_aggregate_openrpc_json — fixes the pre-#82 "last domain wins" behaviour for multi-domain services.
  • Single-domain services still emit both files for layout uniformity.
  • Per-domain info.title = "<service>:<domain>" (e.g. RecipeService:recipes); aggregate keeps the unqualified service name. Comment on the choice lives in crates/generator/src/generate/openrpc.rs.
  • Generated server's embedded openrpc.discover payload now points at the per-domain file via include_str!; admin scaffold still loads the aggregate.
  • example/recipe_server regenerated under the new layout.

Test plan

  • cargo build --workspace on hero_rpc clean.
  • cargo test -p hero_rpc_generator --lib — 125 passed.
  • cargo build --workspace on example/recipe_server clean.
  • docs/openrpc.json (aggregate, title=RecipeService) and docs/recipes/openrpc.json (per-domain, title=RecipeService:recipes) both present with same 3 methods + matching schema set.
  • Server osis_server_generated.rs embeds docs/recipes/openrpc.json; admin main.rs embeds docs/openrpc.json.

Follow-up

  • hero_skills#274: scaffold doc update + hero_service template regen (separate PR after this merges).

🤖 Generated with Claude Code

Closes #82. ## Summary - Generator now writes per-domain `<workspace>/docs/<domain>/openrpc.json` in addition to the aggregate `<workspace>/docs/openrpc.json` (kept from #73). - Multi-domain builder reads every per-domain file back after the per-domain loop and writes the union as the aggregate via `write_aggregate_openrpc_json` — fixes the pre-#82 "last domain wins" behaviour for multi-domain services. - Single-domain services still emit both files for layout uniformity. - Per-domain `info.title` = `"<service>:<domain>"` (e.g. `RecipeService:recipes`); aggregate keeps the unqualified service name. Comment on the choice lives in `crates/generator/src/generate/openrpc.rs`. - Generated server's embedded `openrpc.discover` payload now points at the per-domain file via `include_str!`; admin scaffold still loads the aggregate. - `example/recipe_server` regenerated under the new layout. ## Test plan - [x] `cargo build --workspace` on hero_rpc clean. - [x] `cargo test -p hero_rpc_generator --lib` — 125 passed. - [x] `cargo build --workspace` on `example/recipe_server` clean. - [x] `docs/openrpc.json` (aggregate, title=`RecipeService`) and `docs/recipes/openrpc.json` (per-domain, title=`RecipeService:recipes`) both present with same 3 methods + matching schema set. - [x] Server `osis_server_generated.rs` embeds `docs/recipes/openrpc.json`; admin `main.rs` embeds `docs/openrpc.json`. ## Follow-up - hero_skills#274: scaffold doc update + hero_service template regen (separate PR after this merges). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(generator): emit per-domain openrpc.json alongside aggregate (#82)
Some checks failed
Test / test (push) Failing after 2m14s
Test / test (pull_request) Failing after 2m10s
d080aa0e4e
The generator now writes both `<workspace>/docs/openrpc.json` (aggregate
across every domain — pre-#82 behaviour from #73) and per-domain
`<workspace>/docs/<domain>/openrpc.json` files. Per-domain specs are useful
for SDK generators that want a focused single-domain contract, OpenAPI
tooling that filters to one domain, and as the `include_str!` target for
the per-domain server's `openrpc.discover` payload. The aggregate stays
the canonical workspace-root spec consumed by `<hero-api-docs>` in the
scaffolded `_admin`.

Per-domain `info.title` is `"<service>:<domain>"` (e.g.
`RecipeService:recipes`); the colon mirrors the `Service.method` notation
used for OpenRPC method names. Aggregate keeps the unqualified service
name so existing consumers stay backwards-compatible.

Single-domain services still emit both files for layout uniformity. The
multi-domain builder reads every per-domain file back after the loop and
writes the union as the aggregate (`write_aggregate_openrpc_json`), so
the aggregate is correct across N domains instead of "last domain wins".

`example/recipe_server` regenerated under the new layout: server's
embedded spec is now `docs/recipes/openrpc.json`, admin still loads the
aggregate at `docs/openrpc.json`, full workspace builds clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
timur merged commit 345b933a89 into development 2026-05-20 07:48:17 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_rpc!84
No description provided.