-
Notifications
You must be signed in to change notification settings - Fork 0
Correctly handle partially-claimed users #380
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
Conversation
Added multi-select functionality for claiming tickets, including state management for selected tickets and bulk success messages.
WalkthroughAdds multi-ticket bulk-claim selection and processing to the ScanTickets UI (fetch/partition purchases, single-auto-claim, modal multi-select, batch claim). Separately renames and replaces Slow Lambda references with HiCpu Lambda across Terraform envs, module variables, outputs, and resources, and increases HiCpu lambda memory. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI as ScanTickets UI
participant Logic as Decision Logic
participant Helper as processTicketCheckIn
participant State as UI State
User->>UI: Scan ticket/merch
UI->>Logic: Fetch all purchases for item (all statuses)
alt No purchases found
Logic->>State: Show "no purchases" error
else Purchases found
Logic->>Logic: Partition into claimable & unclaimable
alt No claimable tickets
Logic->>State: Show contextual error (fulfilled/refunded/invalid)
else Exactly one claimable & no unclaimable
Logic->>Helper: processTicketCheckIn(single)
Helper-->>Logic: Structured result
Logic->>State: Show single success
else Multiple claimable or mixed
Logic->>State: Show multi-select modal (claimable + unclaimable lists)
User->>UI: Select ticket(s)
UI->>Logic: handleClaimSelectedTickets
loop For each selected ticket
Logic->>Helper: processTicketCheckIn(selected)
Helper-->>Logic: Structured result
end
Logic->>State: Aggregate results, show bulk success or first error
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (1 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Comment |
💰 Infracost reportMonthly estimate increased by $5 📈
*Usage costs were estimated using infracost-usage.yml, see docs for other options. Estimate details |
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.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/ui/pages/tickets/ScanTickets.page.tsx (2)
657-689: Add explicit return type for better type safety.The extracted helper is excellent refactoring that enables reuse in batch operations. However, the return type is implicit.
Add an explicit return type:
+type CheckInResult = + | { success: true; result: APIResponseSchema } + | { success: false; error: string; ticketId: string }; + -const processTicketCheckIn = async (ticket: APIResponseSchema) => { +const processTicketCheckIn = async (ticket: APIResponseSchema): Promise<CheckInResult> => {
1000-1002: Replace deprecatedsxprop withstyle.The
sxprop was deprecated in Mantine v7+. With Mantine 8.3.6, you should use thestyleprop instead.Apply this diff to update the claimable ticket styling:
-sx={(theme) => ({ - borderLeft: `5px solid ${theme.colors.green[6]}`, -})} +style={{ + borderLeft: '5px solid var(--mantine-color-green-6)', +}}And for unclaimable tickets:
-sx={(theme) => ({ - borderLeft: `5px solid ${theme.colors[color][6]}`, -})} +style={{ + borderLeft: `5px solid var(--mantine-color-${color}-6)`, +}}Also applies to: 1064-1066
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (1)
src/ui/pages/tickets/ScanTickets.page.tsx(9 hunks)
🧰 Additional context used
🪛 ESLint
src/ui/pages/tickets/ScanTickets.page.tsx
[error] 583-585: Replace ⏎··········"No·purchases·found·for·this·user·and·selected·event/item.",⏎········ with "No·purchases·found·for·this·user·and·selected·event/item."
(prettier/prettier)
[error] 757-758: Replace ⏎··········firstFailure.value·as·{·success:·false;·error:·string·} with firstFailure.value·as·{·success:·false;·error:·string·})
(prettier/prettier)
[error] 759-759: Replace ) with ··
(prettier/prettier)
[error] 945-947: Replace ⏎························Product:·{scanResult.purchaserData.productId}⏎······················ with Product:·{scanResult.purchaserData.productId}
(prettier/prettier)
[error] 954-956: Replace ⏎························Quantity:·{scanResult.purchaserData.quantity}⏎······················ with Quantity:·{scanResult.purchaserData.quantity}
(prettier/prettier)
🪛 GitHub Actions: Required Reviews
src/ui/pages/tickets/ScanTickets.page.tsx
[error] 1-1: Requirement "Base Requirement" is not satisfied by the existing reviews.
🪛 GitHub Check: Run Unit Tests
src/ui/pages/tickets/ScanTickets.page.tsx
[failure] 583-583:
Replace ⏎··········"No·purchases·found·for·this·user·and·selected·event/item.",⏎········ with "No·purchases·found·for·this·user·and·selected·event/item."
[failure] 759-759:
Replace ) with ··
[failure] 757-757:
Replace ⏎··········firstFailure.value·as·{·success:·false;·error:·string·} with firstFailure.value·as·{·success:·false;·error:·string·})
[failure] 954-954:
Replace ⏎························Quantity:·{scanResult.purchaserData.quantity}⏎······················ with Quantity:·{scanResult.purchaserData.quantity}
[failure] 945-945:
Replace ⏎························Product:·{scanResult.purchaserData.productId}⏎······················ with Product:·{scanResult.purchaserData.productId}
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build Application
🔇 Additional comments (6)
src/ui/pages/tickets/ScanTickets.page.tsx (6)
14-15: LGTM! Imports support multi-select functionality.The new imports for
CheckboxandMantineColorare appropriate for the multi-ticket selection feature.
130-139: LGTM! State structure is well-designed.The new state variables appropriately support multi-ticket selection. Using
Set<string>forselectedTicketsToClaimis an efficient choice for tracking selections.
569-637: Excellent refactoring of purchase handling logic.The three-case branching is clear and handles all scenarios appropriately:
- Auto-claims when there's exactly one valid ticket with no context to show
- Shows selection modal for multiple or mixed tickets
- Provides contextual error messages based on the unclaimable reason
The partitioning logic correctly identifies claimable tickets as those that are valid, not refunded, and not fulfilled.
691-714: LGTM! Single-ticket claiming logic is clean.The function properly uses the extracted helper, handles both success and error cases, and thoroughly cleans up selection state.
895-970: LGTM! Modal logic cleanly handles all result types.The three-branch modal structure (error, bulk success, single result) is clear and provides appropriate UI for each scenario.
972-1119: LGTM! Multi-select modal is well-implemented.The ticket selection modal provides excellent UX:
- Clear visual distinction between claimable (green border) and unclaimable tickets
- Checkboxes for selection with proper state management
- Appropriate loading guards to prevent premature modal closure
- Helpful status indicators and disabled states
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.
Actionable comments posted: 0
♻️ Duplicate comments (3)
src/ui/pages/tickets/ScanTickets.page.tsx (3)
717-774: LGTM! Robust batch processing with proper error handling.Excellent use of
Promise.allSettledto process all selected tickets in parallel without short-circuiting on first failure. The error aggregation (showing first error + count) prevents overwhelming the user while still providing actionable information.However, there are Prettier formatting violations at lines 758-760 that need to be fixed.
Run Prettier to fix:
#!/bin/bash npx prettier --write src/ui/pages/tickets/ScanTickets.page.tsx
896-971: LGTM! Modal properly handles three distinct result states.The conditional rendering correctly branches between error, bulk success, and single scan result views. State management ensures only one state is active at a time.
However, there are Prettier formatting violations at lines 946-948 and 955-957 that need to be fixed.
Run Prettier to fix:
#!/bin/bash npx prettier --write src/ui/pages/tickets/ScanTickets.page.tsx
584-586: Fix Prettier formatting violation.This formatting issue has been flagged by the linter and previous reviewer.
Run Prettier to fix:
#!/bin/bash npx prettier --write src/ui/pages/tickets/ScanTickets.page.tsx
🧹 Nitpick comments (1)
src/ui/pages/tickets/ScanTickets.page.tsx (1)
658-690: LGTM! Excellent extraction of reusable logic.This helper function properly separates concerns by handling the API call without side effects, returning a structured result. This enables clean reuse in both single-ticket and batch-claim flows.
Minor suggestion: Consider adding an explicit return type annotation for better type safety:
const processTicketCheckIn = async ( ticket: APIResponseSchema ): Promise< | { success: true; result: APIResponseSchema } | { success: false; error: string; ticketId: string } > => {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (1)
src/ui/pages/tickets/ScanTickets.page.tsx(9 hunks)
🧰 Additional context used
🪛 ESLint
src/ui/pages/tickets/ScanTickets.page.tsx
[error] 584-586: Replace ⏎··········"No·purchases·found·for·this·user·and·selected·event/item.",⏎········ with "No·purchases·found·for·this·user·and·selected·event/item."
(prettier/prettier)
[error] 758-759: Replace ⏎··········firstFailure.value·as·{·success:·false;·error:·string·} with firstFailure.value·as·{·success:·false;·error:·string·})
(prettier/prettier)
[error] 760-760: Replace ) with ··
(prettier/prettier)
[error] 946-948: Replace ⏎························Product:·{scanResult.purchaserData.productId}⏎······················ with Product:·{scanResult.purchaserData.productId}
(prettier/prettier)
[error] 955-957: Replace ⏎························Quantity:·{scanResult.purchaserData.quantity}⏎······················ with Quantity:·{scanResult.purchaserData.quantity}
(prettier/prettier)
🪛 GitHub Actions: Required Reviews
src/ui/pages/tickets/ScanTickets.page.tsx
[error] 1-1: Requirement "Base Requirement" is not satisfied by the existing reviews.
🪛 GitHub Check: Run Unit Tests
src/ui/pages/tickets/ScanTickets.page.tsx
[failure] 584-584:
Replace ⏎··········"No·purchases·found·for·this·user·and·selected·event/item.",⏎········ with "No·purchases·found·for·this·user·and·selected·event/item."
[failure] 760-760:
Replace ) with ··
[failure] 758-758:
Replace ⏎··········firstFailure.value·as·{·success:·false;·error:·string·} with firstFailure.value·as·{·success:·false;·error:·string·})
[failure] 955-955:
Replace ⏎························Quantity:·{scanResult.purchaserData.quantity}⏎······················ with Quantity:·{scanResult.purchaserData.quantity}
[failure] 946-946:
Replace ⏎························Product:·{scanResult.purchaserData.productId}⏎······················ with Product:·{scanResult.purchaserData.productId}
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build Application
🔇 Additional comments (6)
src/ui/pages/tickets/ScanTickets.page.tsx (6)
14-16: LGTM! Necessary imports for multi-select functionality.The new imports support the multi-ticket selection feature:
Checkboxfor UI,MantineColorfor dynamic status colors, andMantineThemefor the style prop functions.
131-140: LGTM! Well-designed state for multi-select flow.Using
Set<string>forselectedTicketsToClaimprovides efficient O(1) lookups. The separation of claimable and unclaimable tickets enables showing full context to users about their purchase history.
524-525: LGTM! Proper state cleanup between scans.Resetting bulk message and selection state prevents stale data from affecting subsequent operations.
570-638: LGTM! Excellent refactoring for partially-claimed users.The three-path flow correctly handles the edge cases:
- No claimable tickets: Provides contextual error based on the reason (fulfilled/refunded/invalid)
- Single claimable, no unclaimable: Auto-claims without user intervention
- Multiple or mixed: Shows selection modal with full context
This properly addresses the PR objective of handling partially-claimed users by showing unclaimable tickets for context.
692-715: LGTM! Proper state management for single-ticket claiming.The function correctly:
- Guards against concurrent operations with
isLoading- Closes the selection modal before processing to prevent double-claiming
- Clears all selection state regardless of outcome
- Shows appropriate success or error modal
973-1123: LGTM! Comprehensive multi-select UI with proper accessibility.The modal implementation is robust:
- ✅ Checkbox-based multi-select with proper
aria-label- ✅ Visual distinction between claimable (green) and unclaimable (orange/red) tickets
- ✅ Loading states prevent concurrent operations
- ✅ All state properly cleared on cancel/close
- ✅ Style prop pattern
style={(theme: MantineTheme) => ({ ... })}is correct for Mantine v8The live count in "Claim Selected (N)" button provides good UX feedback.
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.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/ui/pages/tickets/ScanTickets.page.tsx (2)
656-688: Consider explicit return type annotation.The extracted helper function is well-structured and reusable. However, the return type is inferred rather than explicitly declared, which reduces type safety and documentation clarity.
Add an explicit return type:
+type CheckInResult = + | { success: true; result: APIResponseSchema } + | { success: false; error: string; ticketId: string }; + -const processTicketCheckIn = async (ticket: APIResponseSchema) => { +const processTicketCheckIn = async (ticket: APIResponseSchema): Promise<CheckInResult> => {
690-713: Consider extracting repeated state cleanup logic.The function correctly processes a single ticket, but the state clearing logic (lines 709-711) is duplicated in multiple places throughout the file (e.g., lines 741-743, 971-973, 1099-1101).
Extract the cleanup into a helper function:
const clearSelectionState = () => { setAvailableTickets([]); setUnclaimableTicketsForSelection([]); setSelectedTicketsToClaim(new Set()); };Then replace all instances with
clearSelectionState().
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (1)
src/ui/pages/tickets/ScanTickets.page.tsx(8 hunks)
🧰 Additional context used
🪛 GitHub Actions: Required Reviews
src/ui/pages/tickets/ScanTickets.page.tsx
[error] 1-1: Requirement "Base Requirement" is not satisfied by the existing reviews.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build Application
- GitHub Check: Run Unit Tests
🔇 Additional comments (6)
src/ui/pages/tickets/ScanTickets.page.tsx (6)
14-16: Verify Mantine version compatibility.The comment mentions "v5 style prop" but the library context shows Mantine version 8.3.6 is in use. Mantine v7+ removed support for function-style
styleprops in favor of direct object styles or thestylesAPI. This will be critical when reviewing the style prop usage later in the file (lines 995-997, 1059-1063).
131-140: LGTM!The new state variables are well-typed and appropriately initialized. Using a
Set<string>forselectedTicketsToClaimis an efficient choice for membership checks during selection operations.
524-525: LGTM!Proper state cleanup ensures the UI starts fresh for the next scan operation.
570-636: Well-structured refactor with good UX considerations.The partitioning logic correctly separates claimable from unclaimable tickets. The three-path branching is particularly well thought out:
- The auto-claim at line 626 only triggers when there's exactly one claimable ticket and no unclaimable tickets to display, ensuring users get full context when there are mixed purchase states.
The complementary filter conditions (lines 592-599) ensure complete coverage without overlap.
715-771: Batch processing logic is sound with good error resilience.The use of
Promise.allSettledensures all claims are attempted regardless of individual failures. The error handling shows the first failure with a count (line 760), which is reasonable for UX, though users won't see details of all failed tickets in mixed-result scenarios.
979-981: Good accessibility and loading state management.The modal properly disables interactions during loading operations (lines 979-981), and the checkbox includes an appropriate
aria-labelfor screen readers (line 1011).Also applies to: 1011-1011
This increase in memory will also increase CPU
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.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (1)
src/ui/pages/tickets/ScanTickets.page.tsx(13 hunks)
🧰 Additional context used
🪛 GitHub Actions: Required Reviews
src/ui/pages/tickets/ScanTickets.page.tsx
[error] 1-1: Requirement "Base Requirement" is not satisfied by the existing reviews.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build Application
- GitHub Check: Run Unit Tests
🔇 Additional comments (5)
src/ui/pages/tickets/ScanTickets.page.tsx (5)
591-657: Refactored purchase logic handles partial claims correctly.The three-path logic properly handles scenarios where users have a mix of claimable and unclaimable tickets. The partitioning criteria (valid, not refunded, not fulfilled) is appropriate, and the auto-claim optimization for single tickets is a good UX enhancement.
677-709: Well-designed helper function.Extracting the check-in logic into a pure function that returns structured results (rather than mutating state) is excellent for reusability in both single and batch operations. Including
ticketIdin error cases aids debugging.
711-734: Single ticket claiming logic is correct.The function properly uses the extracted helper, manages loading state, and ensures selection state is cleared regardless of outcome to prevent stale data.
736-790: Bulk claiming implementation is solid.Using
Promise.allSettledcorrectly handles partial failures, and the error reporting strategy (first error + count) provides actionable feedback without overwhelming the user. State cleanup is thorough.
912-1014: Modal result display properly handles all scenarios.The three-way conditional (error, bulk success, single success) is clear and provides appropriate feedback for each case. Using
getFriendlyNameimproves readability.
| style={(theme: MantineTheme) => ({ | ||
| borderLeft: `5px solid ${theme.colors.green[6]}`, | ||
| cursor: "pointer", | ||
| "&:hover": { | ||
| backgroundColor: theme.colors.gray[0], | ||
| }, | ||
| })} |
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.
Critical: Function-style style prop incompatible with Mantine v8.
This code uses style={(theme: MantineTheme) => ({...})} which was removed in Mantine v7+ and is incompatible with Mantine 8.3.6. Additionally, the &:hover pseudo-selector at lines 1057-1059 will not work in inline styles.
This issue was previously flagged and marked as addressed in commit cee28e0, but it remains in the current code.
Solution: Use CSS variables for theme colors and remove the pseudo-selector:
-style={(theme: MantineTheme) => ({
- borderLeft: `5px solid ${theme.colors.green[6]}`,
+style={{
+ borderLeft: '5px solid var(--mantine-color-green-6)',
cursor: "pointer",
- "&:hover": {
- backgroundColor: theme.colors.gray[0],
- },
-})}
+}}For hover effects, use Mantine's styles API or add a class name with proper CSS:
import { Paper } from '@mantine/core';
import classes from './ScanTickets.module.css';
<Paper
className={classes.selectableTicket}
// ... other props
>Then in ScanTickets.module.css:
.selectableTicket {
border-left: 5px solid var(--mantine-color-green-6);
cursor: pointer;
}
.selectableTicket:hover {
background-color: var(--mantine-color-gray-0);
}🤖 Prompt for AI Agents
In src/ui/pages/tickets/ScanTickets.page.tsx around lines 1054 to 1060 the
component uses a function-style style prop (style={(theme: MantineTheme) =>
({...})}) and an inline "&:hover" pseudo-selector which are incompatible with
Mantine v7+ / 8.3.6; replace this by removing the function-style style prop and
instead apply a CSS class (or Mantine styles API) that uses Mantine CSS
variables for colors (e.g. var(--mantine-color-green-6),
var(--mantine-color-gray-0)), import the CSS module (or define styles via
Mantine's styles API) and set className on the component to implement
border-left and cursor rules, and put the hover rule in the CSS file (or in
styles API) so the hover background works correctly.
| <Checkbox | ||
| checked={selectedTicketsToClaim.has(ticket.ticketId)} | ||
| readOnly | ||
| tabIndex={-1} // Removed from tab order, card is the control | ||
| aria-label={`Select ticket ${ticket.ticketId}`} | ||
| /> |
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.
Accessibility concern with checkbox interaction pattern.
The checkbox is marked readOnly with tabIndex={-1}, relying entirely on the parent Paper's onClick for interaction. This pattern may be problematic for keyboard and screen reader users who cannot activate the checkbox directly.
Consider these improvements:
- Add proper ARIA attributes to the Paper to indicate its role:
<Paper
+ role="checkbox"
+ aria-checked={selectedTicketsToClaim.has(ticket.ticketId)}
+ tabIndex={0}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ // Toggle selection logic here
+ }
+ }}
onClick={() => {
// existing logic
}}- Or, make the Checkbox interactive and handle its change event separately:
-<Checkbox
- checked={selectedTicketsToClaim.has(ticket.ticketId)}
- readOnly
- tabIndex={-1}
- aria-label={`Select ticket ${ticket.ticketId}`}
-/>
+<Checkbox
+ checked={selectedTicketsToClaim.has(ticket.ticketId)}
+ onChange={() => {
+ const newSet = new Set(selectedTicketsToClaim);
+ if (newSet.has(ticket.ticketId)) {
+ newSet.delete(ticket.ticketId);
+ } else {
+ newSet.add(ticket.ticketId);
+ }
+ setSelectedTicketsToClaim(newSet);
+ }}
+ aria-label={`Select ticket ${ticket.ticketId}`}
+/>Then adjust the Paper's onClick to avoid duplicate toggles:
onClick={(e) => {
+ // Don't toggle if clicking the checkbox itself
+ if ((e.target as HTMLElement).closest('input[type="checkbox"]')) {
+ return;
+ }
// existing toggle logic
}}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Checkbox | |
| checked={selectedTicketsToClaim.has(ticket.ticketId)} | |
| readOnly | |
| tabIndex={-1} // Removed from tab order, card is the control | |
| aria-label={`Select ticket ${ticket.ticketId}`} | |
| /> | |
| <Checkbox | |
| checked={selectedTicketsToClaim.has(ticket.ticketId)} | |
| onChange={() => { | |
| const newSet = new Set(selectedTicketsToClaim); | |
| if (newSet.has(ticket.ticketId)) { | |
| newSet.delete(ticket.ticketId); | |
| } else { | |
| newSet.add(ticket.ticketId); | |
| } | |
| setSelectedTicketsToClaim(newSet); | |
| }} | |
| aria-label={`Select ticket ${ticket.ticketId}`} | |
| /> |
🤖 Prompt for AI Agents
In src/ui/pages/tickets/ScanTickets.page.tsx around lines 1063 to 1068, the
Checkbox is set readOnly and removed from tab order while the parent Paper
handles clicks, which breaks keyboard and screen-reader interaction; either make
the Checkbox fully interactive (remove readOnly and tabIndex, add an onChange
handler that toggles selection, keep Paper onClick but guard it from
double-toggling) or keep the Checkbox non-focusable but give the Paper proper
accessible semantics (role="checkbox", aria-checked reflecting selection state,
keyboard handlers for Enter/Space that toggle selection, and appropriate
aria-label/aria-labelledby) so keyboard and assistive tech can activate the
control. Ensure only one activation path toggles the ticket and update
tests/handlers accordingly.
| style={(theme: MantineTheme) => ({ | ||
| cursor: "not-allowed", | ||
| opacity: 0.6, | ||
| borderLeft: `5px solid ${theme.colors[color][6]}`, | ||
| })} |
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.
Critical: Function-style style prop incompatible with Mantine v8.
Same issue as lines 1054-1060. The function-style style prop does not work with Mantine v8.
Apply this fix:
-style={(theme: MantineTheme) => ({
+style={{
cursor: "not-allowed",
opacity: 0.6,
- borderLeft: `5px solid ${theme.colors[color][6]}`,
-})}
+ borderLeft: `5px solid var(--mantine-color-${color}-6)`,
+}}🤖 Prompt for AI Agents
In src/ui/pages/tickets/ScanTickets.page.tsx around lines 1113 to 1117, the
function-style style prop is incompatible with Mantine v8; replace it with the
sx prop (sx={(theme: MantineTheme) => ({ cursor: "not-allowed", opacity: 0.6,
borderLeft: `5px solid ${theme.colors[color][6]}`, })}) or with a plain style
object if theme access is not needed so the styling works under Mantine v8.
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.
Actionable comments posted: 1
🧹 Nitpick comments (2)
terraform/modules/frontend/main.tf (1)
2-2: Implicit region dependency:all_regionsnow derived fromCoreHiCpuLambdaHostonly.Previously derived from
CoreSlowLambdaHost, theall_regionslocal is now sourced fromCoreHiCpuLambdaHostkeys. This is used for S3 bucket provisioning and other region-specific resources (lines 9, 14, 56, 385).While both
CoreLambdaHostandCoreHiCpuLambdaHostcurrently have the same regions (us-east-2, us-west-2), this creates a tight coupling without explicit documentation. If regions ever diverge, S3 buckets and resources would only be created for HiCpu Lambda regions, not all lambda regions.Consider either:
- Deriving
all_regionsfrom the union of both lambda host keys, or- Adding a dedicated
Regionsvariable to make the dependency explicit.terraform/modules/lambdas/main.tf (1)
406-434: HiCpu Lambda resource and warmer module are well-justified and correctly implemented.The hicpu_lambda resource is a high-memory variant (4096 MB) of the standard api_lambda (2048 MB), provisioned to bypass latency alarms during monitoring. The comment at line 417 clearly explains the intent (2 full vCPU cores for cryptographic operations). Naming follows existing conventions, and the lambda_warmer_hicpu module ensures the function stays warm.
Minor observation: Code is duplicated between
api_lambda(lines 347–370) andhicpu_lambda(lines 406–434). Both use identical source, handler, timeout, and environment variables. If future code changes are anticipated, consider centralizing common configuration (e.g., via data sources or local variables) to reduce maintenance burden.Also applies to: 450-455
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (5)
terraform/envs/prod/main.tf(2 hunks)terraform/envs/qa/main.tf(2 hunks)terraform/modules/frontend/main.tf(4 hunks)terraform/modules/frontend/variables.tf(1 hunks)terraform/modules/lambdas/main.tf(5 hunks)
🧰 Additional context used
🪛 Checkov (3.2.334)
terraform/modules/lambdas/main.tf
[medium] 436-441: Ensure that Lambda function URLs AuthType is not None
(CKV_AWS_258)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run Unit Tests
- GitHub Check: Build Application
🔇 Additional comments (6)
terraform/envs/prod/main.tf (2)
74-74: Straightforward lambda name refactor.The change from
core_api_slow_lambda_nametocore_api_hicpu_lambda_namealigns with the broader renaming across the module and environments. Consistent withterraform/modules/lambdas/main.tfoutputs.
117-120: Variable rename and URL mapping updates are consistent across environments.The
CoreHiCpuLambdaHostvariable and correspondingcore_hicpu_function_urlmappings align with the module-level outputs. Consistent withterraform/envs/qa/main.tf(lines 120–123) and the frontend module input variable definition.terraform/modules/frontend/main.tf (1)
182-195: HiCpu Lambda origins and cache behaviors correctly configured.The new dynamic origin block (lines 182–195) follows the same pattern as the existing
CoreLambdaHostorigins. Cache behaviors for/api/v1/syncIdentity(line 224) and/api/v1/users/findUserByUin(line 238) now correctly targetHiCpuLambdaFunction-${var.CurrentActiveRegion}, routing these endpoints to the higher-memory lambda variant. Naming and region references are consistent.Also applies to: 224-224, 238-238
terraform/modules/frontend/variables.tf (1)
11-14: Breaking change:CoreSlowLambdaHostvariable removed and replaced withCoreHiCpuLambdaHost.This is a hard break for module consumers. Any Terraform code passing
CoreSlowLambdaHostto the frontend module will fail until updated to useCoreHiCpuLambdaHost. Consider adding a migration guide or deprecation notice in release notes.The variable definition itself is correct; type and description align with
CoreLambdaHostabove.Confirm that all internal consumers of this module (e.g.,
terraform/envs/prod/main.tf,terraform/envs/qa/main.tf) have been updated to useCoreHiCpuLambdaHost.terraform/envs/qa/main.tf (1)
76-76: QA environment changes mirror production, ensuring consistency across deployments.Line 76 aligns with prod/main.tf, and lines 120–123 correctly map
CoreHiCpuLambdaHosttocore_hicpu_function_urlfor both us-east-2 and us-west-2 regions. No regional or naming inconsistencies detected.Also applies to: 120-123
terraform/modules/lambdas/main.tf (1)
526-527: HiCpu Lambda outputs correctly export function URL and lambda name.The
core_hicpu_function_urloutput (lines 526–527) properly extracts and processes the function URL fromhicpu_api_lambda_function_url, andcore_api_hicpu_lambda_name(lines 534–536) exports the local name. Both are consumed by the frontend module (prod/main.tf lines 118–119, qa/main.tf lines 121–122) with correct references.Also applies to: 534-536
| resource "aws_lambda_function_url" "hicpu_api_lambda_function_url" { | ||
| region = var.region | ||
| function_name = aws_lambda_function.slow_lambda.function_name | ||
| function_name = aws_lambda_function.hicpu_lambda.function_name | ||
| authorization_type = "NONE" | ||
| invoke_mode = "RESPONSE_STREAM" | ||
| } |
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.
🧩 Analysis chain
The hicpu_api_lambda_function_url resource has authorization_type = "NONE", enabling unauthenticated public invocation. This security posture matches the existing api_lambda_function_url (line 399-404), but represents a risk vector:
- Unauthenticated users can invoke the Lambda without AWS credentials.
- Exposure depends on whether application-level authentication is sufficient.
- DDoS risk if rate-limiting relies solely on Lambda concurrency limits.
Recommended actions:
- If this endpoint must be public, ensure rate-limiting, input validation, and monitoring are robust at the application level.
- If this is a mistake, set
authorization_type = "AWS_IAM"to require AWS credentials. - Alternatively, remove the function URL and route traffic through API Gateway or ALB for centralized authentication and rate-limiting.
Note: This issue exists in the existing api_lambda_function_url as well; consider addressing both in a security review.
Verify that this public access is intentional and documented in the application's threat model or architecture review. If not intentional, apply authorization_type = "AWS_IAM" to both function URLs.
I need to verify the review comment by examining the codebase and confirming the security concerns. Let me gather the necessary information.
[/run_scripts]
[/web_search]
🏁 Script executed:
#!/bin/bash
# Find and display the relevant sections from terraform/modules/lambdas/main.tf
if [ -f "terraform/modules/lambdas/main.tf" ]; then
echo "=== Lines 436-441 (hicpu_api_lambda_function_url) ==="
sed -n '436,441p' terraform/modules/lambdas/main.tf
echo ""
echo "=== Lines 399-404 (api_lambda_function_url) ==="
sed -n '399,404p' terraform/modules/lambdas/main.tf
echo ""
echo "=== Search for all aws_lambda_function_url resources ==="
rg -n "resource\s+\"aws_lambda_function_url\"" terraform/modules/lambdas/main.tf -A 6
else
echo "File not found: terraform/modules/lambdas/main.tf"
fiLength of output: 1189
🌐 Web query:
Checkov CKV_AWS_258 Lambda function URL authorization
💡 Result:
Summary: CKV_AWS_258 ensures Lambda Function URLs do NOT use AuthType = "NONE" (i.e., require AWS_IAM). Remediation: set AuthType = "AWS_IAM" (CloudFormation/SAM/CLI/Terraform) or remove public resource-based policy.
Examples:
-
CloudFormation / SAM:
- AuthType: AWS_IAM on AWS::Lambda::Url. [example]. [2]
-
Terraform (aws_lambda_function_url):
- auth_type = "AWS_IAM".
Why: AuthType NONE allows unauthenticated public invocation unless you explicitly lock the resource policy; using AWS_IAM enforces IAM-based invocation permission (lambda:InvokeFunctionUrl / lambda:InvokeFunction). [2]
Sources:
- Checkov policy index: CKV_AWS_258 — "Ensure that Lambda function URLs AuthType is not None." [1]
- AWS Lambda function URLs (AuthType, permissions, examples). [2]
References:
[1] https://www.checkov.io (Policy index entry for CKV_AWS_258).
[2] https://docs.aws.amazon.com/lambda/latest/dg/urls-auth.html and https://docs.aws.amazon.com/lambda/latest/dg/urls-configuration.html.
Verification confirms the review comment is accurate and identifies a documented security vulnerability.
All findings verified:
- Authorization_type = "NONE" is flagged by CKV_AWS_258, a Checkov rule that ensures Lambda function URLs do not use unauthenticated access
- Both Lambda function URLs in the file have
authorization_type = "NONE"at lines 399-404 and 436-441 - The remediation is to set authorization_type = "AWS_IAM"
The review comment is comprehensive and the security concern is legitimate. The code requires fixes.
🧰 Tools
🪛 Checkov (3.2.334)
[medium] 436-441: Ensure that Lambda function URLs AuthType is not None
(CKV_AWS_258)
🤖 Prompt for AI Agents
In terraform/modules/lambdas/main.tf around lines 399-404 and 436-441, both
aws_lambda_function_url resources currently use authorization_type = "NONE"
which allows unauthenticated public access; change authorization_type to
"AWS_IAM" for each function URL to enforce IAM-based invocation. After making
that change, ensure callers have the appropriate IAM policy or role permissions
to invoke the Lambda URL (aws:SourceArn or lambda:InvokeFunction with the
function URL), and remove any configurations that rely on public access;
validate with terraform plan and run security scans to confirm CKV_AWS_258 is
resolved.
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.
I don't want AWS_IAM we do our own auth
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.
@devksingh4 Understood! Application-level authentication is a perfectly valid approach for public Lambda function URLs, especially when you have your own auth system.
Since you're handling authentication at the application layer, just ensure you have:
- Rate limiting/throttling in place (Lambda concurrency limits or CloudFront/API Gateway)
- Robust input validation
- Monitoring for suspicious invocation patterns
I'll add this to my learnings so I don't flag this pattern in the future.
add repo: acm-uiuc/core description: Lambda function URLs in this project intentionally use authorization_type = "NONE" because the project implements its own application-level authentication system. Do not flag CKV_AWS_258 or suggest changing to AWS_IAM for Lambda function URLs.
Summary by CodeRabbit
New Features
Improvements