Upgrade example/recipe_server to end-to-end demo of new pattern #57

Open
opened 2026-05-18 12:37:10 +00:00 by timur · 3 comments
Owner

Goal

The example/recipe_server/ is the in-tree reference for hero_rpc users. Today it predates the current standards and won't pass lab infocheck. Upgrade it to be the end-to-end demo of the new scaffold-then-generate flow.

Scope

After the scaffold (#scaffold-full-service-repo) and codegen-alignment (#codegen-alignment) issues land, regenerate example/recipe_server/ from scratch using:

hero_rpc scaffold recipes --schema schemas/recipes/recipes.oschema --out example/recipe_server

Result should include:

  • Workspace with hero_recipes_server, hero_recipes_sdk, hero_recipes_admin, hero_recipes_examples crates.
  • service.toml at each binary crate root (generated, not hand-edited).
  • build.rs per binary reduced to ≤5 lines.
  • Generated SDK actually used by hero_recipes_examples (no hand-rolled client).
  • _admin binary serving the framework default screens at admin.sock + a recipes-specific page.
  • Pre-filled RecipeServiceTrait impl demonstrating both a CRUD-only method and a custom business-logic method.
  • README walking through: 1) what was scaffolded, 2) what the user edits (the trait impl), 3) what cargo build regenerates, 4) lab service recipes --start to run it.

Stretch — AI-driven narrative

Document (and ideally script) the flow:

  1. Agent reads the scaffold skill (#hero_skills issue) for context.
  2. Agent calls hero_rpc scaffold with the user's name + schema.
  3. Agent fills in the preserved trait stubs based on a higher-level task description.
  4. Agent runs cargo build (which triggers codegen) and lab infocheck until clean.

This is the example that makes hero_rpc tangible for both humans and agents — referenced by the new context skill.

Acceptance

  • cd example/recipe_server && cargo build && lab infocheck all succeed cleanly.
  • lab service recipes --start works and curl --unix-socket .../rpc.sock /health returns ok.
  • README documents the AI-driven workflow with copy-pasteable commands.
  • petstore_server / petstore_client examples are either deleted (if redundant) or kept with a note explaining when each pattern applies.

Depends on

  • #scaffold-full-service-repo
  • #codegen-alignment
  • #generator-build-rs-modularization
  • hero_website_framework issues (for the _admin crate to wire cleanly)
## Goal The `example/recipe_server/` is the in-tree reference for hero_rpc users. Today it predates the current standards and won't pass `lab infocheck`. Upgrade it to be the **end-to-end demo** of the new scaffold-then-generate flow. ## Scope After the scaffold (#scaffold-full-service-repo) and codegen-alignment (#codegen-alignment) issues land, regenerate `example/recipe_server/` from scratch using: ``` hero_rpc scaffold recipes --schema schemas/recipes/recipes.oschema --out example/recipe_server ``` Result should include: - Workspace with `hero_recipes_server`, `hero_recipes_sdk`, `hero_recipes_admin`, `hero_recipes_examples` crates. - `service.toml` at each binary crate root (generated, not hand-edited). - `build.rs` per binary reduced to ≤5 lines. - Generated SDK actually used by `hero_recipes_examples` (no hand-rolled client). - `_admin` binary serving the framework default screens at `admin.sock` + a recipes-specific page. - Pre-filled `RecipeServiceTrait` impl demonstrating both a CRUD-only method and a custom business-logic method. - README walking through: 1) what was scaffolded, 2) what the user edits (the trait impl), 3) what `cargo build` regenerates, 4) `lab service recipes --start` to run it. ## Stretch — AI-driven narrative Document (and ideally script) the flow: 1. Agent reads the scaffold skill (#hero_skills issue) for context. 2. Agent calls `hero_rpc scaffold` with the user's name + schema. 3. Agent fills in the preserved trait stubs based on a higher-level task description. 4. Agent runs `cargo build` (which triggers codegen) and `lab infocheck` until clean. This is the example that makes hero_rpc tangible for both humans and agents — referenced by the new context skill. ## Acceptance - `cd example/recipe_server && cargo build && lab infocheck` all succeed cleanly. - `lab service recipes --start` works and `curl --unix-socket .../rpc.sock /health` returns ok. - README documents the AI-driven workflow with copy-pasteable commands. - `petstore_server` / `petstore_client` examples are either deleted (if redundant) or kept with a note explaining when each pattern applies. ## Depends on - #scaffold-full-service-repo - #codegen-alignment - #generator-build-rs-modularization - hero_website_framework issues (for the `_admin` crate to wire cleanly)
Author
Owner

Parent / context tracker: hero_skills#262 — read it before starting work on this issue. Locked decisions, reference materials, and execution order live there. Iterate via comments here; consolidation passes on the body only after feedback settles.

Parent / context tracker: [hero_skills#262](https://forge.ourworld.tf/lhumina_code/hero_skills/issues/262) — read it before starting work on this issue. Locked decisions, reference materials, and execution order live there. Iterate via comments here; consolidation passes on the body only after feedback settles.
Author
Owner

State refresh

Pulled latest. example/recipe_server/build.rs is unchanged (still 42 lines, hand-rolled rustfmt pass, hand-listed output paths). Upgrade work in this issue is still entirely pending.

Still depends on #54, #55, #56 landing first.

## State refresh Pulled latest. `example/recipe_server/build.rs` is unchanged (still 42 lines, hand-rolled rustfmt pass, hand-listed output paths). Upgrade work in this issue is still entirely pending. Still depends on [#54](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/54), [#55](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/55), [#56](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/56) landing first.
Author
Owner

Status — recipe_server upgraded to end-to-end demo

Branch: issue-57-recipe-server-e2e (off development, all four dep issues #54/#55/#56/#60 already merged). Commit: 13ee65c.

What landed

  • Regenerated from scratch via the scaffolder. The legacy single-crate recipe_server is gone — replaced by what hero_rpc_generator --name hero_recipes --workspace-dir example/recipe_server produces. 5 crates: hero_recipes, hero_recipes_server, hero_recipes_sdk, hero_recipes_rhai, hero_recipes_admin, hero_recipes_examples.
  • Independent workspace. example/recipe_server is now excluded from the parent hero_rpc workspace and carries its own [workspace] block — same shape downstream users get when they scaffold into their own repo.
  • In-tree compile via [patch]. The scaffolded Cargo.toml pins hero_rpc_* + hero_lifecycle to git URL on development; a single [patch."https://forge.ourworld.tf/lhumina_code/hero_rpc.git"] block at the workspace root remaps them to the sibling ../../crates/* so the in-tree demo builds against the current branch. Users scaffolding into their own repo don't need this block.
  • service.toml per binary, no Makefile. Both hero_recipes_server and hero_recipes_admin carry service.toml, use service_base!(), validate_service_toml, handle_info_flag, print_startup_banner, prepare_sockets (the §5 boilerplate from #55). No Makefile, no scripts/*.sh, no service_recipes.nu (ADR-0001).
  • RecipeServiceTrait impl filled. Demonstrates both patterns from the issue body: get_by_category/get_by_difficulty as read-only filters composed over the auto-CRUD primitives, and add_to_collection as cross-object business logic.
  • hero_recipes_admin consumes hero_admin_lib. Standard routes (/health, /.well-known/heroservice.json, /static/shared/*) come from the framework. Service-specific surface: a /recipes page embedding <hero-api-docs> against a build-time-included copy of the OpenRPC spec (/openrpc.json on the admin socket).
  • README walks the AI-driven flow. example/recipe_server/README.md covers: scaffolded layout, the two files you actually write (.oschema + rpc.rs), what cargo build regenerates (table), the build/run loop with lab service recipes --install --start, smoke-test curl commands, the 6-step agent workflow, and how to add a domain.
  • example/README.md indexes the four examples and explains when to use each (scaffold flow vs. recipe_sdk_rpc2 vs. petstore_). Per the issue: petstore_ kept with the explanatory note — they remain the reference for the hand-written OpenRPC pattern.

Acceptance evidence

  • cd example/recipe_server && cargo build --workspaceclean (one upstream unused-import warning in types_generated.rs from the codegen; pre-existing, not introduced here).
  • cargo build --workspace at the hero_rpc parent — clean.
  • hero_recipes_server --info / --info --json — embedded service.toml parses, the JSON descriptor is canonical.
  • Live JSON-RPC round trip on the UDS:
    • GET /health{"status":"ok",...}
    • GET /openrpc.json → 26 methods (5 auto-CRUD × 2 root objects + 3 custom + 11 standard rpc.*/system.*)
    • POST /rpc recipe.list → list of 17 SIDs (server picked up seed data from ~/hero/var/data/...)
    • POST /rpc RecipeService.get_by_category {"category":"dessert"} → typed slice
  • lab infocheckhero_recipes_server and hero_recipes_admin both clean. The four other failures (crates/generator, crates/hero_lifecycle, example/petstore_*) are pre-existing in hero_rpc and outside the scope of #57.
  • cargo test -p hero_rpc_generator --lib — 125 passed (scaffolder tests still green).

Out of scope / follow-ups

  • Pre-existing infocheck failures on generator, hero_lifecycle, petstore_server, petstore_client should be its own cleanup pass — not landed here so this PR stays focused on #57.
  • The scaffolder still emits a multi-line core-crate build.rs (~25 lines: OschemaBuildConfig::new().schemas_dir(...).client_crate_dir(...)...). The literal "≤5-line build.rs" target only fully kicks in once from_service_toml() works for the core crate too (today it's binary-only). Counted as a minor follow-up.

Branch ready to PR

https://forge.ourworld.tf/lhumina_code/hero_rpc/compare/development...issue-57-recipe-server-e2e

## Status — recipe_server upgraded to end-to-end demo Branch: [`issue-57-recipe-server-e2e`](https://forge.ourworld.tf/lhumina_code/hero_rpc/src/branch/issue-57-recipe-server-e2e) (off `development`, all four dep issues #54/#55/#56/#60 already merged). Commit: [`13ee65c`](https://forge.ourworld.tf/lhumina_code/hero_rpc/commit/13ee65c). ### What landed - **Regenerated from scratch via the scaffolder.** The legacy single-crate `recipe_server` is gone — replaced by what `hero_rpc_generator --name hero_recipes --workspace-dir example/recipe_server` produces. 5 crates: `hero_recipes`, `hero_recipes_server`, `hero_recipes_sdk`, `hero_recipes_rhai`, `hero_recipes_admin`, `hero_recipes_examples`. - **Independent workspace.** `example/recipe_server` is now `exclude`d from the parent hero_rpc workspace and carries its own `[workspace]` block — same shape downstream users get when they scaffold into their own repo. - **In-tree compile via `[patch]`.** The scaffolded `Cargo.toml` pins `hero_rpc_*` + `hero_lifecycle` to git URL on `development`; a single `[patch."https://forge.ourworld.tf/lhumina_code/hero_rpc.git"]` block at the workspace root remaps them to the sibling `../../crates/*` so the in-tree demo builds against the current branch. Users scaffolding into their own repo don't need this block. - **`service.toml` per binary, no Makefile.** Both `hero_recipes_server` and `hero_recipes_admin` carry `service.toml`, use `service_base!()`, `validate_service_toml`, `handle_info_flag`, `print_startup_banner`, `prepare_sockets` (the §5 boilerplate from #55). No `Makefile`, no `scripts/*.sh`, no `service_recipes.nu` (ADR-0001). - **`RecipeServiceTrait` impl filled.** Demonstrates both patterns from the issue body: `get_by_category`/`get_by_difficulty` as read-only filters composed over the auto-CRUD primitives, and `add_to_collection` as cross-object business logic. - **`hero_recipes_admin` consumes `hero_admin_lib`.** Standard routes (`/health`, `/.well-known/heroservice.json`, `/static/shared/*`) come from the framework. Service-specific surface: a `/recipes` page embedding `<hero-api-docs>` against a build-time-included copy of the OpenRPC spec (`/openrpc.json` on the admin socket). - **README walks the AI-driven flow.** `example/recipe_server/README.md` covers: scaffolded layout, the two files you actually write (`.oschema` + `rpc.rs`), what `cargo build` regenerates (table), the build/run loop with `lab service recipes --install --start`, smoke-test curl commands, the 6-step agent workflow, and how to add a domain. - **`example/README.md`** indexes the four examples and explains when to use each (scaffold flow vs. recipe_sdk_rpc2 vs. petstore_*). Per the issue: petstore_* kept with the explanatory note — they remain the reference for the hand-written OpenRPC pattern. ### Acceptance evidence - `cd example/recipe_server && cargo build --workspace` — **clean** (one upstream unused-import warning in `types_generated.rs` from the codegen; pre-existing, not introduced here). - `cargo build --workspace` at the hero_rpc parent — **clean**. - `hero_recipes_server --info` / `--info --json` — embedded `service.toml` parses, the JSON descriptor is canonical. - Live JSON-RPC round trip on the UDS: - `GET /health` → `{"status":"ok",...}` - `GET /openrpc.json` → 26 methods (5 auto-CRUD × 2 root objects + 3 custom + 11 standard `rpc.*`/`system.*`) - `POST /rpc` `recipe.list` → list of 17 SIDs (server picked up seed data from `~/hero/var/data/...`) - `POST /rpc` `RecipeService.get_by_category {"category":"dessert"}` → typed slice - `lab infocheck` — `hero_recipes_server` and `hero_recipes_admin` both clean. The four other failures (`crates/generator`, `crates/hero_lifecycle`, `example/petstore_*`) are pre-existing in hero_rpc and outside the scope of #57. - `cargo test -p hero_rpc_generator --lib` — 125 passed (scaffolder tests still green). ### Out of scope / follow-ups - Pre-existing infocheck failures on `generator`, `hero_lifecycle`, `petstore_server`, `petstore_client` should be its own cleanup pass — not landed here so this PR stays focused on #57. - The scaffolder still emits a multi-line core-crate `build.rs` (~25 lines: `OschemaBuildConfig::new().schemas_dir(...).client_crate_dir(...)...`). The literal "≤5-line build.rs" target only fully kicks in once `from_service_toml()` works for the core crate too (today it's binary-only). Counted as a minor follow-up. ### Branch ready to PR https://forge.ourworld.tf/lhumina_code/hero_rpc/compare/development...issue-57-recipe-server-e2e
Sign in to join this conversation.
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#57
No description provided.