-
Notifications
You must be signed in to change notification settings - Fork 14
update: more code additons, mainly admin stuff #93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
The preview deployment is ready. 🟢 Open Preview | Open Build Logs Last updated at: 2025-11-16 08:50:06 CET |
…, and user impersonation UI/UX Improvements: - Make JSON field monospace on shop item form - Redirect to shop items list after creating new item - Restore auto-calculation of ticket price based on USD cost - Consolidate all admin CSS into admin.scss - Add borders to .card and .table-data classes Warehouse Order Fixes (High Priority): - Fix quantity bug: treat agh_contents as per-unit spec, multiply by order quantity - Add per_unit_contents() and contents_for_order_qty() to WarehouseItem - Add warehouse_pick_lines() to ShopOrder for individual orders - Add combined_pick_lines_for_package() for batched orders - Create PackageBuilder service for batching warehouse orders Blazer Audit Log Protection: - Add database triggers to prevent UPDATE/DELETE on blazer_audits table - Create Blazer::Audit model with immutability callbacks - Remove updated_at column from blazer_audits (audits should never update) User Impersonation: - Add impersonate action for admins to view site as another user - Add stop_impersonating action with session validation - Display prominent red impersonation banner with animations - Log all impersonation starts/ends in PaperTrail audit log - Show impersonation events in user action history - Add helper methods: impersonating?, original_admin Admin Action History: - Display all actions performed on a user (flipper toggles, impersonation, etc.) - Show feature names in flipper events (fixed symbol/string key handling) - Link action history to full audit logs - Add link to admin names in audit log tables
…h audit logging - Add approve, reject, place_on_hold, release_from_hold actions to ShopOrdersController - Manual PaperTrail logging with whodunnit and state transitions - Compact horizontal grid layout for order details (Status, Created, User, Item, Qty/Cost) - Reject modal form with reason input - Vertical audit log showing who made changes, old/new status, rejection reasons - Exclude frozen_address from audit log for privacy - Add btn-danger CSS styling - Add faker gem for shop order seeding - Seed shop orders with 10-20 randomized orders in various states Amp-Thread-ID: https://ampcode.com/threads/T-fe30d0ef-c2a9-4428-b52e-c683f94c5ef0 Co-authored-by: Amp <[email protected]>
|
The preview deployment is ready. 🟢 Open Preview | Open Build Logs Last updated at: 2025-11-17 05:19:40 CET |
ad4abea to
bc5880f
Compare
…nto neon-admin-stuff
- Implemented region filtering for shop orders based on user roles. - Added mass reject orders feature in the UsersController. - Updated views to support new region selection and order rejection UI. - Added region column to users table with migration.
| case params[:sort] | ||
| when "id_asc" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Calling .order() on an Array after to_a.select converts an ActiveRecord relation to an Array.
Severity: CRITICAL | Confidence: High
🔍 Detailed Analysis
When params[:region] is present, the orders ActiveRecord relation is converted to a Ruby Array by to_a.select on lines 67-76. Subsequently, on lines 79-91, the code attempts to call the .order() method on this Array, which does not possess this method, leading to a NoMethodError and an application crash.
💡 Suggested Fix
Ensure orders remains an ActiveRecord relation before calling .order(). Apply sorting before converting to an Array or implement array-based sorting.
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app/controllers/admin/shop_orders_controller.rb#L79-L80
Potential issue: When `params[:region]` is present, the `orders` ActiveRecord relation
is converted to a Ruby `Array` by `to_a.select` on lines 67-76. Subsequently, on lines
79-91, the code attempts to call the `.order()` method on this `Array`, which does not
possess this method, leading to a `NoMethodError` and an application crash.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| <body class="<%= current_user.present? ? 'signed-in' : '' %>" | ||
| <% if current_user.present? %> | ||
| <%= render "shared/sidebar" %> | ||
| <% end %> | ||
| <main> | ||
| <%= render "shared/flash" %> | ||
| <%= yield %> | ||
| </main> | ||
| <%= yield %>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Syntax error: The closing <main> tag is missing. Line 43 has an extra > character at the end of <%= yield %>> and the <main> tag is opened on line 42 but never closed. This will break the HTML structure of all pages.
Severity: CRITICAL
💡 Suggested Fix
| <body class="<%= current_user.present? ? 'signed-in' : '' %>" | |
| <% if current_user.present? %> | |
| <%= render "shared/sidebar" %> | |
| <% end %> | |
| <main> | |
| <%= render "shared/flash" %> | |
| <%= yield %> | |
| </main> | |
| <%= yield %>> | |
| <body class="<%= current_user.present? ? 'signed-in' : '' %>"> | |
| <% if current_user.present? %> | |
| <%= render "shared/sidebar" %> | |
| <% end %> | |
| <main> | |
| <%= render "shared/flash" %> | |
| <%= yield %> | |
| </main> | |
| </body> |
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
|
|
||
| # Create the order | ||
| # This is a simplified version. In a real app, you'd want to: | ||
| # 1. Check stock | ||
| # 2. Check balance/charge user | ||
| # 3. Handle different item types | ||
|
|
||
| @order = current_user.shop_orders.new( | ||
| shop_item: @shop_item, | ||
| quantity: quantity, | ||
| # Assuming address is stored as json in user model now, but for order history we might want to snapshot it | ||
| # For now just getting it to save | ||
| ) | ||
|
|
||
| # Set initial state if using AASM | ||
| if @shop_item.is_a?(ShopItem::FreeStickers) | ||
| @order.aasm_state = "fulfilled" | ||
| @order.fulfilled_at = Time.current | ||
| elsif @order.respond_to?(:aasm_state=) | ||
| @order.aasm_state = "pending" | ||
| end | ||
|
|
||
| if @order.save | ||
| @order.mark_stickers_received if @shop_item.is_a?(ShopItem::FreeStickers) | ||
| redirect_to shop_my_orders_path, notice: "Order placed successfully!" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The create_order method does not set the frozen_address before saving, but ShopOrder has a check_regional_availability validation that depends on it. This will cause all non-FreeStickers orders to fail validation. The address should be set from current_user.address before validation runs.
Severity: HIGH
💡 Suggested Fix
| # Create the order | |
| # This is a simplified version. In a real app, you'd want to: | |
| # 1. Check stock | |
| # 2. Check balance/charge user | |
| # 3. Handle different item types | |
| @order = current_user.shop_orders.new( | |
| shop_item: @shop_item, | |
| quantity: quantity, | |
| # Assuming address is stored as json in user model now, but for order history we might want to snapshot it | |
| # For now just getting it to save | |
| ) | |
| # Set initial state if using AASM | |
| if @shop_item.is_a?(ShopItem::FreeStickers) | |
| @order.aasm_state = "fulfilled" | |
| @order.fulfilled_at = Time.current | |
| elsif @order.respond_to?(:aasm_state=) | |
| @order.aasm_state = "pending" | |
| end | |
| if @order.save | |
| @order.mark_stickers_received if @shop_item.is_a?(ShopItem::FreeStickers) | |
| redirect_to shop_my_orders_path, notice: "Order placed successfully!" | |
| @order = current_user.shop_orders.new( | |
| shop_item: @shop_item, | |
| quantity: quantity, | |
| frozen_address: current_user.address | |
| ) |
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| } | ||
|
|
||
| getPriceRange(range) { | ||
| if (range.includes("$0")) return [0, 100000]; | ||
| if (range.includes("$100,000 - $500,000")) return [100000, 500000]; | ||
| if (range.includes(">$500,000")) return [500000, Infinity]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The getPriceRange method is checking for string patterns like '$0' and '$100,000', but the shop now uses '🍪' (cookie emoji) as currency in the UI. The price range strings in the dropdown have been updated to use '🍪0 - 🍪1000' format, but this extraction logic hasn't been updated to match. The filtering will fail because the patterns won't match.
Severity: HIGH
💡 Suggested Fix
| } | |
| getPriceRange(range) { | |
| if (range.includes("$0")) return [0, 100000]; | |
| if (range.includes("$100,000 - $500,000")) return [100000, 500000]; | |
| if (range.includes(">$500,000")) return [500000, Infinity]; | |
| getPriceRange(range) { | |
| if (range.includes("🍪0")) return [0, 1000]; | |
| if (range.includes("🍪1000 - 🍪5000")) return [1000, 5000]; | |
| if (range.includes(">🍪5000")) return [5000, Infinity]; | |
| return [0, Infinity]; | |
| } |
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| const items = document.querySelectorAll(".shop-item-card"); | ||
| items.forEach((item) => { | ||
| if (category === "Grants") { | ||
| item.style.display = "flex"; | ||
| } else if (category === "Warehouse") { | ||
| item.style.display = "flex"; | ||
| } else if (category === "Third Party") { | ||
| item.style.display = "flex"; | ||
| } | ||
| }); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The filterByCategory method shows all items for any category selection (Grants, Warehouse, Third Party). This doesn't actually filter anything - all branches set item.style.display = 'flex'. This functionality needs to be implemented to filter items by their type based on the selected category.
Severity: MEDIUM
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app/javascript/controllers/dropdown_controller.js#L28-L38
Potential issue: The `filterByCategory` method shows all items for any category
selection (Grants, Warehouse, Third Party). This doesn't actually filter anything - all
branches set `item.style.display = 'flex'`. This functionality needs to be implemented
to filter items by their type based on the selected category.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| def address | ||
| { | ||
| name: display_name, | ||
| street1: "15 Falls Rd", | ||
| street2: nil, | ||
| city: "Shelburne", | ||
| state: "VT", | ||
| zip: "05482", | ||
| country: "US", | ||
| email: email |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The address method returns a hardcoded address in Vermont instead of using the user's actual address from the identity provider. This will cause all orders to be frozen with the same address. The address should either be stored in the User model during login, or retrieved from the User::Identity.
Severity: HIGH
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app/models/user.rb#L107-L116
Potential issue: The `address` method returns a hardcoded address in Vermont instead of
using the user's actual address from the identity provider. This will cause all orders
to be frozen with the same address. The address should either be stored in the User
model during login, or retrieved from the User::Identity.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| <div class="mb-3"> | ||
| <%= f.label :image, class: "form-label" %> | ||
| <%= f.file_field :image, class: "form-control" %> | ||
| <%= f.file_field :image, class: "form-control", required: !shop_item.persisted? %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The image field has required: !shop_item.persisted? which means it's required on create but not on update. However, the model validates :image, presence: true, on: :create. This is inconsistent - if updates also shouldn't require an image, the validation should allow null on update. If updates should allow skipping the image, consider what happens to orders if the image is removed.
Severity: MEDIUM
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app/views/admin/shop_items/_form.html.erb#L41
Potential issue: The image field has `required: !shop_item.persisted?` which means it's
required on create but not on update. However, the model validates `:image, presence:
true, on: :create`. This is inconsistent - if updates also shouldn't require an image,
the validation should allow null on update. If updates should allow skipping the image,
consider what happens to orders if the image is removed.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| # Apply region filter after stats calculation (converts to array) | ||
| if current_user.fulfillment_person? && !current_user.admin? && current_user.region.present? | ||
| orders = orders.to_a.select do |order| | ||
| if order.frozen_address.present? | ||
| order_region = Shop::Regionalizable.country_to_region(order.frozen_address["country"]) | ||
| order_region == current_user.region | ||
| else | ||
| false | ||
| end | ||
| end | ||
| elsif params[:region].present? | ||
| orders = orders.to_a.select do |order| | ||
| if order.frozen_address.present? | ||
| order_region = Shop::Regionalizable.country_to_region(order.frozen_address["country"]) | ||
| order_region == params[:region].upcase | ||
| else | ||
| false | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the index method, when a fulfillment person with a region is filtering orders, the code converts the entire orders query to an array with .to_a.select. This loads all orders into memory and then filters them client-side, which is very inefficient for large datasets. This should be done at the database level using a scope or SQL join.
Severity: HIGH
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app/controllers/admin/shop_orders_controller.rb#L57-L74
Potential issue: In the `index` method, when a fulfillment person with a region is
filtering orders, the code converts the entire orders query to an array with
`.to_a.select`. This loads all orders into memory and then filters them client-side,
which is very inefficient for large datasets. This should be done at the database level
using a scope or SQL join.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| authorize :admin, :access_fulfillment_view? | ||
| else | ||
| authorize :admin, :access_shop_orders? | ||
| end | ||
| @order = ShopOrder.find(params[:id]) | ||
| @can_view_address = @order.can_view_address?(current_user) | ||
|
|
||
| # Load user's order history for fraud dept |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The manual PaperTrail version creation in approve, reject, place_on_hold, release_from_hold, and mark_fulfilled methods duplicates logic that should be handled by PaperTrail automatically via has_paper_trail. The AASM state transitions should already be tracked. Consider removing these manual version creations and letting PaperTrail handle it, or add a consistent callback across all state changes.
Severity: MEDIUM
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app/controllers/admin/shop_orders_controller.rb#L112-L119
Potential issue: The manual PaperTrail version creation in `approve`, `reject`,
`place_on_hold`, `release_from_hold`, and `mark_fulfilled` methods duplicates logic that
should be handled by PaperTrail automatically via `has_paper_trail`. The AASM state
transitions should already be tracked. Consider removing these manual version creations
and letting PaperTrail handle it, or add a consistent callback across all state changes.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| <div class="<%= dropdown_classes %>" data-controller="dropdown"> | ||
| <div class="dropdown__label"><%= label %></div> | ||
| <button class="dropdown__button"> | ||
| <span class="dropdown__selected"> | ||
| <button class="dropdown__button" data-action="click->dropdown#toggle" data-dropdown-target="button"> | ||
| <span class="dropdown__selected" data-dropdown-target="selected"> | ||
| <%= selected_option %> | ||
| </span> | ||
| <%= helpers.inline_svg_tag "icons/chevron-down.svg", class: "dropdown__icon" %> | ||
| </button> | ||
| <ul class="dropdown__menu"> | ||
| <ul class="dropdown__menu" data-dropdown-target="menu"> | ||
| <% options.each do |option| %> | ||
| <li class="dropdown__item"><%= option %></li> | ||
| <li class="dropdown__item" data-action="click->dropdown#select"><%= option %></li> | ||
| <% end %> | ||
| </ul> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dropdown component doesn't provide a fallback action for the 'Region' dropdown. Looking at the controller, the Region filter doesn't trigger any JavaScript action, it relies on form submission. However, the Stimulus controller's select method only triggers actions for Category, Price Range, and Sort by. Region changes won't work without adding form submission logic or updating the controller.
Severity: MEDIUM
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app/components/dropdown_component.html.erb#L1-L14
Potential issue: The dropdown component doesn't provide a fallback action for the
'Region' dropdown. Looking at the controller, the Region filter doesn't trigger any
JavaScript action, it relies on form submission. However, the Stimulus controller's
`select` method only triggers actions for Category, Price Range, and Sort by. Region
changes won't work without adding form submission logic or updating the controller.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| <% unless current_user.fulfillment_person? %> | ||
| <div> | ||
| <%= f.label :region, "Region" %> | ||
| <%= f.select :region, options_for_select([ | ||
| ['All regions', ''], | ||
| ['United States', 'US'], | ||
| ['EU + UK', 'EU'], | ||
| ['India', 'IN'], | ||
| ['Canada', 'CA'], | ||
| ['Australia & NZ', 'AU'], | ||
| ['Rest of World', 'XX'] | ||
| ], params[:region]), {}, { class: "form-control" } %> | ||
| </div> | ||
| <% end %> | ||
| <% unless current_user.fulfillment_person? %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Region filter is only shown to non-fulfillment users, but fulfillment users actually need to see their region assignment. This creates confusion because fulfillment users can't manually change the region filter, even though their view is filtered by region. The UI/logic should be clarified - either show the filter and explain it's read-only, or provide a way to change their assigned region.
Severity: MEDIUM
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app/views/admin/shop_orders/_filters.html.erb#L16-L30
Potential issue: The Region filter is only shown to non-fulfillment users, but
fulfillment users actually need to see their region assignment. This creates confusion
because fulfillment users can't manually change the region filter, even though their
view is filtered by region. The UI/logic should be clarified - either show the filter
and explain it's read-only, or provide a way to change their assigned region.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| frozen_address | ||
| end | ||
|
|
||
| def warehouse_pick_lines | ||
| return [] unless shop_item.is_a?(ShopItem::WarehouseItem) | ||
| shop_item.contents_for_order_qty(quantity || 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The decrypted_address_for method creates a PaperTrail version entry for every address access, which could quickly bloat the versions table. This creates an audit log entry for every admin who views an address. Consider batching these or using a separate audit log table specifically for address accesses to avoid polluting the main versions table.
Severity: MEDIUM
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app/models/shop_order.rb#L93-L110
Potential issue: The `decrypted_address_for` method creates a PaperTrail version entry
for every address access, which could quickly bloat the versions table. This creates an
audit log entry for every admin who views an address. Consider batching these or using a
separate audit log table specifically for address accesses to avoid polluting the main
versions table.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| if order.save(validate: false) | ||
| # Randomly assign a state (skip AASM callbacks to avoid payout issues) | ||
| random_state = states.sample | ||
| state_name = random_state.to_s | ||
|
|
||
| ShopOrder.where(id: order.id).update_all(aasm_state: state_name) | ||
|
|
||
| # Set timestamp for fulfilled state | ||
| if random_state == :fulfilled | ||
| ShopOrder.where(id: order.id).update_all( | ||
| fulfilled_at: Time.current, | ||
| fulfilled_by: "SEED", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The seed script uses order.save(validate: false) to bypass validations, then directly updates the aasm_state without using AASM events. This creates orders that don't properly trigger callbacks or state transition logic. For testing purposes, either ensure validations pass naturally, or document why they're being bypassed.
Severity: MEDIUM
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: db/seeds/shop_orders.rb#L51-L62
Potential issue: The seed script uses `order.save(validate: false)` to bypass
validations, then directly updates the aasm_state without using AASM events. This
creates orders that don't properly trigger callbacks or state transition logic. For
testing purposes, either ensure validations pass naturally, or document why they're
being bypassed.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The impersonation banner CSS targets body:has(.impersonation-banner) main to adjust margin, but the application layout now has a broken HTML structure with the missing closing <main> tag. This selector won't work until that's fixed. Additionally, the selector assumes a main element exists as a sibling, which may not be reliable.
Severity: MEDIUM
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app/assets/stylesheets/components/_impersonation.scss#L93-L95
Potential issue: The impersonation banner CSS targets `body:has(.impersonation-banner)
main` to adjust margin, but the application layout now has a broken HTML structure with
the missing closing `<main>` tag. This selector won't work until that's fixed.
Additionally, the selector assumes a `main` element exists as a sibling, which may not
be reliable.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3348374
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 70 out of 73 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ) %> | ||
| <% @shop_items.each do |item| %> | ||
| <% if item.image.present? %> | ||
| <!-- DEBUG: item.type = <%= item.type %> --> |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential XSS vulnerability: HTML comment with dynamic content <!-- DEBUG: item.type = <%= item.type %> --> should be removed from production code. Debug comments can leak sensitive information and should not be present in views.
| </div> | ||
|
|
||
| <% unless @has_identity_linked %> | ||
| <%= form_tag "/auth/idv", method: :post, data: {turbo: false} do %> |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing Turbo configuration. The form at line 39 has data: {turbo: false} but Turbo is part of the Hotwire stack. This attribute should be data: { turbo: "false" } (string value) to properly disable Turbo for this form.
| return redirect_to(root_path, alert: "Authentication failed") if identity_data.blank? | ||
|
|
||
| user_email, display_name, verification_status, slack_id, uid = extract_identity_fields(identity_data) | ||
| user_email, display_name, verification_status, slack_id, uid, = extract_identity_fields(identity_data) |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing comma in parameter list. Line 17 has a trailing comma after the uid variable assignment which will cause a syntax error or unexpected behavior. The comma should be removed.
| user_email, display_name, verification_status, slack_id, uid, = extract_identity_fields(identity_data) | |
| user_email, display_name, verification_status, slack_id, uid, _address = extract_identity_fields(identity_data) |
| <body class="<%= current_user.present? ? 'signed-in' : '' %>" | ||
| <% if current_user.present? %> | ||
| <%= render "shared/sidebar" %> | ||
| <% end %> | ||
| <main> | ||
| <%= render "shared/flash" %> | ||
| <%= yield %> | ||
| </main> | ||
| <%= yield %>> |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Syntax error: Missing closing tag for <body>. Line 39 has an incomplete opening tag <body class="<%= current_user.present? ? 'signed-in' : '' %>" without a closing >. Additionally, line 44 has an extra > after <%= yield %> creating <%= yield %>> which will render as text.
| add_index :blazer_audits, :created_at if index_exists?(:blazer_audits, :created_at) | ||
| end |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Migration rollback issue: In the down method, add_index is called when it should be remove_index. The condition also appears incorrect - it should remove the index if it exists, not add it.
| color: var(--color-bg); | ||
| padding: 1em 2em; | ||
| font-size: 1.5rem; | ||
| font-family: var(--font-family-text); |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spelling error in comment: "fanily" should be "family" in the font-family property comment.
No description provided.