Skip to content

Conversation

@joeauyeung
Copy link
Contributor

@joeauyeung joeauyeung commented Jan 23, 2026

What does this PR do?

Adds display of the assignment reason in two places:

  1. Organizer booking emails - Shows a translated category label (e.g., "Routed", "Reassigned") followed by the detailed reason string
  2. Booking single view page - Shows a user-friendly badge (e.g., "Routed", "Reassigned", "Salesforce Assigned") plus the detailed reason when the host or team member is viewing the booking while logged in

This helps organizers understand why a particular booking was assigned to them, especially useful for round-robin and routing form scenarios.

Updates since last revision

  • Added unit tests: Added comprehensive tests for getAssignmentReasonCategory (7 tests covering all enum values) and withAssignmentReason builder method (3 tests)
  • Added category label to emails: Organizer emails now display the translated category (e.g., "Routed: Language: English, Region: US") instead of just the raw reason string
  • Created shared utility: Added getAssignmentReasonCategory.ts in packages/features/bookings/lib/ to map AssignmentReasonEnum to translation keys
  • Updated CalendarEvent type: Changed assignmentReason from string | null to { category: string; details?: string | null } | null to support both category and details
  • Updated CalendarEventBuilder: Now extracts reasonEnum and converts it to a category using the shared utility
  • Updated BookingRepository: Now fetches both reasonEnum and reasonString for the email builder

Type Changes

The EventPayloadType was modified to use Omit<CalendarEvent, "assignmentReason"> because:

  • Emails need assignmentReason as { category, details } object
  • Webhooks need assignmentReason as an array of objects with reasonEnum and reasonString

This allows both use cases to coexist without type conflicts.

image Screenshot From 2026-01-23 12-52-46

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 - no documentation changes needed.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  1. For organizer emails:

    • Create a round-robin event type
    • Have a booking made through a routing form or reassign a booking
    • Check the organizer's email - should show "Assignment reason: Routed: [detailed reason]" or "Assignment reason: Reassigned: [detailed reason]"
  2. For booking single view:

    • Create a booking with an assignment reason (via routing form or reassignment)
    • Log in as the host/organizer or a team member
    • Navigate to /booking/[uid]
    • Should see a gray badge with translated label (e.g., "Routed") and the detailed reason text below it
  3. For unit tests:

    • Run yarn test packages/features/bookings/lib/getAssignmentReasonCategory.test.ts
    • Run yarn test packages/features/CalendarEventBuilder.test.ts -t "assignment reason"

Checklist

  • I have read the contributing guide
  • My code follows the style guidelines of this project
  • I have checked if my changes generate no new warnings
  • My PR is appropriately sized

Human Review Checklist

  • Verify translations exist for category keys: "routed", "reassigned", "rerouted", "salesforce_assigned"
  • Verify canViewHiddenData correctly gates assignment reason display (same pattern as UTM params)
  • Verify the as AssignmentReasonEnum type cast in booking single view is safe
  • Confirm the EventPayloadType change doesn't break existing webhook consumers
  • Verify CalendarEventBuilder.fromBooking() correctly extracts reasonEnum from the assignment reason array
  • Verify email displays correctly with the new ${t(category)}: ${details} format
  • Check for duplicate import: getAssignmentReasonCategory appears to be imported twice in RegularBookingService.ts - verify this doesn't cause issues

Requested by: @joeauyeung
Link to Devin run: https://app.devin.ai/sessions/9abb95b7a90f496c90a47a51b7f52c0e

…e view

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.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

devin-ai-integration bot and others added 2 commits January 23, 2026 14:28
…ency

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
@pull-request-size pull-request-size bot added size/L and removed size/S labels Jan 23, 2026
devin-ai-integration bot and others added 8 commits January 23, 2026 15:44
…isplay

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
- Update CalendarEvent type to use object with category and details
- Create shared getAssignmentReasonCategory utility function
- Update CalendarEventBuilder to pass both category and details
- Update BookingRepository to fetch reasonEnum for category mapping
- Update email template to display translated category label with details
- Update EventPayloadType to accept new assignment reason structure

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
…ails

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
…ntReason

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
@joeauyeung joeauyeung marked this pull request as ready for review January 23, 2026 18:36
@joeauyeung joeauyeung requested a review from a team as a code owner January 23, 2026 18:36
@graphite-app graphite-app bot added core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO labels Jan 23, 2026
@graphite-app graphite-app bot requested a review from a team January 23, 2026 18:36
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 12 files

Comment on lines +770 to +772
bookingInfo.assignmentReason &&
bookingInfo.assignmentReason.length > 0 &&
bookingInfo.assignmentReason[0].reasonEnum && (
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit we could use null safe accessor ?

@volnei volnei merged commit 3355fab into main Jan 23, 2026
88 of 89 checks passed
@volnei volnei deleted the devin/1769177194-display-assignment-reason branch January 23, 2026 23:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO ready-for-e2e size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants