cccux 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.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +67 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +382 -0
  5. data/Rakefile +8 -0
  6. data/app/assets/config/cccux_manifest.js +1 -0
  7. data/app/assets/stylesheets/cccux/application.css +102 -0
  8. data/app/controllers/cccux/ability_permissions_controller.rb +271 -0
  9. data/app/controllers/cccux/application_controller.rb +37 -0
  10. data/app/controllers/cccux/authorization_controller.rb +10 -0
  11. data/app/controllers/cccux/cccux_controller.rb +64 -0
  12. data/app/controllers/cccux/dashboard_controller.rb +172 -0
  13. data/app/controllers/cccux/home_controller.rb +19 -0
  14. data/app/controllers/cccux/roles_controller.rb +290 -0
  15. data/app/controllers/cccux/simple_controller.rb +7 -0
  16. data/app/controllers/cccux/users_controller.rb +112 -0
  17. data/app/controllers/concerns/cccux/application_controller_concern.rb +32 -0
  18. data/app/helpers/cccux/application_helper.rb +4 -0
  19. data/app/helpers/cccux/authorization_helper.rb +228 -0
  20. data/app/jobs/cccux/application_job.rb +4 -0
  21. data/app/mailers/cccux/application_mailer.rb +6 -0
  22. data/app/models/cccux/ability.rb +142 -0
  23. data/app/models/cccux/ability_permission.rb +61 -0
  24. data/app/models/cccux/application_record.rb +5 -0
  25. data/app/models/cccux/role.rb +90 -0
  26. data/app/models/cccux/role_ability.rb +49 -0
  27. data/app/models/cccux/user_role.rb +42 -0
  28. data/app/models/concerns/cccux/authorizable.rb +25 -0
  29. data/app/models/concerns/cccux/scoped_ownership.rb +183 -0
  30. data/app/models/concerns/cccux/user_concern.rb +87 -0
  31. data/app/views/cccux/ability_permissions/edit.html.erb +58 -0
  32. data/app/views/cccux/ability_permissions/index.html.erb +108 -0
  33. data/app/views/cccux/ability_permissions/new.html.erb +308 -0
  34. data/app/views/cccux/dashboard/index.html.erb +69 -0
  35. data/app/views/cccux/dashboard/model_discovery.html.erb +148 -0
  36. data/app/views/cccux/home/index.html.erb +42 -0
  37. data/app/views/cccux/roles/_flash.html.erb +10 -0
  38. data/app/views/cccux/roles/_form.html.erb +78 -0
  39. data/app/views/cccux/roles/_role.html.erb +67 -0
  40. data/app/views/cccux/roles/edit.html.erb +317 -0
  41. data/app/views/cccux/roles/index.html.erb +51 -0
  42. data/app/views/cccux/roles/new.html.erb +3 -0
  43. data/app/views/cccux/roles/show.html.erb +99 -0
  44. data/app/views/cccux/users/edit.html.erb +117 -0
  45. data/app/views/cccux/users/index.html.erb +99 -0
  46. data/app/views/cccux/users/new.html.erb +94 -0
  47. data/app/views/cccux/users/show.html.erb +138 -0
  48. data/app/views/layouts/cccux/admin.html.erb +168 -0
  49. data/app/views/layouts/cccux/application.html.erb +17 -0
  50. data/app/views/shared/_footer.html.erb +101 -0
  51. data/config/routes.rb +63 -0
  52. data/db/migrate/20250626194001_create_cccux_roles.rb +15 -0
  53. data/db/migrate/20250626194007_create_cccux_ability_permissions.rb +18 -0
  54. data/db/migrate/20250626194011_create_cccux_user_roles.rb +13 -0
  55. data/db/migrate/20250626194016_create_cccux_role_abilities.rb +10 -0
  56. data/db/migrate/20250627170611_add_owned_to_cccux_role_abilities.rb +9 -0
  57. data/db/migrate/20250705193709_add_context_to_cccux_role_abilities.rb +9 -0
  58. data/db/migrate/20250706214415_add_ownership_configuration_to_role_abilities.rb +21 -0
  59. data/db/seeds.rb +136 -0
  60. data/lib/cccux/engine.rb +50 -0
  61. data/lib/cccux/version.rb +3 -0
  62. data/lib/cccux.rb +7 -0
  63. data/lib/tasks/cccux.rake +703 -0
  64. data/lib/tasks/view_helpers.rake +274 -0
  65. metadata +188 -0
@@ -0,0 +1,274 @@
1
+ namespace :cccux do
2
+ desc "Convert standard Rails view helpers to CCCUX authorization helpers in a directory"
3
+ task :convert_views, [:view_path] => :environment do |task, args|
4
+ view_path = args[:view_path]
5
+
6
+ if view_path.blank?
7
+ puts "❌ Please provide a view path"
8
+ puts "Usage: rails cccux:convert_views[app/views/products]"
9
+ puts " rails cccux:convert_views[app/views/stores]"
10
+ exit 1
11
+ end
12
+
13
+ # Normalize the path
14
+ view_path = view_path.gsub(/^\/+/, '').gsub(/\/+$/, '')
15
+ full_path = Rails.root.join(view_path)
16
+
17
+ unless Dir.exist?(full_path)
18
+ puts "❌ Directory not found: #{full_path}"
19
+ exit 1
20
+ end
21
+
22
+ puts "🔍 Converting view helpers in: #{full_path}"
23
+ puts ""
24
+
25
+ # Find all .erb files in the directory
26
+ erb_files = Dir.glob(File.join(full_path, "**", "*.erb"))
27
+
28
+ if erb_files.empty?
29
+ puts "❌ No .erb files found in #{full_path}"
30
+ exit 1
31
+ end
32
+
33
+ conversions_made = 0
34
+ files_modified = 0
35
+
36
+ erb_files.each do |file_path|
37
+ relative_path = file_path.gsub("#{Rails.root}/", "")
38
+ puts "📝 Processing: #{relative_path}"
39
+
40
+ original_content = File.read(file_path)
41
+ modified_content = original_content.dup
42
+ file_conversions = 0
43
+
44
+ # Convert complex nested conditional patterns for edit/show links
45
+ # Pattern: <% if @project %><%= link_to "Edit this task", edit_project_task_path(@project, @task) %><% else %><%= link_to "Edit this task", edit_task_path(@task) %><% end %>
46
+ modified_content.gsub!(/<%\s*if\s+@(\w+)\s*%>\s*<%=\s*link_to\s+"([^"]+)",\s*edit_(\w+)_(\w+)_path\(@\w+,\s*(@\w+)\)\s*%>\s*<%\s*else\s*%>\s*<%=\s*link_to\s+"[^"]*",\s*edit_(\w+)_path\((@\w+)\)\s*%>\s*<%\s*end\s*%>/m) do |match|
47
+ parent_var, text, parent_model, child_model, model1, child_singular, model2 = $1, $2, $3, $4, $5, $6, $7
48
+ file_conversions += 1
49
+ "<%= link_if_can_edit #{model1}, \"#{text}\", @#{parent_var} ? edit_#{parent_model}_#{child_model}_path(@#{parent_var}, #{model1}) : edit_#{child_singular}_path(#{model1}) %>"
50
+ end
51
+
52
+ # Convert complex nested conditional patterns for show links
53
+ # Pattern: <% if @project %><%= link_to "Show this task", project_task_path(@project, @task) %><% else %><%= link_to "Show this task", @task %><% end %>
54
+ modified_content.gsub!(/<%\s*if\s+@(\w+)\s*%>\s*<%=\s*link_to\s+"([^"]+)",\s*(\w+)_(\w+)_path\(@\w+,\s*(@\w+)\)\s*%>\s*<%\s*else\s*%>\s*<%=\s*link_to\s+"[^"]*",\s*(@\w+)\s*%>\s*<%\s*end\s*%>/m) do |match|
55
+ parent_var, text, parent_model, child_model, model1, model2 = $1, $2, $3, $4, $5, $6
56
+ file_conversions += 1
57
+ "<%= link_if_can_show #{model1}, \"#{text}\", @#{parent_var} ? #{parent_model}_#{child_model}_path(@#{parent_var}, #{model1}) : #{model1} %>"
58
+ end
59
+
60
+ # Convert complex nested conditional patterns for destroy buttons
61
+ # Pattern: <% if @project %><%= button_to "Destroy this task", project_task_path(@project, @task), method: :delete %><% else %><%= button_to "Destroy this task", @task, method: :delete %><% end %>
62
+ modified_content.gsub!(/<%\s*if\s+@(\w+)\s*%>\s*<%=\s*button_to\s+"([^"]+)",\s*(\w+)_(\w+)_path\(@\w+,\s*(@\w+)\),\s*method:\s*:delete[^%]*%>\s*<%\s*else\s*%>\s*<%=\s*button_to\s+"[^"]*",\s*(@\w+),\s*method:\s*:delete[^%]*%>\s*<%\s*end\s*%>/m) do |match|
63
+ parent_var, text, parent_model, child_model, model1, model2 = $1, $2, $3, $4, $5, $6
64
+ file_conversions += 1
65
+ "<%= button_if_can_destroy #{model1}, \"#{text}\", @#{parent_var} ? #{parent_model}_#{child_model}_path(@#{parent_var}, #{model1}) : #{model1}, method: :delete %>"
66
+ end
67
+
68
+ # Convert complex nested conditional patterns for "Back to" links
69
+ # Pattern: <% if @project %><%= link_to "Back to tasks", project_tasks_path(@project) %><% else %><%= link_to "Back to tasks", tasks_path %><% end %>
70
+ modified_content.gsub!(/<%\s*if\s+@(\w+)\s*%>\s*<%=\s*link_to\s+"([^"]+)",\s*(\w+)_(\w+)_path\(@\w+\)\s*%>\s*<%\s*else\s*%>\s*<%=\s*link_to\s+"[^"]*",\s*(\w+)_path\s*%>\s*<%\s*end\s*%>/m) do |match|
71
+ parent_var, text, parent_model, child_model, simple_model = $1, $2, $3, $4, $5
72
+ file_conversions += 1
73
+
74
+ # Extract the model name from the path
75
+ model_name = simple_model.singularize.camelize
76
+ "<%= link_if_can_index #{model_name}, \"#{text}\", @#{parent_var} ? #{parent_model}_#{child_model}_path(@#{parent_var}) : #{simple_model}_path %>"
77
+ end
78
+
79
+ # Convert complex nested conditional patterns for new links
80
+ # Pattern: <% if @project %><%= link_to "New task", new_project_task_path(@project) %><% else %><%= link_to "New task", new_task_path %><% end %>
81
+ modified_content.gsub!(/<%\s*if\s+@(\w+)\s*%>\s*<%=\s*link_to\s+"(?:New|Add)\s+(\w+)",\s*new_(\w+)_(\w+)_path\(@\w+\)\s*%>\s*<%\s*else\s*%>\s*<%=\s*link_to\s+"[^"]*",\s*new_(\w+)_path\s*%>\s*<%\s*end\s*%>/m) do |match|
82
+ parent_var, model_name, parent_model, child_model, simple_model = $1, $2, $3, $4, $5
83
+ file_conversions += 1
84
+
85
+ # Use the child model name for the creation check
86
+ model_class = child_model.camelize
87
+ "<%= link_if_can_create #{model_class}.new, \"New #{model_name}\", @#{parent_var} ? new_#{parent_model}_#{child_model}_path(@#{parent_var}) : new_#{simple_model}_path %>"
88
+ end
89
+
90
+ # Convert link_to with conditions to link_if_can helpers
91
+ # Pattern: <% if can? :show, @model %><%= link_to ... %><% end %>
92
+ modified_content.gsub!(/<%\s*if\s+can\?\s*[:\(](\w+)[:\)]?,\s*(@\w+)\s*%>\s*<%=\s*link_to\s+"([^"]+)",\s*(\w+_path\(@\w+\))\s*%>\s*<%\s*end\s*%>/m) do |match|
93
+ action, model, text, path = $1, $2, $3, $4
94
+ file_conversions += 1
95
+ case action
96
+ when 'show', 'read'
97
+ "<%= link_if_can_show #{model}, \"#{text}\", #{path} %>"
98
+ when 'edit', 'update'
99
+ "<%= link_if_can_edit #{model}, \"#{text}\", #{path} %>"
100
+ when 'destroy', 'delete'
101
+ "<%= button_if_can_destroy #{model}, \"#{text}\", #{path}, method: :delete %>"
102
+ else
103
+ match # Keep original if we don't recognize the action
104
+ end
105
+ end
106
+
107
+ # Convert simple link_to edit patterns
108
+ modified_content.gsub!(/<%=\s*link_to\s+"Edit(?:\s+this\s+\w+)?",\s*edit_(\w+)_path\((@\w+)\)\s*%>/) do |match|
109
+ model = $2
110
+ file_conversions += 1
111
+ "<%= link_if_can_edit #{model}, \"Edit this #{$1}\", edit_#{$1}_path(#{model}) %>"
112
+ end
113
+
114
+ # Convert simple link_to show patterns
115
+ modified_content.gsub!(/<%=\s*link_to\s+"(?:Show|View)(?:\s+this\s+\w+)?",\s*(\w+_path\((@\w+)\))\s*%>/) do |match|
116
+ path, model = $1, $2
117
+ file_conversions += 1
118
+ "<%= link_if_can_show #{model}, \"Show this #{path.split('_').first}\", #{path} %>"
119
+ end
120
+
121
+ # Convert simple link_to show patterns with just the model
122
+ modified_content.gsub!(/<%=\s*link_to\s+"Show this (\w+)",\s*(@\w+)\s*%>/) do |match|
123
+ model_name, model = $1, $2
124
+ file_conversions += 1
125
+ "<%= link_if_can_show #{model}, \"Show this #{model_name}\", #{model} %>"
126
+ end
127
+
128
+ # Convert simple link_to new patterns
129
+ modified_content.gsub!(/<%=\s*link_to\s+"(?:New|Add)\s*(\w+)",\s*new_(\w+)_path\s*%>/) do |match|
130
+ model_name, model_singular = $1, $2
131
+ file_conversions += 1
132
+ "<%= link_if_can_create #{model_singular.camelize}.new, \"New #{model_name}\", new_#{model_singular}_path %>"
133
+ end
134
+
135
+ # Convert link_to with method: :delete to button_if_can_destroy
136
+ modified_content.gsub!(/<%=\s*link_to\s+"(?:Delete|Destroy)(?:\s+this\s+\w+)?",\s*(\w+_path\((@\w+)\)),\s*method:\s*:delete(?:,\s*[^%]+)?\s*%>/) do |match|
137
+ path, model = $1, $2
138
+ file_conversions += 1
139
+ "<%= button_if_can_destroy #{model}, \"Delete this #{path.split('_').first}\", #{path}, method: :delete %>"
140
+ end
141
+
142
+ # Convert button_to with method: :delete to button_if_can_destroy
143
+ modified_content.gsub!(/<%=\s*button_to\s+"(?:Delete|Destroy)(?:\s+this\s+\w+)?",\s*(\w+_path\((@\w+)\)),\s*method:\s*:delete(?:,\s*[^%]+)?\s*%>/) do |match|
144
+ path, model = $1, $2
145
+ file_conversions += 1
146
+ "<%= button_if_can_destroy #{model}, \"Destroy this #{path.split('_').first}\", #{path}, method: :delete %>"
147
+ end
148
+
149
+ # Convert button_to with just model to button_if_can_destroy
150
+ modified_content.gsub!(/<%=\s*button_to\s+"(?:Delete|Destroy)(?:\s+this\s+\w+)?",\s*(@\w+),\s*method:\s*:delete(?:,\s*[^%]+)?\s*%>/) do |match|
151
+ model = $1
152
+ file_conversions += 1
153
+ "<%= button_if_can_destroy #{model}, \"Destroy this #{model.gsub('@', '').singularize}\", #{model}, method: :delete %>"
154
+ end
155
+
156
+ # Convert form_with authorization checks
157
+ modified_content.gsub!(/<%\s*if\s+can\?\s*[:\(](\w+)[:\)]?,\s*(@\w+)\s*%>\s*(<%=\s*form_with[^%]+%>.*?<%\s*end\s*%>)\s*<%\s*end\s*%>/m) do |match|
158
+ action, model, form_block = $1, $2, $3
159
+ if action == 'update' || action == 'edit'
160
+ file_conversions += 1
161
+ "<% content_if_can_edit #{model} do %>\n #{form_block}\n<% end %>"
162
+ elsif action == 'create' || action == 'new'
163
+ file_conversions += 1
164
+ "<% content_if_can_create #{model} do %>\n #{form_block}\n<% end %>"
165
+ else
166
+ match # Keep original if we don't recognize the action
167
+ end
168
+ end
169
+
170
+ # Convert nested resource links (e.g., store_product_path)
171
+ modified_content.gsub!(/<%=\s*link_to\s+"New\s+(\w+)",\s*new_(\w+)_(\w+)_path\((@\w+)\)\s*%>/) do |match|
172
+ child_name, parent_singular, child_singular, parent_model = $1, $2, $3, $4
173
+ file_conversions += 1
174
+ "<%= link_if_can_create #{parent_model}.#{child_singular.pluralize}.build, \"New #{child_name}\", new_#{parent_singular}_#{child_singular}_path(#{parent_model}) %>"
175
+ end
176
+
177
+ if file_conversions > 0
178
+ File.write(file_path, modified_content)
179
+ files_modified += 1
180
+ conversions_made += file_conversions
181
+ puts " ✅ Made #{file_conversions} conversions"
182
+ else
183
+ puts " ⏭️ No conversions needed"
184
+ end
185
+ end
186
+
187
+ puts ""
188
+ puts "🎉 Conversion complete!"
189
+ puts "📊 Files processed: #{erb_files.length}"
190
+ puts "📝 Files modified: #{files_modified}"
191
+ puts "🔄 Total conversions: #{conversions_made}"
192
+
193
+ if conversions_made > 0
194
+ puts ""
195
+ puts "📋 Summary of conversions made:"
196
+ puts " • Standard link_to → link_if_can_show, link_if_can_edit"
197
+ puts " • Delete links → button_if_can_destroy"
198
+ puts " • New links → link_if_can_create"
199
+ puts " • Conditional forms → content_if_can_edit/create"
200
+ puts " • Nested resource links → context-aware helpers"
201
+ puts " • Complex nested conditionals → smart context-aware helpers"
202
+ puts ""
203
+ puts "⚠️ Please review the changes and test your views!"
204
+ puts "💡 You may need to adjust some conversions manually for complex cases."
205
+ end
206
+ end
207
+
208
+ desc "Show examples of view helper conversions"
209
+ task :view_examples => :environment do
210
+ puts "🎯 CCCUX View Helper Conversion Examples"
211
+ puts ""
212
+
213
+ puts "📝 BEFORE → AFTER conversions:"
214
+ puts ""
215
+
216
+ puts "1️⃣ Show links:"
217
+ puts " <%= link_to \"Show\", product_path(@product) %>"
218
+ puts " → <%= link_if_can_show @product, \"Show\", product_path(@product) %>"
219
+ puts ""
220
+
221
+ puts "2️⃣ Edit links:"
222
+ puts " <%= link_to \"Edit\", edit_product_path(@product) %>"
223
+ puts " → <%= link_if_can_edit @product, \"Edit\", edit_product_path(@product) %>"
224
+ puts ""
225
+
226
+ puts "3️⃣ Delete links:"
227
+ puts " <%= link_to \"Delete\", product_path(@product), method: :delete %>"
228
+ puts " → <%= button_if_can_destroy @product, \"Delete\", product_path(@product), method: :delete %>"
229
+ puts ""
230
+
231
+ puts "4️⃣ New links:"
232
+ puts " <%= link_to \"New Product\", new_product_path %>"
233
+ puts " → <%= link_if_can_create Product.new, \"New Product\", new_product_path %>"
234
+ puts ""
235
+
236
+ puts "5️⃣ Conditional links:"
237
+ puts " <% if can? :edit, @product %><%= link_to \"Edit\", edit_product_path(@product) %><% end %>"
238
+ puts " → <%= link_if_can_edit @product, \"Edit\", edit_product_path(@product) %>"
239
+ puts ""
240
+
241
+ puts "6️⃣ Nested resources:"
242
+ puts " <%= link_to \"New Product\", new_store_product_path(@store) %>"
243
+ puts " → <%= link_if_can_create @store.products.build, \"New Product\", new_store_product_path(@store) %>"
244
+ puts ""
245
+
246
+ puts "7️⃣ Complex nested conditionals:"
247
+ puts " <% if @project %>"
248
+ puts " <%= link_to \"Edit this task\", edit_project_task_path(@project, @task) %>"
249
+ puts " <% else %>"
250
+ puts " <%= link_to \"Edit this task\", edit_task_path(@task) %>"
251
+ puts " <% end %>"
252
+ puts " →"
253
+ puts " <%= link_if_can_edit @task, \"Edit this task\", @project ? edit_project_task_path(@project, @task) : edit_task_path(@task) %>"
254
+ puts ""
255
+
256
+ puts "8️⃣ Conditional forms:"
257
+ puts " <% if can? :edit, @product %>"
258
+ puts " <%= form_with model: @product do |f| %>"
259
+ puts " <!-- form fields -->"
260
+ puts " <% end %>"
261
+ puts " <% end %>"
262
+ puts " →"
263
+ puts " <% content_if_can_edit @product do %>"
264
+ puts " <%= form_with model: @product do |f| %>"
265
+ puts " <!-- form fields -->"
266
+ puts " <% end %>"
267
+ puts " <% end %>"
268
+ puts ""
269
+
270
+ puts "🚀 To convert your views:"
271
+ puts " rails cccux:convert_views[app/views/products]"
272
+ puts " rails cccux:convert_views[app/views/stores]"
273
+ end
274
+ end
metadata ADDED
@@ -0,0 +1,188 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cccux
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - John
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-07-08 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '7.1'
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 7.1.5.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '7.1'
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 7.1.5.1
32
+ - !ruby/object:Gem::Dependency
33
+ name: cancancan
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - "~>"
37
+ - !ruby/object:Gem::Version
38
+ version: '3.0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - "~>"
44
+ - !ruby/object:Gem::Version
45
+ version: '3.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: zeitwerk
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '2.6'
53
+ type: :runtime
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.6'
60
+ - !ruby/object:Gem::Dependency
61
+ name: sqlite3
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.4'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '1.4'
74
+ - !ruby/object:Gem::Dependency
75
+ name: rspec-rails
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '6.0'
81
+ type: :development
82
+ prerelease: false
83
+ version_requirements: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '6.0'
88
+ description: CCCUX provides a comprehensive admin interface and user experience layer
89
+ for CanCanCan authorization. It includes role-based access control (RBAC) models,
90
+ admin controllers for managing users, roles, and permissions, and a clean interface
91
+ for authorization management.
92
+ email:
93
+ - bagus@bagus.org
94
+ executables: []
95
+ extensions: []
96
+ extra_rdoc_files: []
97
+ files:
98
+ - CHANGELOG.md
99
+ - MIT-LICENSE
100
+ - README.md
101
+ - Rakefile
102
+ - app/assets/config/cccux_manifest.js
103
+ - app/assets/stylesheets/cccux/application.css
104
+ - app/controllers/cccux/ability_permissions_controller.rb
105
+ - app/controllers/cccux/application_controller.rb
106
+ - app/controllers/cccux/authorization_controller.rb
107
+ - app/controllers/cccux/cccux_controller.rb
108
+ - app/controllers/cccux/dashboard_controller.rb
109
+ - app/controllers/cccux/home_controller.rb
110
+ - app/controllers/cccux/roles_controller.rb
111
+ - app/controllers/cccux/simple_controller.rb
112
+ - app/controllers/cccux/users_controller.rb
113
+ - app/controllers/concerns/cccux/application_controller_concern.rb
114
+ - app/helpers/cccux/application_helper.rb
115
+ - app/helpers/cccux/authorization_helper.rb
116
+ - app/jobs/cccux/application_job.rb
117
+ - app/mailers/cccux/application_mailer.rb
118
+ - app/models/cccux/ability.rb
119
+ - app/models/cccux/ability_permission.rb
120
+ - app/models/cccux/application_record.rb
121
+ - app/models/cccux/role.rb
122
+ - app/models/cccux/role_ability.rb
123
+ - app/models/cccux/user_role.rb
124
+ - app/models/concerns/cccux/authorizable.rb
125
+ - app/models/concerns/cccux/scoped_ownership.rb
126
+ - app/models/concerns/cccux/user_concern.rb
127
+ - app/views/cccux/ability_permissions/edit.html.erb
128
+ - app/views/cccux/ability_permissions/index.html.erb
129
+ - app/views/cccux/ability_permissions/new.html.erb
130
+ - app/views/cccux/dashboard/index.html.erb
131
+ - app/views/cccux/dashboard/model_discovery.html.erb
132
+ - app/views/cccux/home/index.html.erb
133
+ - app/views/cccux/roles/_flash.html.erb
134
+ - app/views/cccux/roles/_form.html.erb
135
+ - app/views/cccux/roles/_role.html.erb
136
+ - app/views/cccux/roles/edit.html.erb
137
+ - app/views/cccux/roles/index.html.erb
138
+ - app/views/cccux/roles/new.html.erb
139
+ - app/views/cccux/roles/show.html.erb
140
+ - app/views/cccux/users/edit.html.erb
141
+ - app/views/cccux/users/index.html.erb
142
+ - app/views/cccux/users/new.html.erb
143
+ - app/views/cccux/users/show.html.erb
144
+ - app/views/layouts/cccux/admin.html.erb
145
+ - app/views/layouts/cccux/application.html.erb
146
+ - app/views/shared/_footer.html.erb
147
+ - config/routes.rb
148
+ - db/migrate/20250626194001_create_cccux_roles.rb
149
+ - db/migrate/20250626194007_create_cccux_ability_permissions.rb
150
+ - db/migrate/20250626194011_create_cccux_user_roles.rb
151
+ - db/migrate/20250626194016_create_cccux_role_abilities.rb
152
+ - db/migrate/20250627170611_add_owned_to_cccux_role_abilities.rb
153
+ - db/migrate/20250705193709_add_context_to_cccux_role_abilities.rb
154
+ - db/migrate/20250706214415_add_ownership_configuration_to_role_abilities.rb
155
+ - db/seeds.rb
156
+ - lib/cccux.rb
157
+ - lib/cccux/engine.rb
158
+ - lib/cccux/version.rb
159
+ - lib/tasks/cccux.rake
160
+ - lib/tasks/view_helpers.rake
161
+ homepage: https://github.com/bagus1/cccux
162
+ licenses:
163
+ - MIT
164
+ metadata:
165
+ homepage_uri: https://github.com/bagus1/cccux
166
+ source_code_uri: https://github.com/bagus1/cccux
167
+ changelog_uri: https://github.com/bagus1/cccux/blob/main/CHANGELOG.md
168
+ documentation_uri: https://github.com/bagus1/cccux/blob/main/README.md
169
+ bug_tracker_uri: https://github.com/bagus1/cccux/issues
170
+ rdoc_options: []
171
+ require_paths:
172
+ - lib
173
+ required_ruby_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: 3.0.0
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ requirements: []
184
+ rubygems_version: 3.6.2
185
+ specification_version: 4
186
+ summary: CanCanCan UX - Admin interface and user experience enhancements for CanCanCan
187
+ authorization
188
+ test_files: []