Skip to content

Conversation

@devksingh4
Copy link
Member

@devksingh4 devksingh4 commented Nov 13, 2025

  • Log checkin correctly to audit log
  • Ask for confirmation in manual check-in

Summary by CodeRabbit

  • New Features
    • Added a confirmation modal to manually fulfill tickets with purchaser email confirmation, validation, countdown enablement, and clear success/error feedback; fulfillment refreshes the ticket list on success.
  • Refactor
    • Adjusted server flow so audit logging runs and includes any optional audit context before responses are returned, improving logging consistency.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 13, 2025

Walkthrough

Added optional x-auditlog-context header support and moved audit-log entry creation to occur before sending responses in the tickets API; added a manual-fulfill confirmation modal in the tickets UI that validates purchaser email and sends the audit context header when calling the fulfillment endpoint.

Changes

Cohort / File(s) Summary
Tickets API — request & audit flow
src/api/routes/tickets.ts
Accept optional x-auditlog-context header, extract headerReason, pass it into createAuditLogEntry using fastify.dynamoClient, perform audit-log creation before sending the HTTP response, and ensure the handler returns after reply.
Tickets UI — manual fulfillment modal & API call
src/ui/pages/tickets/ViewTickets.page.tsx
Add confirmation modal state and handlers, countdown to enable confirm, purchaser email input and validation (must match), call fulfillment API with x-auditlog-context header, handle success/error notifications, and refresh ticket list.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant UI as Browser (ViewTickets)
participant API as Tickets API
participant Audit as AuditLog (DynamoDB)
rect rgb(220,240,255)
UI->>UI: Open confirm modal, enter purchaser email, wait countdown
UI->>API: POST /tickets/:id/fulfill + header x-auditlog-context
end
rect rgb(240,255,230)
API->>Audit: createAuditLogEntry(fastify.dynamoClient, headerReason)
Audit-->>API: Audit entry created
API-->>UI: 200 OK (fulfillment logged)
end

mermaid
sequenceDiagram
participant Client as Caller
participant Route as tickets.ts handler
participant Dynamo as fastify.dynamoClient
Route->>Dynamo: createAuditLogEntry(..., headerReason?)
Dynamo-->>Route: success/failure
alt success
Route-->>Client: reply.send(200)
else failure
Route-->>Client: reply.send(error)
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify createAuditLogEntry call-site uses fastify.dynamoClient correctly and handles errors.
  • Confirm x-auditlog-context header parsing/encoding is safe and not causing injection or logging issues.
  • Review modal countdown, visibility handling, and email-match validation for edge cases (focus/visibility loss).
  • Ensure no code path bypasses audit logging or fails to send a response.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Setup guards for check-in' is partially related to the changeset. It captures the confirmation modal/guard aspect but misses the primary change of audit log improvements for check-in operations.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dsingh14/patch-audit-log

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 13, 2025

💰 Infracost report

Monthly estimate generated

This comment will be updated when code changes.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (1)
src/api/routes/tickets.ts (1)

529-529: Consider refactoring the message construction for better readability.

The audit log message uses conditional string concatenation with template literals, which works but could be more maintainable.

Apply this diff to improve readability:

-          message: `checked in ticket of type "${request.body.type}" ${request.body.type === "merch" ? `purchased by email ${request.body.email}.` : "."}${headerReason ? `\nUser-provided context: "${headerReason}"` : ""}`,
+          message: [
+            `checked in ticket of type "${request.body.type}"`,
+            request.body.type === "merch" ? `purchased by email ${request.body.email}` : "",
+            headerReason ? `User-provided context: "${headerReason}"` : "",
+          ]
+            .filter(Boolean)
+            .join("\n"),
📜 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

📥 Commits

Reviewing files that changed from the base of the PR and between 1e2e079 and f0e6b1e.

📒 Files selected for processing (2)
  • src/api/routes/tickets.ts (2 hunks)
  • src/ui/pages/tickets/ViewTickets.page.tsx (4 hunks)
⏰ 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 (7)
src/api/routes/tickets.ts (3)

395-400: LGTM! Proper use of Zod v4 optional header schema.

The optional header schema for audit context is well-defined using Zod v4 syntax with .meta() for description.


533-538: LGTM! Explicit return ensures audit log completes before response.

Moving the response to after audit log creation with an explicit return ensures logging completes before the handler terminates, which aligns with the PR objective.


522-532: Confirm audit log table is deployed in us-east-2 (or your application's default region).

The code change routes audit log writes from UsEast1DynamoClient (us-east-1) to fastify.dynamoClient, which uses genericConfig.AwsRegion (defaults to us-east-2 via process.env.AWS_REGION ?? "us-east-2"). This is consistent with the intent stated in tickets.ts lines 113–114—audit logs should reside in the application's default region, not with legacy ticket data stuck in us-east-1. Verify that the "infra-core-api-audit-log" table is actually deployed in that target region to avoid write failures.

src/ui/pages/tickets/ViewTickets.page.tsx (4)

80-86: LGTM! Well-structured state for confirmation modal.

The modal state variables are clearly named and appropriately typed.


125-137: LGTM! Clean modal lifecycle handlers.

The open and close handlers properly initialize and reset modal state.


145-153: LGTM! Robust email validation with case-insensitive comparison.

The email validation correctly handles case differences and whitespace, providing a clear error message when validation fails.


340-413: LGTM! Well-designed confirmation modal with clear warnings.

The modal implementation effectively:

  • Displays a prominent warning about irreversibility
  • Shows all relevant purchase details
  • Requires exact email confirmation
  • Provides clear action buttons with appropriate states

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (1)
src/ui/pages/tickets/ViewTickets.page.tsx (1)

185-232: Critical: API payload still doesn't match backend schema for ticket type.

This issue was previously flagged but remains unaddressed. The API request always sends email and stripePi fields (lines 205-207), but the backend schema expects different fields based on ticket type:

  • Merch: { type: "merch", email: string, stripePi: string }
  • Ticket: { type: "ticket", ticketId: string } ✗ (currently sending email and stripePi)

This will cause validation errors when trying to manually fulfill ticket-type purchases.

Apply this diff to conditionally construct the correct payload:

     try {
-      const response = await api.post(
-        `/api/v1/tickets/checkIn`,
-        {
-          type: ticketToFulfill.type,
-          email: ticketToFulfill.purchaserData.email,
-          stripePi: ticketToFulfill.ticketId,
-        },
-        {
-          headers: {
-            "x-auditlog-context": "Manually marked as fulfilled.",
-          },
-        },
-      );
+      const payload =
+        ticketToFulfill.type === "merch"
+          ? {
+              type: "merch" as const,
+              email: ticketToFulfill.purchaserData.email,
+              stripePi: ticketToFulfill.ticketId,
+            }
+          : {
+              type: "ticket" as const,
+              ticketId: ticketToFulfill.ticketId,
+            };
+
+      const response = await api.post(`/api/v1/tickets/checkIn`, payload, {
+        headers: {
+          "x-auditlog-context": "Manually marked as fulfilled.",
+        },
+      });
       if (!response.data.valid) {
🧹 Nitpick comments (1)
src/ui/pages/tickets/ViewTickets.page.tsx (1)

81-89: Minor inconsistency in countdown initialization.

Line 89 initializes countdown to 3, but it should be WAIT_BEFORE_FULFILLING_SECS for consistency. While the value is reset when the modal opens (line 94), using a consistent initial value improves code clarity.

Apply this diff:

-  const [countdown, setCountdown] = useState(3);
+  const [countdown, setCountdown] = useState(WAIT_BEFORE_FULFILLING_SECS);
📜 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

📥 Commits

Reviewing files that changed from the base of the PR and between f0e6b1e and da568ac.

📒 Files selected for processing (1)
  • src/ui/pages/tickets/ViewTickets.page.tsx (5 hunks)
⏰ 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)
src/ui/pages/tickets/ViewTickets.page.tsx (6)

67-67: LGTM!

The 15-second guard is a good security measure to prevent accidental fulfillment.


91-130: LGTM! Solid countdown implementation with visibility guards.

The countdown logic correctly prevents users from bypassing the wait time by switching tabs or hiding the page. The visibility change handler and the interval guard work together effectively.

Minor note: Line 99 sets the countdown to WAIT_BEFORE_FULFILLING_SECS + 1 when the page is hidden, adding a 1-second penalty. This appears intentional but consider documenting this behavior if it's a deliberate security measure.


169-183: LGTM!

Modal handlers correctly manage state transitions and reset logic.


234-236: LGTM!

Correctly updated to open the confirmation modal instead of immediately fulfilling.


386-461: LGTM! Well-designed confirmation modal with good UX.

The modal implementation includes:

  • Clear warning alert about irreversible action
  • Purchase details for verification
  • Email confirmation with validation
  • Countdown guard to prevent accidental clicks
  • Good accessibility with autofocus on input

Mantine's Modal component uses portals by default, so the placement within the component tree doesn't affect rendering behavior.


20-20: No issues found—the import path is valid.

The import import * as z from "zod/v4"; is an officially supported subpath export from Zod that remains available. Zod exposes subpaths like "zod/v4" for incremental migration. This pattern is used consistently across 50+ files in the codebase and requires no changes.

Likely an incorrect or invalid review comment.

@devksingh4 devksingh4 merged commit 922f8da into main Nov 13, 2025
11 of 12 checks passed
@devksingh4 devksingh4 deleted the dsingh14/patch-audit-log branch November 13, 2025 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants