@spree/docs 0.1.113 → 0.1.115
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.
|
@@ -6,7 +6,7 @@ description: "Every Spree Admin API v3 endpoint at a glance — method, path, re
|
|
|
6
6
|
|
|
7
7
|
{/* Generated from docs/api-reference/admin.yaml by packages/cli/scripts/generate-endpoints-doc.mjs — do not edit by hand. */}
|
|
8
8
|
|
|
9
|
-
All
|
|
9
|
+
All 209 Admin API operations, with the [scope](authentication.md) a secret API key needs for each. JWT-authenticated admin users are governed by their roles instead of scopes. The same index is available offline via the CLI: `spree api endpoints`.
|
|
10
10
|
|
|
11
11
|
Endpoints marked — are exempt from scope checks (authentication and session endpoints) or resolve their scope at request time.
|
|
12
12
|
|
|
@@ -36,7 +36,9 @@ Endpoints marked — are exempt from scope checks (authentication and session en
|
|
|
36
36
|
| `GET` | `/api_keys` | `read_api_keys` | List API keys |
|
|
37
37
|
| `POST` | `/api_keys` | `write_api_keys` | Create an API key |
|
|
38
38
|
| `GET` | `/api_keys/{id}` | `read_api_keys` | Show an API key |
|
|
39
|
+
| `PATCH` | `/api_keys/{id}` | `write_api_keys` | Update an API key |
|
|
39
40
|
| `DELETE` | `/api_keys/{id}` | `write_api_keys` | Delete an API key |
|
|
41
|
+
| `GET` | `/api_keys/current` | *none* | Describe the current API key |
|
|
40
42
|
| `PATCH` | `/api_keys/{id}/revoke` | `write_api_keys` | Revoke an API key |
|
|
41
43
|
|
|
42
44
|
## Auth
|
|
@@ -47,6 +49,20 @@ Endpoints marked — are exempt from scope checks (authentication and session en
|
|
|
47
49
|
| `POST` | `/auth/refresh` | — | Refresh token |
|
|
48
50
|
| `POST` | `/auth/logout` | — | Logout |
|
|
49
51
|
|
|
52
|
+
## Categories
|
|
53
|
+
|
|
54
|
+
| Method | Path | Required scope | Summary |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| `GET` | `/categories` | `read_categories` | List categories |
|
|
57
|
+
| `POST` | `/categories` | `write_categories` | Create a category |
|
|
58
|
+
| `GET` | `/categories/{id}` | `read_categories` | Get a category |
|
|
59
|
+
| `PATCH` | `/categories/{id}` | `write_categories` | Update a category |
|
|
60
|
+
| `DELETE` | `/categories/{id}` | `write_categories` | Delete a category |
|
|
61
|
+
| `PATCH` | `/categories/{id}/reposition` | `write_categories` | Reposition a category |
|
|
62
|
+
| `GET` | `/categories/{category_id}/products` | `read_categories` | List category products |
|
|
63
|
+
| `POST` | `/categories/{category_id}/products` | `write_categories` | Add a product to a category |
|
|
64
|
+
| `PATCH` | `/categories/{category_id}/products/{id}/reposition` | `write_categories` | Reposition a category product |
|
|
65
|
+
|
|
50
66
|
## Channels
|
|
51
67
|
|
|
52
68
|
| Method | Path | Required scope | Summary |
|
|
@@ -141,6 +157,12 @@ Endpoints marked — are exempt from scope checks (authentication and session en
|
|
|
141
157
|
| `DELETE` | `/invitations/{id}` | `write_settings` | Revoke an invitation |
|
|
142
158
|
| `PATCH` | `/invitations/{id}/resend` | `write_settings` | Resend an invitation |
|
|
143
159
|
|
|
160
|
+
## Locales
|
|
161
|
+
|
|
162
|
+
| Method | Path | Required scope | Summary |
|
|
163
|
+
|---|---|---|---|
|
|
164
|
+
| `GET` | `/locales` | `read_settings` | List supported locales |
|
|
165
|
+
|
|
144
166
|
## Markets
|
|
145
167
|
|
|
146
168
|
| Method | Path | Required scope | Summary |
|
|
@@ -156,6 +178,7 @@ Endpoints marked — are exempt from scope checks (authentication and session en
|
|
|
156
178
|
| Method | Path | Required scope | Summary |
|
|
157
179
|
|---|---|---|---|
|
|
158
180
|
| `GET` | `/me` | — | Get current admin user and permissions |
|
|
181
|
+
| `PATCH` | `/me` | — | Update the current admin profile |
|
|
159
182
|
|
|
160
183
|
## Option types
|
|
161
184
|
|
|
@@ -172,6 +195,7 @@ Endpoints marked — are exempt from scope checks (authentication and session en
|
|
|
172
195
|
| Method | Path | Required scope | Summary |
|
|
173
196
|
|---|---|---|---|
|
|
174
197
|
| `GET` | `/orders/{order_id}/fulfillments` | `read_fulfillments` | List fulfillments |
|
|
198
|
+
| `POST` | `/orders/{order_id}/fulfillments` | `write_fulfillments` | Create a fulfillment |
|
|
175
199
|
| `GET` | `/orders/{order_id}/fulfillments/{id}` | `read_fulfillments` | Show a shipment |
|
|
176
200
|
| `PATCH` | `/orders/{order_id}/fulfillments/{id}` | `write_fulfillments` | Update a shipment |
|
|
177
201
|
| `PATCH` | `/orders/{order_id}/fulfillments/{id}/fulfill` | `write_fulfillments` | Fulfill a fulfillment |
|
|
@@ -246,6 +270,7 @@ Endpoints marked — are exempt from scope checks (authentication and session en
|
|
|
246
270
|
| `GET` | `/products/{product_id}/custom_fields/{id}` | `read_products` | Show a product custom field |
|
|
247
271
|
| `PATCH` | `/products/{product_id}/custom_fields/{id}` | `write_products` | Update a product custom field |
|
|
248
272
|
| `DELETE` | `/products/{product_id}/custom_fields/{id}` | `write_products` | Delete a product custom field |
|
|
273
|
+
| `GET` | `/products/{product_id}/translations` | `read_products` | List product translations |
|
|
249
274
|
| `GET` | `/products` | `read_products` | List products |
|
|
250
275
|
| `POST` | `/products` | `write_products` | Create a product |
|
|
251
276
|
| `GET` | `/products/{id}` | `read_products` | Get a product |
|
|
@@ -331,6 +356,18 @@ Endpoints marked — are exempt from scope checks (authentication and session en
|
|
|
331
356
|
|---|---|---|---|
|
|
332
357
|
| `GET` | `/tags` | — | List tags |
|
|
333
358
|
|
|
359
|
+
## Translatable resources
|
|
360
|
+
|
|
361
|
+
| Method | Path | Required scope | Summary |
|
|
362
|
+
|---|---|---|---|
|
|
363
|
+
| `GET` | `/translatable_resources` | `read_settings` | List translatable resources |
|
|
364
|
+
|
|
365
|
+
## Translations
|
|
366
|
+
|
|
367
|
+
| Method | Path | Required scope | Summary |
|
|
368
|
+
|---|---|---|---|
|
|
369
|
+
| `POST` | `/translations/batch` | *write_<resource> for every resource type in the batch (for API-key authentication)* | Batch upsert translations |
|
|
370
|
+
|
|
334
371
|
## Webhook endpoints
|
|
335
372
|
|
|
336
373
|
| Method | Path | Required scope | Summary |
|
|
@@ -18,7 +18,7 @@ Each tenant (store) can have its own isolated data and configuration, including:
|
|
|
18
18
|
* store settings (name, logo, etc.)
|
|
19
19
|
* etc.
|
|
20
20
|
|
|
21
|
-
All data is fully isolated
|
|
21
|
+
All data is fully isolated besides the staff users, which can manage multiple tenants. This allows you to create a SaaS platform where each tenant can have its own store with its own branding and configuration. Isolation works across admin dashboard and API.
|
|
22
22
|
|
|
23
23
|
> **INFO:** If you need individual seller/supplier/vendor accounts but shared product listings under one site you should use [multi vendor recipe](../multi-vendor.md) instead.
|
|
24
24
|
|
|
@@ -32,9 +32,19 @@ All data is fully isolated besided the staff users, which can manage multiple te
|
|
|
32
32
|
|
|
33
33
|
> **INFO:** You will need to add these environment variables to your CI/CD pipeline and staging/production environments.
|
|
34
34
|
|
|
35
|
-
##
|
|
35
|
+
## Installation
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
### Eject the Spree backend
|
|
38
|
+
|
|
39
|
+
If you've created your project with `create-spree-app` you will need to eject the backend to be able to install the Enterprise and Multi-Tenant gems. You can do this by running:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
spree eject
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Adding gems
|
|
46
|
+
|
|
47
|
+
1. Add the following code to your `backend/Gemfile`:
|
|
38
48
|
|
|
39
49
|
```ruby
|
|
40
50
|
source "https://license:#{ENV['KEYGEN_LICENSE_KEY']}@rubygems.pkg.keygen.sh/#{ENV['KEYGEN_ACCOUNT_ID']}" do
|
|
@@ -43,7 +53,57 @@ All data is fully isolated besided the staff users, which can manage multiple te
|
|
|
43
53
|
end
|
|
44
54
|
```
|
|
45
55
|
|
|
46
|
-
2.
|
|
56
|
+
2. Configure the Docker image build to authenticate against the Keygen source.
|
|
57
|
+
|
|
58
|
+
If you use the Spree CLI (Docker), `spree bundle install` resolves the licensed
|
|
59
|
+
gems **inside the image at build time**, so the Keygen credentials must be available
|
|
60
|
+
during `bundle install` in the `Dockerfile` — not just at runtime. Pass them as
|
|
61
|
+
[BuildKit secrets](https://docs.docker.com/build/building/secrets/) so they are mounted
|
|
62
|
+
as environment variables for the `bundle install` step only, and never baked into the
|
|
63
|
+
image layers or history (unlike `ARG`/`ENV`/`COPY`).
|
|
64
|
+
|
|
65
|
+
> **INFO:** Skip this step if you install without the Spree CLI (plain `bundle install` on the host).
|
|
66
|
+
> In that case the Gemfile reads `KEYGEN_LICENSE_KEY` / `KEYGEN_ACCOUNT_ID` directly from
|
|
67
|
+
> your shell environment.
|
|
68
|
+
|
|
69
|
+
Wrap **every** `bundle install` in your `backend/Dockerfile` with the secret mounts. There
|
|
70
|
+
are usually two — one in the build stage and one in the dev stage:
|
|
71
|
+
|
|
72
|
+
```dockerfile backend/Dockerfile
|
|
73
|
+
COPY .ruby-version Gemfile Gemfile.lock ./
|
|
74
|
+
RUN bundle install # [!code --]
|
|
75
|
+
RUN --mount=type=secret,id=keygen_license_key,env=KEYGEN_LICENSE_KEY,required=false \ # [!code ++]
|
|
76
|
+
--mount=type=secret,id=keygen_account_id,env=KEYGEN_ACCOUNT_ID,required=false \ # [!code ++]
|
|
77
|
+
bundle install # [!code ++]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Then wire the secrets into **both** compose files (`docker-compose.yml` and
|
|
81
|
+
`docker-compose.dev.yml` — the latter is what `spree eject` copies over) so the CLI
|
|
82
|
+
supplies them to the build:
|
|
83
|
+
|
|
84
|
+
```yaml docker-compose.yml
|
|
85
|
+
x-app: &app
|
|
86
|
+
build:
|
|
87
|
+
context: ./backend
|
|
88
|
+
dockerfile: Dockerfile
|
|
89
|
+
target: dev
|
|
90
|
+
secrets: # [!code ++]
|
|
91
|
+
- keygen_license_key # [!code ++]
|
|
92
|
+
- keygen_account_id # [!code ++]
|
|
93
|
+
|
|
94
|
+
# ...at the bottom of the file, declare where the secrets come from:
|
|
95
|
+
secrets: # [!code ++]
|
|
96
|
+
keygen_license_key: # [!code ++]
|
|
97
|
+
environment: KEYGEN_LICENSE_KEY # [!code ++]
|
|
98
|
+
keygen_account_id: # [!code ++]
|
|
99
|
+
environment: KEYGEN_ACCOUNT_ID # [!code ++]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
> **INFO:** Compose reads `environment:`-sourced secrets from the **shell environment** that runs
|
|
103
|
+
> the build, not from `.env`. Make sure `KEYGEN_LICENSE_KEY` and `KEYGEN_ACCOUNT_ID` are
|
|
104
|
+
> exported in the shell (and in your CI/CD and production build environments).
|
|
105
|
+
|
|
106
|
+
3. Install gems:
|
|
47
107
|
|
|
48
108
|
|
|
49
109
|
|
|
@@ -57,7 +117,7 @@ All data is fully isolated besided the staff users, which can manage multiple te
|
|
|
57
117
|
|
|
58
118
|
|
|
59
119
|
|
|
60
|
-
|
|
120
|
+
4. Run generators:
|
|
61
121
|
|
|
62
122
|
|
|
63
123
|
|
|
@@ -72,9 +132,13 @@ All data is fully isolated besided the staff users, which can manage multiple te
|
|
|
72
132
|
|
|
73
133
|
|
|
74
134
|
> **INFO:** This will copy and run migrations for `spree_enterprise` and `spree_multi_tenant` gems.
|
|
135
|
+
> The `spree_multi_tenant:install` generator also edits `config/routes.rb` (to add the
|
|
136
|
+
> tenant domain routing constraints), your customer user model, and your admin user model
|
|
137
|
+
> — see [Post-install configuration](#post-install-configuration) below.
|
|
75
138
|
|
|
139
|
+
## Post-install configuration
|
|
76
140
|
|
|
77
|
-
|
|
141
|
+
### Setting root domain
|
|
78
142
|
|
|
79
143
|
Usually multi-tenant applications are configured to use subdomains for each tenant. For example, if your root domain is `example.com`, you can have tenants like `tenant1.example.com`, `tenant2.example.com`, etc.
|
|
80
144
|
To make it work you need to set the `Spree.root_domain` in your `config/initializers/spree.rb` file, eg.
|
|
@@ -86,23 +150,87 @@ Spree.root_domain = 'example.com'
|
|
|
86
150
|
or use environment variable:
|
|
87
151
|
|
|
88
152
|
```ruby
|
|
89
|
-
Spree.root_domain = ENV.fetch('SPREE_ROOT_DOMAIN', '
|
|
153
|
+
Spree.root_domain = ENV.fetch('SPREE_ROOT_DOMAIN', 'lvh.me')
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
You need to use `lvh.me` for local development, so cross-subdomain cookies will work, `localhost` will **not** work.
|
|
157
|
+
|
|
158
|
+
> **WARNING:** `localhost` cannot be used as a cookie domain by browsers, so the session cookie set on
|
|
159
|
+
> `store1.localhost` is rejected and never sent back — you get logged out when moving between
|
|
160
|
+
> subdomains, and admin sign-in fails with `ActionController::InvalidAuthenticityToken`
|
|
161
|
+
> ("Can't verify CSRF token authenticity"). Use `lvh.me` (or `localtest.me`); both resolve to
|
|
162
|
+
> `127.0.0.1` and are valid cookie domains.
|
|
163
|
+
|
|
164
|
+
#### Sharing the session cookie across subdomains
|
|
165
|
+
|
|
166
|
+
For staff to stay signed in while moving between the app domain (`app.example.com`) and tenant
|
|
167
|
+
subdomains (`store1.example.com`), the session cookie must be scoped to the parent domain. Set
|
|
168
|
+
`COOKIE_TLD_LENGTH` to the number of labels in your root domain:
|
|
169
|
+
|
|
170
|
+
| Root domain | `COOKIE_TLD_LENGTH` | Cookie domain |
|
|
171
|
+
| ----------- | ------------------- | ------------- |
|
|
172
|
+
| `lvh.me` | `2` | `.lvh.me` |
|
|
173
|
+
| `example.com` | `2` | `.example.com` |
|
|
174
|
+
| `shop.example.co.uk` | `3` | `.example.co.uk` |
|
|
175
|
+
|
|
176
|
+
```bash .env
|
|
177
|
+
SPREE_ROOT_DOMAIN=lvh.me
|
|
178
|
+
COOKIE_TLD_LENGTH=2
|
|
90
179
|
```
|
|
91
180
|
|
|
92
|
-
|
|
181
|
+
#### Allowing tenant subdomains through host authorization
|
|
182
|
+
|
|
183
|
+
Rails' host authorization blocks unknown hosts. `.localhost` and `.test` are permitted in
|
|
184
|
+
development by default, but `.lvh.me` (and your production domain) are not — requests to
|
|
185
|
+
`app.lvh.me` are rejected with a "Blocked hosts" error until you allow them. Add your root
|
|
186
|
+
domain to `config/environments/development.rb`:
|
|
187
|
+
|
|
188
|
+
```ruby backend/config/environments/development.rb
|
|
189
|
+
if (root_domain = ENV['SPREE_ROOT_DOMAIN']).present?
|
|
190
|
+
config.hosts << ".#{root_domain}"
|
|
191
|
+
end
|
|
192
|
+
```
|
|
93
193
|
|
|
94
|
-
|
|
194
|
+
### Customer User Class adjustment
|
|
95
195
|
|
|
96
196
|
We need to make slight adjustments to the user class so it can work in a multi-tenant environment.
|
|
97
197
|
|
|
98
|
-
|
|
198
|
+
The `spree_multi_tenant:install` generator adds `include SpreeMultiTenant::CustomerUserConcern`
|
|
199
|
+
to your customer user model automatically. You then need to **remove the `:validatable` module**
|
|
200
|
+
manually. `:validatable` validates the user's email uniqueness globally; the concern re-validates
|
|
201
|
+
it in the scope of the tenant instead, so the same email can exist across different tenants.
|
|
99
202
|
|
|
100
203
|
```ruby backend/app/models/spree/user.rb
|
|
101
|
-
class User <
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
204
|
+
class Spree::User < Spree.base_class
|
|
205
|
+
include Spree::UserAddress
|
|
206
|
+
include Spree::UserMethods
|
|
207
|
+
include Spree::UserPaymentSource
|
|
208
|
+
include SpreeMultiTenant::CustomerUserConcern # added by the generator
|
|
209
|
+
|
|
210
|
+
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable # [!code --]
|
|
211
|
+
devise :database_authenticatable, :registerable, :recoverable, :rememberable # [!code ++]
|
|
212
|
+
end
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
> **WARNING:** Only remove `:validatable`. Do not add other Devise modules (such as `:confirmable`) here
|
|
216
|
+
> unless your app is already set up for them — `:confirmable`, for example, requires additional
|
|
217
|
+
> columns and a confirmation flow, and adding it will break sign-in.
|
|
105
218
|
|
|
106
|
-
|
|
219
|
+
### Admin User Class adjustment
|
|
220
|
+
|
|
221
|
+
The generator also changes your admin user model's base class from `Spree.base_class` to
|
|
222
|
+
`Spree::Base`. If your `admin_user.rb` exists, this is applied automatically; otherwise make the
|
|
223
|
+
change yourself:
|
|
224
|
+
|
|
225
|
+
```ruby backend/app/models/spree/admin_user.rb
|
|
226
|
+
class Spree::AdminUser < Spree.base_class # [!code --]
|
|
227
|
+
class Spree::AdminUser < Spree::Base # [!code ++]
|
|
228
|
+
include Spree::AdminUserMethods
|
|
229
|
+
|
|
230
|
+
devise :database_authenticatable, :registerable,
|
|
231
|
+
:recoverable, :rememberable, :validatable
|
|
107
232
|
end
|
|
108
233
|
```
|
|
234
|
+
|
|
235
|
+
> **INFO:** Unlike the customer user model, the admin user model keeps `:validatable` — staff accounts are
|
|
236
|
+
> global and can manage multiple tenants, so their emails remain globally unique.
|