plutonium 0.33.1 → 0.34.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.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/# Plutonium: The pre-alpha demo.md +4 -2
  3. data/.claude/skills/assets/SKILL.md +416 -0
  4. data/.claude/skills/connect-resource/SKILL.md +112 -0
  5. data/.claude/skills/controller/SKILL.md +302 -0
  6. data/.claude/skills/create-resource/SKILL.md +240 -0
  7. data/.claude/skills/definition/SKILL.md +218 -0
  8. data/.claude/skills/definition-actions/SKILL.md +386 -0
  9. data/.claude/skills/definition-fields/SKILL.md +474 -0
  10. data/.claude/skills/definition-query/SKILL.md +334 -0
  11. data/.claude/skills/forms/SKILL.md +439 -0
  12. data/.claude/skills/installation/SKILL.md +300 -0
  13. data/.claude/skills/interaction/SKILL.md +382 -0
  14. data/.claude/skills/model/SKILL.md +267 -0
  15. data/.claude/skills/model-features/SKILL.md +286 -0
  16. data/.claude/skills/nested-resources/SKILL.md +274 -0
  17. data/.claude/skills/package/SKILL.md +191 -0
  18. data/.claude/skills/policy/SKILL.md +352 -0
  19. data/.claude/skills/portal/SKILL.md +400 -0
  20. data/.claude/skills/resource/SKILL.md +281 -0
  21. data/.claude/skills/rodauth/SKILL.md +452 -0
  22. data/.claude/skills/views/SKILL.md +563 -0
  23. data/Appraisals +46 -4
  24. data/CHANGELOG.md +32 -1
  25. data/app/assets/plutonium.css +2 -2
  26. data/config/brakeman.ignore +239 -0
  27. data/config/initializers/action_policy.rb +1 -1
  28. data/docs/.vitepress/config.ts +132 -47
  29. data/docs/concepts/architecture.md +226 -0
  30. data/docs/concepts/auto-detection.md +254 -0
  31. data/docs/concepts/index.md +61 -0
  32. data/docs/concepts/packages-portals.md +304 -0
  33. data/docs/concepts/resources.md +224 -0
  34. data/docs/cookbook/blog.md +412 -0
  35. data/docs/cookbook/index.md +289 -0
  36. data/docs/cookbook/saas.md +481 -0
  37. data/docs/getting-started/index.md +56 -0
  38. data/docs/getting-started/installation.md +146 -0
  39. data/docs/getting-started/tutorial/01-setup.md +118 -0
  40. data/docs/getting-started/tutorial/02-first-resource.md +180 -0
  41. data/docs/getting-started/tutorial/03-authentication.md +246 -0
  42. data/docs/getting-started/tutorial/04-authorization.md +170 -0
  43. data/docs/getting-started/tutorial/05-custom-actions.md +202 -0
  44. data/docs/getting-started/tutorial/06-nested-resources.md +147 -0
  45. data/docs/getting-started/tutorial/07-customizing-ui.md +254 -0
  46. data/docs/getting-started/tutorial/index.md +64 -0
  47. data/docs/guides/adding-resources.md +420 -0
  48. data/docs/guides/authentication.md +551 -0
  49. data/docs/guides/authorization.md +468 -0
  50. data/docs/guides/creating-packages.md +380 -0
  51. data/docs/guides/custom-actions.md +523 -0
  52. data/docs/guides/index.md +45 -0
  53. data/docs/guides/multi-tenancy.md +302 -0
  54. data/docs/guides/nested-resources.md +411 -0
  55. data/docs/guides/search-filtering.md +266 -0
  56. data/docs/guides/theming.md +321 -0
  57. data/docs/index.md +67 -26
  58. data/docs/public/CLAUDE.md +64 -21
  59. data/docs/reference/assets/index.md +496 -0
  60. data/docs/reference/controller/index.md +363 -0
  61. data/docs/reference/definition/actions.md +400 -0
  62. data/docs/reference/definition/fields.md +350 -0
  63. data/docs/reference/definition/index.md +252 -0
  64. data/docs/reference/definition/query.md +342 -0
  65. data/docs/reference/generators/index.md +469 -0
  66. data/docs/reference/index.md +49 -0
  67. data/docs/reference/interaction/index.md +445 -0
  68. data/docs/reference/model/features.md +248 -0
  69. data/docs/reference/model/index.md +219 -0
  70. data/docs/reference/policy/index.md +385 -0
  71. data/docs/reference/portal/index.md +382 -0
  72. data/docs/reference/views/forms.md +396 -0
  73. data/docs/reference/views/index.md +479 -0
  74. data/gemfiles/rails_7.gemfile +9 -2
  75. data/gemfiles/rails_7.gemfile.lock +146 -111
  76. data/gemfiles/rails_8.0.gemfile +20 -0
  77. data/gemfiles/rails_8.0.gemfile.lock +417 -0
  78. data/gemfiles/rails_8.1.gemfile +20 -0
  79. data/gemfiles/rails_8.1.gemfile.lock +419 -0
  80. data/lib/generators/pu/gem/dotenv/templates/.env +2 -0
  81. data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +3 -1
  82. data/lib/generators/pu/lib/plutonium_generators/model_generator_base.rb +13 -16
  83. data/lib/generators/pu/pkg/portal/USAGE +65 -0
  84. data/lib/generators/pu/pkg/portal/portal_generator.rb +22 -9
  85. data/lib/generators/pu/res/conn/USAGE +71 -0
  86. data/lib/generators/pu/res/model/USAGE +106 -110
  87. data/lib/generators/pu/res/model/templates/model.rb.tt +6 -2
  88. data/lib/generators/pu/res/scaffold/USAGE +85 -0
  89. data/lib/generators/pu/rodauth/install_generator.rb +2 -6
  90. data/lib/generators/pu/rodauth/templates/config/initializers/url_options.rb +17 -0
  91. data/lib/generators/pu/skills/sync/USAGE +14 -0
  92. data/lib/generators/pu/skills/sync/sync_generator.rb +66 -0
  93. data/lib/plutonium/action_policy/sti_policy_lookup.rb +1 -1
  94. data/lib/plutonium/core/controller.rb +2 -2
  95. data/lib/plutonium/interaction/base.rb +1 -0
  96. data/lib/plutonium/package/engine.rb +2 -2
  97. data/lib/plutonium/query/adhoc_block.rb +6 -2
  98. data/lib/plutonium/query/model_scope.rb +1 -1
  99. data/lib/plutonium/railtie.rb +4 -0
  100. data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +1 -1
  101. data/lib/plutonium/resource/query_object.rb +38 -8
  102. data/lib/plutonium/ui/table/components/scopes_bar.rb +39 -34
  103. data/lib/plutonium/version.rb +1 -1
  104. data/lib/tasks/release.rake +19 -4
  105. data/package.json +1 -1
  106. metadata +76 -39
  107. data/brakeman.ignore +0 -28
  108. data/docs/api-examples.md +0 -49
  109. data/docs/guide/claude-code-guide.md +0 -74
  110. data/docs/guide/deep-dive/authorization.md +0 -189
  111. data/docs/guide/deep-dive/multitenancy.md +0 -256
  112. data/docs/guide/deep-dive/resources.md +0 -390
  113. data/docs/guide/getting-started/01-installation.md +0 -165
  114. data/docs/guide/index.md +0 -28
  115. data/docs/guide/introduction/01-what-is-plutonium.md +0 -211
  116. data/docs/guide/introduction/02-core-concepts.md +0 -440
  117. data/docs/guide/tutorial/01-project-setup.md +0 -75
  118. data/docs/guide/tutorial/02-creating-a-feature-package.md +0 -45
  119. data/docs/guide/tutorial/03-defining-resources.md +0 -90
  120. data/docs/guide/tutorial/04-creating-a-portal.md +0 -101
  121. data/docs/guide/tutorial/05-customizing-the-ui.md +0 -128
  122. data/docs/guide/tutorial/06-adding-custom-actions.md +0 -101
  123. data/docs/guide/tutorial/07-implementing-authorization.md +0 -90
  124. data/docs/markdown-examples.md +0 -85
  125. data/docs/modules/action.md +0 -244
  126. data/docs/modules/authentication.md +0 -236
  127. data/docs/modules/configuration.md +0 -599
  128. data/docs/modules/controller.md +0 -443
  129. data/docs/modules/core.md +0 -316
  130. data/docs/modules/definition.md +0 -1308
  131. data/docs/modules/display.md +0 -759
  132. data/docs/modules/form.md +0 -495
  133. data/docs/modules/generator.md +0 -400
  134. data/docs/modules/index.md +0 -167
  135. data/docs/modules/interaction.md +0 -642
  136. data/docs/modules/package.md +0 -151
  137. data/docs/modules/policy.md +0 -176
  138. data/docs/modules/portal.md +0 -710
  139. data/docs/modules/query.md +0 -297
  140. data/docs/modules/resource_record.md +0 -618
  141. data/docs/modules/routing.md +0 -690
  142. data/docs/modules/table.md +0 -301
  143. data/docs/modules/ui.md +0 -631
@@ -1,151 +0,0 @@
1
- ---
2
- title: Package Module
3
- ---
4
-
5
- # Package Module
6
-
7
- The Package module provides the foundation for modular application organization in Plutonium. It enables Rails engines to work within the Plutonium ecosystem by providing specialized engine configuration and view path management.
8
-
9
- ::: tip
10
- The core of the Package module is `Plutonium::Package::Engine`, which should be included in your package's `engine.rb` file.
11
- :::
12
-
13
- ## Overview
14
-
15
- - **Engine Foundation**: Provides base functionality for all Plutonium packages (which are Rails Engines).
16
- - **View Path Control**: Manages view lookups for proper isolation between packages.
17
- - **Migration Management**: Automatically includes package migrations in the application's migration path.
18
-
19
- ## Usage
20
-
21
- The primary way to use the Package module is by including `Plutonium::Package::Engine` in your package's engine file. This is handled automatically by the generators.
22
-
23
- ::: code-group
24
- ```bash [Generate a Feature Package]
25
- rails generate pu:pkg:package blogging
26
- ```
27
- ```ruby [packages/blogging/lib/engine.rb]
28
- module Blogging
29
- class Engine < Rails::Engine
30
- # This inclusion provides the core package functionality.
31
- include Plutonium::Package::Engine
32
- end
33
- end
34
- ```
35
- :::
36
-
37
- ::: code-group
38
- ```bash [Generate a Portal Package]
39
- rails generate pu:pkg:portal admin
40
- ```
41
- ```ruby [packages/admin_portal/lib/engine.rb]
42
- module AdminPortal
43
- class Engine < Rails::Engine
44
- # Portal::Engine includes Package::Engine, so you get both.
45
- include Plutonium::Portal::Engine
46
- end
47
- end
48
- ```
49
- :::
50
-
51
- ## Key Features
52
-
53
- ### View Path Management
54
-
55
- The Package module intentionally prevents Rails from automatically adding a package's view paths to the global lookup. Instead, view resolution is handled at the controller level by Plutonium's `Bootable` concern. This provides finer-grained control and ensures that packages remain isolated.
56
-
57
- ### Migration Integration
58
-
59
- Package migrations are automatically detected and added to the application's main `db/migrate` path. This allows you to run `rails db:migrate` from your application root, and it will correctly process migrations from all your packages.
60
-
61
- ::: details Package Engine Implementation
62
- The `Plutonium::Package::Engine` concern handles this automatically.
63
- ```ruby
64
- # lib/plutonium/package/engine.rb
65
- module Plutonium
66
- module Package
67
- module Engine
68
- extend ActiveSupport::Concern
69
-
70
- included do
71
- # This block hijacks the default Rails view path initializer
72
- # and replaces it with an empty one, giving Plutonium control.
73
- config.before_configuration do
74
- # ... logic to find and disable the default `add_view_paths` initializer
75
- end
76
-
77
- # This initializer appends the package's migrations to the host app.
78
- initializer :append_migrations do |app|
79
- unless app.root.to_s.match root.to_s
80
- config.paths["db/migrate"].expanded.each do |expanded_path|
81
- app.config.paths["db/migrate"] << expanded_path
82
- end
83
- end
84
- end
85
- end
86
- end
87
- end
88
- end
89
- ```
90
- :::
91
-
92
- ## Package Loading
93
-
94
- Packages are loaded automatically via `config/packages.rb`, which is created by the `pu:core:install` generator. This file simply finds and loads all `engine.rb` files within your `packages/` directory.
95
-
96
- ```ruby
97
- # config/packages.rb
98
- # This file is required in `config/application.rb`
99
-
100
- Dir.glob(File.expand_path("../packages/**/lib/engine.rb", __dir__)) do |package|
101
- load package
102
- end
103
- ```
104
-
105
- ::: tip
106
- You can package and ship your packages as gems.
107
- :::
108
-
109
- ## Generator Integration
110
-
111
- ### Package Generator
112
-
113
- ```bash
114
- # Create a feature package
115
- rails generate pu:pkg:package blogging
116
- ```
117
-
118
- Generates the basic structure with `Plutonium::Package::Engine` included.
119
-
120
- ### Portal Generator
121
-
122
- ```bash
123
- # Create a portal package
124
- rails generate pu:pkg:portal admin
125
- ```
126
-
127
- Generates a portal structure with `Plutonium::Portal::Engine` (which includes Package::Engine).
128
-
129
- ## Package Types
130
-
131
- The package system supports two main types:
132
-
133
- 1. **Feature Packages**: Business logic packages that include `Plutonium::Package::Engine`
134
- 2. **Portal Packages**: User interface packages that include `Plutonium::Portal::Engine`
135
-
136
- Both types benefit from the foundational features provided by the Package module.
137
-
138
- ## Best Practices
139
-
140
- 1. **Use Generators**: Always use `pu:pkg:package` or `pu:pkg:portal` generators
141
- 2. **Namespace Consistency**: Keep package names consistent with their directory structure
142
- 3. **Migration Organization**: Place package-specific migrations in the package's `db/migrate` directory
143
- 4. **Engine Simplicity**: Keep engine.rb files minimal - they're just configuration points
144
-
145
- ## Integration with Other Modules
146
-
147
- The Package module works closely with:
148
- - **Portal Module**: Provides the foundation for portal functionality
149
- - **Generator Module**: Scaffolds package structure
150
- - **Core Module**: Integrates with controller bootable system
151
- - **Routing Module**: Supports resource registration within packages
@@ -1,176 +0,0 @@
1
- ---
2
- title: Policy Module
3
- ---
4
-
5
- # Policy Module
6
-
7
- The Policy module provides comprehensive authorization and access control for Plutonium applications. Built on top of [ActionPolicy](https://actionpolicy.evilmartians.io/), it offers fine-grained permissions, resource scoping, and entity-based authorization with a secure-by-default approach.
8
-
9
- ::: tip
10
- The base policy class is `Plutonium::Resource::Policy`. Resource policies are typically located in `app/policies/`.
11
- :::
12
-
13
- ## Overview
14
-
15
- - **Resource-Level Authorization**: Control access to CRUD operations and custom actions.
16
- - **Attribute-Level Permissions**: Fine-grained control over which fields a user can see or edit.
17
- - **Association Control**: Manage access to related resources.
18
- - **Entity Scoping**: Built-in support for multi-tenant authorization.
19
- - **Secure Defaults**: Policies default to denying access, requiring explicit permission.
20
-
21
- ## Basic Policy Structure
22
-
23
- Resource policies inherit from `Plutonium::Resource::Policy` and define methods to control access.
24
-
25
- ::: code-group
26
- ```ruby [app/policies/post_policy.rb]
27
- class PostPolicy < Plutonium::Resource::Policy
28
- # Who can see a list of posts?
29
- def index?
30
- true # Everyone can see the list
31
- end
32
-
33
- # Who can see a single post?
34
- def show?
35
- record.published? || user == record.author || user.admin?
36
- end
37
-
38
- # Who can create a post?
39
- def create?
40
- user.present? # Any signed-in user
41
- end
42
-
43
- # Who can update a post?
44
- def update?
45
- user == record.author || user.admin?
46
- end
47
-
48
- # Who can destroy a post?
49
- def destroy?
50
- user.admin? # Only admins
51
- end
52
-
53
- # Who can run the custom 'publish' action?
54
- def publish?
55
- update? && record.draft? # Can only publish if you can update
56
- end
57
- end
58
- ```
59
- ```ruby [Authorization Context]
60
- # Policies automatically receive context from the controller.
61
- class Plutonium::Resource::Policy < ActionPolicy::Base
62
- # `user` is the current authenticated user. It is required.
63
- authorize :user, allow_nil: false
64
-
65
- # `entity_scope` is the current portal's scoping entity (e.g., Organization).
66
- # It is optional.
67
- authorize :entity_scope, allow_nil: true
68
- end
69
- ```
70
- :::
71
-
72
- ::: danger Secure by Default
73
- If a permission method (like `create?` or `publish?`) is not defined in your policy, it will default to `false`. You must explicitly grant permissions.
74
- :::
75
-
76
- ## Attribute Permissions
77
-
78
- You can control which attributes (fields) are visible or editable based on the action and user.
79
-
80
- ::: code-group
81
- ```ruby [Read Permissions]
82
- class PostPolicy < Plutonium::Resource::Policy
83
- # Defines which attributes are visible on `show` and `index` pages.
84
- def permitted_attributes_for_read
85
- # Start with a base set of attributes
86
- attrs = [:title, :content, :category, :published_at]
87
- # Add admin-only attributes conditionally
88
- attrs << :internal_notes if user.admin?
89
- attrs
90
- end
91
- end
92
- ```
93
- ```ruby [Create/Update Permissions]
94
- class PostPolicy < Plutonium::Resource::Policy
95
- # Defines which attributes can be submitted in `new` and `edit` forms.
96
- def permitted_attributes_for_create
97
- [:title, :content, :category]
98
- end
99
-
100
- def permitted_attributes_for_update
101
- # Inherits from create by default, but can be customized.
102
- attrs = permitted_attributes_for_create
103
- attrs << :slug if user.admin? # Only admins can edit the slug
104
- attrs
105
- end
106
- end
107
- ```
108
- :::
109
-
110
- ::: details Full Permission Hierarchy
111
- Plutonium uses a hierarchical permission system. Defining a core action permission (like `read?` or `create?`) automatically grants permission for related actions unless you override them.
112
-
113
- **Action Permissions:**
114
- - `index?` and `show?` inherit from `read?`
115
- - `new?` inherits from `create?`
116
- - `edit?` inherits from `update?`
117
- - `update?` and `destroy?` inherit from `create?` by default.
118
-
119
- **Attribute Permissions:**
120
- - `_for_show` and `_for_index` inherit from `_for_read`.
121
- - `_for_new` inherits from `_for_create`.
122
- - `_for_edit` inherits from `_for_update`.
123
- :::
124
-
125
- ## Scoping Collections
126
-
127
- Use `relation_scope` to filter which records appear in a collection (e.g., on the `index` page).
128
-
129
- ::: code-group
130
- ```ruby [Simple Scope]
131
- class PostPolicy < Plutonium::Resource::Policy
132
- relation_scope do |relation|
133
- # make sure to call super unless you want to bypass the default behavior
134
- # plutonium offers
135
- relation = super(relation)
136
-
137
- if user.admin?
138
- relation # Admins see all posts
139
- else
140
- # Other users only see their own posts or published posts
141
- relation.where(author: user).or(relation.where(published: true))
142
- end
143
- end
144
- end
145
- ```
146
- ```ruby [Multi-Tenant Scope]
147
- class PostPolicy < Plutonium::Resource::Policy
148
- relation_scope do |relation|
149
- # `super` applies the portal's entity scoping first.
150
- # e.g., `relation.associated_with(current_organization)`
151
- relation = super(relation)
152
-
153
- # Then, apply additional logic.
154
- if user.admin?
155
- relation
156
- else
157
- relation.where(published: true)
158
- end
159
- end
160
- end
161
- ```
162
- :::
163
-
164
- ## Association Permissions
165
-
166
- Control which associated resources can be accessed or rendered.
167
-
168
- ```ruby
169
- class PostPolicy < Plutonium::Resource::Policy
170
- # This determines which associations can be rendered in the UI,
171
- # especially for nested forms or displays.
172
- def permitted_associations
173
- [:comments, :author, :tags]
174
- end
175
- end
176
- ```