backstage 0.1.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +27 -0
- data/CONTRIBUTING.md +70 -0
- data/LICENSE +21 -0
- data/README.md +195 -0
- data/app/assets/stylesheets/backstage/backstage.css +5 -0
- data/app/controllers/backstage/actions_controller.rb +27 -0
- data/app/controllers/backstage/application_controller.rb +21 -0
- data/app/controllers/backstage/dashboards_controller.rb +15 -0
- data/app/controllers/backstage/home_controller.rb +14 -0
- data/app/controllers/backstage/resources_controller.rb +94 -0
- data/app/views/backstage/dashboards/show.html.erb +36 -0
- data/app/views/backstage/fields/_belongs_to.html.erb +7 -0
- data/app/views/backstage/fields/_boolean.html.erb +1 -0
- data/app/views/backstage/fields/_date.html.erb +1 -0
- data/app/views/backstage/fields/_datetime.html.erb +1 -0
- data/app/views/backstage/fields/_enum.html.erb +4 -0
- data/app/views/backstage/fields/_has_many.html.erb +19 -0
- data/app/views/backstage/fields/_image_url.html.erb +5 -0
- data/app/views/backstage/fields/_integer.html.erb +1 -0
- data/app/views/backstage/fields/_string.html.erb +1 -0
- data/app/views/backstage/fields/_text.html.erb +1 -0
- data/app/views/backstage/fields/_thumbnails.html.erb +13 -0
- data/app/views/backstage/home/index.html.erb +24 -0
- data/app/views/backstage/resources/edit.html.erb +18 -0
- data/app/views/backstage/resources/index.html.erb +54 -0
- data/app/views/backstage/resources/new.html.erb +13 -0
- data/app/views/layouts/backstage/backstage.html.erb +59 -0
- data/config/routes.rb +15 -0
- data/lib/backstage/association_config.rb +31 -0
- data/lib/backstage/auto_discovery.rb +58 -0
- data/lib/backstage/configuration.rb +31 -0
- data/lib/backstage/dashboard_config.rb +15 -0
- data/lib/backstage/engine.rb +11 -0
- data/lib/backstage/field.rb +39 -0
- data/lib/backstage/registry.rb +32 -0
- data/lib/backstage/resource_config.rb +91 -0
- data/lib/backstage/sidebar_config.rb +15 -0
- data/lib/backstage/version.rb +3 -0
- data/lib/backstage.rb +56 -0
- data/lib/generators/backstage/install/install_generator.rb +29 -0
- data/lib/generators/backstage/install/templates/SKILL.md +221 -0
- data/lib/generators/backstage/install/templates/backstage.yml +16 -0
- metadata +95 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: backstage-install
|
|
3
|
+
description: Install and configure the Backstage admin engine gem. Checks compatibility, wires up authentication, registers models, optionally configures per-resource DSL and associations, and verifies the admin interface is reachable.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# backstage-install
|
|
7
|
+
|
|
8
|
+
Complete installation and setup of the Backstage admin engine in this Rails app. Work through each step in order, confirming with the user before making any changes.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Step 1 — Compatibility check
|
|
13
|
+
|
|
14
|
+
Read `Gemfile`, `Gemfile.lock`, and `.ruby-version` (if present) to check:
|
|
15
|
+
|
|
16
|
+
- **Ruby >= 3.2** — stop with a clear error if not met
|
|
17
|
+
- **Rails >= 8.0** — check `Gemfile.lock` for the rails gem version; stop if not met
|
|
18
|
+
- **Asset pipeline** — check Gemfile for `propshaft`. Backstage vendors its own CSS and serves it via Propshaft. If the app uses Sprockets instead, warn the user and note that they may need to add `//= link backstage/backstage.css` to `app/assets/config/manifest.js`
|
|
19
|
+
- **Conflicts** — check for other admin gems (`rails_admin`, `activeadmin`, `administrate`). Note any found but do not block installation
|
|
20
|
+
|
|
21
|
+
Report findings before proceeding.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Step 2 — Add gem to Gemfile
|
|
26
|
+
|
|
27
|
+
Check if `backstage` already appears in the Gemfile. If not:
|
|
28
|
+
|
|
29
|
+
- Add `gem "backstage"` to the Gemfile
|
|
30
|
+
- Run `bundle install`
|
|
31
|
+
|
|
32
|
+
If already present, skip to Step 3.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Step 3 — Run the install generator
|
|
37
|
+
|
|
38
|
+
Check `config/routes.rb` for an existing `mount Backstage::Engine` line.
|
|
39
|
+
|
|
40
|
+
If absent, run the generator:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bin/rails generate backstage:install
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
This creates `config/backstage.yml` and adds the mount to `config/routes.rb`. If the generator has already been run, skip this step and proceed with the existing files.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Step 4 — Configure authentication
|
|
51
|
+
|
|
52
|
+
Backstage calls a method on `current_user` to check admin access. You must tell it how to find the current user.
|
|
53
|
+
|
|
54
|
+
Ask the user:
|
|
55
|
+
|
|
56
|
+
1. **How is the current user provided?** Common answers: Devise (`current_user`), a custom session helper, a JWT token — or "I don't have auth yet"
|
|
57
|
+
2. **What method on the user object indicates admin access?** (default: `is_admin?`)
|
|
58
|
+
3. **Where should non-admins be redirected?** (default: `/`)
|
|
59
|
+
|
|
60
|
+
Check `config/initializers/` for an existing Backstage initializer. If none exists, create `config/initializers/backstage.rb`:
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
Rails.application.config.to_prepare do
|
|
64
|
+
Backstage::ApplicationController.class_eval do
|
|
65
|
+
def current_user
|
|
66
|
+
# TODO: replace with your actual current_user lookup
|
|
67
|
+
# e.g. User.find_by(id: session[:user_id])
|
|
68
|
+
# e.g. Current.user (if using Current attributes)
|
|
69
|
+
nil
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Then update `config/backstage.yml` with the answers from above:
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
admin_user_method: is_admin? # or whatever method they specified
|
|
79
|
+
redirect_on_failure: /login # or wherever they want non-admins to go
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If the user doesn't have authentication set up yet, add the TODO comment and note that the admin will redirect everyone until it's wired up.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Step 5 — Register models
|
|
87
|
+
|
|
88
|
+
Read `app/models/` to list the available ActiveRecord models (skip `ApplicationRecord` and concerns).
|
|
89
|
+
|
|
90
|
+
Show the list and ask: **Which models should appear in the admin?**
|
|
91
|
+
|
|
92
|
+
Update the `models:` list in `config/backstage.yml` with their choices:
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
models:
|
|
96
|
+
- Article
|
|
97
|
+
- User
|
|
98
|
+
- Tag
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Backstage auto-discovers columns for each model — no further configuration is needed for basic CRUD.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Step 6 — Optional: per-resource DSL
|
|
106
|
+
|
|
107
|
+
Ask the user: **"Would you like to configure any field overrides, associations, or sidebar links for these models? (optional — you can always add these later)"**
|
|
108
|
+
|
|
109
|
+
If yes, for each model they want to configure, create `config/backstage/<model_name_lowercase>.rb`. Common patterns:
|
|
110
|
+
|
|
111
|
+
**Set the display column** (used in belongs-to dropdowns and search):
|
|
112
|
+
```ruby
|
|
113
|
+
Backstage.resource(:Article) do |c|
|
|
114
|
+
c.display_column :title
|
|
115
|
+
end
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Override a field type:**
|
|
119
|
+
```ruby
|
|
120
|
+
Backstage.resource(:Article) do |c|
|
|
121
|
+
c.field :body, as: :text
|
|
122
|
+
c.field :cover_image_url, as: :image_url
|
|
123
|
+
end
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Belongs-to association** (replaces the raw foreign key field with a dropdown):
|
|
127
|
+
```ruby
|
|
128
|
+
Backstage.resource(:Article) do |c|
|
|
129
|
+
c.belongs_to :author, display_column: :name, class_name: "User"
|
|
130
|
+
end
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Has-many checkbox list:**
|
|
134
|
+
```ruby
|
|
135
|
+
Backstage.resource(:Article) do |c|
|
|
136
|
+
c.has_many :tags, display_column: :name
|
|
137
|
+
end
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Sidebar links on the edit page:**
|
|
141
|
+
```ruby
|
|
142
|
+
Backstage.resource(:Article) do |c|
|
|
143
|
+
c.sidebar do |s|
|
|
144
|
+
s.link "View on site", ->(record) { "/posts/#{record.id}" }
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Only create files for models where the user wants customisation. Skip this step entirely if they prefer to configure later.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Step 7 — Optional: dashboard
|
|
154
|
+
|
|
155
|
+
Ask: **"Would you like a dashboard — a filtered view of a model with a named scope? (optional)"**
|
|
156
|
+
|
|
157
|
+
If yes, ask for:
|
|
158
|
+
1. The model name
|
|
159
|
+
2. The scope name (must be a named scope on the model, e.g. `published`, `pending`)
|
|
160
|
+
3. A display name for the dashboard (e.g. "Published Articles")
|
|
161
|
+
|
|
162
|
+
Add to `config/backstage.yml`:
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
dashboards:
|
|
166
|
+
- name: "Published Articles"
|
|
167
|
+
model: Article
|
|
168
|
+
scope:
|
|
169
|
+
status: published
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Note: the scope value must match a value that `Model.where(scope_hash)` can accept. For integer-backed enums, use the integer value (e.g. `status: 1`).
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Step 8 — Verify
|
|
177
|
+
|
|
178
|
+
Start the Rails server (if not already running) and ask the user to visit `/admin` (or whatever path the engine is mounted at).
|
|
179
|
+
|
|
180
|
+
Check `config/routes.rb` to confirm the mount path. If the path is not `/admin`, tell the user the correct URL.
|
|
181
|
+
|
|
182
|
+
Expected results:
|
|
183
|
+
- Non-admin users (or unauthenticated users) are redirected to `redirect_on_failure`
|
|
184
|
+
- Admin users see the Backstage home page listing registered models and their record counts
|
|
185
|
+
- Each model links to a paginated, searchable index table
|
|
186
|
+
- Each record has an edit form with auto-discovered fields
|
|
187
|
+
|
|
188
|
+
If the user reports a problem, help diagnose:
|
|
189
|
+
- 404 → engine not mounted, or wrong path
|
|
190
|
+
- Redirect loop → `current_user` method raises or returns unexpected value
|
|
191
|
+
- Empty model list → `config/backstage.yml` not loaded, or model names misspelled
|
|
192
|
+
- Missing columns → model table may not exist yet; run `rails db:migrate`
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Step 9 — Optional commit
|
|
197
|
+
|
|
198
|
+
Ask: **"Would you like to commit these changes?"**
|
|
199
|
+
|
|
200
|
+
If yes, stage only the files created or modified during this setup:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
git add Gemfile Gemfile.lock config/routes.rb config/backstage.yml \
|
|
204
|
+
config/initializers/backstage.rb
|
|
205
|
+
# add any DSL files created in Step 6:
|
|
206
|
+
# git add config/backstage/article.rb config/backstage/user.rb
|
|
207
|
+
git commit -m "Install Backstage admin engine"
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Do not use `git add -A` — only stage Backstage-related files.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Summary
|
|
215
|
+
|
|
216
|
+
After all steps complete, print a summary of:
|
|
217
|
+
- Mount path and admin URL
|
|
218
|
+
- Models registered
|
|
219
|
+
- Authentication method wired up (or TODOs remaining)
|
|
220
|
+
- Any DSL or dashboard configuration added
|
|
221
|
+
- Any manual steps remaining (implementing `current_user`, adding `is_admin?` to the User model, Sprockets manifest updates if applicable)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Backstage configuration
|
|
2
|
+
#
|
|
3
|
+
# List the models you want to manage:
|
|
4
|
+
# models:
|
|
5
|
+
# - Article
|
|
6
|
+
# - User
|
|
7
|
+
models: []
|
|
8
|
+
|
|
9
|
+
# Method called on current_user to check admin access (default: is_admin?)
|
|
10
|
+
# admin_user_method: is_admin?
|
|
11
|
+
|
|
12
|
+
# Where to redirect non-admin users (default: /)
|
|
13
|
+
# redirect_on_failure: /
|
|
14
|
+
|
|
15
|
+
# Records per page (default: 25)
|
|
16
|
+
# per_page: 25
|
metadata
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: backstage
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Gareth James
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-05-18 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: railties
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '8.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '8.0'
|
|
26
|
+
email:
|
|
27
|
+
- g.claude@bemused.org
|
|
28
|
+
executables: []
|
|
29
|
+
extensions: []
|
|
30
|
+
extra_rdoc_files: []
|
|
31
|
+
files:
|
|
32
|
+
- CHANGELOG.md
|
|
33
|
+
- CONTRIBUTING.md
|
|
34
|
+
- LICENSE
|
|
35
|
+
- README.md
|
|
36
|
+
- app/assets/stylesheets/backstage/backstage.css
|
|
37
|
+
- app/controllers/backstage/actions_controller.rb
|
|
38
|
+
- app/controllers/backstage/application_controller.rb
|
|
39
|
+
- app/controllers/backstage/dashboards_controller.rb
|
|
40
|
+
- app/controllers/backstage/home_controller.rb
|
|
41
|
+
- app/controllers/backstage/resources_controller.rb
|
|
42
|
+
- app/views/backstage/dashboards/show.html.erb
|
|
43
|
+
- app/views/backstage/fields/_belongs_to.html.erb
|
|
44
|
+
- app/views/backstage/fields/_boolean.html.erb
|
|
45
|
+
- app/views/backstage/fields/_date.html.erb
|
|
46
|
+
- app/views/backstage/fields/_datetime.html.erb
|
|
47
|
+
- app/views/backstage/fields/_enum.html.erb
|
|
48
|
+
- app/views/backstage/fields/_has_many.html.erb
|
|
49
|
+
- app/views/backstage/fields/_image_url.html.erb
|
|
50
|
+
- app/views/backstage/fields/_integer.html.erb
|
|
51
|
+
- app/views/backstage/fields/_string.html.erb
|
|
52
|
+
- app/views/backstage/fields/_text.html.erb
|
|
53
|
+
- app/views/backstage/fields/_thumbnails.html.erb
|
|
54
|
+
- app/views/backstage/home/index.html.erb
|
|
55
|
+
- app/views/backstage/resources/edit.html.erb
|
|
56
|
+
- app/views/backstage/resources/index.html.erb
|
|
57
|
+
- app/views/backstage/resources/new.html.erb
|
|
58
|
+
- app/views/layouts/backstage/backstage.html.erb
|
|
59
|
+
- config/routes.rb
|
|
60
|
+
- lib/backstage.rb
|
|
61
|
+
- lib/backstage/association_config.rb
|
|
62
|
+
- lib/backstage/auto_discovery.rb
|
|
63
|
+
- lib/backstage/configuration.rb
|
|
64
|
+
- lib/backstage/dashboard_config.rb
|
|
65
|
+
- lib/backstage/engine.rb
|
|
66
|
+
- lib/backstage/field.rb
|
|
67
|
+
- lib/backstage/registry.rb
|
|
68
|
+
- lib/backstage/resource_config.rb
|
|
69
|
+
- lib/backstage/sidebar_config.rb
|
|
70
|
+
- lib/backstage/version.rb
|
|
71
|
+
- lib/generators/backstage/install/install_generator.rb
|
|
72
|
+
- lib/generators/backstage/install/templates/SKILL.md
|
|
73
|
+
- lib/generators/backstage/install/templates/backstage.yml
|
|
74
|
+
homepage: https://github.com/gjtorikian/backstage
|
|
75
|
+
licenses:
|
|
76
|
+
- MIT
|
|
77
|
+
metadata: {}
|
|
78
|
+
rdoc_options: []
|
|
79
|
+
require_paths:
|
|
80
|
+
- lib
|
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
|
+
requirements:
|
|
83
|
+
- - ">="
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: 3.2.0
|
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '0'
|
|
91
|
+
requirements: []
|
|
92
|
+
rubygems_version: 3.6.2
|
|
93
|
+
specification_version: 4
|
|
94
|
+
summary: A lightweight, configurable admin interface for Rails 8
|
|
95
|
+
test_files: []
|