docs: migrate docs to the jobs model#20
Conversation
WalkthroughThe PR replaces command-side “Services” terminology with “Jobs” across the spec and documentation, updates example handler signatures and job-queue usage, adds crash-safety and naming guidance, and revises contributor notes plus the simple example README. ChangesJobs documentation shift
Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
How to use the Graphite Merge QueueAdd the label add-to-gt-merge-queue to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has required the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
9a4b95f to
a7d1b09
Compare
7b0f794 to
2e99de9
Compare
a7d1b09 to
bfcb3db
Compare
bfcb3db to
1760f55
Compare
48ee433 to
500ca31
Compare
1760f55 to
6cc8e9f
Compare
500ca31 to
d6cd320
Compare
6cc8e9f to
f2752ab
Compare
d6cd320 to
a8f14b3
Compare
9947e4e to
9d1a600
Compare
a8f14b3 to
4947d61
Compare
4947d61 to
718b565
Compare
9d1a600 to
95a21bd
Compare
718b565 to
8d31830
Compare
95a21bd to
3cfa702
Compare
3cfa702 to
ec562c0
Compare
8d31830 to
cdaabcd
Compare
Co-authored-by: Cursor <cursoragent@cursor.com>
ec562c0 to
2d6d324
Compare
cdaabcd to
1f2408b
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/cqrs.md`:
- Around line 245-311: The worker example is converting the job backend to
storage twice, because build_supervised_worker! already handles the storage
conversion internally. Update the jobs worker example that uses
JobBackend::<PlaceOrder> so it passes backend directly instead of
backend.into_storage(), while keeping the existing Job, WORKER_NAME, KIND, and
label() usage unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 22f5855f-44b1-4067-b2e5-11dae74f55d4
📒 Files selected for processing (6)
AGENTS.mdREADME.mdSPEC.mddocs/cqrs.mddocs/domain.mdexamples/simple/README.md
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: Graphite / mergeability_check
🧰 Additional context used
📓 Path-based instructions (5)
README.md
📄 CodeRabbit inference engine (AGENTS.md)
Update
README.mdwhen project structure, features, commands, or architecture change.
Files:
README.md
*
⚙️ CodeRabbit configuration file
Focus on providing constructive criticism. Whenever you see a suboptimal approach, suggest more idiomatic or robust alternative(s). Flag potential footguns. Suggest FP alternatives to mutable/imperative code. Point out architectural flaws like leaky abstractions, tight coupling, wrong level of abstraction, poor type modeling, over-abstraction, unclear domain boundaries. Code should generally be organized based on business concerns rather than technical aspects - suggest improvements if you find violations. Point out gaps in test coverage but suggest tests that are not too coupled to the implementation and actually test domain invariants and business logic
Files:
README.mdAGENTS.mdSPEC.md
**/*.md
⚙️ CodeRabbit configuration file
Focus on the contents of the docs and not on cosmetic things like markdown formatting. We use markdown files for various docs including but not limited to guidelines for AI contributors (AGENTS.md), project overview and instructions for human contributors (README.md), and topic-focused references under docs/ (cqrs.md, sqlx.md, ttdd.md). Think about the target audience of a document when deciding what comment to leave. For instructions, suggest better rules and guidelines and point out missing instructions. For topic references, suggest improvements that would make non-obvious framework behavior or pitfalls easier to discover. In all cases, flag needless bloat, prefer clear concise writing, and consider the structure of the document and order of the sections
Files:
README.mdAGENTS.mddocs/domain.mdexamples/simple/README.mdSPEC.mddocs/cqrs.md
AGENTS.md
📄 CodeRabbit inference engine (CLAUDE.md)
Refer to AGENTS.md documentation for agent-specific guidelines and requirements
When editing
AGENTS.md, keep the file under 40,000 characters and usewc -c AGENTS.mdto check the size; if it exceeds the limit, condense explanations rather than removing guidelines.
Files:
AGENTS.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Update or add documentation under
docs/when research or trial-and-error reveals non-obvious patterns, pitfalls, or framework behavior; prioritize documenting framework idioms, integration gotchas, and failures like "X doesn't work because Y".
Files:
docs/domain.mddocs/cqrs.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Before doing any work, read `SPEC.md` and `docs/domain.md`; read `docs/cqrs.md`, `docs/sqlx.md`, and `docs/ttdd.md` when they are relevant to the task.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Treat `SPEC.md` as the source of truth: new features must be spec'ed there first, and if a change contradicts the spec, update the spec first with user approval or change the implementation approach.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Follow the project document hierarchy: SPEC.md first, then ROADMAP.md/GitHub issues, then planning, then tests, then implementation.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Organize planning around the goal and decompose epics by coupling boundaries so each branch is independently valid, with shared dependencies extracted first and integration deferred to the end.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Every pull request must be associated with at least one Linear issue, and split PRs must have split issues/sub-issues that each PR references or closes.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Keep pull requests small: prefer under 500 additions, allow up to 1,000 only when splitting would be artificial, and split larger work when possible.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Keep a granular task list for the current request and remove completed tasks from the active list as work progresses.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: All new or modified logic must have corresponding test coverage before moving on.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Before implementing, deeply understand the task by reading relevant docs and source, forming and critiquing an initial approach, and keeping the resulting diff small and reviewable.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: If the user asks a question or a new approach is proposed, answer first and do not silently change direction; ask for confirmation before changing approach unless the user already clearly told you to proceed.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: When the user points out a bug or problem, fix it immediately and re-evaluate the rest of the session work for similar issues.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: If user action is required and the task is blocked, stop after stating what you need; if not blocked, continue but clearly state the request when stopping.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: If a significant architectural decision is not already covered by docs, write an ADR under `adrs/$INDEX-$PROPOSAL_NAME.md`, summarize it for the user, and stop for review before proceeding.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Before handing over, self-review the diff, revert unjustified changes, and remove any scope creep.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Use `cargo check`, `cargo nextest run`, `cargo clippy`, and `cargo fmt` as the normal verification flow; do not use `cargo build` for routine verification.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Never manually create migration files; use `sqlx migrate add <migration_name>` instead, and do not add further migrations to the `events` table after the initial one.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Never manually edit `Cargo.toml` to add dependencies; use `cargo add` so version resolution and features are handled correctly.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Do not run commands just to show output, do not run speculative binaries, and do not write ad-hoc scripts for debugging or automation.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: In consuming applications, each aggregate must have exactly one `SqliteCqrs<A>` instance created once at startup; do not construct it per request except in tests, CLI, or migration code.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Never write directly to the `events` table; always emit events through `CqrsFramework::execute()` or `execute_with_metadata()`.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Use cqrs-es services for side effects in aggregate `handle()` methods so event emission and side effects remain atomic.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Log command execution in the aggregate's `handle()` method, not at the call site.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Model invalid states in types: use ADTs/enums, newtypes, and typestate rather than runtime validation when possible.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Accept domain newtypes and convert to SDK primitives inside the callee, except at cross-crate boundaries where the callee cannot depend on caller domain types.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Keep schemas consistent with type modeling: avoid contradictory columns and avoid denormalized columns that can be computed from other data.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Prefer functional/ADT patterns, iterators, and pattern matching over imperative loops unless complexity increases.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Follow the import organization rule: external imports first, then workspace imports, then crate-internal imports; no function-level imports except enum-variant imports inside function bodies.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Use top-of-module imports only, qualify imports only when needed to prevent ambiguity, and keep test-module imports inside the test module itself.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Do not use `unwrap()` or `.expect()` in production code; they are acceptable in test code only.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Design error types without opaque `String` payloads; prefer typed variants, `#[from]`, `?`, `#[source]`, and context-preserving error handling.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Always log a warning or error before an early return in `let-else` or similar patterns that would otherwise fail silently.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Keep visibility as restrictive as possible, preferring private items over `pub(crate)` over `pub`.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Only add type aliases when clippy requires them for type complexity; otherwise prefer the full type or use newtypes to distinguish concepts.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Never silently mask numeric failures: no capping, fallback defaults, precision truncation, or `unwrap_or*` on numeric values; use explicit error handling and checked conversions.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Never read files containing secrets or sensitive configuration without explicit user permission; treat `.env*`, key/cert files, and sensitive databases as protected.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Test strategy: use in-memory SQLite databases via `sqlite_es::testing::create_test_pool()`, cover edge cases, and keep most coverage in unit tests.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Tests must assert correct behavior, not document known gaps; do not delete, skip, or bypass existing tests to ease a refactor.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Prefer property-based testing with `proptest` when invariants, roundtrips, boundaries, or numeric edge cases are a good fit.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Use `assert_eq!` with exact values in tests; avoid `assert!(is_some())`, `assert!(is_err())`, and `assert!(is_ok())`, and assert serialized output against literals like `json!()`.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: In production code, prefer exhaustive `match` over `matches!` so the compiler catches new variants; `matches!` is acceptable in tests.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Use ASCII in identifiers, comments, log messages, and config keys; use unicode only in user-facing string literals when it improves readability.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Do not use single-letter variable names, arguments, or generic type parameters except for short, unambiguous closures.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Keep modules flat by default, put public API before private implementation and tests, and add a `//!` docstring to every module.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Keep doc comment and long macro string lines under 100 characters.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Use no one-line helpers; inline single-expression helpers unless they encapsulate multi-step logic.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Do not split simple-but-long pattern matches into tiny helpers; keep a single match when arms are trivial, even if it exceeds line-count lints, and ask for permission before suppressing such lints.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: During development, scope checks to the active package first, then run full workspace checks before handover.
Learnt from: CR
Repo: ST0x-Technology/event-sorcery
Timestamp: 2026-06-27T03:19:38.104Z
Learning: Never bypass, disable, or suppress quality-control mechanisms without explicit permission; if a lint seems intentional, request permission before suppressing it.
🪛 LanguageTool
examples/simple/README.md
[grammar] ~5-~5: Use a hyphen to join words.
Context: ...d a materialized view backed by a SQLite generated column for filtered queries. ...
(QB_NEW_EN_HYPHEN)
🔇 Additional comments (19)
SPEC.md (4)
89-90: LGTM!
102-106: LGTM!
200-224: LGTM!
146-171: No issueJobBackend<J>is the worker-side apalis storage wrapper for a single job type, so the description is accurate.docs/cqrs.md (3)
72-77: LGTM!
89-92: LGTM!
683-707: LGTM!docs/domain.md (3)
60-67: LGTM!
130-143: LGTM!
195-207: LGTM!AGENTS.md (4)
31-31: LGTM!
126-132: LGTM!
229-229: LGTM!
325-328: No issue:nushellis already included in the dev shell, so the scripting policy matches the project tooling.> Likely an incorrect or invalid review comment.README.md (1)
38-38: LGTM!examples/simple/README.md (4)
4-5: 🎯 Functional Correctness | ⚡ Quick winAmbiguous phrasing: "commands carry... a materialized view"
Line 5 parses as if the commands carry both a timestamp and a materialized view, which is impossible. The "whose" antecedent (
SupportTicketaggregate) should distribute clearly across two predicates. Insert a comma before "and" or restructure:-`Open -> Pending -> Closed`, whose commands carry their own timestamp and a -materialized view backed by a SQLite generated column for filtered queries. +`Open -> Pending -> Closed`, whose commands carry their own timestamp, with a +materialized view backed by a SQLite generated column for filtered queries.Or more explicitly:
-`Open -> Pending -> Closed`, whose commands carry their own timestamp and a -materialized view backed by a SQLite generated column for filtered queries. +`Open -> Pending -> Closed`. Commands carry their own timestamp; a +materialized view backed by a SQLite generated column enables filtered queries.
22-23: LGTM!
51-57: 🎯 Functional Correctness | ⚡ Quick winBroken inline code span across line break.
Lines 54-55 split
`Open { subject,andat }`across two lines. Most Markdown renderers will break the inline code span at the newline or render it incorrectly. Keep each code fragment on one line:-`Open { subject, -at }`, `Close { at }`. Production passes `chrono::Utc::now()`; +`Open { subject, at }`, `Close { at }`. Production passes `chrono::Utc::now()`;Also consider mentioning
AwaitCustomer { at }since it completes theOpen -> Pending -> Closedflow described in the opening.
59-63:jobs![...]matches the crate macro syntax.
| ## Jobs Pattern | ||
|
|
||
| Handlers are sync and pure: they must not call external systems. Side-effecting | ||
| work is enqueued as a durable job and runs in a separate worker. The enqueue | ||
| commits in the same SQLite transaction as the events that triggered it, so a job | ||
| exists iff its events do. | ||
|
|
||
| The worker retries `perform` on failure and re-runs it after a crash, so jobs | ||
| are delivered **at-least-once** -- `perform` must be idempotent. Carry any dedup | ||
| key in the job payload or `Input`. | ||
|
|
||
| Declare a job and the entity's job list: | ||
|
|
||
| ```rust | ||
| #[derive(Serialize, Deserialize)] | ||
| struct PlaceOrder { order_id: OrderId, quantity: u32 } | ||
|
|
||
| impl Job for PlaceOrder { | ||
| type Input = Arc<dyn OrderPlacer>; // dependency bundle, injected by the worker | ||
| type Output = (); | ||
| type Error = PlaceOrderError; | ||
|
|
||
| Inject external dependencies into command handlers: | ||
| const WORKER_NAME: &'static str = "place-order"; | ||
| const KIND: &'static str = "PlaceOrder"; | ||
|
|
||
| fn label(&self) -> Label { Label(format!("place-order:{}", self.order_id)) } | ||
|
|
||
| async fn perform(&self, placer: &Self::Input) -> Result<(), Self::Error> { | ||
| placer.place_order(self.order_id, self.quantity).await | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ```rust | ||
| type Services = Arc<dyn OrderPlacer>; | ||
| type Jobs = jobs![PlaceOrder]; // Nil if the entity dispatches none | ||
| ``` | ||
|
|
||
| async fn transition( | ||
| Enqueue from a handler through the `jobs` handle. `push` is synchronous and | ||
| buffers; the framework flushes the buffer at commit. `push::<J>` only compiles | ||
| when `J` is in the entity's `Jobs` list (`HasJob<J>`): | ||
|
|
||
| ```rust | ||
| fn transition( | ||
| &self, | ||
| command: Self::Command, | ||
| services: &Self::Services, | ||
| jobs: &mut JobQueue<Self::Jobs>, | ||
| ) -> Result<Vec<Self::Event>, Self::Error> { | ||
| let result = services.place_order(/* ... */).await?; | ||
| Ok(vec![MyEvent::OrderPlaced { /* ... */ }]) | ||
| jobs.push(PlaceOrder { order_id: self.id, quantity: command.quantity }); | ||
| Ok(vec![MyEvent::OrderRequested { /* ... */ }]) | ||
| } | ||
| ``` | ||
|
|
||
| Pass services when building the `Store`: | ||
| A queued row is never observable mid-handler -- the push is buffered, not a live | ||
| `INSERT`. Reads a handler once did via `Services` (clock, config, idempotency | ||
| keys) move into the `Command`; the caller supplies them at dispatch time. | ||
|
|
||
| Run the jobs in a worker, wired with the shared retry/backoff/circuit-breaker | ||
| policy. `Input` is the only context handed in: | ||
|
|
||
| ```rust | ||
| let store = StoreBuilder::<MyEntity>::new(pool) | ||
| .build(services) | ||
| .await?; | ||
| ``` | ||
| let placer: Arc<dyn OrderPlacer> = Arc::new(/* ... */); | ||
| let backend = JobBackend::<PlaceOrder>::new(&pool); | ||
|
|
||
| For entities that don't need services, use `type Services = ()`. | ||
| Monitor::new().register(build_supervised_worker!( | ||
| ::<PlaceOrder>, 0, backend.into_storage(), placer, fail_stop, failure_notify, | ||
| )); | ||
| ``` |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify Job trait definition and its required items
rg -n "trait Job" --type=rust -A 30
rg -n "WORKER_NAME|TERMINAL_FAILURE_MSG|fn label" --type=rustRepository: ST0x-Technology/event-sorcery
Length of output: 167
🏁 Script executed:
#!/bin/bash
# Verify build_supervised_worker! macro definition and usage
rg -n "macro_rules! build_supervised_worker" --type=rust -A 20Repository: ST0x-Technology/event-sorcery
Length of output: 167
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the repository and locate relevant Rust/doc files
git ls-files | sed -n '1,220p'Repository: ST0x-Technology/event-sorcery
Length of output: 1924
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the Job trait and the worker helper definitions/usages
sed -n '1,240p' crates/event-sorcery/src/job.rs
printf '\n---\n'
rg -n "build_supervised_worker|supervised_worker|Worker" crates/event-sorcery crates/sqlite-es examples docs -S -g '!target'Repository: ST0x-Technology/event-sorcery
Length of output: 9922
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the build_supervised_worker! macro definition and nearby usage
sed -n '420,560p' crates/event-sorcery/src/job.rs
printf '\n---\n'
sed -n '800,850p' crates/event-sorcery/src/job.rs
printf '\n---\n'
sed -n '280,320p' docs/cqrs.mdRepository: ST0x-Technology/event-sorcery
Length of output: 8036
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect JobBackend::into_storage and the surrounding API
rg -n "fn into_storage|into_storage\\(" crates/event-sorcery/src/job.rs -A 8 -B 8Repository: ST0x-Technology/event-sorcery
Length of output: 1210
Fix the worker example to pass JobBackend directly.
Job, WORKER_NAME, KIND, TERMINAL_FAILURE_MSG, and label() match the API, but build_supervised_worker! already calls .into_storage() internally. Pass backend, not backend.into_storage(), or the example will try to convert the storage twice. docs/cqrs.md:304-311
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/cqrs.md` around lines 245 - 311, The worker example is converting the
job backend to storage twice, because build_supervised_worker! already handles
the storage conversion internally. Update the jobs worker example that uses
JobBackend::<PlaceOrder> so it passes backend directly instead of
backend.into_storage(), while keeping the existing Job, WORKER_NAME, KIND, and
label() usage unchanged.

Motivation
The README, SPEC, domain terminology, and CQRS docs still describe the removed
Servicesmodel. The docs need to teach the jobs API separately from the example crate migration.Solution
Servicesto the jobs model.JobQueue, worker wiring, and the updated examples at the documentation layer.Closes RAI-946.
Summary by CodeRabbit