From da70a5f404fb1121e9ced2c8702b2c4ec3a2acbb Mon Sep 17 00:00:00 2001 From: Edimo Date: Thu, 7 May 2026 17:55:45 -0300 Subject: [PATCH 1/2] Fix UserDashboard id field type after UUID migration UserDashboard declared id: Field::Number, which calls Float() on the value. After the users.id migration to uuid in #223, visiting /admin raised "invalid value for Float(): \"\"" before any rows could render. Switching to Field::String (matching ApiRequestLogDashboard) lets Administrate render the UUID as plain text. Verified end-to-end: GET /admin and every dashboard introduced in #223 (/admin/users, /admin/api_request_logs, /admin/daily_overview, /admin/requests_dashboard, /admin/api_error_logs, /admin/user_analytics, /admin/user_lookup, /admin/request_logs_by_payload) return 200. Co-Authored-By: Claude Opus 4.7 (1M context) --- backend/app/dashboards/user_dashboard.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/dashboards/user_dashboard.rb b/backend/app/dashboards/user_dashboard.rb index 18355ac..60281dc 100644 --- a/backend/app/dashboards/user_dashboard.rb +++ b/backend/app/dashboards/user_dashboard.rb @@ -10,7 +10,7 @@ class UserDashboard < Administrate::BaseDashboard # which determines how the attribute is displayed # on pages throughout the dashboard. ATTRIBUTE_TYPES = { - id: Field::Number, + id: Field::String, admin: Field::Boolean, email: Field::String, password: Field::String, From 455543b3fa31e564e6599b4f4d58e99ce324a4ce Mon Sep 17 00:00:00 2001 From: Edimo Date: Thu, 7 May 2026 17:58:47 -0300 Subject: [PATCH 2/2] Redirect admins to /admin after sign in Override after_sign_in_path_for in ApplicationController so that a User with admin? lands on admin_root_path. Non-admin users continue to use Devise's default (stored_location_for or root_path via super). Verified manually: signing in as admin@email.com returns 303 to http://localhost:3002/admin. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../app/controllers/application_controller.rb | 6 ++++ backend/spec/requests/sessions_spec.rb | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 backend/spec/requests/sessions_spec.rb diff --git a/backend/app/controllers/application_controller.rb b/backend/app/controllers/application_controller.rb index dd8dd73..a3d1132 100644 --- a/backend/app/controllers/application_controller.rb +++ b/backend/app/controllers/application_controller.rb @@ -2,4 +2,10 @@ class ApplicationController < ActionController::Base before_action :set_paper_trail_whodunnit + + def after_sign_in_path_for(resource) + return admin_root_path if resource.is_a?(User) && resource.admin? + + super + end end diff --git a/backend/spec/requests/sessions_spec.rb b/backend/spec/requests/sessions_spec.rb new file mode 100644 index 0000000..01c9399 --- /dev/null +++ b/backend/spec/requests/sessions_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe "Sessions" do + describe "POST /users/sign_in" do + let(:password) { "password" } + + context "when the user is an admin" do + let(:user) { create(:user, admin: true, password: password) } + + before do + post user_session_path, params: { user: { email: user.email, password: password } } + end + + it { expect(response).to redirect_to(admin_root_path) } + end + + context "when the user is not an admin" do + let(:user) { create(:user, password: password) } + + before do + post user_session_path, params: { user: { email: user.email, password: password } } + end + + it { expect(response).not_to redirect_to(admin_root_path) } + end + end +end