Three of the five highest-risk functions in cal.com are named handler. They live in booking creation, webhook processing, and cancellation — the core of what the platform does. That naming pattern is worth pausing on: when the primary logic unit for a major feature is a generic handler, it often means the function has been accumulating responsibility rather than having it deliberately assigned.
The standout is RegularBookingService.handler, with a cyclomatic complexity of 243. The next entry sits at CC 46. That gap — nearly 5× — is the first thing to understand about this codebase’s risk profile.
The table below ranks functions by activity-weighted risk — a score that multiplies structural complexity by recent commit frequency. A function that is both hard to understand (high cyclomatic complexity) and actively changing is a higher priority than one that is complex but untouched. CC = cyclomatic complexity (independent execution paths); ND = max nesting depth; FO = fan-out (distinct callees).
Top 5 Hotspots
| Function | File | Risk | CC | ND | FO |
|---|---|---|---|---|---|
handler | packages/features/bookings/lib/service/RegularBookingService.ts | 22.4 | 243 | 8 | 175 |
_getBusyTimesFromLimitsForUsers | packages/trpc/server/routers/viewer/slots/util.ts | 18.8 | 46 | 7 | 30 |
handler | packages/app-store/vital/api/webhook.ts | 18.0 | 28 | 7 | 24 |
Signup | apps/web/modules/signup-view.tsx | 17.9 | 43 | 5 | 57 |
handler | packages/features/bookings/lib/handleCancelBooking.ts | 17.3 | 72 | 4 | 46 |
Large Repo Analysis
cal.com is a large repository. To stay within memory constraints, this analysis used hybrid touch mode: structural complexity — CC, ND, FO — is measured precisely for every function. Git activity is tracked at the function level (via git log -L) only for files with 5 or more commits in the last 30 days; other files use a file-level approximation. Rankings therefore surface functions that are both structurally complex and in the most actively-changing parts of the codebase. Dormant code with high structural complexity will rank lower than it would under a full per-function analysis — to surface it, run hotspots analyze . --per-function-touches on a machine with sufficient memory.
handler — packages/features/bookings/lib/service/RegularBookingService.ts
CC 243 is not just high — it means there are 243 independent execution paths through this function. Paired with a nesting depth of 8 and fan-out of 175, this is the structural centre of gravity for booking creation: it calls into 175 distinct functions, making it a hub that pulls in nearly every subsystem the platform touches. Every new booking type, integration, or edge case that has landed here instead of in a dedicated service has compounded the complexity. The god_function and long_function patterns confirm what the metrics show — this is a function that has taken on orchestration, validation, persistence, and notification concerns all at once. Splitting it along those responsibility boundaries (a dedicated validateBookingRequest, a persistBooking, a notifyParticipants) would let each piece be tested and changed independently, and would bring the per-unit CC down to something reviewers can hold in their heads.
_getBusyTimesFromLimitsForUsers — packages/trpc/server/routers/viewer/slots/util.ts
This function sits in the slot-availability calculation path, where it needs to reconcile booking limits, user schedules, and time zone rules across potentially many users at once. CC 46 and ND 7 reflect how many combinations of limit types and scheduling constraints have been folded into a single traversal. The deeply_nested pattern here suggests that limit-type branching is nested inside user iteration, rather than the limit logic being separated into its own evaluated structure. Extracting a getLimitsForUser helper that returns a normalised structure — and then applying it uniformly — would flatten the nesting and make the combinations easier to test in isolation.
handler — packages/app-store/vital/api/webhook.ts
With CC 28 and ND 7, this webhook handler punches above its complexity weight for its size. Nesting depth of 7 in a webhook handler typically indicates that event-type branching is deeply nested rather than dispatched — each event type adds another layer rather than routing to a dedicated processor. The exit_heavy pattern reinforces this: early returns are being used to manage the branching rather than a clean dispatch table. Refactoring toward an event-type registry or a simple switch with extracted handlers per event type would reduce both the nesting and the number of exit points.
Signup — apps/web/modules/signup-view.tsx
The metrics here — CC 43, ND 5, FO 57 — point to a React component that has absorbed too much: form state, validation logic, API calls, error handling, and conditional rendering for multiple signup flows (SSO, email, invite token, etc.). Fan-out of 57 means it is coordinating with a large slice of the application surface.
A signup view with this profile is typically the result of incremental feature additions — each new auth method or onboarding variant adding a branch rather than a dedicated sub-component. Splitting by concern (a useSignupForm hook for state and validation, dedicated components per signup variant) would shrink the function and make each path independently testable without a full render cycle.
handler — packages/features/bookings/lib/handleCancelBooking.ts
CC 72 with FO 46 and ND 4 makes this the structurally second-most-complex booking handler in the top five, despite its lower nesting than the others. The complex_branching and exit_heavy patterns suggest it handles many cancellation scenarios in sequence — host-initiated vs. attendee-initiated, with or without refunds, recurring vs. single events — using guard clauses that grow longer with each new case. The relatively shallow nesting (ND 4) is a positive sign: the function is wide rather than deep, which makes extraction more tractable. Grouping cancellation scenarios into explicit case handlers (handleAttendeeCancel, handleRecurringCancel) would reduce CC meaningfully without requiring a deep restructure.
Patterns Found
Antipatterns detected across the top functions in this snapshot:
| Pattern | Occurrences |
|---|---|
complex_branching | 5 |
exit_heavy | 5 |
god_function | 5 |
long_function | 5 |
deeply_nested | 4 |
hub_function | 1 |
These labels belong to two tiers — Tier 1 (structural): complex_branching, deeply_nested, exit_heavy, long_function, god_function. Tier 2 (relational/temporal): hub_function, cyclic_hub, middle_man, neighbor_risk, stale_complex, churn_magnet, shotgun_target, volatile_god.
Reproduce This Analysis
git clone https://github.com/calcom/cal.com
cd cal.com
git checkout 180ede28f0bddf2738933a6e60a8e80f6116d7da
hotspots analyze . --mode snapshot --explain-patterns --force --hybrid-touches 5
To run the same analysis on your own codebase, run hotspots analyze . --mode snapshot in any local git repo — no configuration required.
Hotspots highlights structural and activity risk — not “bad code.” Findings are a prioritization aid, not a bug predictor. Editorial policy →