@spree/docs 0.1.85 → 0.1.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,8 +7,6 @@ description: "Overview of the Spree Admin REST API for managing products, orders
7
7
  import { Since } from '/snippets/since.mdx';
8
8
 
9
9
 
10
- > **WARNING:** **Developer Preview.** The Admin API is in active development and may change between major versions.
11
-
12
10
  The Admin API is a REST API for managing Spree stores programmatically — products, orders, customers, fulfillments, payments, and more. It is intended for backend integrations, custom admin tooling, and automation.
13
11
 
14
12
  All routes are prefixed with `/api/v3/admin`. During development the API is available under `http://localhost:3000/api/v3/admin`. For production, replace `http://localhost:3000` with your Spree application URL.
@@ -55,16 +53,6 @@ const { data: orders } = await client.orders.list({
55
53
  })
56
54
  ```
57
55
 
58
- ## What's covered
59
-
60
- The Admin API today (in Spree 5.5) covers:
61
-
62
- - **Catalog** — products, variants, prices
63
- - **Orders** — list, create, update, items, complete, cancel, approve, resume; nested fulfillments, payments, refunds, gift cards, store credits
64
- - **Customers** — full CRUD, addresses, store credits, credit cards
65
-
66
- See the **Endpoints** section in the sidebar for the complete reference, generated from the OpenAPI spec.
67
-
68
56
  Before integrating, read:
69
57
 
70
58
  - [Authentication](authentication.md) — secret API keys, scopes, and JWT tokens
@@ -0,0 +1,64 @@
1
+ ---
2
+ title: "Agent Skills"
3
+ sidebarTitle: Agent Skills
4
+ description: "Teach your AI coding agent Spree's conventions — 25 installable skills, a Spree expert subagent, slash commands, and safety hooks."
5
+ ---
6
+
7
+ [spree/agent-skills](https://github.com/spree/agent-skills) is a collection of agent skills for Spree Commerce. Skills are markdown instructions your coding agent loads on demand — they encode Spree's conventions, customization decision trees, API patterns, and upgrade flows, so the agent does things the Spree way instead of improvising from training data.
8
+
9
+ The skills work with Claude Code, Codex, Cursor, GitHub Copilot, Cline, Aider, Zed, Windsurf, OpenCode, and 60+ other agentic tools.
10
+
11
+ ## Install
12
+
13
+ Run from your project directory:
14
+
15
+ ```bash
16
+ npx skills add spree/agent-skills
17
+ ```
18
+
19
+ The [skills CLI](https://github.com/vercel-labs/skills) auto-detects which agent tools you have configured and copies the skill files into each tool's native location.
20
+
21
+ Useful variants:
22
+
23
+ ```bash
24
+ npx skills add spree/agent-skills --list # see what's available without installing
25
+ npx skills add spree/agent-skills --skill spree-api-v3 # install a subset
26
+ npx skills update # update installed skills later
27
+ ```
28
+
29
+ ## What's inside
30
+
31
+ | | |
32
+ |---|---|
33
+ | **25 skills** | Project conventions, the customization decision tree (subscriber vs decorator vs dependency injection vs generator), the v3 Store + Admin API, the `spree:model` / `spree:api_resource` generators, TypeScript SDKs, upgrades, and domain deep-dives: catalog, checkout, payments, promotions, pricing, shipping, i18n, testing, security, performance, deployment. |
34
+ | **`spree-expert` subagent** | A Claude Code agent for multi-step investigations (upgrade audits, checkout-flow debugging, API surface planning). It researches in its own context window and returns a focused report, keeping your main session lean. |
35
+ | **2 slash commands** | `/spree:doctor` diagnoses the local dev stack (containers, env, migrations, job queues) and prescribes fixes. `/spree:audit-upgrade [version]` runs a read-only upgrade-readiness audit against your codebase. |
36
+ | **2 safety hooks** | Block destructive database commands (`db:drop`, `DROP TABLE spree_*`, mass deletes, force-pushes to main) and warn when an edit introduces a hardcoded secret (Stripe live keys, AWS keys, API tokens). Disable with `SPREE_HOOKS_DISABLE=1`. |
37
+
38
+ Skills activate automatically based on what you're working on — asking your agent to "add a Brand model with an API" pulls in the resource-generator skill; "why is this promotion not applying" pulls in the promotions skill. There's nothing to invoke manually.
39
+
40
+ ## Claude Code plugin (adds commands + hooks)
41
+
42
+ The `npx skills add` path installs the skills and the subagent. The slash commands and safety hooks need the Claude Code plugin install — run inside a Claude Code session:
43
+
44
+ ```text
45
+ /plugin marketplace add spree/agent-skills
46
+ /plugin install spree@spree
47
+ ```
48
+
49
+ The plugin delivers everything the skills CLI does **plus** `/spree:doctor`, `/spree:audit-upgrade`, and the two safety hooks. Use one install path or the other — installing both makes the skills collide.
50
+
51
+ ## Works in any Spree project
52
+
53
+ The skills detect your project flavor before running commands:
54
+
55
+ - **create-spree-app projects** (Docker, Rails app in `backend/`) — commands route through the [Spree CLI](../cli/quickstart.md) (`spree migrate`, `spree console`, …).
56
+ - **Classic Rails apps** (Spree gems in a plain Rails app, no Docker — typical for apps created before Spree 5.4) — the skills fall back to native commands (`bin/rails`, `bundle exec rake`) from the app root.
57
+
58
+ ## Updating
59
+
60
+ ```bash
61
+ npx skills update # skills CLI installs
62
+ ```
63
+
64
+ Plugin installs update through Claude Code's plugin system (`/plugin` → check for updates). New Spree releases ship matching skill updates — update the skills when you upgrade Spree so the guidance matches your installed version.
@@ -0,0 +1,55 @@
1
+ ---
2
+ title: "LLM-Ready Documentation"
3
+ sidebarTitle: LLM-Ready Docs
4
+ description: "Every page of the Spree docs is consumable by LLMs — llms.txt indexes, per-page Markdown, and a local npm package for offline agent reads."
5
+ ---
6
+
7
+ Beyond the [MCP server](mcp.md), the Spree documentation is published in formats designed for direct LLM consumption. Use these when you want to feed docs into a prompt, point a custom agent at an index, or give agents fast local file access.
8
+
9
+ ## llms.txt
10
+
11
+ Following the [llms.txt convention](https://llmstxt.org), two indexes are published:
12
+
13
+ | URL | Contents |
14
+ |---|---|
15
+ | [`spreecommerce.org/docs/llms.txt`](https://spreecommerce.org/docs/llms.txt) | An index of every documentation page with links — lets an agent discover and fetch exactly the pages it needs |
16
+ | [`spreecommerce.org/docs/llms-full.txt`](https://spreecommerce.org/docs/llms-full.txt) | The entire documentation in one file — for tools that ingest a single context dump |
17
+
18
+ ## Per-page Markdown
19
+
20
+ Append `.md` to any docs URL to get the raw Markdown for that page — ideal for fetching a single authoritative page into context:
21
+
22
+ ```text
23
+ https://spreecommerce.org/docs/developer/cli/quickstart.md
24
+ https://spreecommerce.org/docs/developer/core-concepts/orders.md
25
+ ```
26
+
27
+ ## The `@spree/docs` npm package
28
+
29
+ The full developer documentation also ships as an npm package, so agents working in your repository can `Read` doc files locally — no network round-trips, works offline, and version-pinned to what you installed:
30
+
31
+ ```bash
32
+ npm install --save-dev @spree/docs
33
+ ```
34
+
35
+ ```text
36
+ node_modules/@spree/docs/dist/
37
+ ├── developer/
38
+ │ ├── getting-started/ # setup and quickstarts
39
+ │ ├── core-concepts/ # products, orders, payments, inventory, …
40
+ │ ├── customization/ # decorators, dependencies, events, …
41
+ │ ├── storefront/ # Next.js storefront guides
42
+ │ ├── sdk/ # TypeScript SDK docs
43
+ │ ├── admin/ # admin customization, form builder, components
44
+ │ └── how-to/ # focused guides
45
+ └── api-reference/
46
+ └── store.yaml # the full Store API OpenAPI spec
47
+ ```
48
+
49
+ Projects scaffolded with [create-spree-app](../create-spree-app/quickstart.md) install it automatically.
50
+
51
+ > **NOTE:** The package tracks the docs published at install time and is versioned independently of your Spree gems — run your package manager's update to refresh it, and prefer the [MCP server](mcp.md) when you need the absolute latest.
52
+
53
+ ## Generated agent instructions
54
+
55
+ `create-spree-app` scaffolds every project with a `CLAUDE.md` that tells coding agents where the local docs live, which CLI commands to use (`spree dev`, `spree migrate`, `spree console`), and the customization patterns to follow — so an agent dropped into a fresh project is productive without any prompting. The scaffold's next-steps also suggest installing the [agent skills](agent-skills.md) for the full experience.
@@ -0,0 +1,75 @@
1
+ ---
2
+ title: "Docs MCP Server"
3
+ sidebarTitle: MCP
4
+ description: "Connect your AI agent to the Spree documentation MCP server to search and read the latest docs while building."
5
+ ---
6
+
7
+ Spree hosts a [Model Context Protocol](https://modelcontextprotocol.io) server on top of this documentation. Once connected, your agent can search the docs and read full pages on demand — answering questions from the latest published documentation instead of stale training data.
8
+
9
+ ```text
10
+ https://spreecommerce.org/docs/mcp
11
+ ```
12
+
13
+ The server exposes two tools: full-text **search** across the documentation, and **reading** doc pages as Markdown.
14
+
15
+ ## Setup
16
+
17
+ **Claude Code:**
18
+
19
+ ```bash
20
+ claude mcp add --transport http spree-docs https://spreecommerce.org/docs/mcp
21
+ ```
22
+
23
+ Scope it to the project (`--scope project`) to share the connection with your team via `.mcp.json`, or keep the default local scope for just yourself.
24
+
25
+ **Claude.ai / Claude Desktop:**
26
+
27
+ Go to [Settings → Connectors](https://claude.ai/settings/connectors), click **Add custom connector**, and paste the URL:
28
+
29
+ ```text
30
+ https://spreecommerce.org/docs/mcp
31
+ ```
32
+
33
+ **Cursor:**
34
+
35
+ Add to `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` globally):
36
+
37
+ ```json
38
+ {
39
+ "mcpServers": {
40
+ "spree-docs": {
41
+ "url": "https://spreecommerce.org/docs/mcp"
42
+ }
43
+ }
44
+ }
45
+ ```
46
+
47
+ **VS Code (Copilot):**
48
+
49
+ Add to `.vscode/mcp.json` in your project:
50
+
51
+ ```json
52
+ {
53
+ "servers": {
54
+ "spree-docs": {
55
+ "type": "http",
56
+ "url": "https://spreecommerce.org/docs/mcp"
57
+ }
58
+ }
59
+ }
60
+ ```
61
+
62
+ **Other tools:**
63
+
64
+ Any MCP client that supports remote servers over streamable HTTP can connect — point it at `https://spreecommerce.org/docs/mcp`. No authentication is required.
65
+
66
+
67
+ ## When to use MCP vs the other doc channels
68
+
69
+ | Channel | Best for |
70
+ |---|---|
71
+ | **MCP server** (this page) | The latest published docs; agents working outside a scaffolded project; questions the installed skills don't cover |
72
+ | **[`@spree/docs` npm package](llm-docs.md)** | Fast local reads inside a project — no network round-trip, works offline, pinned to what you installed |
73
+ | **[Agent skills](agent-skills.md)** | Conventions and how-to knowledge the agent should apply without searching at all |
74
+
75
+ > **NOTE:** In create-spree-app projects the generated `CLAUDE.md` already points agents at the local `@spree/docs` package first — MCP complements it for anything newer than your installed docs version.
@@ -0,0 +1,31 @@
1
+ ---
2
+ title: "Agentic Development"
3
+ sidebarTitle: Overview
4
+ description: "Build, customize, and upgrade Spree with AI coding agents — agent skills, a docs MCP server, and LLM-ready documentation."
5
+ ---
6
+
7
+ Spree ships first-class tooling for AI-assisted development. Whether you use Claude Code, Cursor, Codex, Copilot, or any other coding agent, your agent can learn Spree's conventions, read the right docs at the right time, and run the project safely.
8
+
9
+ ## Why Spree works well with AI agents
10
+
11
+ - **Strong conventions** — everything is namespaced under `Spree::`, models follow predictable patterns (prefixed IDs, `Spree.base_class`, service objects, events), and the v3 REST API uses flat request/response shapes. Conventions are what agents are best at following.
12
+ - **Docs designed for machine consumption** — the full documentation is available as [llms.txt, per-page Markdown, and a local npm package](llm-docs.md), so agents read authoritative content instead of guessing from training data.
13
+ - **A guided project workflow** — [create-spree-app](../create-spree-app/quickstart.md) scaffolds projects with a generated `CLAUDE.md`, local docs, and the [Spree CLI](../cli/quickstart.md), so an agent can boot, migrate, generate code, and run tests without bespoke setup.
14
+
15
+ ## The toolbox
16
+
17
+
18
+ - [Agent Skills](agent-skills.md) — 25 skills teaching agents Spree's conventions, customization patterns, and upgrade flows — installable into 60+ agent tools, plus a Claude Code plugin with slash commands and safety hooks.
19
+ - [Docs MCP Server](mcp.md) — Connect your agent to the Spree documentation MCP server to search and read the latest docs while building.
20
+ - [LLM-Ready Docs](llm-docs.md) — llms.txt, per-page Markdown, and the `@spree/docs` npm package for fast local reads.
21
+ - [Spree CLI](../cli/quickstart.md) — A predictable command surface (`spree dev`, `spree generate`, `spree migrate`, `spree upgrade`) that agents can drive end-to-end.
22
+
23
+
24
+ ## A typical agentic workflow
25
+
26
+ 1. **Scaffold** a project with `npx create-spree-app@latest my-store` — it generates a `CLAUDE.md`, installs `@spree/docs` for local reference, and wires up the CLI.
27
+ 2. **Install the agent skills** with `npx skills add spree/agent-skills` so your agent knows the decision tree for customizations (subscriber vs decorator vs dependency injection vs generator) before it writes a line of code.
28
+ 3. **Connect the docs MCP server** so questions the skills don't cover get answered from the live documentation.
29
+ 4. **Let the agent work** — generate an API resource (`spree generate api_resource Brand name:string`), customize checkout, integrate a payment provider, or run an upgrade with `spree upgrade`.
30
+
31
+ > **TIP:** Skills, local docs, and MCP are complementary: skills encode *how to do things the Spree way*, local docs give *fast authoritative lookups*, and MCP covers *the latest published documentation*. Most teams use all three.
@@ -185,6 +185,7 @@ Run a generator inside the container. Bare generator names are auto-prefixed wit
185
185
  ```bash
186
186
  spree generate model Brand name:string slug:string:uniq # runs spree:model
187
187
  spree generate api_resource Brand name:string slug:string:uniq # runs spree:api_resource — model + v3 Store/Admin API
188
+ spree generate subscriber OmsOrderSync order.completed # runs spree:subscriber — event subscriber + registration
188
189
  spree generate migration AddPositionToSpreeBrands position:integer # Rails built-in, forwarded as-is
189
190
  ```
190
191
 
@@ -283,3 +284,7 @@ spree task load_sample_data
283
284
  spree task spree:price_history:seed
284
285
  spree task spree:price_history:prune
285
286
  ```
287
+
288
+ ## Pair with AI agents
289
+
290
+ The CLI's predictable command surface is what AI coding agents drive when working on Spree projects. The [Spree agent skills](../agentic/agent-skills.md) teach agents these commands and conventions, and the Claude Code plugin adds `/spree:doctor` (stack diagnosis) and `/spree:audit-upgrade` (upgrade-readiness audit) on top. See [Agentic Development](../agentic/overview.md).
@@ -432,16 +432,14 @@ Issues that are open for 14 days without actionable information or activity will
432
432
 
433
433
  Spree comes with an [AGENTS.md](https://github.com/spree/spree/blob/main/AGENTS.md) file that instructs coding agents like Claude Code or Codex to help you with your development.
434
434
 
435
- We also have an MCP server built on top of our Documentation website to help you with your development.
435
+ We also ship [agent skills](../agentic/agent-skills.md) (`npx skills add spree/agent-skills`), a [docs MCP server](../agentic/mcp.md), and [LLM-ready documentation](../agentic/llm-docs.md) see the [Agentic Development docs](../agentic/overview.md) for setup across Claude Code, Cursor, Copilot, and other tools.
436
436
 
437
- Add this URL to your AI tools:
437
+ The MCP server URL for quick setup:
438
438
 
439
439
  ```
440
440
  https://spreecommerce.org/docs/mcp
441
441
  ```
442
442
 
443
- In Claude Code you need to go to [Connectors](https://claude.ai/settings/connectors) settings and add the URL.
444
-
445
443
  ## That's a wrap!
446
444
 
447
445
  Thank you for participating in Open Source and improving Spree - you're awesome!
@@ -56,30 +56,40 @@ flowchart TB
56
56
 
57
57
  ## Creating a Subscriber
58
58
 
59
- Create a subscriber class in `app/subscribers/` that inherits from `Spree::Subscriber`:
59
+ The fastest path is the generator — it creates the class, a spec stub, and registers the subscriber in `config/initializers/spree.rb` (the step that's easy to forget):
60
60
 
61
- ```ruby app/subscribers/my_app/order_completed_subscriber.rb
62
- module MyApp
63
- class OrderCompletedSubscriber < Spree::Subscriber
64
- subscribes_to 'order.completed'
65
61
 
66
- def handle(event)
67
- order_id = event.payload['id']
68
- order = Spree::Order.find_by_prefix_id(order_id)
69
- return unless order
62
+ ```bash Spree CLI (Docker)
63
+ spree generate subscriber OrderCompleted order.completed
64
+ ```
70
65
 
71
- # Your custom logic here
72
- ExternalService.notify_order_placed(order)
73
- end
66
+ ```bash Without Spree CLI
67
+ bin/rails g spree:subscriber OrderCompleted order.completed
68
+ ```
69
+
70
+
71
+ Or create the class by hand in `app/subscribers/`, inheriting from `Spree::Subscriber`:
72
+
73
+ ```ruby app/subscribers/order_completed_subscriber.rb
74
+ class OrderCompletedSubscriber < Spree::Subscriber
75
+ subscribes_to 'order.completed'
76
+
77
+ def handle(event)
78
+ order_id = event.payload['id']
79
+ order = Spree::Order.find_by_prefix_id(order_id)
80
+ return unless order
81
+
82
+ # Your custom logic here
83
+ ExternalService.notify_order_placed(order)
74
84
  end
75
85
  end
76
86
  ```
77
87
 
78
88
  Then register it in an initializer — subscribers are not auto-discovered (see [Registering Subscribers](#registering-subscribers)):
79
89
 
80
- ```ruby config/initializers/event_subscribers.rb
90
+ ```ruby config/initializers/spree.rb
81
91
  Rails.application.config.after_initialize do
82
- Spree.subscribers << MyApp::OrderCompletedSubscriber
92
+ Spree.subscribers << OrderCompletedSubscriber
83
93
  end
84
94
  ```
85
95
 
@@ -108,37 +118,35 @@ end
108
118
 
109
119
  When subscribing to multiple events, use the `on` DSL to route events to specific methods:
110
120
 
111
- ```ruby app/subscribers/my_app/order_audit_subscriber.rb
112
- module MyApp
113
- class OrderAuditSubscriber < Spree::Subscriber
114
- subscribes_to 'order.completed', 'order.canceled', 'order.resumed'
121
+ ```ruby app/subscribers/order_audit_subscriber.rb
122
+ class OrderAuditSubscriber < Spree::Subscriber
123
+ subscribes_to 'order.completed', 'order.canceled', 'order.resumed'
115
124
 
116
- on 'order.completed', :log_order_completed
117
- on 'order.canceled', :log_order_canceled
118
- on 'order.resumed', :log_order_resumed
125
+ on 'order.completed', :log_order_completed
126
+ on 'order.canceled', :log_order_canceled
127
+ on 'order.resumed', :log_order_resumed
119
128
 
120
- private
129
+ private
121
130
 
122
- def log_order_completed(event)
123
- create_audit_log(event, 'completed')
124
- end
131
+ def log_order_completed(event)
132
+ create_audit_log(event, 'completed')
133
+ end
125
134
 
126
- def log_order_canceled(event)
127
- create_audit_log(event, 'canceled')
128
- end
135
+ def log_order_canceled(event)
136
+ create_audit_log(event, 'canceled')
137
+ end
129
138
 
130
- def log_order_resumed(event)
131
- create_audit_log(event, 'resumed')
132
- end
139
+ def log_order_resumed(event)
140
+ create_audit_log(event, 'resumed')
141
+ end
133
142
 
134
- def create_audit_log(event, action)
135
- AuditLog.create!(
136
- resource_type: 'Spree::Order',
137
- resource_id: event.payload['id'],
138
- action: action,
139
- occurred_at: event.created_at
140
- )
141
- end
143
+ def create_audit_log(event, action)
144
+ AuditLog.create!(
145
+ resource_type: 'Spree::Order',
146
+ resource_id: event.payload['id'],
147
+ action: action,
148
+ occurred_at: event.created_at
149
+ )
142
150
  end
143
151
  end
144
152
  ```
@@ -363,8 +371,8 @@ Spree.api.order_serializer = 'MyApp::OrderSerializer'
363
371
 
364
372
  If you add a custom model that publishes events, create a V3 serializer:
365
373
 
366
- ```ruby app/models/my_app/subscription.rb
367
- module MyApp
374
+ ```ruby app/models/spree/subscription.rb
375
+ module Spree
368
376
  class Subscription < Spree.base_class
369
377
  publishes_lifecycle_events
370
378
 
@@ -403,17 +411,17 @@ Models without a matching serializer will use a minimal fallback payload contain
403
411
 
404
412
  ## Registering Subscribers
405
413
 
406
- Subscribers are not auto-discovered — every subscriber must be registered explicitly, regardless of where the class lives. Add it to the `Spree.subscribers` array in an initializer:
414
+ Subscribers are not auto-discovered — every subscriber must be registered explicitly, regardless of where the class lives. Add it to the `Spree.subscribers` array in `config/initializers/spree.rb` (or any initializer):
407
415
 
408
- ```ruby config/initializers/event_subscribers.rb
416
+ ```ruby config/initializers/spree.rb
409
417
  Rails.application.config.after_initialize do
410
- Spree.subscribers << MyApp::CustomSubscriber
418
+ Spree.subscribers << CustomSubscriber
411
419
  end
412
420
  ```
413
421
 
414
422
  To remove a built-in subscriber:
415
423
 
416
- ```ruby config/initializers/event_subscribers.rb
424
+ ```ruby config/initializers/spree.rb
417
425
  Rails.application.config.after_initialize do
418
426
  Spree.subscribers.delete(Spree::ExportSubscriber)
419
427
  end
@@ -457,10 +465,10 @@ This is useful for:
457
465
 
458
466
  ### Testing Event Handling
459
467
 
460
- ```ruby spec/subscribers/my_app/order_completed_subscriber_spec.rb
468
+ ```ruby spec/subscribers/order_completed_subscriber_spec.rb
461
469
  require 'spec_helper'
462
470
 
463
- RSpec.describe MyApp::OrderCompletedSubscriber do
471
+ RSpec.describe OrderCompletedSubscriber do
464
472
  let(:order) { create(:completed_order_with_totals) }
465
473
  let(:event) do
466
474
  Spree::Event.new(
@@ -509,41 +517,39 @@ end
509
517
 
510
518
  Here's a complete example of a subscriber that sends alerts when inventory is low:
511
519
 
512
- ```ruby app/subscribers/my_app/inventory_alert_subscriber.rb
513
- module MyApp
514
- class InventoryAlertSubscriber < Spree::Subscriber
515
- subscribes_to 'stock_item.updated'
520
+ ```ruby app/subscribers/inventory_alert_subscriber.rb
521
+ class InventoryAlertSubscriber < Spree::Subscriber
522
+ subscribes_to 'stock_item.updated'
516
523
 
517
- LOW_STOCK_THRESHOLD = 10
524
+ LOW_STOCK_THRESHOLD = 10
518
525
 
519
- def handle(event)
520
- stock_item = find_stock_item(event)
521
- return unless stock_item
522
- return unless stock_dropped_below_threshold?(event, stock_item)
526
+ def handle(event)
527
+ stock_item = find_stock_item(event)
528
+ return unless stock_item
529
+ return unless stock_dropped_below_threshold?(event, stock_item)
523
530
 
524
- send_low_stock_alert(stock_item)
525
- end
531
+ send_low_stock_alert(stock_item)
532
+ end
526
533
 
527
- private
534
+ private
528
535
 
529
- def find_stock_item(event)
530
- Spree::StockItem.find_by_prefix_id(event.payload['id'])
531
- end
536
+ def find_stock_item(event)
537
+ Spree::StockItem.find_by_prefix_id(event.payload['id'])
538
+ end
532
539
 
533
- def stock_dropped_below_threshold?(event, stock_item)
534
- previous_count = event.payload['count_on_hand_before_last_save']
535
- current_count = stock_item.count_on_hand
540
+ def stock_dropped_below_threshold?(event, stock_item)
541
+ previous_count = event.payload['count_on_hand_before_last_save']
542
+ current_count = stock_item.count_on_hand
536
543
 
537
- previous_count >= LOW_STOCK_THRESHOLD && current_count < LOW_STOCK_THRESHOLD
538
- end
544
+ previous_count >= LOW_STOCK_THRESHOLD && current_count < LOW_STOCK_THRESHOLD
545
+ end
539
546
 
540
- def send_low_stock_alert(stock_item)
541
- InventoryMailer.low_stock_alert(
542
- variant: stock_item.variant,
543
- stock_location: stock_item.stock_location,
544
- count_on_hand: stock_item.count_on_hand
545
- ).deliver_later
546
- end
547
+ def send_low_stock_alert(stock_item)
548
+ InventoryMailer.low_stock_alert(
549
+ variant: stock_item.variant,
550
+ stock_location: stock_item.stock_location,
551
+ count_on_hand: stock_item.count_on_hand
552
+ ).deliver_later
547
553
  end
548
554
  end
549
555
  ```
@@ -6,7 +6,7 @@ description: >-
6
6
 
7
7
  Before you start customizing Spree API endpoints, make sure you reviewed all existing API endpoints in the [Spree API docs](/api-reference).
8
8
 
9
- For a step-by-step walkthrough of adding a complete new resource (model, serializer, controller, routes), see the [Store API tutorial](../tutorial/store-api.md).
9
+ For a step-by-step walkthrough of adding a complete new resource (model, serializer, controller, routes), see the [API tutorial](../tutorial/api.md).
10
10
 
11
11
  ## Customizing JSON Responses
12
12
 
@@ -36,7 +36,7 @@ Restart the server and the Product API will include your new attribute.
36
36
 
37
37
  ### Adding an Association
38
38
 
39
- Let's say you've created a `Spree::Brand` model that belongs to `Product` (see the [tutorial](../tutorial/store-api.md) for the full example).
39
+ Let's say you've created a `Spree::Brand` model that belongs to `Product` (see the [tutorial](../tutorial/api.md) for the full example).
40
40
 
41
41
  Create a serializer for the new model:
42
42
 
@@ -102,19 +102,17 @@ There are two approaches for adding logic around checkout state transitions:
102
102
 
103
103
  For actions that should happen **after** a checkout step completes (syncing with external services, sending notifications, logging, etc.), use [Events subscribers](../core-concepts/events.md). This is the recommended approach because it keeps your code decoupled from Spree internals.
104
104
 
105
- ```ruby app/subscribers/my_app/order_completed_subscriber.rb
106
- module MyApp
107
- class OrderCompletedSubscriber < Spree::Subscriber
108
- subscribes_to 'order.completed'
109
-
110
- def handle(event)
111
- order = Spree::Order.find_by_prefix_id(event.payload['id'])
112
- return unless order
113
-
114
- # Sync to fulfillment system, notify warehouse, etc.
115
- FulfillmentService.notify(order)
116
- AnalyticsService.track_purchase(order)
117
- end
105
+ ```ruby app/subscribers/order_completed_subscriber.rb
106
+ class OrderCompletedSubscriber < Spree::Subscriber
107
+ subscribes_to 'order.completed'
108
+
109
+ def handle(event)
110
+ order = Spree::Order.find_by_prefix_id(event.payload['id'])
111
+ return unless order
112
+
113
+ # Sync to fulfillment system, notify warehouse, etc.
114
+ FulfillmentService.notify(order)
115
+ AnalyticsService.track_purchase(order)
118
116
  end
119
117
  end
120
118
  ```
@@ -483,19 +483,17 @@ end
483
483
 
484
484
  **After (Events subscriber):**
485
485
 
486
- ```ruby app/subscribers/my_app/product_sync_subscriber.rb
487
- module MyApp
488
- class ProductSyncSubscriber < Spree::Subscriber
489
- subscribes_to 'product.updated'
490
-
491
- def handle(event)
492
- product = Spree::Product.find_by_prefix_id(event.payload['id'])
493
- return unless product
494
-
495
- # The payload includes changes, check if name changed
496
- if event.payload['previous_changes']&.key?('name')
497
- ExternalSyncJob.perform_later(product)
498
- end
486
+ ```ruby app/subscribers/product_sync_subscriber.rb
487
+ class ProductSyncSubscriber < Spree::Subscriber
488
+ subscribes_to 'product.updated'
489
+
490
+ def handle(event)
491
+ product = Spree::Product.find_by_prefix_id(event.payload['id'])
492
+ return unless product
493
+
494
+ # The payload includes changes, check if name changed
495
+ if event.payload['previous_changes']&.key?('name')
496
+ ExternalSyncJob.perform_later(product)
499
497
  end
500
498
  end
501
499
  end
@@ -56,18 +56,16 @@ Spree is a flexible platform allowing you to customize every part of it to suit
56
56
 
57
57
  Spree's event system lets you subscribe to events like `order.completed`, `product.updated`, `payment.paid`, etc.:
58
58
 
59
- ```ruby app/subscribers/my_app/order_completed_subscriber.rb
60
- module MyApp
61
- class OrderCompletedSubscriber < Spree::Subscriber
62
- subscribes_to 'order.completed'
59
+ ```ruby app/subscribers/order_completed_subscriber.rb
60
+ class OrderCompletedSubscriber < Spree::Subscriber
61
+ subscribes_to 'order.completed'
63
62
 
64
- def handle(event)
65
- order = Spree::Order.find_by_prefix_id(event.payload['id'])
66
- return unless order
63
+ def handle(event)
64
+ order = Spree::Order.find_by_prefix_id(event.payload['id'])
65
+ return unless order
67
66
 
68
- # Sync to external service, send notification, etc.
69
- ExternalService.notify_order_placed(order)
70
- end
67
+ # Sync to external service, send notification, etc.
68
+ ExternalService.notify_order_placed(order)
71
69
  end
72
70
  end
73
71
  ```
@@ -73,6 +73,17 @@ Upon successful authentication, you should see the admin screen:
73
73
 
74
74
  <img src="/images/spree_admin_dashboard.png" />
75
75
 
76
+ ## Next Steps
77
+
78
+
79
+ - [Build with AI Agents](../agentic/overview.md) — Install the Spree agent skills and connect the docs MCP server — Claude Code, Cursor, Copilot, and 60+ other tools learn Spree's conventions and build features with you.
80
+ - [Customization Tutorial](../tutorial/introduction.md) — Build a complete custom feature — model, admin UI, API, and TypeScript SDK — step by step.
81
+ - [Core Concepts](../core-concepts/architecture.md) — Understand how Spree models commerce — stores, products, orders, payments.
82
+ - [Next.js Storefront](../storefront/nextjs/quickstart.md) — Customize and extend the headless storefront.
83
+
84
+
85
+ > **TIP:** Using an AI coding agent? Run `npx skills add spree/agent-skills` in your new project — it teaches your agent the customization patterns before you write a line of code. See [Agentic Development](../agentic/overview.md).
86
+
76
87
  ---
77
88
 
78
89
  Congrats! You've set up your Spree Commerce and it's looking amazing!