plutonium 0.45.2 → 0.46.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 +146 -0
- data/.claude/skills/plutonium-assets/SKILL.md +248 -157
- data/.claude/skills/{plutonium-rodauth → plutonium-auth}/SKILL.md +195 -229
- data/.claude/skills/plutonium-controller/SKILL.md +9 -2
- data/.claude/skills/plutonium-create-resource/SKILL.md +22 -1
- data/.claude/skills/plutonium-definition/SKILL.md +521 -7
- data/.claude/skills/plutonium-entity-scoping/SKILL.md +317 -0
- data/.claude/skills/plutonium-forms/SKILL.md +8 -1
- data/.claude/skills/plutonium-installation/SKILL.md +25 -2
- data/.claude/skills/plutonium-interaction/SKILL.md +9 -2
- data/.claude/skills/plutonium-invites/SKILL.md +11 -7
- data/.claude/skills/plutonium-model/SKILL.md +50 -50
- data/.claude/skills/plutonium-nested-resources/SKILL.md +8 -1
- data/.claude/skills/plutonium-package/SKILL.md +8 -1
- data/.claude/skills/plutonium-policy/SKILL.md +69 -78
- data/.claude/skills/plutonium-portal/SKILL.md +26 -70
- data/.claude/skills/plutonium-views/SKILL.md +9 -2
- data/CHANGELOG.md +33 -0
- data/app/assets/plutonium.css +1 -1
- data/app/views/rodauth/_login_form.html.erb +0 -3
- data/app/views/rodauth/confirm_password.html.erb +0 -4
- data/app/views/rodauth/create_account.html.erb +0 -3
- data/app/views/rodauth/logout.html.erb +0 -3
- data/config/initializers/pagy.rb +1 -1
- data/docs/superpowers/plans/2026-04-08-plutonium-skills-overhaul.md +481 -0
- data/docs/superpowers/specs/2026-04-08-plutonium-skills-overhaul-design.md +236 -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 +8 -0
- data/lib/generators/pu/gem/active_shrine/active_shrine_generator.rb +56 -0
- data/lib/generators/pu/invites/install_generator.rb +8 -1
- data/lib/generators/pu/lib/plutonium_generators/concerns/actions.rb +43 -0
- data/lib/generators/pu/profile/concerns/profile_arguments.rb +10 -4
- data/lib/generators/pu/profile/conn_generator.rb +9 -12
- data/lib/generators/pu/profile/install_generator.rb +5 -2
- data/lib/generators/pu/rodauth/templates/app/rodauth/account_rodauth_plugin.rb.tt +3 -0
- data/lib/generators/pu/saas/portal_generator.rb +4 -9
- data/lib/generators/pu/saas/welcome/templates/app/views/welcome/onboarding.html.erb.tt +2 -2
- data/lib/plutonium/engine.rb +18 -5
- data/lib/plutonium/ui/layout/rodauth_layout.rb +6 -1
- data/lib/plutonium/version.rb +1 -1
- data/package.json +1 -1
- metadata +7 -8
- data/.claude/skills/plutonium/skill.md +0 -130
- data/.claude/skills/plutonium-definition-actions/SKILL.md +0 -424
- data/.claude/skills/plutonium-definition-query/SKILL.md +0 -364
- data/.claude/skills/plutonium-profile/SKILL.md +0 -276
- data/.claude/skills/plutonium-theming/SKILL.md +0 -424
|
@@ -1,10 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plutonium-policy
|
|
3
|
-
description: Use
|
|
3
|
+
description: Use BEFORE writing relation_scope, permitted_attributes, permitted_associations, or any policy override. For tenant-scoped relation_scope, also load plutonium-entity-scoping.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Plutonium Policies
|
|
7
7
|
|
|
8
|
+
## 🚨 Critical (read first)
|
|
9
|
+
- **Use generators.** `pu:res:scaffold` and `pu:res:conn` create policies — never hand-write policy files.
|
|
10
|
+
- **Never bypass `default_relation_scope`.** Overriding `relation_scope` with a raw `where(organization: …)` or manual joins skips entity scoping and triggers `verify_default_relation_scope_applied!` at runtime. Compose like this: `relation_scope { |r| default_relation_scope(r).where(archived: false) }`. Call `default_relation_scope(r)` **explicitly** — `super` is unreliable inside the DSL block. Full rules in `plutonium-entity-scoping`.
|
|
11
|
+
- **Derived actions inherit.** `update?` falls back to `create?`, `show?` falls back to `read?` — don't duplicate unless the rules genuinely differ. Override `create?` and `read?` explicitly; they default to `false`.
|
|
12
|
+
- **Define `permitted_attributes_for_*` explicitly.** Auto-detection works in development but raises in production.
|
|
13
|
+
- **For `has_cents` fields, list the virtual name (`:price`), not the column (`:price_cents`).** Generators occasionally emit the wrong one — fix it (and verify the model has `has_cents`). See `plutonium-model` › Monetary Handling.
|
|
14
|
+
- **Related skills:** `plutonium-entity-scoping` (tenant-scoped overrides — required for `relation_scope`), `plutonium-model` (`associated_with`), `plutonium-definition` (`permitted_attributes` usage), `plutonium-controller` (how controllers use policies).
|
|
15
|
+
|
|
16
|
+
## Quick checklist
|
|
17
|
+
|
|
18
|
+
Writing / editing a policy:
|
|
19
|
+
|
|
20
|
+
1. Confirm the policy was created by `pu:res:scaffold` or `pu:res:conn`.
|
|
21
|
+
2. Override `create?` and `read?` explicitly — they default to `false`.
|
|
22
|
+
3. Define `permitted_attributes_for_read` and `permitted_attributes_for_create` (derived methods inherit).
|
|
23
|
+
4. For custom actions, add `def <action>?` matching the definition's `action :<action>`.
|
|
24
|
+
5. If you need `relation_scope`, compose with `default_relation_scope(relation).where(...)` — never bypass it.
|
|
25
|
+
6. For tenant scoping, load `plutonium-entity-scoping` and fix the **model**, not the policy.
|
|
26
|
+
7. Per-portal overrides go in the portal's policy file (created by `pu:res:conn`).
|
|
27
|
+
8. Test: log in as a user who should NOT see a record, verify it's filtered out.
|
|
28
|
+
|
|
8
29
|
**Policies are generated automatically** - never create them manually:
|
|
9
30
|
- `rails g pu:res:scaffold` creates the base policy
|
|
10
31
|
- `rails g pu:res:conn` creates portal-specific policies with attribute permissions
|
|
@@ -153,119 +174,89 @@ def permitted_attributes_for_read
|
|
|
153
174
|
end
|
|
154
175
|
```
|
|
155
176
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
In development, undefined attribute methods auto-detect from the model. This raises errors in production - always define explicitly.
|
|
177
|
+
**Key insight:** `permitted_attributes_for_*` controls *which fields appear* on each view (form, show, index). The `column`/`field`/`input`/`display` declarations in the **definition** only control *how those fields render* — they do NOT add or remove fields from the page. If your index page is showing fields you didn't want, override `permitted_attributes_for_index` (it does NOT inherit from `_for_read` automatically when you want a different shape). The same applies to forms: a `field :name` in the definition won't be rendered unless `:name` is in `permitted_attributes_for_create`/`_update`.
|
|
159
178
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
Control which associations can be rendered:
|
|
179
|
+
### Anti-pattern: nested_attributes hashes in permitted_attributes
|
|
163
180
|
|
|
164
181
|
```ruby
|
|
165
|
-
|
|
166
|
-
|
|
182
|
+
# ❌ DO NOT DO THIS
|
|
183
|
+
def permitted_attributes_for_create
|
|
184
|
+
[
|
|
185
|
+
:name,
|
|
186
|
+
{variants_attributes: [:id, :name, :_destroy]},
|
|
187
|
+
{comments_attributes: [:id, :body, :_destroy]}
|
|
188
|
+
]
|
|
167
189
|
end
|
|
168
190
|
```
|
|
169
191
|
|
|
170
|
-
|
|
171
|
-
- Nested forms
|
|
172
|
-
- Related data displays
|
|
173
|
-
- Association fields in tables
|
|
174
|
-
|
|
175
|
-
## Collection Scoping
|
|
192
|
+
Plutonium's form pipeline extracts nested params via the **form definition** (`build_form(...).extract_input(...)`), not the policy. Hash entries in `permitted_attributes_for_*` get iterated as field names by the form renderer and end up as literal text inputs with names like `model[{:variants_attributes=>[...]}]`.
|
|
176
193
|
|
|
177
|
-
|
|
194
|
+
The correct pattern:
|
|
178
195
|
|
|
179
196
|
```ruby
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
else
|
|
184
|
-
relation.where(author: user)
|
|
185
|
-
end
|
|
197
|
+
# ✅ Policy permits just the association name
|
|
198
|
+
def permitted_attributes_for_create
|
|
199
|
+
[:name, :variants, :comments]
|
|
186
200
|
end
|
|
187
201
|
```
|
|
188
202
|
|
|
189
|
-
### With Parent Scoping (Nested Resources)
|
|
190
|
-
|
|
191
|
-
For nested resources, call `super` to apply automatic parent scoping:
|
|
192
|
-
|
|
193
203
|
```ruby
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
else
|
|
200
|
-
relation.where(published: true)
|
|
204
|
+
# ✅ Definition declares the nested input (this drives both rendering AND param extraction)
|
|
205
|
+
class PostDefinition < ResourceDefinition
|
|
206
|
+
nested_input :variants do |n|
|
|
207
|
+
n.input :name
|
|
208
|
+
n.input :is_default, as: :boolean
|
|
201
209
|
end
|
|
202
210
|
end
|
|
203
211
|
```
|
|
204
212
|
|
|
205
|
-
**Parent scoping takes precedence over entity scoping.** When a parent is present:
|
|
206
|
-
- For `has_many`: scopes via `parent.association_name`
|
|
207
|
-
- For `has_one`: scopes via `where(foreign_key: parent.id)`
|
|
208
|
-
|
|
209
|
-
### With Entity Scoping (Multi-tenancy)
|
|
210
|
-
|
|
211
|
-
When no parent is present, `super` applies entity scoping:
|
|
212
|
-
|
|
213
213
|
```ruby
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
# ✅ Model declares accepts_nested_attributes_for + inverse_of on the back-reference
|
|
215
|
+
class Post < ApplicationRecord
|
|
216
|
+
has_many :variants, inverse_of: :post, dependent: :destroy
|
|
217
|
+
accepts_nested_attributes_for :variants, allow_destroy: true, reject_if: :all_blank
|
|
218
|
+
end
|
|
216
219
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
else
|
|
220
|
-
relation.where(published: true)
|
|
221
|
-
end
|
|
220
|
+
class Variant < ApplicationRecord
|
|
221
|
+
belongs_to :post, inverse_of: :variants # ← required for nested validation
|
|
222
222
|
end
|
|
223
223
|
```
|
|
224
224
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
Plutonium verifies that `default_relation_scope` is called in every `relation_scope`. This prevents accidental multi-tenancy leaks when overriding scopes.
|
|
225
|
+
See `plutonium-definition` for the full `nested_input` API.
|
|
228
226
|
|
|
229
|
-
|
|
230
|
-
# ❌ This will raise an error
|
|
231
|
-
relation_scope do |relation|
|
|
232
|
-
relation.where(published: true) # Missing default_relation_scope!
|
|
233
|
-
end
|
|
227
|
+
### Auto-Detection (Development Only)
|
|
234
228
|
|
|
235
|
-
|
|
236
|
-
relation_scope do |relation|
|
|
237
|
-
default_relation_scope(relation).where(published: true)
|
|
238
|
-
end
|
|
229
|
+
In development, undefined attribute methods auto-detect from the model. This raises errors in production - always define explicitly.
|
|
239
230
|
|
|
240
|
-
|
|
241
|
-
relation_scope do |relation|
|
|
242
|
-
super(relation).where(published: true)
|
|
243
|
-
end
|
|
244
|
-
```
|
|
231
|
+
## Association Permissions
|
|
245
232
|
|
|
246
|
-
|
|
233
|
+
Control which associations can be rendered:
|
|
247
234
|
|
|
248
235
|
```ruby
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
# Replace inherited scope but keep Plutonium's parent/entity scoping
|
|
252
|
-
default_relation_scope(relation)
|
|
253
|
-
end
|
|
236
|
+
def permitted_associations
|
|
237
|
+
%i[comments tags author]
|
|
254
238
|
end
|
|
255
239
|
```
|
|
256
240
|
|
|
257
|
-
|
|
241
|
+
Used for:
|
|
242
|
+
- Nested forms
|
|
243
|
+
- Related data displays
|
|
244
|
+
- Association fields in tables
|
|
258
245
|
|
|
259
|
-
|
|
246
|
+
## Collection Scoping (relation_scope)
|
|
247
|
+
|
|
248
|
+
Filter which records users can see:
|
|
260
249
|
|
|
261
250
|
```ruby
|
|
262
251
|
relation_scope do |relation|
|
|
263
|
-
|
|
264
|
-
relation
|
|
252
|
+
relation = default_relation_scope(relation)
|
|
253
|
+
user.admin? ? relation : relation.where(author: user)
|
|
265
254
|
end
|
|
266
255
|
```
|
|
267
256
|
|
|
268
|
-
|
|
257
|
+
**Always compose with `default_relation_scope(relation)` explicitly** — not `super`. Plutonium enforces this via `verify_default_relation_scope_applied!`. Anything else (a raw `where(organization: ...)`, manual joins) bypasses Plutonium's tenancy handling and will raise.
|
|
258
|
+
|
|
259
|
+
> **For the full rules — why `default_relation_scope` is required, how parent vs entity scoping interact, safe override patterns, `skip_default_relation_scope!`, and how `associated_with` resolution works — see the [plutonium-entity-scoping](../plutonium-entity-scoping/SKILL.md) skill. It is the single source of truth for Plutonium tenant scoping.**
|
|
269
260
|
|
|
270
261
|
## Portal-Specific Policies
|
|
271
262
|
|
|
@@ -453,7 +444,7 @@ end
|
|
|
453
444
|
|
|
454
445
|
1. **Always override `create?` and `read?`** - They default to `false`
|
|
455
446
|
2. **Define attributes explicitly** - Auto-detection only works in development
|
|
456
|
-
3. **Call `
|
|
447
|
+
3. **Call `default_relation_scope(relation)` in `relation_scope`** - Preserves parent/entity scoping (do not rely on `super` from inside the block)
|
|
457
448
|
4. **Use derived methods** - Let `update?` inherit from `create?` when appropriate
|
|
458
449
|
5. **Keep policies focused** - Authorization logic only, no business logic
|
|
459
450
|
6. **Test edge cases** - Archived records, nil associations, role combinations
|
|
@@ -461,5 +452,5 @@ end
|
|
|
461
452
|
## Related Skills
|
|
462
453
|
|
|
463
454
|
- `plutonium` - How policies fit in the resource architecture
|
|
464
|
-
- `plutonium-definition
|
|
455
|
+
- `plutonium-definition` - Actions that need policy methods
|
|
465
456
|
- `plutonium-controller` - How controllers use policies
|
|
@@ -1,12 +1,32 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plutonium-portal
|
|
3
|
-
description: Use
|
|
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
4
|
---
|
|
5
5
|
|
|
6
6
|
# Plutonium Portals
|
|
7
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
|
+
|
|
8
15
|
Portals are Rails engines that provide web interfaces for specific user types.
|
|
9
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
|
+
|
|
10
30
|
## Creating a Portal
|
|
11
31
|
|
|
12
32
|
```bash
|
|
@@ -181,11 +201,7 @@ end
|
|
|
181
201
|
|
|
182
202
|
## Entity Scoping (Multi-tenancy)
|
|
183
203
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
### Path Strategy
|
|
187
|
-
|
|
188
|
-
Entity ID in URL path:
|
|
204
|
+
Portals can scope all data to a parent entity via `scope_to_entity`:
|
|
189
205
|
|
|
190
206
|
```ruby
|
|
191
207
|
module AdminPortal
|
|
@@ -199,71 +215,11 @@ module AdminPortal
|
|
|
199
215
|
end
|
|
200
216
|
```
|
|
201
217
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
### Custom Strategy
|
|
205
|
-
|
|
206
|
-
Implement your own lookup method:
|
|
207
|
-
|
|
208
|
-
```ruby
|
|
209
|
-
module AdminPortal
|
|
210
|
-
class Engine < Rails::Engine
|
|
211
|
-
include Plutonium::Portal::Engine
|
|
218
|
+
Strategies: `:path` (entity id in URL) or a custom method name on the portal controller concern.
|
|
212
219
|
|
|
213
|
-
|
|
214
|
-
scope_to_entity Organization, strategy: :current_organization
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
end
|
|
220
|
+
Access in controllers/views: `current_scoped_entity`, `scoped_to_entity?`. In policies: `entity_scope`.
|
|
218
221
|
|
|
219
|
-
|
|
220
|
-
module AdminPortal
|
|
221
|
-
module Concerns
|
|
222
|
-
module Controller
|
|
223
|
-
extend ActiveSupport::Concern
|
|
224
|
-
include Plutonium::Portal::Controller
|
|
225
|
-
|
|
226
|
-
private
|
|
227
|
-
|
|
228
|
-
# Method name must match strategy
|
|
229
|
-
def current_organization
|
|
230
|
-
@current_organization ||= Organization.find_by!(subdomain: request.subdomain)
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### Accessing the Scoped Entity
|
|
238
|
-
|
|
239
|
-
```ruby
|
|
240
|
-
current_scoped_entity # The current Organization/Account/etc.
|
|
241
|
-
scoped_to_entity? # true if scoping is active
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### Model Requirements
|
|
245
|
-
|
|
246
|
-
Models must have an association path to the scoped entity:
|
|
247
|
-
|
|
248
|
-
```ruby
|
|
249
|
-
# Direct association (preferred)
|
|
250
|
-
class Post < ResourceRecord
|
|
251
|
-
belongs_to :organization
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
# Through association
|
|
255
|
-
class Comment < ResourceRecord
|
|
256
|
-
belongs_to :post
|
|
257
|
-
has_one :organization, through: :post
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
# Complex (define custom scope)
|
|
261
|
-
class AuditLog < ResourceRecord
|
|
262
|
-
scope :associated_with_organization, ->(org) {
|
|
263
|
-
joins(:user).where(users: { organization_id: org.id })
|
|
264
|
-
}
|
|
265
|
-
end
|
|
266
|
-
```
|
|
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.**
|
|
267
223
|
|
|
268
224
|
## Routes
|
|
269
225
|
|
|
@@ -448,7 +404,7 @@ rails g pu:res:conn Post --dest=admin_portal
|
|
|
448
404
|
## Related Skills
|
|
449
405
|
|
|
450
406
|
- `plutonium-package` - Package overview (features vs portals)
|
|
451
|
-
- `plutonium-
|
|
407
|
+
- `plutonium-auth` - Authentication setup and configuration
|
|
452
408
|
- `plutonium-policy` - Portal-specific policies
|
|
453
409
|
- `plutonium-definition` - Portal-specific definitions
|
|
454
410
|
- `plutonium-controller` - Portal-specific controllers
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plutonium-views
|
|
3
|
-
description: Use
|
|
3
|
+
description: Use BEFORE building a custom page, panel, table, layout, or Phlex component in Plutonium. Also when overriding IndexPage/ShowPage/Form classes in a definition.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Plutonium Views
|
|
7
7
|
|
|
8
|
+
## 🚨 Critical (read first)
|
|
9
|
+
- **Override via nested classes in the definition.** `class ShowPage < ShowPage; end`, `class Form < Form; end` — don't replace the entire view layer.
|
|
10
|
+
- **Use the render hooks.** `render_before_content`, `render_after_content`, `render_before_toolbar`, etc. — they exist so you don't have to override `view_template` and re-implement everything.
|
|
11
|
+
- **All pages inherit `DynaFrameContent`** so turbo-frame requests render only the content. Don't fight it — modals and frame nav "just work".
|
|
12
|
+
- **For custom components, use `Plutonium::UI::Component::Base`** so you inherit the component kit (`PageHeader`, `Panel`, `Block`, etc.) and access to resource helpers.
|
|
13
|
+
- **Related skills:** `plutonium-forms` (form customization), `plutonium-assets` (theming + component classes), `plutonium-definition` (field-level rendering), `plutonium-controller` (presentation hooks like `present_parent?`).
|
|
14
|
+
|
|
8
15
|
Plutonium uses [Phlex](https://www.phlex.fun/) for all view components. This provides a Ruby-first approach to building HTML with full IDE support and type safety.
|
|
9
16
|
|
|
10
17
|
## Architecture Overview
|
|
@@ -580,6 +587,6 @@ end
|
|
|
580
587
|
- `plutonium-forms` - Custom form templates and field builders
|
|
581
588
|
- `plutonium-assets` - TailwindCSS and component theming
|
|
582
589
|
- `plutonium-definition` - Field/input/display configuration
|
|
583
|
-
- `plutonium-definition
|
|
590
|
+
- `plutonium-definition` - Action buttons and interactions
|
|
584
591
|
- `plutonium-controller` - Presentation hooks (`present_parent?`, etc.)
|
|
585
592
|
- `plutonium-portal` - Portal-specific customization
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
## [0.46.0] - 2026-04-11
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- *(profile)* Default profile model to {UserModel}Profile
|
|
6
|
+
- *(generators)* Sync skills during pu:core:update if plutonium skill is installed
|
|
7
|
+
- *(generators/active_shrine)* Disable Active Storage railtie and include ActiveShrine::Model
|
|
8
|
+
|
|
9
|
+
### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- *(engine)* Resolve scoped entity class lazily to survive autoreload
|
|
12
|
+
- *(rodauth)* Render page title in layout, drop per-view h1s
|
|
13
|
+
- *(generators/invites)* Use derived user association in current_membership
|
|
14
|
+
- *(generators/rodauth)* Redirect to login after verification email sent
|
|
15
|
+
|
|
16
|
+
### 🚜 Refactor
|
|
17
|
+
|
|
18
|
+
- *(generators)* Add inject_into_concerns_controller to merge included blocks
|
|
19
|
+
|
|
20
|
+
### 📚 Documentation
|
|
21
|
+
|
|
22
|
+
- *(skills)* Clarify generator gotchas for installation, rodauth, and unattended runs
|
|
23
|
+
- *(skills)* Comprehensive Plutonium skills overhaul
|
|
24
|
+
- *(skills)* Document nested_attributes gotchas in policy and definition
|
|
25
|
+
|
|
26
|
+
### ⚙️ Miscellaneous Tasks
|
|
27
|
+
|
|
28
|
+
- Update test lockfiles
|
|
29
|
+
## [0.45.3] - 2026-04-07
|
|
30
|
+
|
|
31
|
+
### 🐛 Bug Fixes
|
|
32
|
+
|
|
33
|
+
- *(pagy)* Use Pagy::OPTIONS instead of frozen DEFAULT
|
|
1
34
|
## [0.45.2] - 2026-04-07
|
|
2
35
|
|
|
3
36
|
### 🐛 Bug Fixes
|