@spree/docs 0.1.81 → 0.1.83
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/store-api/errors.md +4 -4
- package/dist/api-reference/store-api/idempotency.md +2 -2
- package/dist/developer/cli/quickstart.md +150 -2
- package/dist/developer/contributing/creating-an-extension.md +2 -2
- package/dist/developer/contributing/developing-spree.md +168 -79
- package/dist/developer/core-concepts/addresses.md +11 -11
- package/dist/developer/core-concepts/adjustments.md +2 -2
- package/dist/developer/core-concepts/customers.md +2 -2
- package/dist/developer/core-concepts/events.md +13 -7
- package/dist/developer/core-concepts/markets.md +11 -11
- package/dist/developer/core-concepts/media.md +3 -3
- package/dist/developer/core-concepts/orders.md +11 -11
- package/dist/developer/core-concepts/pricing.md +2 -2
- package/dist/developer/core-concepts/products.md +12 -12
- package/dist/developer/core-concepts/promotions.md +2 -2
- package/dist/developer/core-concepts/search-filtering.md +12 -12
- package/dist/developer/core-concepts/shipments.md +3 -3
- package/dist/developer/core-concepts/slugs.md +4 -4
- package/dist/developer/core-concepts/stores.md +2 -2
- package/dist/developer/core-concepts/translations.md +2 -2
- package/dist/developer/core-concepts/users.md +2 -2
- package/dist/developer/create-spree-app/quickstart.md +9 -8
- package/dist/developer/customization/checkout.md +2 -2
- package/dist/developer/customization/decorators.md +11 -9
- package/dist/developer/customization/quickstart.md +2 -2
- package/dist/developer/deployment/environment_variables.md +2 -1
- package/dist/developer/sdk/store/markets.md +6 -6
- package/dist/developer/tutorial/extending-models.md +2 -2
- package/dist/developer/upgrades/5.4-to-5.5.md +84 -17
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Errors
|
|
3
|
-
description:
|
|
3
|
+
description: Reference for Spree Store API error responses — JSON format, machine-readable codes, HTTP status codes, validation details, and retry strategies.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
The Store API uses a consistent, Stripe-style error format across all endpoints. Every error response includes a machine-readable `code` and a human-readable `message`.
|
|
@@ -145,7 +145,7 @@ Validation errors include an additional `details` field with per-field error mes
|
|
|
145
145
|
|
|
146
146
|
```bash
|
|
147
147
|
curl https://api.mystore.com/api/v3/store/products/prod_nonexistent \
|
|
148
|
-
-H "
|
|
148
|
+
-H "X-Spree-API-Key: pk_xxx"
|
|
149
149
|
```
|
|
150
150
|
|
|
151
151
|
```json 404
|
|
@@ -185,7 +185,7 @@ curl -X POST https://api.mystore.com/api/v3/store/account/addresses \
|
|
|
185
185
|
|
|
186
186
|
```bash
|
|
187
187
|
curl -X POST https://api.mystore.com/api/v3/store/carts/cart_xxx/items \
|
|
188
|
-
-H "
|
|
188
|
+
-H "X-Spree-API-Key: pk_xxx" \
|
|
189
189
|
-H "X-Spree-Token: abc123" \
|
|
190
190
|
-H "Content-Type: application/json" \
|
|
191
191
|
-d '{"variant_id": "var_xxx", "quantity": 999}'
|
|
@@ -204,7 +204,7 @@ curl -X POST https://api.mystore.com/api/v3/store/carts/cart_xxx/items \
|
|
|
204
204
|
|
|
205
205
|
```bash
|
|
206
206
|
curl -X POST https://api.mystore.com/api/v3/store/carts/cart_xxx/complete \
|
|
207
|
-
-H "
|
|
207
|
+
-H "X-Spree-API-Key: pk_xxx"
|
|
208
208
|
```
|
|
209
209
|
|
|
210
210
|
```json 422
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Idempotency"
|
|
3
3
|
sidebarTitle: "Idempotency"
|
|
4
|
-
description: "
|
|
4
|
+
description: "Use Idempotency-Key headers on Spree Store API mutations to safely retry carts, checkouts, and payments without creating duplicate side effects."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
The Store API supports idempotency keys on mutating endpoints. This lets you safely retry requests without risking duplicate side effects — for example, adding an item to cart twice or creating duplicate payments due to network timeouts.
|
|
@@ -16,7 +16,7 @@ Include an `Idempotency-Key` header with a unique value (e.g., a UUID) on any su
|
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
curl -X POST https://api.mystore.com/api/v3/store/carts/cart_xxx/items \
|
|
19
|
-
-H "
|
|
19
|
+
-H "X-Spree-API-Key: pk_xxx" \
|
|
20
20
|
-H "X-Spree-Token: abc123" \
|
|
21
21
|
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
|
|
22
22
|
-H "Content-Type: application/json" \
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Spree CLI
|
|
3
3
|
sidebarTitle: Overview
|
|
4
|
-
description:
|
|
4
|
+
description: Install and use the @spree/cli to scaffold, run, build, migrate, and upgrade Docker-based Spree Commerce projects from the command line.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
The Spree CLI (`@spree/cli`) manages Docker-based Spree projects created with [create-spree-app](../create-spree-app/quickstart.md).
|
|
@@ -40,7 +40,7 @@ spree init --no-open # Skip opening browser
|
|
|
40
40
|
|
|
41
41
|
### `spree dev`
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Run the app in the foreground — streams web + worker logs; `Ctrl+C` stops them. The databases keep running for a fast next boot (`spree stop` shuts everything down).
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
spree dev
|
|
@@ -54,6 +54,16 @@ Stop all services.
|
|
|
54
54
|
spree stop
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
### `spree restart`
|
|
58
|
+
|
|
59
|
+
Restart `web` and `worker` in place — same image, same volumes, fresh Rails process. Good for `config/initializers/*.rb` changes or anything Zeitwerk doesn't auto-reload.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
spree restart
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Not appropriate for Gemfile changes (use `spree bundle install`, then Ctrl+C and re-run `spree dev`), Dockerfile / `.ruby-version` changes (use `spree build`), or compose file changes (Ctrl+C and re-run `spree dev`).
|
|
66
|
+
|
|
57
67
|
### `spree update`
|
|
58
68
|
|
|
59
69
|
Pull the latest Spree Docker image and recreate containers. Migrations run automatically on startup.
|
|
@@ -62,6 +72,34 @@ Pull the latest Spree Docker image and recreate containers. Migrations run autom
|
|
|
62
72
|
spree update
|
|
63
73
|
```
|
|
64
74
|
|
|
75
|
+
### `spree build`
|
|
76
|
+
|
|
77
|
+
Rebuild the dev image after Dockerfile or `.ruby-version` changes. Only relevant after `spree eject`.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
spree build
|
|
81
|
+
spree build --reset-bundle # Also drop the bundle_cache volume so gems re-seed
|
|
82
|
+
spree build --yes # Skip confirmation prompts (for CI)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`spree bundle add` does NOT require a rebuild — gems land in the `bundle_cache` volume which survives image rebuilds.
|
|
86
|
+
|
|
87
|
+
`--reset-bundle` only drops `bundle_cache`. Postgres, Redis, Meilisearch, and storage volumes are preserved.
|
|
88
|
+
|
|
89
|
+
### `spree upgrade`
|
|
90
|
+
|
|
91
|
+
Walk a Spree version upgrade end-to-end inside the dev stack. Runs `bundle update`, applies pending migrations, then walks the version-specific data backfills from the upgrade manifest.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
spree upgrade # Detect target, run the full sequence interactively
|
|
95
|
+
spree upgrade --plan # Print the plan without executing (DRY_RUN=1)
|
|
96
|
+
spree upgrade --to 5.5 # Cap the walk at a specific target version
|
|
97
|
+
spree upgrade --step <id> # Re-run a single step idempotently (skips bundle + migrate)
|
|
98
|
+
spree upgrade --yes # Skip the per-step prompts
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Production upgrades only need the third stage — `bundle install` and `db:migrate` happen in your deploy pipeline. The CLI runs all three for local development. See [Upgrades](../upgrades.md) for the manual production path.
|
|
102
|
+
|
|
65
103
|
### `spree eject`
|
|
66
104
|
|
|
67
105
|
Switch from the prebuilt Docker image to building from your local `backend/` directory. This lets you customize the Rails app — add gems, override models, add migrations, etc.
|
|
@@ -135,3 +173,113 @@ spree api-key create --name "Storefront" --type publishable # Store API key
|
|
|
135
173
|
spree api-key create --name "Admin" --type secret # Admin API key
|
|
136
174
|
spree api-key revoke <id> # Revoke a key
|
|
137
175
|
```
|
|
176
|
+
|
|
177
|
+
## Dev workflow commands
|
|
178
|
+
|
|
179
|
+
These mirror the Rails commands you'd run if you were running the app directly on your host — but each is routed through `docker compose exec` against the running stack.
|
|
180
|
+
|
|
181
|
+
### `spree generate`
|
|
182
|
+
|
|
183
|
+
Run a generator inside the container. Bare generator names are auto-prefixed with `spree:` — `model` runs `spree:model`, `api_resource` runs `spree:api_resource` — so you get the Spree conventions (`Spree::` namespace, `spree_`-prefixed table, prefixed IDs, `null: false`, no FK constraints) by default. Rails built-ins (`migration`, `scaffold`, `mailer`, `job`, …) and any name containing `:` are forwarded as-is.
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
spree generate model Brand name:string slug:string:uniq # runs spree:model
|
|
187
|
+
spree generate api_resource Brand name:string slug:string:uniq # runs spree:api_resource — model + v3 Store/Admin API
|
|
188
|
+
spree generate migration AddPositionToSpreeBrands position:integer # Rails built-in, forwarded as-is
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
`spree:api_resource` scaffolds the full v3 surface: model, migration, Store + Admin controllers and serializers, factory, controller specs, and routes.
|
|
192
|
+
|
|
193
|
+
### `spree migrate`
|
|
194
|
+
|
|
195
|
+
Install pending Spree migrations from gems, then run `db:migrate` — the canonical post-update sequence.
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
spree migrate
|
|
199
|
+
spree migrate:status # show the migration log (`db:migrate:status`)
|
|
200
|
+
spree migrate:rollback STEP=2 # roll back (`db:rollback`)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### `spree db:reset`
|
|
204
|
+
|
|
205
|
+
Drop, recreate, migrate, and seed the database. **Destructive** — wipes everything. Asks for confirmation.
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
spree db:reset
|
|
209
|
+
spree db:reset --yes # Skip confirmation (for CI)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### `spree db:console`
|
|
213
|
+
|
|
214
|
+
Open a `psql` session against the dev Postgres database (runs inside the `postgres` container).
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
spree db:console
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### `spree routes`
|
|
221
|
+
|
|
222
|
+
Show Rails routes. All flags pass through to `bin/rails routes`.
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
spree routes
|
|
226
|
+
spree routes -g products # Filter by pattern
|
|
227
|
+
spree routes -c Spree::Api::V3::Store::ProductsController # Filter by controller
|
|
228
|
+
spree routes --expanded
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Running things inside the container
|
|
232
|
+
|
|
233
|
+
These are passthrough commands — anything after the subcommand reaches the inner Rails/Bundle/Rake invocation as-is. Useful for ad-hoc commands that don't have a dedicated wrapper.
|
|
234
|
+
|
|
235
|
+
### `spree exec`
|
|
236
|
+
|
|
237
|
+
Run an arbitrary command inside the `web` container.
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
spree exec ls -la
|
|
241
|
+
spree exec env
|
|
242
|
+
spree exec ruby -v
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### `spree rails`
|
|
246
|
+
|
|
247
|
+
Run a `bin/rails` command.
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
spree rails c # Console (alias of `spree console`)
|
|
251
|
+
spree rails routes -g products # Alias of `spree routes -g products`
|
|
252
|
+
spree rails runner "puts Spree::Product.count"
|
|
253
|
+
spree rails new_subcommand arg1 arg2
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### `spree bundle`
|
|
257
|
+
|
|
258
|
+
Run a `bundle` command. Gems land in the `bundle_cache` volume (no image rebuild needed).
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
spree bundle install
|
|
262
|
+
spree bundle add stripe
|
|
263
|
+
spree bundle update spree_core
|
|
264
|
+
spree bundle outdated
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### `spree rake`
|
|
268
|
+
|
|
269
|
+
Run a Rake task.
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
spree rake -T # List tasks
|
|
273
|
+
spree rake spree:upgrade # Run the version-specific data backfills
|
|
274
|
+
spree rake spree:upgrade DRY_RUN=1 # Same, plan only
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### `spree task`
|
|
278
|
+
|
|
279
|
+
Shortcut for `bin/rails <task>` (Spree-style rake tasks registered as Rails tasks).
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
spree task load_sample_data
|
|
283
|
+
spree task spree:price_history:seed
|
|
284
|
+
spree task spree:price_history:prune
|
|
285
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Creating an Extension
|
|
3
|
-
description:
|
|
3
|
+
description: Step-by-step guide to building a Spree extension gem — scaffolding, decorators, migrations, assets, and packaging for distribution.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## Overview
|
|
@@ -248,7 +248,7 @@ module MyExtension
|
|
|
248
248
|
subscribes_to 'product.updated'
|
|
249
249
|
|
|
250
250
|
def handle(event)
|
|
251
|
-
product = Spree::Product.
|
|
251
|
+
product = Spree::Product.find_by_prefix_id(event.payload['id'])
|
|
252
252
|
return unless product
|
|
253
253
|
|
|
254
254
|
ExternalService.sync(product)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Developing Spree
|
|
3
|
-
description:
|
|
4
|
-
This guide covers all the necessary steps to contributing to Spree source
|
|
5
|
-
code. We're happy you're here!
|
|
3
|
+
description: Set up a Spree development environment with Docker, run the test suite, and submit pull requests to contribute to the Spree Commerce source code.
|
|
6
4
|
---
|
|
7
5
|
|
|
6
|
+
Please read our [Code of Conduct](https://github.com/spree/spree/blob/main/CODE_OF_CONDUCT.md) before contributing.
|
|
7
|
+
|
|
8
8
|
## Cloning the repository
|
|
9
9
|
|
|
10
10
|
Spree is a big monorepo. For a faster clone, use a **partial clone** which downloads file contents on demand while keeping full commit history for `git log` and `git blame`:
|
|
@@ -24,66 +24,98 @@ You need **Node.js 20+** to run the workspace scripts (including `pnpm server:se
|
|
|
24
24
|
Spree is a monorepo with three main areas:
|
|
25
25
|
|
|
26
26
|
- **`spree/`** — Ruby gems (core, api, admin, emails) distributed as separate packages via RubyGems
|
|
27
|
-
- **`packages/`** — TypeScript packages (SDKs, CLI, project scaffolding, docs)
|
|
28
|
-
- **`server/`** — A Rails application cloned from [spree-starter](https://github.com/spree/spree-starter) that mounts the Spree gems (not checked in —
|
|
27
|
+
- **`packages/`** — TypeScript packages (SDKs, CLI, project scaffolding, docs, React dashboard)
|
|
28
|
+
- **`server/`** — A Rails application cloned from [spree-starter](https://github.com/spree/spree-starter) that mounts the local Spree gems (not checked in — `pnpm server:setup` creates it)
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## Setup
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
A single command bootstraps the whole monorepo for both backend and frontend work. You need **Docker** running locally (Docker Desktop, OrbStack, or any compatible runtime) — no Ruby, Postgres, or Redis on your host.
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
```bash
|
|
35
|
+
pnpm install # workspace dependencies
|
|
36
|
+
pnpm server:setup # ~5–10 min on first run; idempotent
|
|
37
|
+
```
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|---|---|---|
|
|
38
|
-
| `core` | `spree_core` | Models, services, business logic |
|
|
39
|
-
| `api` | `spree_api` | REST APIs |
|
|
40
|
-
| `admin` | `spree_admin` | Admin dashboard |
|
|
41
|
-
| `emails` | `spree_emails` | Transactional emails |
|
|
39
|
+
`pnpm server:setup` clones [spree-starter](https://github.com/spree/spree-starter) into `./server/`, wires it to load Spree gems from the monorepo via a Docker compose overlay, builds the dev image, starts the stack (Postgres + Redis + Meilisearch + Rails `web` + Sidekiq `worker`), and prepares the database. The full sequence lives in `scripts/server-setup.sh`.
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
When it's done, the backend is up at [http://localhost:3000](http://localhost:3000) and the admin is at [http://localhost:3000/admin](http://localhost:3000/admin). Sign in with the seed admin: **`spree@example.com`** / **`spree123`** (override at seed time with `ADMIN_EMAIL` / `ADMIN_PASSWORD` env vars — see `spree/core/app/services/spree/seeds/admin_user.rb`).
|
|
44
42
|
|
|
45
|
-
|
|
43
|
+
Optionally load sample products, taxonomies, and option types:
|
|
46
44
|
|
|
47
|
-
|
|
45
|
+
```bash
|
|
46
|
+
pnpm server:load_sample_data
|
|
47
|
+
```
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
## Running a backend day-to-day
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
After the one-time setup, use these to bring the stack up and down:
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
|
-
pnpm server:
|
|
54
|
+
pnpm server:dev # run the stack in the foreground — streams web + worker logs, Ctrl+C stops them
|
|
55
|
+
pnpm server:stop # full teardown (also stops postgres / redis / meilisearch)
|
|
56
|
+
pnpm server:restart # restart web + worker in place
|
|
57
|
+
pnpm server:logs # follow web container logs (when the stack runs detached)
|
|
58
|
+
pnpm server:console # open a Rails console inside the container
|
|
59
|
+
pnpm server:seed # re-run database seeds
|
|
60
|
+
pnpm server:build # rebuild the dev image (only after Dockerfile / .ruby-version changes)
|
|
55
61
|
```
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
`server:dev` behaves like any TS dev server (`vite dev`, the dashboard's `pnpm dev`): it runs in the foreground and Ctrl+C stops the app containers. Postgres, Redis, and Meilisearch keep running for a fast next boot — `pnpm server:stop` shuts everything down.
|
|
58
64
|
|
|
59
|
-
|
|
65
|
+
Run any CLI command against the running backend from `server/`:
|
|
60
66
|
|
|
61
67
|
```bash
|
|
62
68
|
cd server
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
pnpm exec spree migrate
|
|
70
|
+
pnpm exec spree generate model Brand name:string
|
|
71
|
+
pnpm exec spree upgrade --plan
|
|
66
72
|
```
|
|
67
73
|
|
|
68
|
-
|
|
74
|
+
See the [`@spree/cli` README](https://github.com/spree/spree/blob/main/packages/cli/README.md) for the full command surface.
|
|
69
75
|
|
|
70
|
-
|
|
71
|
-
docker compose up -d postgres redis meilisearch
|
|
72
|
-
```
|
|
76
|
+
Which command after which change:
|
|
73
77
|
|
|
74
|
-
|
|
78
|
+
| What changed | What to run |
|
|
79
|
+
|---|---|
|
|
80
|
+
| Ruby code in `spree/*` gems | Nothing — gems are bind-mounted; code reloads on the next request |
|
|
81
|
+
| A new migration in a gem | `cd server && pnpm exec spree migrate` |
|
|
82
|
+
| Gem dependencies (gemspec / Gemfile) | `cd server && pnpm exec spree bundle install` (persists in the `bundle_cache` volume) |
|
|
83
|
+
| Compose files / `server/.env` | `pnpm server:dev` (force-recreates the containers) |
|
|
84
|
+
| `server/Dockerfile` / `.ruby-version` | `pnpm server:build`, then `pnpm server:dev` |
|
|
85
|
+
| Broken beyond repair | `pnpm server:setup` (full reset — wipes the database and volumes) |
|
|
75
86
|
|
|
76
|
-
|
|
87
|
+
Re-run `pnpm server:setup` **only** to fully reset — it does `docker compose down -v` + `rm -rf ./server`, wiping all DB data.
|
|
77
88
|
|
|
78
|
-
|
|
89
|
+
## Native Ruby (advanced)
|
|
79
90
|
|
|
80
|
-
|
|
91
|
+
If you prefer the fastest possible inner loop and don't mind installing Ruby, Postgres, Redis, and Meilisearch on your host directly, you can skip Docker:
|
|
81
92
|
|
|
82
93
|
```bash
|
|
83
|
-
pnpm server:
|
|
84
|
-
|
|
94
|
+
pnpm server:create # clones spree-starter, writes server/.env with SPREE_PATH=..
|
|
95
|
+
cd server
|
|
96
|
+
bin/setup # installs Ruby (via mise), Postgres/Redis/Meilisearch (via brew bundle on macOS), gems, prepares the database
|
|
97
|
+
bin/dev # starts Rails + Sidekiq + CSS watchers via Foreman
|
|
85
98
|
```
|
|
86
99
|
|
|
100
|
+
This path is faster per request but means more on your host. It also runs against your installed system services, not a sandboxed Docker stack.
|
|
101
|
+
|
|
102
|
+
## Backend Development (Ruby)
|
|
103
|
+
|
|
104
|
+
### Engines overview
|
|
105
|
+
|
|
106
|
+
The Spree [Rails engines](https://guides.rubyonrails.org/engines.html) live inside `spree/` and are distributed as separate gems (Ruby packages installed via Bundler):
|
|
107
|
+
|
|
108
|
+
| Engine | Gem | Description |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| `core` | `spree_core` | Models, services, business logic |
|
|
111
|
+
| `api` | `spree_api` | REST APIs |
|
|
112
|
+
| `admin` | `spree_admin` | Admin dashboard |
|
|
113
|
+
| `emails` | `spree_emails` | Transactional emails |
|
|
114
|
+
|
|
115
|
+
### Spree namespace
|
|
116
|
+
|
|
117
|
+
All Spree models, controllers and other Ruby classes are namespaced by the `Spree` keyword, eg. `Spree::Product`. This means that those files are also located in `spree` sub-directories eg. [app/models/spree/product.rb](https://github.com/spree/spree/blob/main/spree/core/app/models/spree/product.rb).
|
|
118
|
+
|
|
87
119
|
### Running engine tests
|
|
88
120
|
|
|
89
121
|
Each engine has its own test suite. First install the shared dependencies at the `spree/` level, then navigate into the specific engine to set up and run its tests:
|
|
@@ -148,9 +180,9 @@ bundle exec parallel_rspec -n 4 spec
|
|
|
148
180
|
|
|
149
181
|
After schema changes, re-run `bundle exec rake parallel_setup` to update the worker databases.
|
|
150
182
|
|
|
151
|
-
### Integration tests (
|
|
183
|
+
### Integration tests (legacy Rails admin)
|
|
152
184
|
|
|
153
|
-
The
|
|
185
|
+
The legacy Rails admin (`spree/admin`) ships feature specs that run in a real browser via chromedriver. You only need this if you're touching the legacy admin UI.
|
|
154
186
|
|
|
155
187
|
Install chromedriver on macOS:
|
|
156
188
|
|
|
@@ -158,47 +190,35 @@ Install chromedriver on macOS:
|
|
|
158
190
|
brew install chromedriver
|
|
159
191
|
```
|
|
160
192
|
|
|
161
|
-
|
|
193
|
+
The 6.0 React dashboard (`packages/dashboard`) has its own end-to-end test suite running on Playwright against a real Rails backend — see [Dashboard E2E tests](#dashboard-e2e-tests) under TypeScript Development.
|
|
162
194
|
|
|
163
|
-
|
|
195
|
+
### Performance in development mode
|
|
164
196
|
|
|
165
|
-
|
|
197
|
+
Spree runs slower in development because caching is disabled and code reloads on each request. To turn on caching:
|
|
166
198
|
|
|
167
199
|
```bash
|
|
168
|
-
cd server &&
|
|
200
|
+
cd server && pnpm exec spree rails dev:cache
|
|
169
201
|
```
|
|
170
202
|
|
|
171
|
-
|
|
203
|
+
Restart the Rails server after running this (Ctrl+C the running `pnpm server:dev` and start it again).
|
|
172
204
|
|
|
173
205
|
## TypeScript Development
|
|
174
206
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
TypeScript developers don't need Ruby installed. Docker Compose from the repository root starts the backend using a prebuilt image:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
docker compose up -d
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
This boots PostgreSQL, Redis, Meilisearch, and the Spree backend automatically (no `pnpm server:setup` needed). The API is available at `http://localhost:3000`.
|
|
184
|
-
|
|
185
|
-
Then install dependencies and start all packages in watch mode:
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
pnpm install
|
|
189
|
-
pnpm dev
|
|
190
|
-
```
|
|
207
|
+
The backend setup is the same as for Ruby work — see [Setup](#setup) above. With `pnpm server:setup` done, the Rails backend is running and you can start the packages you want to work on.
|
|
191
208
|
|
|
192
209
|
### Packages
|
|
193
210
|
|
|
194
|
-
| Package | Path | Description |
|
|
195
|
-
|
|
196
|
-
| `@spree/sdk` | `packages/sdk` | TypeScript SDK for the Spree Store API |
|
|
197
|
-
| `@spree/
|
|
198
|
-
|
|
|
199
|
-
|
|
|
200
|
-
|
|
201
|
-
|
|
211
|
+
| Package | Path | Published | Description |
|
|
212
|
+
|---|---|---|---|
|
|
213
|
+
| `@spree/sdk` | `packages/sdk` | yes | TypeScript SDK for the Spree Store API |
|
|
214
|
+
| `@spree/admin-sdk` | `packages/admin-sdk` | yes | TypeScript SDK for the Spree Admin API |
|
|
215
|
+
| `@spree/cli` | `packages/cli` | yes | CLI for managing Spree Commerce projects |
|
|
216
|
+
| `create-spree-app` | `packages/create-spree-app` | yes | Project scaffolding (`npm create spree-app`) |
|
|
217
|
+
| `@spree/docs` | `packages/docs` | yes | Developer documentation for AI agents and local reference |
|
|
218
|
+
| `@spree/dashboard` | `packages/dashboard` | no | React SPA admin dashboard (Spree 6.0, replaces the legacy Rails admin) |
|
|
219
|
+
| `@spree/dashboard-core` | `packages/dashboard-core` | no | Framework: registries, providers, generic infra hooks for the dashboard |
|
|
220
|
+
| `@spree/dashboard-ui` | `packages/dashboard-ui` | no | Design system used by the dashboard |
|
|
221
|
+
| `@spree/sdk-core` | `packages/sdk-core` | no | Shared HTTP/retry/error layer used by both SDKs |
|
|
202
222
|
|
|
203
223
|
### Common commands
|
|
204
224
|
|
|
@@ -206,7 +226,7 @@ Run from the repository root — [Turborepo](https://turbo.build/) orchestrates
|
|
|
206
226
|
|
|
207
227
|
| Command | Description |
|
|
208
228
|
|---|---|
|
|
209
|
-
| `pnpm dev` |
|
|
229
|
+
| `pnpm dev` | Watch mode for all packages (does not boot the backend — use `pnpm server:dev` for that) |
|
|
210
230
|
| `pnpm build` | Build all packages (Turbo resolves dependency order) |
|
|
211
231
|
| `pnpm test` | Run tests in all packages |
|
|
212
232
|
| `pnpm lint` | Lint all packages |
|
|
@@ -225,21 +245,86 @@ pnpm --filter @spree/sdk generate:zod
|
|
|
225
245
|
|
|
226
246
|
Tests use [Vitest](https://vitest.dev/) with [MSW](https://mswjs.io/) for API mocking at the network level.
|
|
227
247
|
|
|
228
|
-
###
|
|
248
|
+
### Working on the React dashboard
|
|
249
|
+
|
|
250
|
+
The dashboard runs as a Vite dev server (port 5173) that proxies `/api/*` to the Rails backend on port 3000 — required for the auth refresh cookie to work over plain HTTP.
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# Terminal 1: backend
|
|
254
|
+
pnpm server:dev
|
|
255
|
+
|
|
256
|
+
# Terminal 2: dashboard
|
|
257
|
+
cd packages/dashboard
|
|
258
|
+
pnpm dev # http://localhost:5173
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Sign in with `spree@example.com` / `spree123`. To point at a non-default backend, set `VITE_SPREE_API_URL` (also needs to be set at build time for production bundles, not just dev):
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
VITE_SPREE_API_URL=https://my-spree.example.com pnpm dev
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Gotcha:** the dashboard imports `@spree/admin-sdk` from its **built** `dist/`, not source. If you edit `admin-sdk` (or `sdk-core`, or `sdk`) and want the dashboard to see the changes, run `pnpm build` from the monorepo root first (Turbo-cached). Editing dashboard code alone doesn't need this.
|
|
268
|
+
|
|
269
|
+
See the [dashboard README](https://github.com/spree/spree/blob/main/packages/dashboard/README.md) for the full architecture (auth, permissions, extension points, the three-package split between `dashboard`, `dashboard-core`, and `dashboard-ui`).
|
|
270
|
+
|
|
271
|
+
### Dashboard E2E tests
|
|
272
|
+
|
|
273
|
+
The React dashboard ships an end-to-end suite running on [Playwright](https://playwright.dev/) against a real Rails backend — no mocks. The spec files exercise the full UI: login, staff invitation, invitee signup. CI runs the same suite via the `dashboard-e2e` job in `.github/workflows/packages.yml`.
|
|
229
274
|
|
|
230
|
-
|
|
275
|
+
To run locally you need Ruby (the suite boots a real Rails server) and a one-time browser install:
|
|
231
276
|
|
|
232
277
|
```bash
|
|
278
|
+
# Make sure the dummy Rails app exists (one-time, after a fresh checkout).
|
|
233
279
|
cd spree/api
|
|
234
|
-
|
|
235
|
-
bundle
|
|
236
|
-
|
|
280
|
+
bundle install
|
|
281
|
+
bundle exec rake test_app
|
|
282
|
+
|
|
283
|
+
# Install Playwright's Chromium (one-time per machine).
|
|
284
|
+
cd ../../packages/dashboard
|
|
285
|
+
pnpm test:e2e:install
|
|
286
|
+
|
|
287
|
+
# Run the suite. Boots Rails on :3010 + Vite on :5174, runs all specs, tears
|
|
288
|
+
# both down. Safe to re-run repeatedly — the SQLite DB resets each run.
|
|
289
|
+
pnpm test:e2e
|
|
237
290
|
```
|
|
238
291
|
|
|
239
|
-
|
|
292
|
+
For interactive debugging (time-travel through actions, inspect the DOM at each step):
|
|
240
293
|
|
|
241
294
|
```bash
|
|
242
|
-
pnpm
|
|
295
|
+
pnpm test:e2e:ui
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Filter to a single spec or test name:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
pnpm test:e2e e2e/auth.spec.ts
|
|
302
|
+
pnpm test:e2e -g "invites a teammate"
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
When a test fails, Playwright drops a screenshot, video, and DOM snapshot in `packages/dashboard/test-results/<spec>/` — usually enough to diagnose without re-running.
|
|
306
|
+
|
|
307
|
+
### Type generation
|
|
308
|
+
|
|
309
|
+
TypeScript types in `packages/sdk/src/types/generated/` (Store API) and `packages/admin-sdk/src/types/generated/` (Admin API) are auto-generated from the Rails serializers using [typelizer](https://github.com/skryukov/typelizer). Zod schemas in `packages/sdk/src/zod/generated/` are derived from the TS types.
|
|
310
|
+
|
|
311
|
+
A **Lefthook pre-commit hook** regenerates both whenever you commit a change to `spree/api/app/serializers/**/*.rb` and re-stages the generated output. You don't need to run anything manually for the common case.
|
|
312
|
+
|
|
313
|
+
To regenerate manually (useful when iterating on serializers before committing):
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
cd server
|
|
317
|
+
pnpm exec spree rake typelizer:generate # regenerate TS types
|
|
318
|
+
cd ../packages/sdk
|
|
319
|
+
pnpm generate:zod # regenerate Zod schemas
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
If you'd rather avoid the Docker round-trip and have Ruby on your host, the native equivalent works too:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
cd spree/api
|
|
326
|
+
bundle install
|
|
327
|
+
bundle exec rake typelizer:generate
|
|
243
328
|
```
|
|
244
329
|
|
|
245
330
|
### Releasing packages
|
|
@@ -247,29 +332,33 @@ pnpm --filter @spree/sdk generate:zod
|
|
|
247
332
|
Published packages use [Changesets](https://github.com/changesets/changesets) for version management. Each package owns its own `.changeset/` folder, so changesets must be created from inside the package directory:
|
|
248
333
|
|
|
249
334
|
```bash
|
|
250
|
-
cd packages/sdk # or packages/cli, packages/create-spree-app
|
|
335
|
+
cd packages/sdk # or packages/admin-sdk, packages/cli, packages/create-spree-app
|
|
251
336
|
pnpm changeset
|
|
252
337
|
```
|
|
253
338
|
|
|
254
339
|
This creates a changeset file describing your changes. Commit it with your PR. When merged to `main`, a GitHub Action creates a "Version Packages" PR that bumps the version and publishes to npm.
|
|
255
340
|
|
|
341
|
+
Private packages (`@spree/dashboard`, `@spree/dashboard-core`, `@spree/dashboard-ui`, `@spree/sdk-core`) don't need changesets.
|
|
342
|
+
|
|
256
343
|
## Code Style
|
|
257
344
|
|
|
258
345
|
Consistent code style is enforced via automated linters. Please make sure your changes pass linting before submitting a PR.
|
|
259
346
|
|
|
260
|
-
**Ruby:** We use [RuboCop](https://rubocop.org/) for Ruby code. The configuration lives in `server/.rubocop.yml` and is shipped with [spree-starter](https://github.com/spree/spree-starter), so it's only available after running `pnpm server:setup`. Run it
|
|
347
|
+
**Ruby:** We use [RuboCop](https://rubocop.org/) for Ruby code. The configuration lives in `server/.rubocop.yml` and is shipped with [spree-starter](https://github.com/spree/spree-starter), so it's only available after running `pnpm server:setup`. Run it inside the container via the CLI:
|
|
261
348
|
|
|
262
349
|
```bash
|
|
263
350
|
cd server
|
|
264
|
-
bundle exec rubocop
|
|
351
|
+
pnpm exec spree exec bundle exec rubocop
|
|
265
352
|
```
|
|
266
353
|
|
|
267
354
|
To auto-fix correctable offenses:
|
|
268
355
|
|
|
269
356
|
```bash
|
|
270
|
-
bundle exec rubocop -a
|
|
357
|
+
pnpm exec spree exec bundle exec rubocop -a
|
|
271
358
|
```
|
|
272
359
|
|
|
360
|
+
(On the native path, drop the `pnpm exec spree exec` prefix and run `bundle exec rubocop` directly.)
|
|
361
|
+
|
|
273
362
|
**TypeScript:** We use [Biome](https://biomejs.dev/) for linting and formatting TypeScript code. Run it from the repository root:
|
|
274
363
|
|
|
275
364
|
```bash
|
|
@@ -319,7 +408,7 @@ To help us review your PR quickly:
|
|
|
319
408
|
- **Describe your changes.** Explain what you changed and why. Include screenshots for UI changes.
|
|
320
409
|
- **Add tests.** All new features and bug fixes should include appropriate test coverage.
|
|
321
410
|
- **Update documentation.** If your change affects user-facing behavior, update the relevant docs.
|
|
322
|
-
- **Include a changeset** if your change affects a published TypeScript package (`@spree/sdk`, `@spree/cli`, or `create-spree-app`). Run `pnpm changeset` from inside that package's directory — each package owns its own `.changeset/` folder.
|
|
411
|
+
- **Include a changeset** if your change affects a published TypeScript package (`@spree/sdk`, `@spree/admin-sdk`, `@spree/cli`, or `create-spree-app`). Run `pnpm changeset` from inside that package's directory — each package owns its own `.changeset/` folder.
|
|
323
412
|
- **Ensure CI passes.** PRs with failing CI will not be reviewed.
|
|
324
413
|
|
|
325
414
|
## Reporting Bugs
|