Files
calendar/packages/features/routing-trace/domains/RoutingFormTraceService.ts
T
Joe Au-YeungGitHubClaude Opus 4.5joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
7abbc8c22c feat: Routing trace presenter (#27372)
* feat: Add routing trace presenters

Add domain-specific presenters (SalesforceRoutingTracePresenter,
RoutingFormTracePresenter) that format trace steps into human-readable
strings, and a core RoutingTracePresenter that delegates to them based
on step domain. Includes unit tests for all presenters.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Add findByBookingUid to RoutingTraceRepository

Add method to look up a routing trace by booking UID, needed by the
routing trace presenter tRPC endpoint.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Add getRoutingTrace tRPC endpoint

Expose routing trace data for a booking via viewer.bookings.getRoutingTrace.
Tries the permanent RoutingTrace first (round robin bookings), then falls
back to PendingRoutingTrace via the booking's form response relation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Add routing trace side sheet to booking list item

Add a route icon button on booking list items that came from routing
forms. Clicking it opens a side sheet displaying the full routing trace
as human-readable steps. Adds RoutingTraceSheet component, store state,
and translation key.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: Move routing trace action to dropdown menu

Move the routing trace button from a standalone icon on the booking list
item into the actions dropdown menu alongside "Report wrong assignment".
The RoutingTraceSheet is now rendered from BookingActionsDropdown.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Improve routing trace UI and handle unnamed routes

- Redesign RoutingTraceSheet with vertical timeline layout, domain badges,
  skeleton loading state, and millisecond timestamps
- Use Salesforce app-store icon for Salesforce steps
- Fall back to "Unnamed route" when route name is missing or matches route ID
- Fix dropdown menu icon to git-merge (valid icon, unique in menu)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Add tests for getRoutingTrace handler and findByBookingUid repository method

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

* Abstract functions

* Fix build error

* Add permission check

* fix: Update getRoutingTrace tests to include ctx and mock BookingAccessService

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

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 15:26:44 -03:00

51 lines
1.5 KiB
TypeScript

import { ROUTING_TRACE_DOMAINS } from "../constants";
import type { RoutingTraceService } from "../services/RoutingTraceService";
export const ROUTING_FORM_STEPS = {
ROUTE_MATCHED: "route_matched",
FALLBACK_ROUTE_USED: "fallback_route_used",
ATTRIBUTE_LOGIC_EVALUATED: "attribute-logic-evaluated",
ATTRIBUTE_FALLBACK_USED: "attribute_fallback_used",
} as const;
export class RoutingFormTraceService {
constructor(private readonly traceService: RoutingTraceService) {}
routeMatched(data: { routeId: string; routeName: string }): void {
this.traceService.addStep({
domain: ROUTING_TRACE_DOMAINS.ROUTING_FORM,
step: ROUTING_FORM_STEPS.ROUTE_MATCHED,
data,
});
}
fallbackRouteUsed(data: { routeId: string; routeName: string }): void {
this.traceService.addStep({
domain: ROUTING_TRACE_DOMAINS.ROUTING_FORM,
step: ROUTING_FORM_STEPS.FALLBACK_ROUTE_USED,
data,
});
}
attributeLogicEvaluated(data: {
routeName?: string;
routeIsFallback?: boolean;
checkedFallback?: boolean;
attributeRoutingDetails?: Array<{ attributeName: string; attributeValue: string }>;
}): void {
this.traceService.addStep({
domain: ROUTING_TRACE_DOMAINS.ROUTING_FORM,
step: ROUTING_FORM_STEPS.ATTRIBUTE_LOGIC_EVALUATED,
data,
});
}
attributeFallbackUsed(data: { routeName?: string }): void {
this.traceService.addStep({
domain: ROUTING_TRACE_DOMAINS.ROUTING_FORM,
step: ROUTING_FORM_STEPS.ATTRIBUTE_FALLBACK_USED,
data,
});
}
}