Skip to content

feat: improve booking history error handling with context-aware messages#28457

Closed
hariombalhara wants to merge 3 commits intomainfrom
devin/1773678199-booking-audit-error-handling
Closed

feat: improve booking history error handling with context-aware messages#28457
hariombalhara wants to merge 3 commits intomainfrom
devin/1773678199-booking-audit-error-handling

Conversation

@hariombalhara
Copy link
Member

@hariombalhara hariombalhara commented Mar 16, 2026

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:

ℹ️ Audit logs are not available for this booking.

Error codes: EVENT_TYPE_NOT_IN_ORGANIZATION (new), OWNER_NOT_IN_ORGANIZATION, BOOKING_HAS_NO_OWNER, BOOKING_NOT_FOUND_OR_PERMISSION_DENIED, ORGANIZATION_ID_REQUIRED

Part 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:

ℹ️ You don't have permission to view audit logs
Contact your organization or team admin to get access.

Error code: ORG_MEMBER_PERMISSION_DENIED

Unknown 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. Added EVENT_TYPE_NOT_IN_ORGANIZATION.
  • BookingAuditAccessService: Replaced custom BookingAuditPermissionError with standard ErrorWithCode. Restructured assertPermissions() to perform scope check (Part 1) before PBAC check (Part 2). Renamed PERMISSION_DENIEDORG_MEMBER_PERMISSION_DENIED.
  • BookingRepository: findByUidIncludeEventType() now includes team.parentId (for both direct and managed/parent event types) to support the scope check.
  • getBookingHistory.handler.ts: Catches ErrorWithCode and forwards the error code string as the TRPCError message. Removed server-side i18n translation of error messages.
  • BookingHistory.tsx: Checks error.message against known BookingAuditErrorCode values 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)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  1. 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."

  2. Part 2 — Permission denied: Log in as a user who is part of the booking's organization but lacks booking.readTeamAuditLogs and booking.readOrgAuditLogs PBAC 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."

  3. Happy path: User with proper permissions viewing an in-scope booking → audit logs display normally.

  4. Unit tests:

    TZ=UTC yarn test packages/features/booking-audit/lib/service/__tests__/BookingAuditAccessService.test.ts
    TZ=UTC yarn test apps/web/modules/booking-audit/components/BookingHistory.test.tsx
    

Important review points

  • Scope check logic (BookingAuditAccessService.ts): The Part 1 check uses bookingEventTypeTeamId === organizationId || teamParentId === organizationId to 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.
  • BookingRepository change: Added team: { select: { parentId: true } } to the Prisma query in two places (direct event type and parent event type). Verify the Team model has parentId field available via this relation.
  • The error code string (e.g. ORG_MEMBER_PERMISSION_DENIED) is forwarded as the raw TRPCError.message. The frontend matches on error.message === BookingAuditErrorCode.X.
  • Old i18n keys (audit_logs_organization_required, audit_logs_booking_not_found_or_permission_denied, etc.) are still in common.json — they may now be dead code unless used elsewhere.

Link to Devin session: https://app.devin.ai/sessions/8db46069e4a148b7a9275e8ec040245b
Requested by: @hariombalhara

- 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>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 6 files

hariombalhara and others added 2 commits March 16, 2026 17:38
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant