plutonium 0.50.0 → 0.51.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 +4 -4
- data/.claude/skills/plutonium/SKILL.md +85 -102
- data/.claude/skills/plutonium-app/SKILL.md +572 -0
- data/.claude/skills/plutonium-auth/SKILL.md +163 -300
- data/.claude/skills/plutonium-behavior/SKILL.md +838 -0
- data/.claude/skills/plutonium-resource/SKILL.md +1176 -0
- data/.claude/skills/plutonium-tenancy/SKILL.md +655 -0
- data/.claude/skills/plutonium-testing/SKILL.md +6 -5
- data/.claude/skills/plutonium-ui/SKILL.md +900 -0
- data/CHANGELOG.md +27 -2
- data/Rakefile +2 -1
- data/app/assets/plutonium.css +1 -11
- data/app/assets/plutonium.js +1009 -1214
- data/app/assets/plutonium.js.map +3 -3
- data/app/assets/plutonium.min.js +52 -51
- data/app/assets/plutonium.min.js.map +3 -3
- data/docs/.vitepress/config.ts +37 -27
- data/docs/getting-started/index.md +22 -29
- data/docs/getting-started/installation.md +37 -80
- data/docs/getting-started/tutorial/index.md +4 -5
- data/docs/guides/adding-resources.md +66 -377
- data/docs/guides/authentication.md +94 -463
- data/docs/guides/authorization.md +124 -370
- data/docs/guides/creating-packages.md +94 -296
- data/docs/guides/custom-actions.md +121 -441
- data/docs/guides/index.md +22 -42
- data/docs/guides/multi-tenancy.md +116 -187
- data/docs/guides/nested-resources.md +103 -431
- data/docs/guides/search-filtering.md +123 -240
- data/docs/guides/testing.md +5 -4
- data/docs/guides/theming.md +157 -407
- data/docs/guides/troubleshooting.md +5 -3
- data/docs/guides/user-invites.md +106 -425
- data/docs/guides/user-profile.md +76 -243
- data/docs/index.md +1 -1
- data/docs/reference/app/generators.md +517 -0
- data/docs/reference/app/index.md +158 -0
- data/docs/reference/app/packages.md +146 -0
- data/docs/reference/app/portals.md +377 -0
- data/docs/reference/auth/accounts.md +230 -0
- data/docs/reference/auth/index.md +88 -0
- data/docs/reference/auth/profile.md +185 -0
- data/docs/reference/behavior/controllers.md +395 -0
- data/docs/reference/behavior/index.md +22 -0
- data/docs/reference/behavior/interactions.md +341 -0
- data/docs/reference/behavior/policies.md +417 -0
- data/docs/reference/index.md +56 -49
- data/docs/reference/resource/actions.md +423 -0
- data/docs/reference/resource/definition.md +508 -0
- data/docs/reference/resource/index.md +50 -0
- data/docs/reference/resource/model.md +348 -0
- data/docs/reference/resource/query.md +305 -0
- data/docs/reference/tenancy/entity-scoping.md +361 -0
- data/docs/reference/tenancy/index.md +36 -0
- data/docs/reference/tenancy/invites.md +393 -0
- data/docs/reference/tenancy/nested-resources.md +267 -0
- data/docs/reference/testing/index.md +287 -0
- data/docs/reference/ui/assets.md +400 -0
- data/docs/reference/ui/components.md +165 -0
- data/docs/reference/ui/displays.md +104 -0
- data/docs/reference/ui/forms.md +284 -0
- data/docs/reference/ui/index.md +30 -0
- data/docs/reference/ui/layouts.md +106 -0
- data/docs/reference/ui/pages.md +189 -0
- data/docs/reference/ui/tables.md +117 -0
- data/docs/superpowers/specs/2026-05-09-typeahead-endpoint-design.md +203 -0
- data/docs/superpowers/specs/2026-05-12-skill-compaction-design.md +99 -0
- data/docs/superpowers/specs/2026-05-13-docs-restructure-design.md +186 -0
- data/gemfiles/rails_7.gemfile.lock +1 -1
- data/gemfiles/rails_8.0.gemfile.lock +1 -1
- data/gemfiles/rails_8.1.gemfile.lock +1 -1
- data/lib/generators/pu/core/update/update_generator.rb +0 -20
- data/lib/generators/pu/invites/install_generator.rb +1 -0
- data/lib/plutonium/definition/base.rb +1 -1
- data/lib/plutonium/definition/{views.rb → index_views.rb} +21 -20
- data/lib/plutonium/helpers/turbo_helper.rb +11 -0
- data/lib/plutonium/helpers/turbo_stream_actions_helper.rb +14 -0
- data/lib/plutonium/resource/controller.rb +1 -0
- data/lib/plutonium/resource/controllers/crud_actions.rb +19 -1
- data/lib/plutonium/resource/controllers/typeahead.rb +180 -0
- data/lib/plutonium/resource/policy.rb +7 -0
- data/lib/plutonium/routing/mapper_extensions.rb +15 -0
- data/lib/plutonium/ui/component/methods.rb +4 -0
- data/lib/plutonium/ui/form/base.rb +6 -2
- data/lib/plutonium/ui/form/components/json.rb +58 -0
- data/lib/plutonium/ui/form/components/resource_select.rb +62 -8
- data/lib/plutonium/ui/form/components/secure_association.rb +98 -22
- data/lib/plutonium/ui/form/concerns/typeahead_attributes.rb +83 -0
- data/lib/plutonium/ui/form/resource.rb +0 -4
- data/lib/plutonium/ui/grid/resource.rb +1 -1
- data/lib/plutonium/ui/layout/base.rb +1 -0
- data/lib/plutonium/ui/page/base.rb +0 -7
- data/lib/plutonium/ui/page/index.rb +4 -4
- data/lib/plutonium/ui/table/resource.rb +1 -1
- data/lib/plutonium/version.rb +1 -1
- data/lib/plutonium.rb +8 -0
- data/lib/tasks/release.rake +15 -1
- data/package.json +10 -10
- data/src/css/slim_select.css +4 -0
- data/src/js/controllers/slim_select_controller.js +61 -0
- data/src/js/turbo/turbo_actions.js +33 -0
- data/yarn.lock +553 -543
- metadata +44 -33
- data/.claude/skills/plutonium-assets/SKILL.md +0 -512
- data/.claude/skills/plutonium-controller/SKILL.md +0 -396
- data/.claude/skills/plutonium-create-resource/SKILL.md +0 -303
- data/.claude/skills/plutonium-definition/SKILL.md +0 -1223
- data/.claude/skills/plutonium-entity-scoping/SKILL.md +0 -317
- data/.claude/skills/plutonium-forms/SKILL.md +0 -465
- data/.claude/skills/plutonium-installation/SKILL.md +0 -331
- data/.claude/skills/plutonium-interaction/SKILL.md +0 -413
- data/.claude/skills/plutonium-invites/SKILL.md +0 -408
- data/.claude/skills/plutonium-model/SKILL.md +0 -440
- data/.claude/skills/plutonium-nested-resources/SKILL.md +0 -360
- data/.claude/skills/plutonium-package/SKILL.md +0 -198
- data/.claude/skills/plutonium-policy/SKILL.md +0 -456
- data/.claude/skills/plutonium-portal/SKILL.md +0 -410
- data/.claude/skills/plutonium-views/SKILL.md +0 -651
- data/docs/reference/assets/index.md +0 -496
- data/docs/reference/controller/index.md +0 -412
- data/docs/reference/definition/actions.md +0 -462
- data/docs/reference/definition/fields.md +0 -383
- data/docs/reference/definition/index.md +0 -326
- data/docs/reference/definition/query.md +0 -351
- data/docs/reference/generators/index.md +0 -648
- data/docs/reference/interaction/index.md +0 -449
- data/docs/reference/model/features.md +0 -248
- data/docs/reference/model/index.md +0 -218
- data/docs/reference/policy/index.md +0 -456
- data/docs/reference/portal/index.md +0 -379
- data/docs/reference/views/forms.md +0 -411
- data/docs/reference/views/index.md +0 -544
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: plutonium-portal
|
|
3
|
-
description: Use BEFORE creating a portal, mounting a portal engine, running pu:pkg:portal, configuring entity strategies, or routing portal-specific resources. For tenancy mechanics, also load plutonium-entity-scoping.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Plutonium Portals
|
|
7
|
-
|
|
8
|
-
## 🚨 Critical (read first)
|
|
9
|
-
- **Use `pu:pkg:portal`.** Never hand-craft a portal engine — the generator wires up the controller concerns, routes, and layout.
|
|
10
|
-
- **Always use `pu:res:conn` to connect resources to portals** — resources are invisible until connected. Pass resources directly (not via `--src`) to skip prompts.
|
|
11
|
-
- **Entity scoping is portal-level.** `scope_to_entity Entity, strategy: :path` in the portal engine; then every resource in that portal is scoped automatically. For mechanics, see `plutonium-entity-scoping`.
|
|
12
|
-
- **Pass `--auth=<account>` / `--public` / `--byo`** to `pu:pkg:portal` for unattended runs.
|
|
13
|
-
- **Related skills:** `plutonium-entity-scoping` (tenancy mechanics), `plutonium-auth` (Rodauth integration), `plutonium-package` (portal vs feature packages), `plutonium-policy` (portal-specific policies).
|
|
14
|
-
|
|
15
|
-
Portals are Rails engines that provide web interfaces for specific user types.
|
|
16
|
-
|
|
17
|
-
## Quick checklist
|
|
18
|
-
|
|
19
|
-
Creating a portal and connecting resources:
|
|
20
|
-
|
|
21
|
-
1. Run `rails g pu:pkg:portal <name> --auth=<account>` (or `--public` / `--byo`). Add `--scope=Entity` for multi-tenancy.
|
|
22
|
-
2. Mount the engine in `config/routes.rb`: `mount <Name>Portal::Engine, at: "/<name>"`.
|
|
23
|
-
3. For each resource, run `rails g pu:res:conn ResourceName --dest=<name>_portal`.
|
|
24
|
-
4. For singular resources (profile, settings), pass `--singular`.
|
|
25
|
-
5. Customize the portal's `Concerns::Controller` for auth / before_action hooks.
|
|
26
|
-
6. Override portal-specific policies/definitions as needed.
|
|
27
|
-
7. Verify: `bin/rails routes | grep <name>_portal`.
|
|
28
|
-
8. For multi-tenancy specifics, load `plutonium-entity-scoping`.
|
|
29
|
-
|
|
30
|
-
## Creating a Portal
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
rails g pu:pkg:portal dashboard
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### Generator Options
|
|
37
|
-
|
|
38
|
-
| Option | Description |
|
|
39
|
-
|--------|-------------|
|
|
40
|
-
| `--auth=NAME` | Rodauth account to authenticate with (e.g., `--auth=user`) |
|
|
41
|
-
| `--public` | Grant public access (no authentication) |
|
|
42
|
-
| `--byo` | Bring your own authentication |
|
|
43
|
-
| `--scope=CLASS` | Entity class to scope to for multi-tenancy (e.g., `--scope=Organization`) |
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
# Non-interactive examples
|
|
47
|
-
rails g pu:pkg:portal admin --auth=admin
|
|
48
|
-
rails g pu:pkg:portal api --public
|
|
49
|
-
rails g pu:pkg:portal custom --byo
|
|
50
|
-
|
|
51
|
-
# With entity scoping (multi-tenancy)
|
|
52
|
-
rails g pu:pkg:portal admin --auth=admin --scope=Organization
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Without flags, the generator prompts interactively.
|
|
56
|
-
|
|
57
|
-
## Portal Engine
|
|
58
|
-
|
|
59
|
-
```ruby
|
|
60
|
-
# packages/dashboard_portal/lib/engine.rb
|
|
61
|
-
module DashboardPortal
|
|
62
|
-
class Engine < Rails::Engine
|
|
63
|
-
include Plutonium::Portal::Engine
|
|
64
|
-
|
|
65
|
-
config.after_initialize do
|
|
66
|
-
# Optional: multi-tenancy
|
|
67
|
-
scope_to_entity Organization, strategy: :path
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Connecting Resources to Portals
|
|
74
|
-
|
|
75
|
-
Resources must be connected to a portal to be accessible via its web interface.
|
|
76
|
-
|
|
77
|
-
### Command Syntax
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
rails g pu:res:conn RESOURCE [RESOURCE...] --dest=PORTAL_NAME [--singular]
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
**Always specify resources directly** - this avoids interactive prompts.
|
|
84
|
-
|
|
85
|
-
### Usage Patterns
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
# Main app resources
|
|
89
|
-
rails g pu:res:conn Post Comment Tag --dest=dashboard_portal
|
|
90
|
-
|
|
91
|
-
# Namespaced resources (from a feature package)
|
|
92
|
-
rails g pu:res:conn Blogging::Post Blogging::Comment --dest=admin_portal
|
|
93
|
-
|
|
94
|
-
# Singular resources (profile, dashboard, settings)
|
|
95
|
-
rails g pu:res:conn Profile --dest=customer_portal --singular
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### What Gets Generated
|
|
99
|
-
|
|
100
|
-
For a resource `Post` connected to `admin_portal`:
|
|
101
|
-
|
|
102
|
-
```
|
|
103
|
-
packages/admin_portal/app/
|
|
104
|
-
├── controllers/admin_portal/posts_controller.rb # Portal controller
|
|
105
|
-
├── policies/admin_portal/post_policy.rb # Portal policy
|
|
106
|
-
└── definitions/admin_portal/post_definition.rb # Portal definition
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Plus route registration in `packages/admin_portal/config/routes.rb`.
|
|
110
|
-
|
|
111
|
-
### Generated Controller
|
|
112
|
-
|
|
113
|
-
```ruby
|
|
114
|
-
class AdminPortal::PostsController < ::PostsController
|
|
115
|
-
include AdminPortal::Concerns::Controller
|
|
116
|
-
end
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### Generated Policy
|
|
120
|
-
|
|
121
|
-
```ruby
|
|
122
|
-
class AdminPortal::PostPolicy < ::PostPolicy
|
|
123
|
-
include AdminPortal::ResourcePolicy
|
|
124
|
-
|
|
125
|
-
def permitted_attributes_for_create
|
|
126
|
-
[:title, :content, :user_id]
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def permitted_attributes_for_read
|
|
130
|
-
[:title, :content, :user_id, :created_at, :updated_at]
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def permitted_associations
|
|
134
|
-
%i[]
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Route Registration
|
|
140
|
-
|
|
141
|
-
```ruby
|
|
142
|
-
# In packages/admin_portal/config/routes.rb
|
|
143
|
-
register_resource ::Post
|
|
144
|
-
register_resource ::Profile, singular: true # With --singular
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Important Notes
|
|
148
|
-
|
|
149
|
-
1. **Always specify resources directly** - avoids prompts, no `--src` needed
|
|
150
|
-
2. **Always use the generator** - never manually connect resources
|
|
151
|
-
3. **Run after migrations** - the generator reads model columns for policy attributes
|
|
152
|
-
|
|
153
|
-
## Authentication
|
|
154
|
-
|
|
155
|
-
### Rodauth Integration
|
|
156
|
-
|
|
157
|
-
```ruby
|
|
158
|
-
# packages/dashboard_portal/app/controllers/dashboard_portal/concerns/controller.rb
|
|
159
|
-
module DashboardPortal
|
|
160
|
-
module Concerns
|
|
161
|
-
module Controller
|
|
162
|
-
extend ActiveSupport::Concern
|
|
163
|
-
include Plutonium::Portal::Controller
|
|
164
|
-
include Plutonium::Auth::Rodauth(:user) # Use :user account
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Public Access
|
|
171
|
-
|
|
172
|
-
```ruby
|
|
173
|
-
module DashboardPortal
|
|
174
|
-
module Concerns
|
|
175
|
-
module Controller
|
|
176
|
-
extend ActiveSupport::Concern
|
|
177
|
-
include Plutonium::Portal::Controller
|
|
178
|
-
include Plutonium::Auth::Public
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Custom Authentication
|
|
185
|
-
|
|
186
|
-
```ruby
|
|
187
|
-
module DashboardPortal
|
|
188
|
-
module Concerns
|
|
189
|
-
module Controller
|
|
190
|
-
extend ActiveSupport::Concern
|
|
191
|
-
include Plutonium::Portal::Controller
|
|
192
|
-
include Plutonium::Auth::Public
|
|
193
|
-
|
|
194
|
-
def current_user
|
|
195
|
-
@current_user ||= User.find_by(api_key: request.headers["X-API-Key"])
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
## Entity Scoping (Multi-tenancy)
|
|
203
|
-
|
|
204
|
-
Portals can scope all data to a parent entity via `scope_to_entity`:
|
|
205
|
-
|
|
206
|
-
```ruby
|
|
207
|
-
module AdminPortal
|
|
208
|
-
class Engine < Rails::Engine
|
|
209
|
-
include Plutonium::Portal::Engine
|
|
210
|
-
|
|
211
|
-
config.after_initialize do
|
|
212
|
-
scope_to_entity Organization, strategy: :path
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
Strategies: `:path` (entity id in URL) or a custom method name on the portal controller concern.
|
|
219
|
-
|
|
220
|
-
Access in controllers/views: `current_scoped_entity`, `scoped_to_entity?`. In policies: `entity_scope`.
|
|
221
|
-
|
|
222
|
-
> **For the full entity scoping picture — the three model shapes, `associated_with` resolution, `default_relation_scope` rules, safe `relation_scope` overrides, and how parent scoping takes precedence — see the [plutonium-entity-scoping](../plutonium-entity-scoping/SKILL.md) skill. It is the single source of truth.**
|
|
223
|
-
|
|
224
|
-
## Routes
|
|
225
|
-
|
|
226
|
-
### Portal Routes
|
|
227
|
-
|
|
228
|
-
```ruby
|
|
229
|
-
# packages/dashboard_portal/config/routes.rb
|
|
230
|
-
DashboardPortal::Engine.routes.draw do
|
|
231
|
-
root to: "dashboard#index"
|
|
232
|
-
|
|
233
|
-
# Register resources
|
|
234
|
-
register_resource ::Post
|
|
235
|
-
register_resource Blogging::Comment
|
|
236
|
-
|
|
237
|
-
# Custom routes
|
|
238
|
-
get "settings", to: "settings#index"
|
|
239
|
-
end
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### Custom Routes on Resources
|
|
243
|
-
|
|
244
|
-
Add member or collection routes with a block:
|
|
245
|
-
|
|
246
|
-
```ruby
|
|
247
|
-
register_resource ::Post do
|
|
248
|
-
member do
|
|
249
|
-
get :preview
|
|
250
|
-
get :analytics
|
|
251
|
-
post :publish
|
|
252
|
-
end
|
|
253
|
-
collection do
|
|
254
|
-
get :archived
|
|
255
|
-
post :bulk_publish
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### Mounting in Main App
|
|
261
|
-
|
|
262
|
-
```ruby
|
|
263
|
-
# config/routes.rb
|
|
264
|
-
Rails.application.routes.draw do
|
|
265
|
-
# With authentication constraint
|
|
266
|
-
constraints Rodauth::Rails.authenticate(:user) do
|
|
267
|
-
mount DashboardPortal::Engine, at: "/dashboard"
|
|
268
|
-
end
|
|
269
|
-
|
|
270
|
-
# Or without
|
|
271
|
-
mount PublicPortal::Engine, at: "/public"
|
|
272
|
-
end
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Controller Hierarchy
|
|
276
|
-
|
|
277
|
-
Portal controllers inherit from the feature package's controller if one exists (and include the portal's `Concerns::Controller`). If no feature package controller exists, they inherit from the portal's `ResourceController`.
|
|
278
|
-
|
|
279
|
-
```ruby
|
|
280
|
-
# With feature package controller:
|
|
281
|
-
class DashboardPortal::PostsController < ::PostsController
|
|
282
|
-
include DashboardPortal::Concerns::Controller
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
# Without feature package controller:
|
|
286
|
-
class DashboardPortal::PostsController < DashboardPortal::ResourceController
|
|
287
|
-
end
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
### Portal ResourceController
|
|
291
|
-
|
|
292
|
-
```ruby
|
|
293
|
-
# packages/dashboard_portal/app/controllers/dashboard_portal/resource_controller.rb
|
|
294
|
-
module DashboardPortal
|
|
295
|
-
class ResourceController < ::ResourceController
|
|
296
|
-
include DashboardPortal::Concerns::Controller
|
|
297
|
-
end
|
|
298
|
-
end
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### Non-Resource Controllers
|
|
302
|
-
|
|
303
|
-
For portal pages not tied to a resource (dashboard, settings, etc.), inherit from `PlutoniumController`:
|
|
304
|
-
|
|
305
|
-
```ruby
|
|
306
|
-
module DashboardPortal
|
|
307
|
-
class DashboardController < PlutoniumController
|
|
308
|
-
def index
|
|
309
|
-
# Dashboard home page
|
|
310
|
-
end
|
|
311
|
-
end
|
|
312
|
-
end
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
## Portal-Specific Overrides
|
|
316
|
-
|
|
317
|
-
### Override Definition
|
|
318
|
-
|
|
319
|
-
```ruby
|
|
320
|
-
class DashboardPortal::PostDefinition < ::PostDefinition
|
|
321
|
-
scope :my_posts, -> { where(user: current_user) }
|
|
322
|
-
end
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
### Override Policy
|
|
326
|
-
|
|
327
|
-
```ruby
|
|
328
|
-
class DashboardPortal::PostPolicy < ::PostPolicy
|
|
329
|
-
include DashboardPortal::ResourcePolicy
|
|
330
|
-
|
|
331
|
-
def destroy?
|
|
332
|
-
false # No deletion in user portal
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
def permitted_attributes_for_create
|
|
336
|
-
%i[title content] # Fewer fields than admin
|
|
337
|
-
end
|
|
338
|
-
end
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
### Override Controller
|
|
342
|
-
|
|
343
|
-
```ruby
|
|
344
|
-
module DashboardPortal
|
|
345
|
-
class PostsController < ResourceController
|
|
346
|
-
private
|
|
347
|
-
|
|
348
|
-
def preferred_action_after_submit
|
|
349
|
-
"index"
|
|
350
|
-
end
|
|
351
|
-
end
|
|
352
|
-
end
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
## Multiple Portals Example
|
|
356
|
-
|
|
357
|
-
```ruby
|
|
358
|
-
# Admin portal - full access
|
|
359
|
-
module AdminPortal
|
|
360
|
-
class Engine < Rails::Engine
|
|
361
|
-
include Plutonium::Portal::Engine
|
|
362
|
-
|
|
363
|
-
config.after_initialize do
|
|
364
|
-
scope_to_entity Organization, strategy: :path
|
|
365
|
-
end
|
|
366
|
-
end
|
|
367
|
-
end
|
|
368
|
-
|
|
369
|
-
# User dashboard - limited access
|
|
370
|
-
module DashboardPortal
|
|
371
|
-
class Engine < Rails::Engine
|
|
372
|
-
include Plutonium::Portal::Engine
|
|
373
|
-
|
|
374
|
-
config.after_initialize do
|
|
375
|
-
scope_to_entity Organization, strategy: :path
|
|
376
|
-
end
|
|
377
|
-
end
|
|
378
|
-
end
|
|
379
|
-
|
|
380
|
-
# Public portal - read-only, no auth
|
|
381
|
-
module PublicPortal
|
|
382
|
-
class Engine < Rails::Engine
|
|
383
|
-
include Plutonium::Portal::Engine
|
|
384
|
-
end
|
|
385
|
-
end
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
## Typical Workflow
|
|
389
|
-
|
|
390
|
-
```bash
|
|
391
|
-
# 1. Create portal
|
|
392
|
-
rails g pu:pkg:portal admin --auth=admin --scope=Organization
|
|
393
|
-
|
|
394
|
-
# 2. Create resources
|
|
395
|
-
rails g pu:res:scaffold Post user:belongs_to title:string 'content:text?' --dest=main_app
|
|
396
|
-
rails db:migrate
|
|
397
|
-
|
|
398
|
-
# 3. Connect resources to portal
|
|
399
|
-
rails g pu:res:conn Post --dest=admin_portal
|
|
400
|
-
|
|
401
|
-
# 4. Customize portal-specific definitions/policies as needed
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
## Related Skills
|
|
405
|
-
|
|
406
|
-
- `plutonium-package` - Package overview (features vs portals)
|
|
407
|
-
- `plutonium-auth` - Authentication setup and configuration
|
|
408
|
-
- `plutonium-policy` - Portal-specific policies
|
|
409
|
-
- `plutonium-definition` - Portal-specific definitions
|
|
410
|
-
- `plutonium-controller` - Portal-specific controllers
|