feat: improve booking history error handling with context-aware messages#28457
Closed
hariombalhara wants to merge 3 commits intomainfrom
Closed
feat: improve booking history error handling with context-aware messages#28457hariombalhara wants to merge 3 commits intomainfrom
hariombalhara wants to merge 3 commits intomainfrom
Conversation
- Replace BookingAuditPermissionError with ErrorWithCode in BookingAuditAccessService - Rename PERMISSION_DENIED to ORG_MEMBER_PERMISSION_DENIED for clarity - Handler catches ErrorWithCode and forwards error code as TRPCError message - Frontend shows info alerts based on error.message instead of generic errors - Never hide the History tab - always show info message - Add BookingHistory component tests for error scenarios - Update BookingAuditAccessService tests for ErrorWithCode Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…e imports in client component Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…Service - Add EVENT_TYPE_NOT_IN_ORGANIZATION error code for when booking's team is not in user's org - Restructure assertPermissions: check scope (Part 1) before permissions (Part 2) - Part 1: Is the booking in user's org? (team parentId check or owner membership check) - Part 2: Does user have PBAC access? (team-level then org-level) - Extend findByUidIncludeEventType to include team.parentId for scope check - Update frontend to handle new EVENT_TYPE_NOT_IN_ORGANIZATION error code - Update service tests (13 tests) and component tests (7 tests) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Replaces generic error messages in the Booking History (audit logs) tab with context-aware info alerts. Instead of showing a red error for all permission failures, the service now splits access checks into two distinct parts, and the frontend shows different guidance for each.
Part 1 — Scope Check: "Is this booking in the user's organization?"
Performed first. If the booking's event type belongs to a team outside the user's organization (or the booking owner isn't in the user's org), we show:
Error codes:
EVENT_TYPE_NOT_IN_ORGANIZATION(new),OWNER_NOT_IN_ORGANIZATION,BOOKING_HAS_NO_OWNER,BOOKING_NOT_FOUND_OR_PERMISSION_DENIED,ORGANIZATION_ID_REQUIREDPart 2 — Permission Check (PBAC): "Does the user have access?"
Only reached if the booking is in scope. If PBAC denies team-level and org-level audit log permissions, we show:
Error code:
ORG_MEMBER_PERMISSION_DENIEDUnknown errors
Still show the generic red error message as a fallback.
The History tab is never hidden — it always shows an informational message.
Key changes:
BookingAuditErrorCode.ts(new): Extracted enum to a shared file with no server-side dependencies, safe for client component import. AddedEVENT_TYPE_NOT_IN_ORGANIZATION.BookingAuditAccessService: Replaced customBookingAuditPermissionErrorwith standardErrorWithCode. RestructuredassertPermissions()to perform scope check (Part 1) before PBAC check (Part 2). RenamedPERMISSION_DENIED→ORG_MEMBER_PERMISSION_DENIED.BookingRepository:findByUidIncludeEventType()now includesteam.parentId(for both direct and managed/parent event types) to support the scope check.getBookingHistory.handler.ts: CatchesErrorWithCodeand forwards the error code string as theTRPCErrormessage. Removed server-side i18n translation of error messages.BookingHistory.tsx: Checkserror.messageagainst knownBookingAuditErrorCodevalues and renders<Alert severity="info">components accordingly.Visual Demo (For contributors especially)
N/A — no visual test environment available. The UI change is an
<Alert severity="info">component (blue info box) replacing a red error<div>, consistent with existing alert patterns in the codebase.Mandatory Tasks (DO NOT REMOVE)
How should this be tested?
Part 1 — Booking not in scope: View audit logs for a booking whose event type belongs to a team in a different organization → should see blue info alert: "Audit logs are not available for this booking."
Part 2 — Permission denied: Log in as a user who is part of the booking's organization but lacks
booking.readTeamAuditLogsandbooking.readOrgAuditLogsPBAC permissions. Open the booking's History tab → should see blue info alert: "You don't have permission to view audit logs" with "Contact your organization or team admin to get access."Happy path: User with proper permissions viewing an in-scope booking → audit logs display normally.
Unit tests:
Important review points
BookingAuditAccessService.ts): The Part 1 check usesbookingEventTypeTeamId === organizationId || teamParentId === organizationIdto determine if a team is in the user's org. Verify this correctly handles: (a) org-level event types where teamId IS the orgId, (b) sub-team event types where team.parentId == orgId, (c) managed events where the parent event's team is checked.team: { select: { parentId: true } }to the Prisma query in two places (direct event type and parent event type). Verify theTeammodel hasparentIdfield available via this relation.ORG_MEMBER_PERMISSION_DENIED) is forwarded as the rawTRPCError.message. The frontend matches onerror.message === BookingAuditErrorCode.X.audit_logs_organization_required,audit_logs_booking_not_found_or_permission_denied, etc.) are still incommon.json— they may now be dead code unless used elsewhere.Link to Devin session: https://app.devin.ai/sessions/8db46069e4a148b7a9275e8ec040245b
Requested by: @hariombalhara