cccux 0.1.0 → 0.3.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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/README.md +124 -112
  4. data/Rakefile +57 -4
  5. data/app/assets/stylesheets/cccux/application.css +96 -72
  6. data/app/controllers/cccux/ability_permissions_controller.rb +138 -33
  7. data/app/controllers/cccux/application_controller.rb +7 -0
  8. data/app/controllers/cccux/cccux_controller.rb +20 -10
  9. data/app/controllers/cccux/dashboard_controller.rb +203 -32
  10. data/app/controllers/cccux/role_abilities_controller.rb +70 -0
  11. data/app/controllers/cccux/roles_controller.rb +70 -81
  12. data/app/controllers/cccux/users_controller.rb +22 -7
  13. data/app/controllers/concerns/cccux/application_controller_concern.rb +6 -2
  14. data/app/helpers/cccux/authorization_helper.rb +29 -21
  15. data/app/models/cccux/ability.rb +83 -32
  16. data/app/models/cccux/ability_permission.rb +9 -0
  17. data/app/models/cccux/post.rb +5 -0
  18. data/app/models/cccux/role.rb +19 -1
  19. data/app/models/cccux/role_ability.rb +3 -0
  20. data/app/models/concerns/cccux/user_concern.rb +5 -2
  21. data/app/views/cccux/ability_permissions/new.html.erb +2 -2
  22. data/app/views/cccux/dashboard/model_discovery.html.erb +7 -2
  23. data/app/views/cccux/roles/_form.html.erb +24 -71
  24. data/app/views/cccux/roles/edit.html.erb +5 -5
  25. data/app/views/cccux/roles/index.html.erb +1 -8
  26. data/app/views/cccux/roles/new.html.erb +1 -3
  27. data/app/views/cccux/users/edit.html.erb +4 -4
  28. data/app/views/cccux/users/new.html.erb +30 -15
  29. data/app/views/layouts/cccux/admin.html.erb +1 -2
  30. data/app/views/shared/_footer.html.erb +1 -1
  31. data/config/routes.rb +7 -6
  32. data/lib/cccux/engine.rb +7 -6
  33. data/lib/cccux/version.rb +1 -1
  34. data/lib/cccux.rb +12 -0
  35. data/lib/tasks/cccux.rake +271 -159
  36. metadata +10 -22
data/lib/tasks/cccux.rake CHANGED
@@ -10,91 +10,117 @@ namespace :cccux do
10
10
 
11
11
  # Step 1: Ensure Devise is installed and working
12
12
  puts "📋 Step 1: Verifying Devise installation..."
13
- # Check if Devise is installed and User model exists with Devise configuration
14
- devise_installed = defined?(Devise)
15
- user_model_exists = false
16
- user_has_devise = false
17
-
18
- if devise_installed
19
- begin
20
- user_class = Object.const_get('User')
21
- user_model_exists = true
22
-
23
- # Check if User model has Devise modules
24
- user_has_devise = user_class.respond_to?(:devise_modules) && user_class.devise_modules.any?
25
-
26
- # Also check if User model file contains Devise configuration as backup
27
- if !user_has_devise
28
- user_model_path = Rails.root.join('app', 'models', 'user.rb')
29
- if File.exist?(user_model_path)
30
- user_content = File.read(user_model_path)
31
- user_has_devise = user_content.include?('devise :')
32
- end
33
- end
34
- rescue NameError
35
- # User model doesn't exist
36
- end
37
- end
38
13
 
39
- unless devise_installed && user_model_exists && user_has_devise
40
- puts "❌ Devise is not properly installed or configured. Please run the following command first:"
41
- puts " "
14
+ # Check if Devise files exist (more reliable than checking loaded state)
15
+ devise_gem_in_gemfile = File.exist?(Rails.root.join('Gemfile')) &&
16
+ File.read(Rails.root.join('Gemfile')).include?('gem "devise"')
17
+ devise_initializer_exists = File.exist?(Rails.root.join('config', 'initializers', 'devise.rb'))
18
+ user_model_has_devise = File.exist?(Rails.root.join('app', 'models', 'user.rb')) &&
19
+ File.read(Rails.root.join('app', 'models', 'user.rb')).include?('devise :')
20
+ routes_has_devise = File.exist?(Rails.root.join('config', 'routes.rb')) &&
21
+ File.read(Rails.root.join('config', 'routes.rb')).include?('devise_for :users')
22
+
23
+ # Check if Devise is loaded in the current environment (optional check)
24
+ devise_loaded = defined?(Devise)
25
+ user_model_exists = defined?(User)
26
+ user_has_devise_methods = user_model_exists && User.respond_to?(:devise)
27
+
28
+ puts " 📋 Devise status check:"
29
+ puts " - Devise gem in Gemfile: #{devise_gem_in_gemfile ? '✅' : '❌'}"
30
+ puts " - Devise initializer: #{devise_initializer_exists ? '✅' : '❌'}"
31
+ puts " - User model has Devise: #{user_model_has_devise ? '✅' : '❌'}"
32
+ puts " - Routes have Devise: #{routes_has_devise ? '✅' : '❌'}"
33
+ puts " - Devise loaded in environment: #{devise_loaded ? '✅' : '❌'}"
34
+ puts " - User model has Devise methods: #{user_has_devise_methods ? '✅' : '❌'}"
35
+
36
+ # If Devise files exist but aren't loaded, that's normal - just continue
37
+ if devise_gem_in_gemfile && devise_initializer_exists && user_model_has_devise && routes_has_devise
38
+ if devise_loaded && user_has_devise_methods
39
+ puts "✅ Devise is properly installed and loaded"
40
+ else
41
+ puts "✅ Devise files are properly installed"
42
+ puts "💡 Devise will be fully loaded after server restart"
43
+ end
44
+ else
45
+ puts "❌ Devise is not properly installed or configured."
46
+ puts "run the following commands to install Devise: "
42
47
  puts " bundle add devise && rails generate devise:install && rails generate devise User && rails db:migrate"
43
- puts " "
44
- puts "Then re-run: rails cccux:setup"
48
+ puts " then run: rails cccux:setup again after Devise is installed"
45
49
  exit 1
46
50
  end
47
51
 
48
52
  puts "✅ Devise is properly installed"
49
53
 
50
- # Step 2: Configure routes
51
- puts "📋 Step 2: Configuring routes..."
54
+ # Step 2: Verify Devise is using default controllers
55
+ puts "📋 Step 2: Verifying Devise configuration..."
56
+ if Dir.exist?(Rails.root.join('app', 'controllers', 'users'))
57
+ puts " âš ī¸ Custom Devise controllers detected - these may cause conflicts"
58
+ puts " â„šī¸ Using default Devise controllers is recommended for stability"
59
+ else
60
+ puts " ✅ Using default Devise controllers (recommended)"
61
+ end
62
+
63
+ # Step 3: Configure routes
64
+ puts "📋 Step 3: Configuring routes..."
52
65
  configure_routes
53
66
  puts "✅ Routes configured"
54
67
 
55
- # Step 3: Configure assets
56
- puts "📋 Step 3: Configuring assets..."
68
+ # Step 4: Configure assets
69
+ puts "📋 Step 4: Configuring assets..."
57
70
  configure_assets
58
71
  puts "✅ Assets configured"
59
72
 
60
- # Step 4: Run CCCUX migrations
61
- puts "📋 Step 4: Running CCCUX migrations..."
62
- Rake::Task['db:migrate'].invoke
73
+ # Step 5: Run CCCUX migrations
74
+ puts "📋 Step 5: Running CCCUX migrations..."
75
+ begin
76
+ Rake::Task['db:migrate'].invoke
77
+ rescue RuntimeError => e
78
+ if e.message.include?("Don't know how to build task 'db:migrate'")
79
+ puts " âš ī¸ Skipping migrations (not available in engine context)"
80
+ else
81
+ raise e
82
+ end
83
+ end
63
84
  puts "✅ CCCUX migrations completed"
64
85
 
65
- # Step 5: Include CCCUX concern in User model
66
- puts "📋 Step 5: Adding CCCUX to User model..."
86
+ # Step 6: Include CCCUX concern in User model
87
+ puts "📋 Step 6: Adding CCCUX to User model..."
67
88
  include_cccux_concern
68
89
  puts "✅ CCCUX concern added to User model"
69
90
 
70
- # Step 5.5: Configure ApplicationController with CCCUX
71
- puts "📋 Step 5.5: Configuring ApplicationController with CCCUX..."
91
+ # Step 7: Configure ApplicationController with CCCUX
92
+ puts "📋 Step 7: Configuring ApplicationController with CCCUX..."
72
93
  configure_application_controller
73
94
  puts "✅ ApplicationController configured with CCCUX"
74
95
 
75
- # Step 6: Create initial roles and permissions
76
- puts "📋 Step 6: Creating initial roles and permissions..."
96
+ # Step 8: Create initial roles and permissions
97
+ puts "📋 Step 8: Creating initial roles and permissions..."
77
98
  create_default_roles_and_permissions
78
99
  puts "✅ Default roles and permissions created"
79
100
 
80
- # Step 7: Create default admin user (if no users exist)
81
- puts "📋 Step 7: Creating default admin user..."
101
+ # Step 9: Create default admin user (if no users exist)
102
+ puts "📋 Step 9: Creating default admin user..."
82
103
  create_default_admin_user
83
104
 
84
- # Step 8: Create footer partial
85
- puts "📋 Step 8: Creating footer partial..."
105
+ # Step 10: Create footer partial
106
+ puts "📋 Step 10: Creating footer partial..."
86
107
  create_footer_partial
87
108
  puts "✅ Footer partial created"
88
109
 
89
- # Step 9: Create home controller if needed
90
- puts "📋 Step 9: Checking for home controller..."
110
+ # Step 11: Create home controller if needed
111
+ puts "📋 Step 11: Checking for home controller..."
91
112
  create_home_controller
92
113
  puts "✅ Home controller check completed"
93
114
 
94
- # Step 10: Verify setup
95
- puts "📋 Step 10: Verifying setup..."
115
+ # Step 12: Verify setup
116
+ puts "📋 Step 12: Verifying setup..."
96
117
  verify_setup
97
118
 
119
+ # Step 13: Precompile assets
120
+ puts "📋 Step 13: Precompiling assets..."
121
+ precompile_assets
122
+ puts "✅ Assets precompiled"
123
+
98
124
  puts ""
99
125
  puts "🎉 CCCUX + Devise setup completed successfully!"
100
126
  puts ""
@@ -106,6 +132,19 @@ namespace :cccux do
106
132
  puts "📚 Need help? Check the CCCUX documentation or README"
107
133
  end
108
134
 
135
+ desc 'test:prepare - Prepare test database for CCCUX engine'
136
+ task 'test:prepare' => :environment do
137
+ puts "đŸ§Ē Preparing CCCUX test database..."
138
+
139
+ # Switch to test environment
140
+ Rails.env = 'test'
141
+
142
+ # Load schema into test database
143
+ system("cd #{Rails.root.join('..', '..')} && RAILS_ENV=test rails db:schema:load")
144
+
145
+ puts "✅ Test database prepared"
146
+ end
147
+
109
148
  desc 'test - Test CCCUX + Devise integration'
110
149
  task test: :environment do
111
150
  puts "đŸ§Ē Testing CCCUX + Devise integration..."
@@ -203,12 +242,124 @@ namespace :cccux do
203
242
  puts "✅ CCCUX removed from application"
204
243
  end
205
244
 
245
+ desc 'megabar:create_mega_role - Discover MegaBar models and create comprehensive permissions'
246
+ task 'megabar:create_mega_role' => :environment do
247
+ puts "🔍 Discovering MegaBar models and creating permissions..."
248
+
249
+ # Check if MegaBar is available
250
+ unless defined?(MegaBar)
251
+ puts "❌ MegaBar engine not detected"
252
+ puts "💡 Make sure MegaBar is properly installed and configured"
253
+ exit 1
254
+ end
255
+
256
+ # Use the new engine discovery approach
257
+ megabar_models = []
258
+
259
+ begin
260
+ # Get all database tables that start with 'mega_bar_'
261
+ application_tables = ActiveRecord::Base.connection.tables.select do |table|
262
+ table.start_with?('mega_bar_')
263
+ end
264
+
265
+ application_tables.each do |table|
266
+ # Convert table name to proper namespaced model name
267
+ model_part = table.gsub('mega_bar_', '').singularize.camelize
268
+ model_name = "MegaBar::#{model_part}"
269
+
270
+ # Verify the model exists and is valid
271
+ begin
272
+ if Object.const_defined?(model_name)
273
+ model_class = Object.const_get(model_name)
274
+ if model_class.respond_to?(:table_name) &&
275
+ model_class.table_name == table
276
+ megabar_models << model_name
277
+ end
278
+ else
279
+ # Model constant doesn't exist yet, but table does - likely a valid model
280
+ megabar_models << model_name
281
+ end
282
+ rescue => e
283
+ # Skip if there's an error
284
+ end
285
+ end
286
+
287
+ rescue => e
288
+ puts "❌ Error detecting MegaBar models: #{e.message}"
289
+ exit 1
290
+ end
291
+
292
+ if megabar_models.empty?
293
+ puts "âš ī¸ No MegaBar models found"
294
+ puts "💡 Make sure MegaBar is properly set up and models exist"
295
+ exit 1
296
+ end
297
+
298
+ puts "📋 Found #{megabar_models.count} MegaBar models:"
299
+ megabar_models.each { |model| puts " - #{model}" }
300
+
301
+ # Create "Mega Role" if it doesn't exist
302
+ mega_role = Cccux::Role.find_or_create_by(name: 'Mega Role') do |role|
303
+ role.description = 'Global permissions for all MegaBar models'
304
+ role.active = true
305
+ end
306
+
307
+ if mega_role.persisted? && !mega_role.previously_persisted?
308
+ puts "✅ Created 'Mega Role'"
309
+ puts "💡 Visit /cccux/users/ to assign users to the 'Mega Role'"
310
+ else
311
+ puts "â„šī¸ 'Mega Role' already exists"
312
+ end
313
+
314
+ # Create CRUD permissions for each MegaBar model
315
+ actions = %w[create read update destroy]
316
+ permissions_created = 0
317
+
318
+ megabar_models.each do |model_name|
319
+ actions.each do |action|
320
+ permission = Cccux::AbilityPermission.find_or_create_by(
321
+ action: action,
322
+ subject: model_name
323
+ ) do |p|
324
+ p.description = "#{action.capitalize} #{model_name.pluralize.downcase}"
325
+ p.active = true
326
+ end
327
+
328
+ if permission.persisted? && !permission.previously_persisted?
329
+ permissions_created += 1
330
+ end
331
+ end
332
+ end
333
+
334
+ # Assign all permissions to the Mega Role
335
+ assigned_permissions = 0
336
+ Cccux::AbilityPermission.where(subject: megabar_models).each do |permission|
337
+ role_ability = Cccux::RoleAbility.find_or_create_by(
338
+ role: mega_role,
339
+ ability_permission: permission
340
+ )
341
+
342
+ if role_ability.persisted? && !role_ability.previously_persisted?
343
+ assigned_permissions += 1
344
+ end
345
+ end
346
+
347
+ puts "✅ Created #{permissions_created} permissions for MegaBar models"
348
+ puts "✅ Assigned #{assigned_permissions} permissions to 'Mega Role'"
349
+ puts ""
350
+ puts "🎉 MegaBar permissions setup completed!"
351
+ puts "💡 Users with 'Mega Role' will have full access to all MegaBar models"
352
+ end
353
+
206
354
  private
207
355
 
208
356
  def configure_routes
209
357
  routes_path = Rails.root.join('config/routes.rb')
210
358
  routes_content = File.read(routes_path)
211
359
 
360
+ # Check if Devise controllers exist
361
+ devise_controllers_exist = Dir.exist?(Rails.root.join('app', 'controllers', 'users'))
362
+
212
363
  # Ensure devise_for :users is before engine mount
213
364
  unless routes_content.include?('devise_for :users')
214
365
  puts " ➕ Adding devise_for :users to routes..."
@@ -217,6 +368,12 @@ namespace :cccux do
217
368
  routes_content = File.read(routes_path)
218
369
  end
219
370
 
371
+ # Ensure routes use default Devise controllers (recommended for stability)
372
+ if devise_controllers_exist
373
+ puts " âš ī¸ Custom Devise controllers detected - consider removing them for stability"
374
+ puts " â„šī¸ Routes will use default Devise controllers"
375
+ end
376
+
220
377
  # Add engine mount if not present
221
378
  unless routes_content.include?('mount Cccux::Engine')
222
379
  puts " ➕ Adding CCCUX engine mount to routes..."
@@ -229,40 +386,9 @@ namespace :cccux do
229
386
  end
230
387
 
231
388
  def configure_assets
232
- # Add CSS assets
233
- css_path = Rails.root.join('app/assets/stylesheets/application.css')
234
- if File.exist?(css_path)
235
- css_content = File.read(css_path)
236
-
237
- # Check if we're using Propshaft or Sprockets
238
- if defined?(Propshaft)
239
- # For Propshaft, copy the actual CSS content since it doesn't process @import
240
- unless css_content.include?('CCCUX Engine Styles')
241
- # Read the CCCUX CSS content
242
- cccux_css_path = File.join(File.dirname(__FILE__), '..', '..', 'app', 'assets', 'stylesheets', 'cccux', 'application.css')
243
- if File.exist?(cccux_css_path)
244
- cccux_css_content = File.read(cccux_css_path)
245
- # Extract just the CSS rules, not the manifest comments
246
- css_rules = cccux_css_content.split('*/').last.strip if cccux_css_content.include?('*/')
247
- css_rules ||= cccux_css_content
248
-
249
- File.open(css_path, 'a') do |f|
250
- f.puts "\n\n/* CCCUX Engine Styles - Added by CCCUX setup */"
251
- f.puts css_rules
252
- end
253
- puts " ✅ Added CCCUX CSS content to application.css (Propshaft)"
254
- else
255
- puts " âš ī¸ Could not find CCCUX CSS file at #{cccux_css_path}"
256
- end
257
- end
258
- else
259
- # Sprockets uses *= require syntax
260
- unless css_content.include?('cccux/application')
261
- File.open(css_path, 'a') { |f| f.puts "/*\n *= require cccux/application\n */" }
262
- puts " ✅ Added CCCUX CSS to application.css (Sprockets)"
263
- end
264
- end
265
- end
389
+ # Note: CCCUX styles are now loaded via the engine's asset pipeline
390
+ # No need to copy styles to host app's application.css
391
+ puts " â„šī¸ CCCUX styles will be loaded via engine asset pipeline"
266
392
 
267
393
  # Add JavaScript assets (if using legacy asset pipeline)
268
394
  js_path = Rails.root.join('app/assets/javascripts/application.js')
@@ -559,10 +685,10 @@ namespace :cccux do
559
685
 
560
686
  footer_path = shared_dir.join('_footer.html.erb')
561
687
 
562
- # Create footer content
688
+ # Create footer content - No inline styles, uses CCCUX engine CSS
563
689
  footer_content = <<~ERB
564
- <!-- CCCUX Footer - Added by CCCUX setup -->
565
- <footer class="cccux-footer" style="margin-top: 2rem; padding: 1rem 0; border-top: 1px solid #e5e5e5; background-color: #f8f9fa;">
690
+ <!-- CCCUX Footer - Styles loaded from CCCUX engine -->
691
+ <footer class="cccux-footer">
566
692
  <div class="container">
567
693
  <div class="row">
568
694
  <div class="col-md-6">
@@ -570,7 +696,7 @@ namespace :cccux do
570
696
  <a href="<%= main_app.root_path %>" class="footer-link">🏠 Home</a>
571
697
  <% if user_signed_in? && current_user.has_role?('Role Manager') %>
572
698
  <span class="footer-separator">|</span>
573
- <a href="<%= cccux.root_path %>" class="footer-link">âš™ī¸ CCCUX Admin</a>
699
+ <a href="/cccux" class="footer-link">âš™ī¸ CCCUX Admin</a>
574
700
  <% end %>
575
701
  </nav>
576
702
  </div>
@@ -579,10 +705,7 @@ namespace :cccux do
579
705
  <span class="user-info">
580
706
  👤 <strong><%= current_user.email %></strong>
581
707
  <span class="footer-separator">|</span>
582
- <%= link_to "đŸšĒ Logout", main_app.destroy_user_session_path,
583
- method: :delete,
584
- class: "footer-link",
585
- data: { turbo_method: :delete } %>
708
+ <%= button_to "Logout", main_app.destroy_user_session_path, method: :delete, class: "footer-link auth-link", style: "background: none; border: none; color: #007bff; text-decoration: none; padding: 5px 10px; border-radius: 4px; transition: all 0.2s ease; font-weight: 500; cursor: pointer; font: inherit;" %>
586
709
  </span>
587
710
  <% else %>
588
711
  <span class="auth-links">
@@ -595,73 +718,23 @@ namespace :cccux do
595
718
  </div>
596
719
  </div>
597
720
  </footer>
598
-
599
- <style>
600
- .cccux-footer {
601
- font-size: 0.9rem;
602
- color: #6c757d;
603
- }
604
- .cccux-footer .footer-link {
605
- color: #007bff;
606
- text-decoration: none;
607
- margin: 0 0.5rem;
608
- }
609
- .cccux-footer .footer-link:hover {
610
- color: #0056b3;
611
- text-decoration: underline;
612
- }
613
- .cccux-footer .footer-separator {
614
- color: #dee2e6;
615
- margin: 0 0.25rem;
616
- }
617
- .cccux-footer .user-info,
618
- .cccux-footer .auth-links {
619
- font-size: 0.85rem;
620
- }
621
- .cccux-footer .container {
622
- max-width: 1200px;
623
- margin: 0 auto;
624
- padding: 0 1rem;
625
- }
626
- .cccux-footer .row {
627
- display: flex;
628
- justify-content: space-between;
629
- align-items: center;
630
- flex-wrap: wrap;
631
- }
632
- .cccux-footer .col-md-6 {
633
- flex: 1;
634
- min-width: 300px;
635
- }
636
- .cccux-footer .text-end {
637
- text-align: right;
638
- }
639
- @media (max-width: 768px) {
640
- .cccux-footer .row {
641
- flex-direction: column;
642
- gap: 0.5rem;
643
- }
644
- .cccux-footer .col-md-6 {
645
- text-align: center;
646
- }
647
- .cccux-footer .text-end {
648
- text-align: center;
649
- }
650
- }
651
- </style>
652
721
  ERB
653
722
 
654
723
  # Write the footer partial
655
724
  File.write(footer_path, footer_content)
656
- puts " ✅ Created footer partial at #{footer_path}"
725
+ puts "✅ Created footer partial at #{footer_path}"
657
726
 
658
- # Also create a simple include instruction for the application layout
727
+ # Include footer in application layout
728
+ include_footer_in_layout
729
+ end
730
+
731
+ def include_footer_in_layout
659
732
  layout_path = Rails.root.join('app', 'views', 'layouts', 'application.html.erb')
660
733
  if File.exist?(layout_path)
661
734
  layout_content = File.read(layout_path)
662
735
 
663
736
  # Check if footer is already included
664
- unless layout_content.include?('render "shared/footer"')
737
+ unless layout_content.include?("render 'shared/footer'")
665
738
  # Add footer before closing body tag
666
739
  if layout_content.include?('</body>')
667
740
  updated_content = layout_content.gsub(
@@ -669,35 +742,74 @@ namespace :cccux do
669
742
  "\\1 <%= render 'shared/footer' %>\n\\1</body>"
670
743
  )
671
744
  File.write(layout_path, updated_content)
672
- puts " ✅ Added footer to application layout"
745
+ puts "✅ Added footer to application layout"
673
746
  else
674
- puts " âš ī¸ Could not find </body> tag in application layout - please manually add: <%= render 'shared/footer' %>"
747
+ puts "âš ī¸ Could not find </body> tag in application layout - please manually add: <%= render 'shared/footer' %>"
675
748
  end
676
749
  else
677
- puts " â„šī¸ Footer already included in application layout"
750
+ puts "â„šī¸ Footer already included in application layout"
678
751
  end
679
752
  else
680
- puts " âš ī¸ Application layout not found - please manually add: <%= render 'shared/footer' %>"
753
+ puts "âš ī¸ Application layout not found - please manually add: <%= render 'shared/footer' %>"
681
754
  end
682
755
  end
683
756
 
684
757
  def verify_setup
685
758
  # Test that User model has CCCUX methods
759
+ # First, try to reload the User model file to pick up the concern
760
+ begin
761
+ load Rails.root.join('app', 'models', 'user.rb')
762
+ rescue => e
763
+ puts " âš ī¸ Could not reload User model: #{e.message}"
764
+ end
765
+
686
766
  user = User.new
687
767
  unless user.respond_to?(:has_role?)
688
768
  puts "❌ User model missing CCCUX methods"
769
+ puts " 💡 This sometimes happens on the first run. Try running 'rails cccux:setup' again."
770
+ puts " 🔧 The concern was added to the User model file, but Rails needs to reload it."
689
771
  exit 1
690
772
  end
691
773
 
692
774
  puts "✅ CCCUX methods available on User model"
693
775
 
694
- # Test route helpers
776
+ # Check if Devise files exist (more reliable than testing routes in rake context)
777
+ devise_initializer_exists = File.exist?(Rails.root.join('config', 'initializers', 'devise.rb'))
778
+ user_model_has_devise = File.exist?(Rails.root.join('app', 'models', 'user.rb')) &&
779
+ File.read(Rails.root.join('app', 'models', 'user.rb')).include?('devise :')
780
+ routes_has_devise = File.exist?(Rails.root.join('config', 'routes.rb')) &&
781
+ File.read(Rails.root.join('config', 'routes.rb')).include?('devise_for :users')
782
+
783
+ puts " 📋 Devise file verification:"
784
+ puts " - Devise initializer: #{devise_initializer_exists ? '✅' : '❌'}"
785
+ puts " - User model has Devise: #{user_model_has_devise ? '✅' : '❌'}"
786
+ puts " - Routes have Devise: #{routes_has_devise ? '✅' : '❌'}"
787
+
788
+ if devise_initializer_exists && user_model_has_devise && routes_has_devise
789
+ puts "✅ Devise files properly configured"
790
+ puts "💡 Devise routes will be available after server restart"
791
+ else
792
+ puts "âš ī¸ Some Devise files may be missing or incomplete"
793
+ puts "💡 This is normal if Devise was just installed - restart your server to complete setup"
794
+ end
795
+ end
796
+
797
+ def precompile_assets
798
+ puts " 🔧 Precompiling CCCUX assets..."
799
+
695
800
  begin
696
- Rails.application.routes.url_helpers.new_user_session_path
697
- puts "✅ Devise routes working"
801
+ # Run assets:precompile task
802
+ Rake::Task['assets:precompile'].invoke
803
+ puts " ✅ Assets precompiled successfully"
804
+ rescue RuntimeError => e
805
+ if e.message.include?("Don't know how to build task 'assets:precompile'")
806
+ puts " âš ī¸ Assets precompile task not available (this is normal in some contexts)"
807
+ puts " â„šī¸ Assets will be compiled automatically when the server starts"
808
+ else
809
+ puts " ❌ Error precompiling assets: #{e.message}"
810
+ end
698
811
  rescue => e
699
- puts "❌ Devise routes not working: #{e.message}"
700
- exit 1
812
+ puts " ❌ Unexpected error during asset precompilation: #{e.message}"
701
813
  end
702
814
  end
703
815
  end
metadata CHANGED
@@ -1,34 +1,34 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cccux
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-07-08 00:00:00.000000000 Z
10
+ date: 2025-07-28 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
17
- - !ruby/object:Gem::Version
18
- version: '7.1'
19
16
  - - ">="
20
17
  - !ruby/object:Gem::Version
21
18
  version: 7.1.5.1
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '9.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - "~>"
27
- - !ruby/object:Gem::Version
28
- version: '7.1'
29
26
  - - ">="
30
27
  - !ruby/object:Gem::Version
31
28
  version: 7.1.5.1
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '9.0'
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: cancancan
34
34
  requirement: !ruby/object:Gem::Requirement
@@ -71,20 +71,6 @@ dependencies:
71
71
  - - "~>"
72
72
  - !ruby/object:Gem::Version
73
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
74
  description: CCCUX provides a comprehensive admin interface and user experience layer
89
75
  for CanCanCan authorization. It includes role-based access control (RBAC) models,
90
76
  admin controllers for managing users, roles, and permissions, and a clean interface
@@ -107,6 +93,7 @@ files:
107
93
  - app/controllers/cccux/cccux_controller.rb
108
94
  - app/controllers/cccux/dashboard_controller.rb
109
95
  - app/controllers/cccux/home_controller.rb
96
+ - app/controllers/cccux/role_abilities_controller.rb
110
97
  - app/controllers/cccux/roles_controller.rb
111
98
  - app/controllers/cccux/simple_controller.rb
112
99
  - app/controllers/cccux/users_controller.rb
@@ -118,6 +105,7 @@ files:
118
105
  - app/models/cccux/ability.rb
119
106
  - app/models/cccux/ability_permission.rb
120
107
  - app/models/cccux/application_record.rb
108
+ - app/models/cccux/post.rb
121
109
  - app/models/cccux/role.rb
122
110
  - app/models/cccux/role_ability.rb
123
111
  - app/models/cccux/user_role.rb