@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.
- package/dist/api-reference/admin-api/introduction.md +0 -12
- package/dist/developer/agentic/agent-skills.md +64 -0
- package/dist/developer/agentic/llm-docs.md +55 -0
- package/dist/developer/agentic/mcp.md +75 -0
- package/dist/developer/agentic/overview.md +31 -0
- package/dist/developer/cli/quickstart.md +5 -0
- package/dist/developer/contributing/developing-spree.md +2 -4
- package/dist/developer/core-concepts/events.md +80 -74
- package/dist/developer/customization/api.md +2 -2
- package/dist/developer/customization/checkout.md +11 -13
- package/dist/developer/customization/decorators.md +11 -13
- package/dist/developer/customization/quickstart.md +8 -10
- package/dist/developer/getting-started/quickstart.md +11 -0
- package/dist/developer/sdk/extending.md +1 -1
- package/dist/developer/sdk/quickstart.md +4 -0
- package/dist/developer/tutorial/admin.md +87 -17
- package/dist/developer/tutorial/{store-api.md → api.md} +118 -14
- package/dist/developer/tutorial/events.md +166 -0
- package/dist/developer/tutorial/extending-models.md +26 -22
- package/dist/developer/tutorial/introduction.md +30 -22
- package/dist/developer/tutorial/model.md +80 -19
- package/dist/developer/tutorial/sdk.md +5 -4
- package/dist/developer/tutorial/testing.md +48 -31
- package/package.json +1 -1
- package/dist/developer/tutorial/file-uploads.md +0 -121
- package/dist/developer/tutorial/rich-text.md +0 -73
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return unless order
|
|
62
|
+
```bash Spree CLI (Docker)
|
|
63
|
+
spree generate subscriber OrderCompleted order.completed
|
|
64
|
+
```
|
|
70
65
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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/
|
|
90
|
+
```ruby config/initializers/spree.rb
|
|
81
91
|
Rails.application.config.after_initialize do
|
|
82
|
-
Spree.subscribers <<
|
|
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/
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
125
|
+
on 'order.completed', :log_order_completed
|
|
126
|
+
on 'order.canceled', :log_order_canceled
|
|
127
|
+
on 'order.resumed', :log_order_resumed
|
|
119
128
|
|
|
120
|
-
|
|
129
|
+
private
|
|
121
130
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
131
|
+
def log_order_completed(event)
|
|
132
|
+
create_audit_log(event, 'completed')
|
|
133
|
+
end
|
|
125
134
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
135
|
+
def log_order_canceled(event)
|
|
136
|
+
create_audit_log(event, 'canceled')
|
|
137
|
+
end
|
|
129
138
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
139
|
+
def log_order_resumed(event)
|
|
140
|
+
create_audit_log(event, 'resumed')
|
|
141
|
+
end
|
|
133
142
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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/
|
|
367
|
-
module
|
|
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
|
|
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/
|
|
416
|
+
```ruby config/initializers/spree.rb
|
|
409
417
|
Rails.application.config.after_initialize do
|
|
410
|
-
Spree.subscribers <<
|
|
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/
|
|
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/
|
|
468
|
+
```ruby spec/subscribers/order_completed_subscriber_spec.rb
|
|
461
469
|
require 'spec_helper'
|
|
462
470
|
|
|
463
|
-
RSpec.describe
|
|
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/
|
|
513
|
-
|
|
514
|
-
|
|
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
|
-
|
|
524
|
+
LOW_STOCK_THRESHOLD = 10
|
|
518
525
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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
|
-
|
|
525
|
-
|
|
531
|
+
send_low_stock_alert(stock_item)
|
|
532
|
+
end
|
|
526
533
|
|
|
527
|
-
|
|
534
|
+
private
|
|
528
535
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
536
|
+
def find_stock_item(event)
|
|
537
|
+
Spree::StockItem.find_by_prefix_id(event.payload['id'])
|
|
538
|
+
end
|
|
532
539
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
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
|
-
|
|
538
|
-
|
|
544
|
+
previous_count >= LOW_STOCK_THRESHOLD && current_count < LOW_STOCK_THRESHOLD
|
|
545
|
+
end
|
|
539
546
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
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 [
|
|
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/
|
|
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/
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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/
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
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/
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
def handle(event)
|
|
64
|
+
order = Spree::Order.find_by_prefix_id(event.payload['id'])
|
|
65
|
+
return unless order
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
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!
|