Skip to content

Feat/chunk availability#7

Open
chay2199 wants to merge 15 commits into
mainfrom
feat/chunk-availability
Open

Feat/chunk availability#7
chay2199 wants to merge 15 commits into
mainfrom
feat/chunk-availability

Conversation

@chay2199

@chay2199 chay2199 commented Jun 6, 2026

Copy link
Copy Markdown

What does this PR do?

  • Fixes #XXXX (GitHub issue number)
  • Fixes CAL-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)

Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).

Video Demo (if applicable):

  • Show screen recordings of the issue or feature.
  • Demonstrate how to reproduce the issue, the behavior before and after the change.

Image Demo (if applicable):

  • Add side-by-side screenshots of the original and updated change.
  • Highlight any significant change(s).

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. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Are there environment variables that should be set?
  • What are the minimal test data to have?
  • What is expected (happy path) to have (input and output)?
  • Any other important info that could help to test that PR

Checklist

  • I haven't read the contributing guide
  • My code doesn't follow the style guidelines of this project
  • I haven't commented my code, particularly in hard-to-understand areas
  • I haven't checked if my changes generate no new warnings

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Added round-robin host chunking to slot fetching so large unweighted host pools can load availability in batches instead of all at once.
  • Wired both web and platform booker flows to request next chunks on demand, with new store state and a shared hook to manage chunk offsets.
  • Exposed chunk metadata in slots responses and inputs, plus tests to verify chunk sizing, ordering, manual paging, and weighted round-robin bypass.

Key Changes by Area

  • Slots API and server logic: Added roundRobinManualChunking and roundRobinChunkOffset inputs, chunked unweighted round-robin processing, and returned roundRobinChunkInfo for client paging.
  • Web booking UI: Passed onLoadNextRoundRobinChunk through wrappers to Booker and AvailableTimeSlots, including a load-more availability action and progress UI.
  • Platform booking flow: Persisted chunk settings in store-aware slot queries and cache keys, and exposed next-chunk loading in platform wrappers/hooks.
  • Booking state and schedule hooks: Added chunk settings/info to booker store and schedule hooks so chunk params flow through slot requests consistently.
  • Types and validation: Added shared chunk info types and updated TRPC/platform input and booking schema types for new chunking fields.
  • Test coverage: Expanded slot util and schedule tests for sequential chunking, manual offsets, ordering, limits, and no-availability paths.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added UI/action wiring for loading the next round-robin chunk.
apps/web/modules/bookings/components/Booker.tsx Threaded next-chunk callback into booking UI flow.
apps/web/modules/bookings/components/BookerWebWrapper.tsx Exposed and passed onLoadNextRoundRobinChunk from web wrapper.
apps/web/public/static/locales/en/common.json Added localization strings for load-more availability UI.
packages/features/bookings/Booker/tests/test-utils.tsx Updated test utilities for new chunking-aware booker state/props.
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook to manage chunk offset increments and reset behavior.
packages/features/bookings/Booker/store.ts Added roundRobinChunkSettings and roundRobinChunkInfo state.
packages/features/bookings/Booker/types.ts Extended booker types for chunk settings/info and callbacks.
packages/features/bookings/Booker/utils/event.ts Included chunk settings/info in booking event payload flow.
packages/features/bookings/lib/bookingCreateBodySchema.ts Updated schema to accept new chunking-related fields.
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Passed chunk params through v2 available slots API calls.
packages/features/schedules/lib/use-schedule/useSchedule.ts Integrated chunk settings/info into schedule fetching flow.
packages/lib/types/roundRobinChunkInfo.ts Added shared type for round-robin chunk metadata.
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Added platform wrapper wiring for next-chunk loading.
packages/platform/atoms/hooks/useAvailableSlots.ts Included chunk params in platform slot query and cache behavior.
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added chunking inputs to platform slots type definitions.
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added chunking inputs to newer get-slots input type.
packages/trpc/server/routers/viewer/slots/types.ts Extended slots response/input types with chunk info fields.
packages/trpc/server/routers/viewer/slots/util.test.ts Added tests for chunk sizing, manual offsets, ordering, and bypass cases.
packages/trpc/server/routers/viewer/slots/util.ts Implemented server-side round-robin chunking and response metadata.

Review Focus Areas

  • Check chunk offset reset conditions in packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts:1 to avoid stale paging across dependency changes.
  • Validate API contract alignment for new inputs and roundRobinChunkInfo across TRPC, platform types, and schedule hooks.
  • Review server chunking behavior in packages/trpc/server/routers/viewer/slots/util.ts:1021 for ordering guarantees and weighted round-robin bypass.

Architecture

  • Design Decisions: The PR moves chunking control into shared client state and hook logic while keeping chunk computation on the server, so clients request incremental host pools using explicit offsets and server-provided chunk metadata.
  • Scalability & Extensibility: This meaningfully improves large-team scheduling by limiting unweighted round-robin work per request and supports future paging UI reuse across web and platform via shared types and callbacks.
  • Risks: The main risk is cross-layer drift between client state, query params, and typed inputs for chunk fields, which could cause mismatched paging behavior if one surface is updated without the others.

...routingParams,
});
const { roundRobinChunkInfo, handleLoadNextRoundRobinChunk } = useRoundRobinChunking({
roundRobinChunkInfo: schedule.data?.roundRobinChunkInfo,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional High

This newly added property access relies on schedule.data having roundRobinChunkInfo, but useAvailableSlots is typed with GetAvailableSlotsResponse from packages/platform/atoms/booker/types.ts, and that type only declares slots. The result is a TypeScript contract break (Property 'roundRobinChunkInfo' does not exist on type 'GetAvailableSlotsResponse') that blocks strict type-check/build for the platform atom path.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/atoms/booker/BookerPlatformWrapper.tsx
Lines: 362-362
Issue Type: functional-high
Severity: high

Issue Description:
This newly added property access relies on `schedule.data` having `roundRobinChunkInfo`, but `useAvailableSlots` is typed with `GetAvailableSlotsResponse` from `packages/platform/atoms/booker/types.ts`, and that type only declares `slots`. The result is a TypeScript contract break (`Property 'roundRobinChunkInfo' does not exist on type 'GetAvailableSlotsResponse'`) that blocks strict type-check/build for the platform atom path.

Current Code:
      roundRobinChunkInfo: schedule.data?.roundRobinChunkInfo,

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Added round-robin availability chunking so large host pools load in batches instead of checking every host at once.
  • Updated web and platform booking flows to pass chunking params and read chunk metadata from slot responses.
  • Added a sticky "Load more availability" action in the timeslot UI so users can fetch more round-robin host availability on demand.

Key Changes by Area

  • Slot fetching API: Added roundRobinManualChunking, roundRobinChunkOffset, and response chunk metadata to support progressive loading for round-robin events.
  • Booker state and hooks: Added store, types, and hook support to track chunk state and request the next availability batch.
  • Booking UI: Updated the web timeslot experience to show load-more controls and progress when more non-fixed round-robin hosts are available.
  • Platform integration: Wired chunking support into platform booker and available-slots hooks so platform clients use the same progressive loading flow.
  • Tests: Added coverage for chunk sizing, sequential and manual chunk loading, weighted-host bypass, and empty-result cases.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added UI for loading more round-robin availability with progress state.
apps/web/modules/bookings/components/Booker.tsx Passed round-robin chunking state into booking flow.
apps/web/modules/bookings/components/BookerWebWrapper.tsx Wired web wrapper to support round-robin chunking state and requests.
apps/web/public/static/locales/en/common.json Added copy for the load-more availability UI.
packages/features/bookings/Booker/tests/test-utils.tsx Updated test helpers for the new booker chunking flow.
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts Added hook to manage chunk offsets and loading more availability.
packages/features/bookings/Booker/store.ts Added store state and actions for round-robin chunking.
packages/features/bookings/Booker/types.ts Added types for round-robin chunking state and metadata.
packages/features/bookings/Booker/utils/event.ts Updated event helpers to account for chunking behavior.
packages/features/bookings/lib/bookingCreateBodySchema.ts Extended booking request schema with round-robin chunking fields.
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Passed chunking params through available-slots API requests.
packages/features/schedules/lib/use-schedule/useSchedule.ts Added schedule hook support for chunked round-robin slot loading.
packages/lib/types/roundRobinChunkInfo.ts Added shared type for round-robin chunk metadata.
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Wired platform booker wrapper to use round-robin chunking.
packages/platform/atoms/hooks/useAvailableSlots.ts Passed round-robin chunking params in platform slot requests.
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added chunking inputs to platform slot request types.
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added chunking inputs to newer platform slot request types.
packages/trpc/server/routers/viewer/slots/types.ts Added slot response types for round-robin chunk metadata.
packages/trpc/server/routers/viewer/slots/util.test.ts Added tests for chunked round-robin availability behavior.
packages/trpc/server/routers/viewer/slots/util.ts Added chunked processing for large round-robin host pools and response metadata.

Review Focus Areas

  • Check server chunking logic in round-robin slot calculation, especially host order, weighted-host bypass, and fallback behavior.
  • Check client state flow for loading the next chunk across web and platform wrappers.
  • Check request and response contract alignment for the new chunking params and roundRobinChunkInfo.

Architecture

Design Decisions

  • The change adds manual chunk controls and chunk metadata to the slots API so clients can progressively request more round-robin hosts instead of loading all hosts in one pass.
  • Chunking is limited to large unweighted non-fixed round-robin pools, which keeps existing weighted-host behavior unchanged.

Scalability & Extensibility

  • This improves slot-fetch performance for large round-robin teams and centralizes chunk metadata in shared types, which helps reuse across web and platform clients.

Risks

  • Intentional: Progressive loading can show partial availability until users request more chunks.
  • Should be reviewed: Client and server now depend on matching chunk offset and metadata handling across multiple wrappers and API versions.

...routingParams,
});
const { roundRobinChunkInfo, handleLoadNextRoundRobinChunk } = useRoundRobinChunking({
roundRobinChunkInfo: schedule.data?.roundRobinChunkInfo,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional High

This new access does not exist on the platform atom response type. packages/platform/atoms/booker/types.ts:134-136 still defines GetAvailableSlotsResponse as only { slots: Record<string, SlotInfo[]> }, and useAvailableSlots is parameterized with that type. As soon as this line is added, the platform package fails type-checking because roundRobinChunkInfo is not a known property on schedule.data.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/atoms/booker/BookerPlatformWrapper.tsx
Lines: 362-362
Issue Type: functional-high
Severity: high

Issue Description:
This new access does not exist on the platform atom response type. `packages/platform/atoms/booker/types.ts:134-136` still defines `GetAvailableSlotsResponse` as only `{ slots: Record<string, SlotInfo[]> }`, and `useAvailableSlots` is parameterized with that type. As soon as this line is added, the platform package fails type-checking because `roundRobinChunkInfo` is not a known property on `schedule.data`.

Current Code:
      roundRobinChunkInfo: schedule.data?.roundRobinChunkInfo,

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +170 to +176
resetDeps: [
props.username,
props.eventSlug,
props.entity.orgSlug,
props.entity.eventTypeId,
event.data?.id,
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

Once a user clicks "Load more availability", roundRobinChunkSettings stays in manual mode until this reset list changes. The problem is that the list only keys off event identity, while useScheduleForEvent also sends the manual chunk offset on every date/month/duration/team-member change (packages/features/bookings/Booker/utils/event.ts:125-126). A concrete failure case is: open chunk 3 for one day, then pick a different day: the next availability request still starts at chunk 3, so chunks 0-2 are skipped and the new day shows incomplete availability.

Suggested fix
      resetDeps: [
        props.username,
        props.eventSlug,
        props.entity.orgSlug,
        props.entity.eventTypeId,
        event.data?.id,
        selectedDate,
        props.month,
        props.duration,
        dayCount,
        props.teamMemberEmail,
      ],
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/BookerWebWrapper.tsx
Lines: 170-176
Issue Type: functional-medium
Severity: medium

Issue Description:
Once a user clicks "Load more availability", `roundRobinChunkSettings` stays in manual mode until this reset list changes. The problem is that the list only keys off event identity, while `useScheduleForEvent` also sends the manual chunk offset on every date/month/duration/team-member change (`packages/features/bookings/Booker/utils/event.ts:125-126`). A concrete failure case is: open chunk 3 for one day, then pick a different day: the next availability request still starts at chunk 3, so chunks 0-2 are skipped and the new day shows incomplete availability.

Current Code:
      resetDeps: [
        props.username,
        props.eventSlug,
        props.entity.orgSlug,
        props.entity.eventTypeId,
        event.data?.id,
      ],

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Added progressive loading for large Round Robin teams. Hosts now load in chunks (20% of total, max 50) instead of all at once, improving performance for events with 100+ hosts.
  • Added manual "Load more availability" button with progress indicator for users to fetch additional host chunks on demand.
  • Added RoundRobinChunkInfo metadata to track pagination state across API responses.

Key Changes by Area

Backend (Slots):

  • packages/trpc/server/routers/viewer/slots/util.ts:1021-1172 - New calculateAvailabilityWithRoundRobinChunks() method processes host chunks sequentially until availability is found. Falls back to fixed-only hosts if no availability found.

API Schema:

  • packages/trpc/server/routers/viewer/slots/types.ts and platform types - Added roundRobinManualChunking and roundRobinChunkOffset input fields for client-controlled pagination.

Frontend (Booker):

  • packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts - Hook managing chunk state and handleLoadNextRoundRobinChunk callback.
  • apps/web/modules/bookings/components/AvailableTimeSlots.tsx:190-240 - Progressive loading UI with circular progress indicator.

State Management:

  • packages/features/bookings/Booker/store.ts:501-506 - Added roundRobinChunkSettings and roundRobinChunkInfo fields (note: not reset on initialize() - see Review Focus Areas).

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added "Load more availability" button with progress indicator; receives onLoadNextRoundRobinChunk prop
apps/web/modules/bookings/components/Booker.tsx Integrated chunking props into booker flow
apps/web/modules/bookings/components/BookerWebWrapper.tsx Added useRoundRobinChunking hook usage with chunk settings
apps/web/public/static/locales/en/common.json Added translation keys for chunking UI (one unused: round_robin_reset_hosts)
packages/features/bookings/Booker/tests/test-utils.tsx Test utilities updated for chunking state
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook for chunk state management and load-next-chunk callback
packages/features/bookings/Booker/store.ts Added roundRobinChunkSettings and roundRobinChunkInfo store fields
packages/features/bookings/Booker/types.ts Updated types for chunking integration
packages/features/bookings/Booker/utils/event.ts Event utility updates for chunking support
packages/features/bookings/lib/bookingCreateBodySchema.ts Schema updates for chunking parameters
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Passes chunking parameters to API calls
packages/features/schedules/lib/use-schedule/useSchedule.ts Passes chunking parameters to API calls
packages/lib/types/roundRobinChunkInfo.ts New type for chunk progress metadata
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Integrated useRoundRobinChunking hook for platform wrapper
packages/platform/atoms/hooks/useAvailableSlots.ts Updated to accept and pass chunking parameters
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added roundRobinManualChunking and roundRobinChunkOffset fields
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added roundRobinManualChunking and roundRobinChunkOffset fields
packages/trpc/server/routers/viewer/slots/types.ts Added chunking input fields to tRPC schema
packages/trpc/server/routers/viewer/slots/util.test.ts Comprehensive tests for chunking logic
packages/trpc/server/routers/viewer/slots/util.ts Core chunking implementation with calculateAvailabilityWithRoundRobinChunks

Review Focus Areas

  • Store state cleanup: roundRobinChunkSettings and roundRobinChunkInfo are not reset when initialize() is called at packages/features/bookings/Booker/store.ts:504-508. This could leak state between event type navigations.
  • Render performance: ProgressIcon SVG in AvailableTimeSlots.tsx:208-222 is recreated on every render. Consider memoizing or extracting to a component.
  • Unused translation: round_robin_reset_hosts key in common.json:586 has no references in source files.

Architecture

Design Decisions:

  • Chunking is disabled when round-robin weights are enabled (isRRWeightsEnabled: true). This is intentional: weights require evaluating all hosts for proper distribution, making chunking incompatible.
  • Sequential processing stops early when slots are found. This optimizes for the common case where early chunks have availability, at the cost of potentially missing "better" slots in later chunks.
  • Fixed hosts are included in every chunk. This ensures consistent availability from fixed hosts regardless of which chunk is processed.

Scalability & Extensibility:

  • Dynamic chunk sizing (20% of hosts, max 50) adapts to team size without configuration. Manual chunking mode allows client override for specific pagination needs.
  • Out of scope: Persistent chunk state across sessions, server-side caching of chunk results, or adaptive chunk sizing based on historical availability patterns.

Risks:

  • Intentional: Users may see fewer initial slots than actually exist if early chunks have limited availability. The "Load more" button mitigates this but requires user action.
  • Unintentional: Store state leak between event types (see Review Focus Areas).

Comment on lines +29 to +32
useEffect(() => {
setRoundRobinChunkSettings(null);
setRoundRobinChunkInfo(null);
}, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Robustness High

The reset useEffect spreads resetDeps directly into the dependency array using [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]. This is explicitly forbidden by React's rules of hooks: the ESLint react-hooks/exhaustive-deps rule rejects dynamic/spread dependency arrays, and the React runtime does not guarantee stable identity for the spread items across renders. More critically, setRoundRobinChunkInfo and setRoundRobinChunkSettings are Zustand setters that are recreated whenever the store is recreated. During mount, both effects run sequentially: the first effect (line 25-27) sets the chunk info, and the reset effect immediately clears it. This causes the store to always be null on the first render, breaking initial chunk display. The reset effect should only run when the actual identity-relevant props (username, eventSlug, etc.) change, not on every render that includes a stable setter.

Suggested fix
  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => {
    setRoundRobinChunkSettings(null);
    setRoundRobinChunkInfo(null);
  // Intentionally spreading resetDeps — these are stable primitive values (strings/numbers/null)
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, resetDeps);
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts
Lines: 29-32
Issue Type: robustness-high
Severity: high

Issue Description:
The reset `useEffect` spreads `resetDeps` directly into the dependency array using `[setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]`. This is explicitly forbidden by React's rules of hooks: the ESLint `react-hooks/exhaustive-deps` rule rejects dynamic/spread dependency arrays, and the React runtime does not guarantee stable identity for the spread items across renders. More critically, `setRoundRobinChunkInfo` and `setRoundRobinChunkSettings` are Zustand setters that are recreated whenever the store is recreated. During mount, both effects run sequentially: the first effect (line 25-27) sets the chunk info, and the reset effect immediately clears it. This causes the store to always be null on the first render, breaking initial chunk display. The reset effect should only run when the actual identity-relevant props (username, eventSlug, etc.) change, not on every render that includes a stable setter.

Current Code:
  useEffect(() => {
    setRoundRobinChunkSettings(null);
    setRoundRobinChunkInfo(null);
  }, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +25 to +27
useEffect(() => {
setRoundRobinChunkInfo(roundRobinChunkInfo ?? null);
}, [roundRobinChunkInfo, setRoundRobinChunkInfo]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Robustness Medium

The effect that syncs roundRobinChunkInfo into the store runs on every render where roundRobinChunkInfo changes (including when it becomes undefined or null). Because the reset effect (lines 29-32) runs after this effect on initial mount (both fire on first mount), the store is first set then immediately cleared, resulting in roundRobinChunkInfo always being null for one render cycle. This leads to the 'Load more' button not appearing on the initial load even when there is more data to fetch. The sync effect should guard against the reset-on-mount issue by checking if the value is actually changing from a non-null to null state deliberately.

Suggested fix
  useEffect(() => {
    if (roundRobinChunkInfo !== undefined) {
      setRoundRobinChunkInfo(roundRobinChunkInfo ?? null);
    }
  }, [roundRobinChunkInfo, setRoundRobinChunkInfo]);
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts
Lines: 25-27
Issue Type: robustness-medium
Severity: medium

Issue Description:
The effect that syncs `roundRobinChunkInfo` into the store runs on every render where `roundRobinChunkInfo` changes (including when it becomes `undefined` or `null`). Because the reset effect (lines 29-32) runs after this effect on initial mount (both fire on first mount), the store is first set then immediately cleared, resulting in `roundRobinChunkInfo` always being `null` for one render cycle. This leads to the 'Load more' button not appearing on the initial load even when there is more data to fetch. The sync effect should guard against the reset-on-mount issue by checking if the value is actually changing from a non-null to null state deliberately.

Current Code:
  useEffect(() => {
    setRoundRobinChunkInfo(roundRobinChunkInfo ?? null);
  }, [roundRobinChunkInfo, setRoundRobinChunkInfo]);

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +34 to +41
const handleLoadNextRoundRobinChunk = useCallback(() => {
if (!roundRobinChunkInfo?.hasMoreNonFixedHosts || isFetching) return;
const currentOffset = roundRobinChunkSettings?.chunkOffset ?? roundRobinChunkInfo.chunkOffset ?? 0;
setRoundRobinChunkSettings({
manual: true,
chunkOffset: currentOffset + 1,
});
}, [roundRobinChunkInfo, roundRobinChunkSettings, isFetching, setRoundRobinChunkSettings]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

handleLoadNextRoundRobinChunk computes the next offset as currentOffset + 1 where currentOffset = roundRobinChunkSettings?.chunkOffset ?? roundRobinChunkInfo.chunkOffset ?? 0. The fallback reads roundRobinChunkInfo.chunkOffset which is the offset of the currently loaded chunk from the server response. On first load (no manual chunking yet), roundRobinChunkSettings is null, so currentOffset = roundRobinChunkInfo.chunkOffset: the offset of the last auto-loaded chunk. The next request will use chunkOffset + 1. However, in sequential auto mode, the server sets chunkOffset to the index where it stopped (where availability was found), not the total number of chunks loaded. So if the server found availability at chunk 0 (offset 0), the user clicking 'Load More' sends chunkOffset: 1: which is the correct next chunk. This seems correct. But consider: if auto-mode processed chunks 0 and 1 (because chunk 0 had no availability) and stopped at chunk 1 with chunkOffset: 1, clicking 'Load More' sends chunkOffset: 2, skipping to chunk 2: also correct. The logic works. However, there is a subtle race: if the user clicks 'Load More' twice quickly before the first fetch completes, isFetching guard at line 35 should block the second click. But isFetching is derived from schedule.isFetching passed as a prop, and the store state update (via setRoundRobinChunkSettings) happens synchronously while isFetching may not yet be true for the next render cycle. This creates a narrow window where double-clicking could increment chunkOffset twice.

Suggested fix
  const handleLoadNextRoundRobinChunk = useCallback(() => {
    if (!roundRobinChunkInfo?.hasMoreNonFixedHosts || isFetching) return;
    // Use functional update pattern with a ref to prevent double-invocation races
    const currentOffset = roundRobinChunkSettings?.chunkOffset ?? roundRobinChunkInfo.chunkOffset ?? 0;
    setRoundRobinChunkSettings({
      manual: true,
      chunkOffset: currentOffset + 1,
    });
  }, [roundRobinChunkInfo, roundRobinChunkSettings, isFetching, setRoundRobinChunkSettings]);
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts
Lines: 34-41
Issue Type: functional-medium
Severity: medium

Issue Description:
`handleLoadNextRoundRobinChunk` computes the next offset as `currentOffset + 1` where `currentOffset = roundRobinChunkSettings?.chunkOffset ?? roundRobinChunkInfo.chunkOffset ?? 0`. The fallback reads `roundRobinChunkInfo.chunkOffset` which is the offset of the **currently loaded** chunk from the server response. On first load (no manual chunking yet), `roundRobinChunkSettings` is `null`, so `currentOffset = roundRobinChunkInfo.chunkOffset`: the offset of the last auto-loaded chunk. The next request will use `chunkOffset + 1`. However, in sequential auto mode, the server sets `chunkOffset` to the index where it **stopped** (where availability was found), not the total number of chunks loaded. So if the server found availability at chunk 0 (offset 0), the user clicking 'Load More' sends `chunkOffset: 1`: which is the correct next chunk. This seems correct. But consider: if auto-mode processed chunks 0 and 1 (because chunk 0 had no availability) and stopped at chunk 1 with `chunkOffset: 1`, clicking 'Load More' sends `chunkOffset: 2`, skipping to chunk 2: also correct. The logic works. However, there is a subtle race: if the user clicks 'Load More' twice quickly before the first fetch completes, `isFetching` guard at line 35 should block the second click. But `isFetching` is derived from `schedule.isFetching` passed as a prop, and the store state update (via `setRoundRobinChunkSettings`) happens synchronously while `isFetching` may not yet be `true` for the next render cycle. This creates a narrow window where double-clicking could increment `chunkOffset` twice.

Current Code:
  const handleLoadNextRoundRobinChunk = useCallback(() => {
    if (!roundRobinChunkInfo?.hasMoreNonFixedHosts || isFetching) return;
    const currentOffset = roundRobinChunkSettings?.chunkOffset ?? roundRobinChunkInfo.chunkOffset ?? 0;
    setRoundRobinChunkSettings({
      manual: true,
      chunkOffset: currentOffset + 1,
    });
  }, [roundRobinChunkInfo, roundRobinChunkSettings, isFetching, setRoundRobinChunkSettings]);

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +193 to +194
const showLoadMoreButton =
roundRobinChunkInfo?.hasMoreNonFixedHosts && onLoadNextRoundRobinChunk;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

showLoadMoreButton is truthy when roundRobinChunkInfo?.hasMoreNonFixedHosts && onLoadNextRoundRobinChunk: but both renderLoadMoreButton() and the sticky footer (line 303) are gated on showLoadMoreButton. However showLoadMoreButton is used in the scrollable container's className at line 274 with "pb-14". If onLoadNextRoundRobinChunk is defined but hasMoreNonFixedHosts is false, no button is shown and no padding is applied: correct. But the inverse case: if hasMoreNonFixedHosts is true and the callback is undefined (which can happen during SSR or if the parent forgets to pass the callback), the padding is never added but logically the button 'should' appear. More importantly, the Button inside renderLoadMoreButton() re-references onLoadNextRoundRobinChunk directly on line 230 without the nullish guard that showLoadMoreButton provides: if someone calls renderLoadMoreButton() outside this guard, a TypeError: onLoadNextRoundRobinChunk is not a function can occur.

Suggested fix
  const showLoadMoreButton =
    Boolean(roundRobinChunkInfo?.hasMoreNonFixedHosts && onLoadNextRoundRobinChunk);
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 193-194
Issue Type: functional-medium
Severity: medium

Issue Description:
`showLoadMoreButton` is truthy when `roundRobinChunkInfo?.hasMoreNonFixedHosts && onLoadNextRoundRobinChunk`: but both `renderLoadMoreButton()` and the sticky footer (line 303) are gated on `showLoadMoreButton`. However `showLoadMoreButton` is used in the scrollable container's className at line 274 with `"pb-14"`. If `onLoadNextRoundRobinChunk` is defined but `hasMoreNonFixedHosts` is `false`, no button is shown and no padding is applied: correct. But the inverse case: if `hasMoreNonFixedHosts` is `true` and the callback is `undefined` (which can happen during SSR or if the parent forgets to pass the callback), the padding is never added but logically the button 'should' appear. More importantly, the `Button` inside `renderLoadMoreButton()` re-references `onLoadNextRoundRobinChunk` directly on line 230 without the nullish guard that `showLoadMoreButton` provides: if someone calls `renderLoadMoreButton()` outside this guard, a `TypeError: onLoadNextRoundRobinChunk is not a function` can occur.

Current Code:
  const showLoadMoreButton =
    roundRobinChunkInfo?.hasMoreNonFixedHosts && onLoadNextRoundRobinChunk;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +199 to +201
const totalLoadedHosts =
roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
roundRobinChunkInfo.loadedNonFixedHosts;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

The totalLoadedHosts calculation uses roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize + roundRobinChunkInfo.loadedNonFixedHosts. This is only valid when chunkOffset represents the 0-based index of the last loaded chunk. However, in manual chunking mode the server returns the requested chunk's offset directly, which is correct. But in sequential (auto) mode, the offset is the index of the chunk where availability was found: not necessarily the total number of chunks loaded. For example, if chunk 0 had no availability and chunk 1 did, chunkOffset=1 and loadedNonFixedHosts = chunkSize, so totalLoadedHosts = 1*chunkSize + chunkSize = 2*chunkSize, suggesting two chunks were loaded. This matches the auto-sequential behavior. But the progress bar will show an incorrect percentage if chunks have variable sizes (the last chunk may have fewer hosts than chunkSize).

Suggested fix
      const totalLoadedHosts =
        (roundRobinChunkInfo.chunkOffset + 1) * roundRobinChunkInfo.chunkSize;
      // Note: last chunk may be smaller; clamp to totalNonFixedHosts
      const clampedTotalLoadedHosts = Math.min(
        totalLoadedHosts,
        roundRobinChunkInfo.totalNonFixedHosts || roundRobinChunkInfo.totalHosts
      );
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 199-201
Issue Type: functional-medium
Severity: medium

Issue Description:
The `totalLoadedHosts` calculation uses `roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize + roundRobinChunkInfo.loadedNonFixedHosts`. This is only valid when `chunkOffset` represents the 0-based index of the **last loaded** chunk. However, in manual chunking mode the server returns the requested chunk's offset directly, which is correct. But in sequential (auto) mode, the offset is the index of the chunk where availability was found: not necessarily the total number of chunks loaded. For example, if chunk 0 had no availability and chunk 1 did, `chunkOffset=1` and `loadedNonFixedHosts = chunkSize`, so `totalLoadedHosts = 1*chunkSize + chunkSize = 2*chunkSize`, suggesting two chunks were loaded. This matches the auto-sequential behavior. But the progress bar will show an incorrect percentage if chunks have variable sizes (the last chunk may have fewer hosts than `chunkSize`).

Current Code:
      const totalLoadedHosts =
        roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
        roundRobinChunkInfo.loadedNonFixedHosts;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +125 to +126
roundRobinManualChunking: roundRobinChunkSettings?.manual,
roundRobinChunkOffset: roundRobinChunkSettings?.chunkOffset,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

roundRobinChunkOffset is passed directly (potentially undefined) to useSchedule at line 126. Inside useSchedule (useSchedule.ts line 125), the condition typeof roundRobinChunkOffset === 'number' is used to spread it into the query input: so undefined is correctly omitted. However, when roundRobinChunkSettings has chunkOffset: 0, the condition roundRobinChunkSettings?.manual on line 125 is true (manual mode enabled), but chunkOffset is 0. The tRPC input spread at useSchedule.ts:124-125 uses ...(roundRobinManualChunking ? { roundRobinManualChunking: true } : {}) which correctly adds the flag, and ...(typeof roundRobinChunkOffset === 'number' ? { roundRobinChunkOffset } : {}): but roundRobinChunkOffset = 0 is falsy-equivalent, and typeof 0 === 'number' is true, so this is fine. The more subtle bug: if roundRobinChunkSettings is non-null but manual is false, then roundRobinManualChunking will be undefined (not passed), but roundRobinChunkOffset WILL be passed if it's a number. This is inconsistent: a non-manual chunk offset without the manual flag will be sent to the server, potentially causing unexpected behaviour.

Suggested fix
    roundRobinManualChunking: roundRobinChunkSettings?.manual ?? undefined,
    roundRobinChunkOffset: roundRobinChunkSettings?.manual ? roundRobinChunkSettings.chunkOffset : undefined,
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/utils/event.ts
Lines: 125-126
Issue Type: functional-medium
Severity: medium

Issue Description:
`roundRobinChunkOffset` is passed directly (potentially `undefined`) to `useSchedule` at line 126. Inside `useSchedule` (useSchedule.ts line 125), the condition `typeof roundRobinChunkOffset === 'number'` is used to spread it into the query input: so `undefined` is correctly omitted. However, when `roundRobinChunkSettings` has `chunkOffset: 0`, the condition `roundRobinChunkSettings?.manual` on line 125 is `true` (manual mode enabled), but `chunkOffset` is `0`. The tRPC input spread at `useSchedule.ts:124-125` uses `...(roundRobinManualChunking ? { roundRobinManualChunking: true } : {})` which correctly adds the flag, and `...(typeof roundRobinChunkOffset === 'number' ? { roundRobinChunkOffset } : {})`: but `roundRobinChunkOffset = 0` is falsy-equivalent, and `typeof 0 === 'number'` is `true`, so this is fine. The more subtle bug: if `roundRobinChunkSettings` is non-null but `manual` is `false`, then `roundRobinManualChunking` will be `undefined` (not passed), but `roundRobinChunkOffset` WILL be passed if it's a number. This is inconsistent: a non-manual chunk offset without the manual flag will be sent to the server, potentially causing unexpected behaviour.

Current Code:
    roundRobinManualChunking: roundRobinChunkSettings?.manual,
    roundRobinChunkOffset: roundRobinChunkSettings?.chunkOffset,

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +230 to +234
@Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
@IsBoolean()
@IsOptional()
@ApiHideProperty()
roundRobinManualChunking?: boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Security Medium

The @Transform for roundRobinManualChunking uses (value ? value.toLowerCase() === 'true' : false). When value is true (boolean, not string: which happens when the value comes from a non-query-string source such as a JSON body), value.toLowerCase() will throw a TypeError: value.toLowerCase is not a function, crashing the request handler. The existing skipContactOwner field on line 130 has the same pattern and is equally vulnerable. Callers from the internal API path may pass a boolean directly. The transform should handle boolean input as well as string input.

Suggested fix
  @Transform(({ value }) => {
    if (typeof value === "boolean") return value;
    return value ? String(value).toLowerCase() === "true" : false;
  })
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/types/slots/slots-2024-04-15/inputs/index.ts
Lines: 230-234
Issue Type: security-medium
Severity: medium

Issue Description:
The `@Transform` for `roundRobinManualChunking` uses `(value ? value.toLowerCase() === 'true' : false)`. When `value` is `true` (boolean, not string: which happens when the value comes from a non-query-string source such as a JSON body), `value.toLowerCase()` will throw a `TypeError: value.toLowerCase is not a function`, crashing the request handler. The existing `skipContactOwner` field on line 130 has the same pattern and is equally vulnerable. Callers from the internal API path may pass a boolean directly. The transform should handle boolean input as well as string input.

Current Code:
  @Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +114 to +118
@Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
@IsBoolean()
@IsOptional()
@ApiHideProperty()
roundRobinManualChunking?: boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Security Medium

Same TypeError vulnerability as in slots-2024-04-15: (value ? value.toLowerCase() === 'true' : false) will throw if value is already a boolean. Since this is duplicated from the other input class, the same fix applies.

Suggested fix
  @Transform(({ value }) => {
    if (typeof value === "boolean") return value;
    return value ? String(value).toLowerCase() === "true" : false;
  })
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts
Lines: 114-118
Issue Type: security-medium
Severity: medium

Issue Description:
Same `TypeError` vulnerability as in slots-2024-04-15: `(value ? value.toLowerCase() === 'true' : false)` will throw if `value` is already a boolean. Since this is duplicated from the other input class, the same fix applies.

Current Code:
  @Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +160 to +161
roundRobinManualChunking: roundRobinManualChunking ? true : undefined,
roundRobinChunkOffset,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

In the useApiV2AvailableSlots call, roundRobinManualChunking is set via roundRobinManualChunking ? true : undefined (line 160), which means if roundRobinManualChunking is explicitly false (passed from the hook consumer), it becomes undefined: so the server never sees roundRobinManualChunking: false. This is fine for the API since omitting == false. However, roundRobinChunkOffset on line 161 is passed directly without a guard. If roundRobinManualChunking is falsy but roundRobinChunkOffset is a number (e.g. 0), the offset is sent without the manual flag, which is semantically incorrect and could cause unexpected server behaviour as noted in the server schema (the schema accepts them independently). The offset should only be sent when manual chunking is enabled.

Suggested fix
    roundRobinManualChunking: roundRobinManualChunking ? true : undefined,
    roundRobinChunkOffset: roundRobinManualChunking ? roundRobinChunkOffset : undefined,
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/schedules/lib/use-schedule/useSchedule.ts
Lines: 160-161
Issue Type: functional-medium
Severity: medium

Issue Description:
In the `useApiV2AvailableSlots` call, `roundRobinManualChunking` is set via `roundRobinManualChunking ? true : undefined` (line 160), which means if `roundRobinManualChunking` is explicitly `false` (passed from the hook consumer), it becomes `undefined`: so the server never sees `roundRobinManualChunking: false`. This is fine for the API since omitting == false. However, `roundRobinChunkOffset` on line 161 is passed directly without a guard. If `roundRobinManualChunking` is falsy but `roundRobinChunkOffset` is a number (e.g. `0`), the offset is sent without the manual flag, which is semantically incorrect and could cause unexpected server behaviour as noted in the server schema (the schema accepts them independently). The offset should only be sent when manual chunking is enabled.

Current Code:
    roundRobinManualChunking: roundRobinManualChunking ? true : undefined,
    roundRobinChunkOffset,

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

Nitpicks (Low Priority)

Found 4 low-priority suggestions for code improvement

Click to expand nitpicks

apps/web/public/static/locales/en/common.json (line 586)

Maintainability Low

The translation key round_robin_reset_hosts is added to en/common.json (line 586) but is never referenced in any of the changed source files. Neither AvailableTimeSlots.tsx, BookerWebWrapper.tsx, BookerPlatformWrapper.tsx, nor useRoundRobinChunking.ts call t('round_robin_reset_hosts'). This is dead localisation string that will cause confusion for translators and adds noise to translation files without being exercised.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/public/static/locales/en/common.json
Lines: 586-586
Issue Type: maintainability-low
Severity: low

Issue Description:
The translation key `round_robin_reset_hosts` is added to `en/common.json` (line 586) but is never referenced in any of the changed source files. Neither `AvailableTimeSlots.tsx`, `BookerWebWrapper.tsx`, `BookerPlatformWrapper.tsx`, nor `useRoundRobinChunking.ts` call `t('round_robin_reset_hosts')`. This is dead localisation string that will cause confusion for translators and adds noise to translation files without being exercised.

Current Code:
  "round_robin_reset_hosts": "Reset host selection",

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



apps/web/modules/bookings/components/AvailableTimeSlots.tsx (lines 208-222)

Maintainability Low

The ProgressIcon SVG is constructed inside renderLoadMoreButton() which is itself called inside the JSX render path. This means a new React element (and SVG object) is created on every render. Additionally, renderLoadMoreButton is a plain function (not a component or memoized value), so it cannot be optimised by React's reconciler: every call creates new element instances. The SVG also uses a hardcoded stroke="#FFFFFF" which will not adapt to dark/light themes or any custom brand color, and stroke="rgba(255,255,255,0.35)" is similarly hardcoded. These should use Tailwind CSS currentColor or a CSS variable tied to the button's text color.

Code Suggestion or Comments
<circle
          cx="10"
          cy="10"
          r="8"
          stroke="currentColor"
          strokeWidth="2"
          fill="none"
          strokeDasharray={`${dashArray} ${circumference}`}
          strokeLinecap="round"
          transform="rotate(-90 10 10)"
        />
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 208-222
Issue Type: maintainability-low
Severity: low

Issue Description:
The `ProgressIcon` SVG is constructed inside `renderLoadMoreButton()` which is itself called inside the JSX render path. This means a new React element (and SVG object) is created on every render. Additionally, `renderLoadMoreButton` is a plain function (not a component or memoized value), so it cannot be optimised by React's reconciler: every call creates new element instances. The SVG also uses a hardcoded `stroke="#FFFFFF"` which will not adapt to dark/light themes or any custom brand color, and `stroke="rgba(255,255,255,0.35)"` is similarly hardcoded. These should use Tailwind CSS `currentColor` or a CSS variable tied to the button's text color.

Current Code:
      <circle
          cx="10"
          cy="10"
          r="8"
          stroke="#FFFFFF"
          strokeWidth="2"
          fill="none"
          strokeDasharray={`${dashArray} ${circumference}`}
          strokeLinecap="round"
          transform="rotate(-90 10 10)"
        />

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



apps/web/modules/bookings/components/BookerWebWrapper.tsx (lines 164-177)

Style Low

The useRoundRobinChunking call has inconsistent indentation: the resetDeps array opening bracket is on the same line as the key but the closing bracket is indented to match the function body instead of the resetDeps key level. The object literal inside useRoundRobinChunking({...}) is also split across two lines (lines 164-165) without consistent alignment. This deviates from the prettier/eslint formatting of the rest of the file.

Code Suggestion or Comments
const { roundRobinChunkInfo, handleLoadNextRoundRobinChunk } = useRoundRobinChunking({
    roundRobinChunkInfo: schedule.data?.roundRobinChunkInfo,
    isFetching: schedule.isFetching,
    roundRobinChunkSettings,
    setRoundRobinChunkSettings,
    resetDeps: [
      props.username,
      props.eventSlug,
      props.entity.orgSlug,
      props.entity.eventTypeId,
      event.data?.id,
    ],
  });
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/BookerWebWrapper.tsx
Lines: 164-177
Issue Type: style-low
Severity: low

Issue Description:
The `useRoundRobinChunking` call has inconsistent indentation: the `resetDeps` array opening bracket is on the same line as the key but the closing bracket is indented to match the function body instead of the `resetDeps` key level. The object literal inside `useRoundRobinChunking({...})` is also split across two lines (lines 164-165) without consistent alignment. This deviates from the prettier/eslint formatting of the rest of the file.

Current Code:
  const { roundRobinChunkInfo, handleLoadNextRoundRobinChunk } =
    useRoundRobinChunking({
      roundRobinChunkInfo: schedule.data?.roundRobinChunkInfo,
      isFetching: schedule.isFetching,
      roundRobinChunkSettings,
      setRoundRobinChunkSettings,
      resetDeps: [
      props.username,
      props.eventSlug,
      props.entity.orgSlug,
      props.entity.eventTypeId,
      event.data?.id,
    ],
  });

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



packages/features/bookings/Booker/store.ts (lines 504-508)

Maintainability Low

The roundRobinChunkSettings and roundRobinChunkInfo store fields are never reset when initialize() is called (lines 349-451). If a user navigates from one event type to another without a full page reload, the store is re-initialized via initialize(), but the chunk settings and info from the previous event type persist. This means the next schedule query for a different event type could be made with an incorrect chunkOffset or manual: true flag inherited from the prior event, returning wrong/stale availability. The initialize() function should explicitly reset these two fields.

Code Suggestion or Comments
roundRobinChunkSettings: null,
    setRoundRobinChunkSettings: (settings: RoundRobinChunkSettings | null) =>
      set({ roundRobinChunkSettings: settings }),
    roundRobinChunkInfo: null,
    setRoundRobinChunkInfo: (info: RoundRobinChunkInfo | null) => set({ roundRobinChunkInfo: info }),
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/store.ts
Lines: 504-508
Issue Type: maintainability-low
Severity: low

Issue Description:
The `roundRobinChunkSettings` and `roundRobinChunkInfo` store fields are never reset when `initialize()` is called (lines 349-451). If a user navigates from one event type to another without a full page reload, the store is re-initialized via `initialize()`, but the chunk settings and info from the previous event type persist. This means the next schedule query for a different event type could be made with an incorrect `chunkOffset` or `manual: true` flag inherited from the prior event, returning wrong/stale availability. The `initialize()` function should explicitly reset these two fields.

Current Code:
    roundRobinChunkSettings: null,
    setRoundRobinChunkSettings: (settings: RoundRobinChunkSettings | null) =>
      set({ roundRobinChunkSettings: settings }),
    roundRobinChunkInfo: null,
    setRoundRobinChunkInfo: (info: RoundRobinChunkInfo | null) => set({ roundRobinChunkInfo: info }),

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



Like Dislike

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Implements progressive loading of Round Robin host availability in chunks when teams have 100+ non-fixed hosts, improving performance for large teams.
  • Adds manual "Load more" pagination with progress indicators for users to fetch additional host availability on demand.
  • Introduces RoundRobinChunkInfo metadata to track pagination state across API and UI layers.

Key Changes by Area

Backend Chunking Logic: Added calculateAvailabilityWithRoundRobinChunks() in packages/trpc/server/routers/viewer/slots/util.ts that processes hosts in dynamic chunks (20% of total, max 50) with early termination when slots are found.

API & Types: Extended slot query inputs with roundRobinManualChunking and roundRobinChunkOffset parameters across tRPC and platform API types.

Frontend State Management: New useRoundRobinChunking hook manages chunk loading state, integrated into both web and platform Booker wrappers.

UI Components: Sticky "Load more availability" button with progress ring in AvailableTimeSlots.tsx, disabled during fetches to prevent duplicates.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added "Load more" button with progress indicator and disabled state during fetching
apps/web/modules/bookings/components/Booker.tsx Receives onLoadNextRoundRobinChunk callback, passes to child components
apps/web/modules/bookings/components/BookerWebWrapper.tsx Integrates useRoundRobinChunking hook for web Booker
apps/web/public/static/locales/en/common.json Added translation strings for chunking UI
packages/features/bookings/Booker/tests/test-utils.tsx Test utilities updated for chunking state
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook managing chunk loading state and API coordination
packages/features/bookings/Booker/store.ts Extended store with roundRobinChunkSettings and roundRobinChunkInfo
packages/features/bookings/Booker/types.ts Added chunk-related types to Booker types
packages/features/bookings/Booker/utils/event.ts Utility updates for chunking support
packages/features/bookings/lib/bookingCreateBodySchema.ts Schema updates for chunking parameters
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Accepts chunking parameters for API v2 slots
packages/features/schedules/lib/use-schedule/useSchedule.ts Accepts roundRobinManualChunking and roundRobinChunkOffset
packages/lib/types/roundRobinChunkInfo.ts New type definition for chunk metadata
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Integrates useRoundRobinChunking for platform Booker
packages/platform/atoms/hooks/useAvailableSlots.ts Updated to pass chunking parameters
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added chunking fields to platform API
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added chunking fields to newer platform API version
packages/trpc/server/routers/viewer/slots/types.ts Added roundRobinManualChunking and roundRobinChunkOffset to input schema
packages/trpc/server/routers/viewer/slots/util.test.ts Comprehensive tests for chunking logic, offsets, and weight preservation
packages/trpc/server/routers/viewer/slots/util.ts Core chunking implementation with dynamic sizing and early termination

Review Focus Areas

  • Chunk size calculation logic: Verify min(50, ceil(totalHosts * 0.2)) handles edge cases (exactly 100 hosts, very large teams).
  • Race conditions in manual chunking: Check that rapid "Load more" clicks are properly debounced/disabled via fetching state.
  • Fixed host handling: Confirm fixed hosts are correctly included in every chunk alongside rotating non-fixed hosts.

Architecture

Design Decisions:

  • Automatic chunking triggers at 100+ non-fixed hosts with weights disabled. This threshold balances performance gain against complexity for smaller teams.
  • Early termination on first available slots found trades completeness for speed. This is intentional: users see some availability faster rather than waiting for all hosts.
  • Manual chunking (roundRobinManualChunking flag) separates automatic backend chunking from user-driven pagination. When manual mode is on, backend returns single chunks and frontend controls offset progression.

Scalability & Extensibility:

  • Dynamic chunk sizing (20% proportional, 50 cap) allows the system to adapt to team sizes without configuration. Out of scope: configurable chunk percentages or admin-tunable thresholds.
  • RoundRobinChunkInfo type is versioned and extensible for future pagination patterns (cursor-based, etc.).

Risks:

  • Intentional: Early termination means users may not see all available slots if sufficient slots exist in early chunks. Acceptable tradeoff for perceived performance.
  • Unintentional: Weight-based host ordering must be preserved across chunks. Tests cover this but production data edge cases (equal weights, weight collisions) need validation.

Comment on lines +29 to +32
useEffect(() => {
setRoundRobinChunkSettings(null);
setRoundRobinChunkInfo(null);
}, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional High

The reset useEffect spreads resetDeps into the dependency array using the spread operator (...resetDeps). This violates the React hooks rules: dependency arrays must be statically analyzable literals; spreading a dynamic array causes the effect to run on every render (since the identity of the spread values changes each render when an array literal is passed), or alternatively to be entirely ignored by React's linter, making the reset behavior unreliable. In BookerWebWrapper.tsx (line 170), the resetDeps array is created inline as a new array literal on every render, so this effect fires on every render, clearing both roundRobinChunkSettings and roundRobinChunkInfo immediately after they are set: effectively preventing the chunking feature from ever advancing beyond the first chunk. The setRoundRobinChunkInfo and setRoundRobinChunkSettings function references are stable (Zustand setters), but they are included in the deps alongside the spread, which compounds the issue.

Suggested fix
  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => {
    setRoundRobinChunkSettings(null);
    setRoundRobinChunkInfo(null);
    // resetDeps intentionally spread — callers must memoize this array
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts
Lines: 29-32
Issue Type: functional-high
Severity: high

Issue Description:
The reset `useEffect` spreads `resetDeps` into the dependency array using the spread operator (`...resetDeps`). This violates the React hooks rules: dependency arrays must be statically analyzable literals; spreading a dynamic array causes the effect to run on every render (since the identity of the spread values changes each render when an array literal is passed), or alternatively to be entirely ignored by React's linter, making the reset behavior unreliable. In `BookerWebWrapper.tsx` (line 170), the `resetDeps` array is created inline as a new array literal on every render, so this effect fires on every render, clearing both `roundRobinChunkSettings` and `roundRobinChunkInfo` immediately after they are set: effectively preventing the chunking feature from ever advancing beyond the first chunk. The `setRoundRobinChunkInfo` and `setRoundRobinChunkSettings` function references are stable (Zustand setters), but they are included in the deps alongside the spread, which compounds the issue.

Current Code:
  useEffect(() => {
    setRoundRobinChunkSettings(null);
    setRoundRobinChunkInfo(null);
  }, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +25 to +27
useEffect(() => {
setRoundRobinChunkInfo(roundRobinChunkInfo ?? null);
}, [roundRobinChunkInfo, setRoundRobinChunkInfo]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

The first useEffect writes roundRobinChunkInfo to the store unconditionally on every change. The second useEffect (the reset effect) also calls setRoundRobinChunkInfo(null). Because both effects run on the same render cycle when resetDeps changes, the order of execution between effects 1 and 2 is deterministic (effect 1 runs before effect 2 in declaration order), but effect 1 runs again after effect 2 resets to null: if roundRobinChunkInfo prop is still non-null from the previous schedule data, it will re-populate the store with stale chunk info from the old event/user. This creates a race where a user navigates to a new event type: the reset effect clears chunk info, but the sync effect immediately restores the stale chunk info from the previous schedule query (which hasn't been garbage-collected yet by react-query).

Suggested fix
  const isResettingRef = useRef(false);

  useEffect(() => {
    if (!isResettingRef.current) {
      setRoundRobinChunkInfo(roundRobinChunkInfo ?? null);
    }
    isResettingRef.current = false;
  }, [roundRobinChunkInfo, setRoundRobinChunkInfo]);

  useEffect(() => {
    isResettingRef.current = true;
    setRoundRobinChunkSettings(null);
    setRoundRobinChunkInfo(null);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts
Lines: 25-27
Issue Type: functional-medium
Severity: medium

Issue Description:
The first `useEffect` writes `roundRobinChunkInfo` to the store unconditionally on every change. The second `useEffect` (the reset effect) also calls `setRoundRobinChunkInfo(null)`. Because both effects run on the same render cycle when `resetDeps` changes, the order of execution between effects 1 and 2 is deterministic (effect 1 runs before effect 2 in declaration order), but effect 1 runs again after effect 2 resets to null: if `roundRobinChunkInfo` prop is still non-null from the previous schedule data, it will re-populate the store with stale chunk info from the old event/user. This creates a race where a user navigates to a new event type: the reset effect clears chunk info, but the sync effect immediately restores the stale chunk info from the previous schedule query (which hasn't been garbage-collected yet by react-query).

Current Code:
  useEffect(() => {
    setRoundRobinChunkInfo(roundRobinChunkInfo ?? null);
  }, [roundRobinChunkInfo, setRoundRobinChunkInfo]);

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +199 to +201
const totalLoadedHosts =
roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
roundRobinChunkInfo.loadedNonFixedHosts;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

The progress calculation for the "Load more" button computes totalLoadedHosts using chunkOffset * chunkSize + loadedNonFixedHosts. This formula is incorrect: chunkOffset is a zero-based index of the current chunk, not the count of fully processed previous chunks. When the user is on chunk 0 (the first chunk), chunkOffset * chunkSize = 0, so totalLoadedHosts = loadedNonFixedHosts which is correct. But on chunk 1, totalLoadedHosts = 1 * chunkSize + loadedNonFixedHosts = chunkSize + chunkSize, double-counting. The correct formula to get the cumulative loaded count should be (chunkOffset + 1) * chunkSize capped at totalNonFixedHosts, or more simply (chunkOffset * chunkSize) + loadedNonFixedHosts: BUT only if loadedNonFixedHosts represents the count for the current chunk alone (which it does per the RoundRobinChunkInfo type). That part is actually correct. However, looking at the auto-chunking logic in util.ts: when hasMoreNonFixedHosts = true the user is shown the button, and chunkOffset is the index of the last loaded chunk. The calculation is in fact (chunkOffset * chunkSize) + loadedNonFixedHosts. For chunk 0 with 21 loaded: 0*50+21=21. For chunk 1 with 21 loaded: 1*50+21=71. This actually appears to be double-counting (50+21=71 when only 71 total were loaded, which happens to be numerically right but accidentally). The real bug is when loadedNonFixedHosts < chunkSize (last chunk): e.g., total=105, chunkSize=21, chunkOffset=4, loadedNonFixedHosts=21: 4*21+21=105 ✓. But on intermediate chunks, a user could receive progressPercentage > 100 if roundRobinChunkInfo becomes stale and totalHosts is 0, which is guarded by the totalHosts > 0 check. The Math.min(100, ...) caps it. The bigger concern is that the formula conflates chunkOffset (0-based index of the most recently fetched chunk) with the number of fully-fetched previous chunks. If in manual mode chunkOffset = 3 but chunks 0-2 were never fetched, the progress would report 3*chunkSize + loadedNonFixedHosts as if all 3 prior chunks were processed.

Suggested fix
      const totalLoadedHosts = Math.min(
        (roundRobinChunkInfo.chunkOffset + 1) * roundRobinChunkInfo.chunkSize,
        roundRobinChunkInfo.totalNonFixedHosts || roundRobinChunkInfo.totalHosts || 0
      );
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 199-201
Issue Type: functional-medium
Severity: medium

Issue Description:
The progress calculation for the "Load more" button computes `totalLoadedHosts` using `chunkOffset * chunkSize + loadedNonFixedHosts`. This formula is incorrect: `chunkOffset` is a zero-based index of the current chunk, not the count of fully processed previous chunks. When the user is on chunk 0 (the first chunk), `chunkOffset * chunkSize = 0`, so `totalLoadedHosts = loadedNonFixedHosts` which is correct. But on chunk 1, `totalLoadedHosts = 1 * chunkSize + loadedNonFixedHosts = chunkSize + chunkSize`, double-counting. The correct formula to get the cumulative loaded count should be `(chunkOffset + 1) * chunkSize` capped at `totalNonFixedHosts`, or more simply `(chunkOffset * chunkSize) + loadedNonFixedHosts`: BUT only if `loadedNonFixedHosts` represents the count for the current chunk alone (which it does per the `RoundRobinChunkInfo` type). That part is actually correct. However, looking at the auto-chunking logic in `util.ts`: when `hasMoreNonFixedHosts = true` the user is shown the button, and `chunkOffset` is the index of the last loaded chunk. The calculation is in fact `(chunkOffset * chunkSize) + loadedNonFixedHosts`. For chunk 0 with 21 loaded: `0*50+21=21`. For chunk 1 with 21 loaded: `1*50+21=71`. This actually appears to be double-counting (50+21=71 when only 71 total were loaded, which happens to be numerically right but accidentally). The real bug is when `loadedNonFixedHosts < chunkSize` (last chunk): e.g., total=105, chunkSize=21, chunkOffset=4, loadedNonFixedHosts=21: `4*21+21=105` ✓. But on intermediate chunks, a user could receive `progressPercentage > 100` if `roundRobinChunkInfo` becomes stale and `totalHosts` is 0, which is guarded by the `totalHosts > 0` check. The `Math.min(100, ...)` caps it. The bigger concern is that the formula conflates `chunkOffset` (0-based index of the most recently fetched chunk) with the number of fully-fetched previous chunks. If in manual mode `chunkOffset = 3` but chunks 0-2 were never fetched, the progress would report `3*chunkSize + loadedNonFixedHosts` as if all 3 prior chunks were processed.

Current Code:
      const totalLoadedHosts =
        roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
        roundRobinChunkInfo.loadedNonFixedHosts;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +125 to +126
roundRobinManualChunking: roundRobinChunkSettings?.manual,
roundRobinChunkOffset: roundRobinChunkSettings?.chunkOffset,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

roundRobinManualChunking is passed as roundRobinChunkSettings?.manual which can be false (when settings are set with manual: false). In useSchedule.ts lines 124-125, when roundRobinManualChunking is falsy, the parameter is omitted from the input object: ...(roundRobinManualChunking ? { roundRobinManualChunking: true } : {}). This means a manual: false setting is silently dropped, which is the intended behavior. However, roundRobinChunkOffset is passed directly as roundRobinChunkSettings?.chunkOffset and in useSchedule.ts it's only conditionally spread: ...(typeof roundRobinChunkOffset === 'number' ? { roundRobinChunkOffset } : {}). When roundRobinChunkSettings is null (default), chunkOffset is undefined, so offset is correctly omitted. But if roundRobinChunkSettings has manual: false but a non-zero chunkOffset, the offset IS sent to the server without roundRobinManualChunking: true. The server would then receive an offset without the manual flag, causing it to use auto-chunking from offset N rather than from 0, potentially returning incorrect slot data.

Suggested fix
    roundRobinManualChunking: roundRobinChunkSettings?.manual || undefined,
    roundRobinChunkOffset: roundRobinChunkSettings?.manual ? roundRobinChunkSettings.chunkOffset : undefined,
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/utils/event.ts
Lines: 125-126
Issue Type: functional-medium
Severity: medium

Issue Description:
`roundRobinManualChunking` is passed as `roundRobinChunkSettings?.manual` which can be `false` (when settings are set with `manual: false`). In `useSchedule.ts` lines 124-125, when `roundRobinManualChunking` is falsy, the parameter is omitted from the input object: `...(roundRobinManualChunking ? { roundRobinManualChunking: true } : {})`. This means a `manual: false` setting is silently dropped, which is the intended behavior. However, `roundRobinChunkOffset` is passed directly as `roundRobinChunkSettings?.chunkOffset` and in `useSchedule.ts` it's only conditionally spread: `...(typeof roundRobinChunkOffset === 'number' ? { roundRobinChunkOffset } : {})`. When `roundRobinChunkSettings` is `null` (default), `chunkOffset` is `undefined`, so offset is correctly omitted. But if `roundRobinChunkSettings` has `manual: false` but a non-zero `chunkOffset`, the offset IS sent to the server without `roundRobinManualChunking: true`. The server would then receive an offset without the manual flag, causing it to use auto-chunking from offset N rather than from 0, potentially returning incorrect slot data.

Current Code:
    roundRobinManualChunking: roundRobinChunkSettings?.manual,
    roundRobinChunkOffset: roundRobinChunkSettings?.chunkOffset,

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +230 to +234
@Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
@IsBoolean()
@IsOptional()
@ApiHideProperty()
roundRobinManualChunking?: boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Robustness Medium

The @Transform for roundRobinManualChunking uses (value ? value.toLowerCase() === 'true' : false). When value is already a boolean true (passed programmatically, not from a query string), calling value.toLowerCase() on a boolean will throw a TypeError: value.toLowerCase is not a function. The same pattern exists in slots-2024-09-04/inputs/get-slots.input.ts line 114. The existing isTeamEvent field on line 197 of the same file has the same pattern but has been shipping without issue: however, for a new field this is a latent bug that would surface if the API is called programmatically with a boolean value.

Also reported at: packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts L114–L118

Suggested fix
  @Transform(({ value }) => {
    if (typeof value === "boolean") return value;
    if (value === undefined || value === null) return false;
    return String(value).toLowerCase() === "true";
  })
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/types/slots/slots-2024-04-15/inputs/index.ts
Lines: 230-234
Issue Type: robustness-medium
Severity: medium

Issue Description:
The `@Transform` for `roundRobinManualChunking` uses `(value ? value.toLowerCase() === 'true' : false)`. When `value` is already a boolean `true` (passed programmatically, not from a query string), calling `value.toLowerCase()` on a boolean will throw a `TypeError: value.toLowerCase is not a function`. The same pattern exists in `slots-2024-09-04/inputs/get-slots.input.ts` line 114. The existing `isTeamEvent` field on line 197 of the same file has the same pattern but has been shipping without issue: however, for a new field this is a latent bug that would surface if the API is called programmatically with a boolean value.

_Also reported at: `packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts` L114–L118_

Current Code:
  @Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Implements progressive loading for Round Robin availability queries by chunking non-fixed hosts (20% of total, max 50) when teams exceed 100 hosts.
  • Adds UI controls and state management for users to manually load additional host chunks on demand.
  • Extends API and type schemas across tRPC and platform APIs to support chunked pagination parameters.

Key Changes by Area

Backend/Availability Engine: Added calculateAvailabilityWithRoundRobinChunks() in packages/trpc/server/routers/viewer/slots/util.ts:1021-1173 with dynamic chunk sizing, sequential processing until availability found, and early termination optimization.

Frontend/Booker UI: New useRoundRobinChunking hook manages chunk state. AvailableTimeSlots.tsx:190-240 adds "Load more availability" button with progress indicator showing percentage of hosts loaded.

API/Types: Extended input schemas in tRPC (types.ts) and platform API (slots-2024-04-15, slots-2024-09-04) with roundRobinManualChunking and roundRobinChunkOffset. New RoundRobinChunkInfo type tracks pagination metadata.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added "Load more availability" button with circular progress indicator for chunked loading
apps/web/modules/bookings/components/Booker.tsx Integrated chunk loading state and callbacks
apps/web/modules/bookings/components/BookerWebWrapper.tsx Connected round robin chunk handlers to booking flow
apps/web/public/static/locales/en/common.json Added translation keys for chunk loading UI (note: round_robin_reset_hosts appears unused)
packages/features/bookings/Booker/tests/test-utils.tsx Test utilities updated for chunking state
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook managing chunk offset state and load next chunk callback
packages/features/bookings/Booker/store.ts Added roundRobinChunkSettings and roundRobinChunkInfo to store (note: type overlap with RoundRobinChunkInfo)
packages/features/bookings/Booker/types.ts Updated types for chunk settings
packages/features/bookings/Booker/utils/event.ts Utility updates for chunk handling
packages/features/bookings/lib/bookingCreateBodySchema.ts Schema updates for chunk parameters
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Added chunk parameter support to API v2 slots hook
packages/features/schedules/lib/use-schedule/useSchedule.ts Integrated chunk offset into schedule fetching
packages/lib/types/roundRobinChunkInfo.ts New type for chunk metadata (note: totalHosts/totalNonFixedHosts ambiguity)
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Integrated chunking hook and load next chunk callback
packages/platform/atoms/hooks/useAvailableSlots.ts Added chunk parameters to available slots query
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added roundRobinManualChunking and roundRobinChunkOffset to platform API
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added chunk parameters to updated platform API
packages/trpc/server/routers/viewer/slots/types.ts Added chunk parameters to tRPC input schema
packages/trpc/server/routers/viewer/slots/util.test.ts Comprehensive tests for chunking logic, dynamic sizing, manual offsets, and weight preservation
packages/trpc/server/routers/viewer/slots/util.ts Core chunking implementation with dynamic sizing and early termination

Review Focus Areas

  • Type consistency between RoundRobinChunkSettings (store.ts:84-87) and RoundRobinChunkInfo (roundRobinChunkInfo.ts) - overlapping fields with different naming.
  • Semantics of totalHosts vs totalNonFixedHosts in RoundRobinChunkInfo - fallback pattern suggests potential for incorrect zero values.
  • Verify round_robin_reset_hosts translation key is either used or removed before merge.

Architecture

Design Decisions: Dynamic chunk sizing (20% of hosts, max 50) balances latency vs. request count for large teams. Early termination when availability is found avoids unnecessary work. Fixed hosts are always included in each chunk to preserve collective availability constraints. Manual chunking mode enables progressive UI loading separate from automatic backend optimization.

Risks:

  • Intentional: Type duplication between store and lib packages creates maintenance burden (accepted tradeoff for package boundaries).
  • Unintentional: Ambiguous fallback logic for totalNonFixedHosts || totalHosts could mask data issues; totalNonFixedHosts being 0 is semantically different from undefined.

Comment on lines +29 to +32
useEffect(() => {
setRoundRobinChunkSettings(null);
setRoundRobinChunkInfo(null);
}, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional High

Spread syntax with dynamic arrays in useEffect dependency array is invalid React Hook usage. The eslint-plugin-react-hooks rule explicitly forbids spreading an array into a dependency array ([setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]). React requires dependency arrays to be static (fixed-length literal arrays) so it can run its static analysis. At runtime the spread still works as plain JavaScript, but since resetDeps can change length between renders (e.g., if the caller passes a different-length array), the effect will behave inconsistently and React will emit a lint error / may produce stale-closure bugs. The effect is supposed to reset chunk state whenever the event identity changes, but because of this dynamic spread the dependency list is not stable across renders. The correct pattern is to accept a stable primitive hash or use a dedicated useEffect in the caller.

Suggested fix
  // Derive a stable string key from the reset dependencies so the
  // hook rule is satisfied and length changes can't silently break things.
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const resetKey = resetDeps.map(String).join("|");

  useEffect(() => {
    setRoundRobinChunkSettings(null);
    setRoundRobinChunkInfo(null);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [resetKey, setRoundRobinChunkInfo, setRoundRobinChunkSettings]);
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts
Lines: 29-32
Issue Type: functional-high
Severity: high

Issue Description:
Spread syntax with dynamic arrays in `useEffect` dependency array is invalid React Hook usage. The eslint-plugin-react-hooks rule explicitly forbids spreading an array into a dependency array (`[setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]`). React requires dependency arrays to be static (fixed-length literal arrays) so it can run its static analysis. At runtime the spread still works as plain JavaScript, but since `resetDeps` can change length between renders (e.g., if the caller passes a different-length array), the effect will behave inconsistently and React will emit a lint error / may produce stale-closure bugs. The effect is supposed to reset chunk state whenever the event identity changes, but because of this dynamic spread the dependency list is not stable across renders. The correct pattern is to accept a stable primitive hash or use a dedicated `useEffect` in the caller.

Current Code:
  useEffect(() => {
    setRoundRobinChunkSettings(null);
    setRoundRobinChunkInfo(null);
  }, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +199 to +201
const totalLoadedHosts =
roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
roundRobinChunkInfo.loadedNonFixedHosts;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

Progress percentage calculation is incorrect. chunkOffset * chunkSize computes the number of non-fixed hosts in previously completed chunks. Adding loadedNonFixedHosts (the count in the current chunk) would double-count the current chunk because chunkOffset already counts the current chunk index (0-based). For example, at offset=1 with chunkSize=21 and loadedNonFixedHosts=21, the formula gives 21*21+21=462 out of 105 total → 100%, but only 2 chunks of 5 have been loaded, so the true progress is ~40%.

The correct formula is: totalLoadedHosts = (chunkOffset) * chunkSize + loadedNonFixedHosts: but chunkOffset is 0-based, so it already equals the number of completed prior chunks. The current code at line 200 does exactly this (chunkOffset * chunkSize + loadedNonFixedHosts). The bug is subtle: when the server returns chunkOffset=1 it means the first index at which data was returned, i.e., 1 prior chunk has been fully processed: so the formula is actually correct for sequential mode but may give >100% in manual mode when chunkOffset jumps ahead. The real issue is the absence of a Math.min guard for the numerator.

Suggested fix
      const totalLoadedHosts = Math.min(
        roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
          roundRobinChunkInfo.loadedNonFixedHosts,
        roundRobinChunkInfo.totalNonFixedHosts || roundRobinChunkInfo.totalHosts || 0
      );
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 199-201
Issue Type: functional-medium
Severity: medium

Issue Description:
Progress percentage calculation is incorrect. `chunkOffset * chunkSize` computes the number of non-fixed hosts in *previously completed* chunks. Adding `loadedNonFixedHosts` (the count in the *current* chunk) would double-count the current chunk because `chunkOffset` already counts the current chunk index (0-based). For example, at offset=1 with chunkSize=21 and loadedNonFixedHosts=21, the formula gives 21*21+21=462 out of 105 total → 100%, but only 2 chunks of 5 have been loaded, so the true progress is ~40%.

The correct formula is: `totalLoadedHosts = (chunkOffset) * chunkSize + loadedNonFixedHosts`: but `chunkOffset` is 0-based, so it already equals the number of *completed prior* chunks. The current code at line 200 does exactly this (`chunkOffset * chunkSize + loadedNonFixedHosts`). The bug is subtle: when the server returns `chunkOffset=1` it means the *first index at which data was returned*, i.e., 1 prior chunk has been fully processed: so the formula is actually correct for sequential mode but may give >100% in manual mode when `chunkOffset` jumps ahead. The real issue is the absence of a `Math.min` guard for the numerator.

Current Code:
      const totalLoadedHosts =
        roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
        roundRobinChunkInfo.loadedNonFixedHosts;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

cx="10"
cy="10"
r="8"
stroke="#FFFFFF"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Security Medium

Hard-coded color value #FFFFFF is used for the SVG progress ring stroke. This is a presentational concern but it means the button icon will be invisible on light-themed or high-contrast mode backgrounds. More importantly, using hard-coded hex literals rather than CSS custom-property tokens bypasses the application's theming contract and accessibility guarantees (prefers-contrast: more). The surrounding circle already uses a CSS class text-emphasis, suggesting the intent was to use the design token; the progress arc should follow suit.

Suggested change
stroke="#FFFFFF"
stroke="currentColor"
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 215-215
Issue Type: security-medium
Severity: medium

Issue Description:
Hard-coded color value `#FFFFFF` is used for the SVG progress ring stroke. This is a presentational concern but it means the button icon will be invisible on light-themed or high-contrast mode backgrounds. More importantly, using hard-coded hex literals rather than CSS custom-property tokens bypasses the application's theming contract and accessibility guarantees (`prefers-contrast: more`). The surrounding circle already uses a CSS class `text-emphasis`, suggesting the intent was to use the design token; the progress arc should follow suit.

Current Code:
          stroke="#FFFFFF"

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +196 to +237
const renderLoadMoreButton = () => {
if (!showLoadMoreButton) return null;

const totalLoadedHosts =
roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
roundRobinChunkInfo.loadedNonFixedHosts;
const totalHosts = roundRobinChunkInfo.totalNonFixedHosts || roundRobinChunkInfo.totalHosts || 0;
const progressPercentage =
totalHosts > 0 ? Math.min(100, Math.round((totalLoadedHosts / totalHosts) * 100)) : 0;
const circumference = 2 * Math.PI * 8;
const dashArray = (progressPercentage / 100) * circumference;

const ProgressIcon = (
<svg width="20" height="20" viewBox="0 0 20 20" className="text-emphasis" aria-hidden>
<circle cx="10" cy="10" r="8" stroke="rgba(255,255,255,0.35)" strokeWidth="2" fill="none" />
<circle
cx="10"
cy="10"
r="8"
stroke="#FFFFFF"
strokeWidth="2"
fill="none"
strokeDasharray={`${dashArray} ${circumference}`}
strokeLinecap="round"
transform="rotate(-90 10 10)"
/>
</svg>
);

return (
<Button
type="button"
color="primary"
className="w-full justify-center gap-2"
onClick={onLoadNextRoundRobinChunk}
disabled={isLoading || schedule?.isFetching}
CustomStartIcon={ProgressIcon}
aria-label={t("round_robin_load_next_hosts")}>
{t("round_robin_load_next_hosts")}
</Button>
);
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Performance Medium

renderLoadMoreButton is defined as a plain function inside the component body and re-creates the entire ProgressIcon JSX subtree (including circumference, dashArray calculations and two SVG circle nodes) on every render, regardless of whether the chunk info has changed. Since showLoadMoreButton already guards the container, the function should at minimum be wrapped in useMemo to avoid re-computing the SVG on every parent re-render. The recalculation is cheap individually but happens on every slot-hover or form-field interaction.

Suggested fix
  const loadMoreButton = useMemo(() => {
    if (!showLoadMoreButton) return null;

    const totalLoadedHosts =
      roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
      roundRobinChunkInfo.loadedNonFixedHosts;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 196-237
Issue Type: performance-medium
Severity: medium

Issue Description:
`renderLoadMoreButton` is defined as a plain function inside the component body and re-creates the entire `ProgressIcon` JSX subtree (including `circumference`, `dashArray` calculations and two SVG circle nodes) on every render, regardless of whether the chunk info has changed. Since `showLoadMoreButton` already guards the container, the function should at minimum be wrapped in `useMemo` to avoid re-computing the SVG on every parent re-render. The recalculation is cheap individually but happens on every slot-hover or form-field interaction.

Current Code:
  const renderLoadMoreButton = () => {
    if (!showLoadMoreButton) return null;

    const totalLoadedHosts =
      roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
      roundRobinChunkInfo.loadedNonFixedHosts;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

skipContactOwner: z.boolean().nullish(),
rrHostSubsetIds: z.array(z.number()).nullish(),
roundRobinManualChunking: z.boolean().optional(),
roundRobinChunkOffset: z.coerce.number().int().min(0).optional(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Robustness Medium

roundRobinChunkOffset is validated with .min(0) on the server schema, but on the client side in useRoundRobinChunking.ts handleLoadNextRoundRobinChunk uses Math.max(0, ...) only when computing the manual offset in calculateAvailabilityWithRoundRobinChunks. At the hook level the offset is currentOffset + 1 without any upper-bound guard. If a client sends a chunkOffset larger than the total number of chunks, the server's safeChunkOffset = Math.min(manualChunkOffset, chunkCount - 1) clamps it: but only if chunkCount > 0. If hostChunks is somehow empty (e.g., all hosts are fixed), chunkCount is set to 1 via hostChunks.length || 1, but hostChunks[safeChunkOffset] could still be undefined for offsets ≥ 1, returning hostsForChunk = [...[], ...fixedHosts] which silently falls back to fixed-hosts-only availability: producing incorrect results without any error signal to the UI.

Suggested change
roundRobinChunkOffset: z.coerce.number().int().min(0).optional(),
roundRobinChunkOffset: z.coerce.number().int().min(0).max(10000).optional(),
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/trpc/server/routers/viewer/slots/types.ts
Lines: 38-38
Issue Type: robustness-medium
Severity: medium

Issue Description:
`roundRobinChunkOffset` is validated with `.min(0)` on the server schema, but on the client side in `useRoundRobinChunking.ts` `handleLoadNextRoundRobinChunk` uses `Math.max(0, ...)` only when computing the manual offset in `calculateAvailabilityWithRoundRobinChunks`. At the hook level the offset is `currentOffset + 1` without any upper-bound guard. If a client sends a `chunkOffset` larger than the total number of chunks, the server's `safeChunkOffset = Math.min(manualChunkOffset, chunkCount - 1)` clamps it: but only if `chunkCount > 0`. If `hostChunks` is somehow empty (e.g., all hosts are fixed), `chunkCount` is set to 1 via `hostChunks.length || 1`, but `hostChunks[safeChunkOffset]` could still be `undefined` for offsets ≥ 1, returning `hostsForChunk = [...[], ...fixedHosts]` which silently falls back to fixed-hosts-only availability: producing incorrect results without any error signal to the UI.

Current Code:
  roundRobinChunkOffset: z.coerce.number().int().min(0).optional(),

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +114 to +118
@Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
@IsBoolean()
@IsOptional()
@ApiHideProperty()
roundRobinManualChunking?: boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

Same @Transform issue as in slots-2024-04-15/inputs/index.ts: roundRobinManualChunking returns false for absent/null values instead of undefined, causing the field to be treated as explicitly set to false by downstream validators and handlers that distinguish between an omitted parameter and an explicitly false one. This is a copy-paste of the same defect.

Suggested fix
  @Transform(({ value }) => {
    if (value === undefined || value === null || value === "") return undefined;
    if (typeof value === "boolean") return value;
    return value.toLowerCase() === "true";
  })
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts
Lines: 114-118
Issue Type: functional-medium
Severity: medium

Issue Description:
Same `@Transform` issue as in `slots-2024-04-15/inputs/index.ts`: `roundRobinManualChunking` returns `false` for absent/null values instead of `undefined`, causing the field to be treated as explicitly set to `false` by downstream validators and handlers that distinguish between an omitted parameter and an explicitly false one. This is a copy-paste of the same defect.

Current Code:
  @Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

Nitpicks (Low Priority)

Found 3 low-priority suggestions for code improvement

Click to expand nitpicks

apps/web/public/static/locales/en/common.json (line 586)

Maintainability Low

The translation key round_robin_reset_hosts ("Reset host selection") is added to the locale file but is never referenced anywhere in the changed files (no t("round_robin_reset_hosts") call is present in any of the files under review). Adding unused translation keys increases bundle size and clutters the locale file. If a reset feature is planned, the key should be added when the feature lands.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/public/static/locales/en/common.json
Lines: 586-586
Issue Type: maintainability-low
Severity: low

Issue Description:
The translation key `round_robin_reset_hosts` ("Reset host selection") is added to the locale file but is never referenced anywhere in the changed files (no `t("round_robin_reset_hosts")` call is present in any of the files under review). Adding unused translation keys increases bundle size and clutters the locale file. If a reset feature is planned, the key should be added when the feature lands.

Current Code:
  "round_robin_reset_hosts": "Reset host selection",

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



packages/features/bookings/Booker/store.ts (lines 84-87)

Maintainability Low

RoundRobinChunkSettings is defined directly in store.ts but is essentially a duplicate/subset of RoundRobinChunkInfo from packages/lib/types/roundRobinChunkInfo.ts. Having two separate types with overlapping fields (chunkOffset, manual/manualChunking) across different packages increases the maintenance burden and is a potential source of drift. The settings type should either re-use fields from the canonical type or be co-located with it.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/store.ts
Lines: 84-87
Issue Type: maintainability-low
Severity: low

Issue Description:
`RoundRobinChunkSettings` is defined directly in `store.ts` but is essentially a duplicate/subset of `RoundRobinChunkInfo` from `packages/lib/types/roundRobinChunkInfo.ts`. Having two separate types with overlapping fields (`chunkOffset`, `manual`/`manualChunking`) across different packages increases the maintenance burden and is a potential source of drift. The settings type should either re-use fields from the canonical type or be co-located with it.

Current Code:
export type RoundRobinChunkSettings = {
  manual: boolean;
  chunkOffset: number;
};

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



packages/lib/types/roundRobinChunkInfo.ts (lines 1-9)

Maintainability Low

The RoundRobinChunkInfo type has both totalHosts and totalNonFixedHosts fields, and callers use totalNonFixedHosts || totalHosts || 0 as a fallback. This implies totalNonFixedHosts could be 0 (falsy) while the correct value is totalHosts, creating ambiguity. If totalNonFixedHosts is a required field, it should never fall back to totalHosts. The type should clarify intent: either make totalNonFixedHosts optional or remove totalHosts from the public progress calculation. As-is, the || totalHosts branch in AvailableTimeSlots.tsx line 202 silently masks a bug where totalNonFixedHosts is 0 and would give a 0-denominator division, but the fallback to totalHosts may itself be incorrect for non-fixed-host progress.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/lib/types/roundRobinChunkInfo.ts
Lines: 1-9
Issue Type: maintainability-low
Severity: low

Issue Description:
The `RoundRobinChunkInfo` type has both `totalHosts` and `totalNonFixedHosts` fields, and callers use `totalNonFixedHosts || totalHosts || 0` as a fallback. This implies `totalNonFixedHosts` could be 0 (falsy) while the correct value is `totalHosts`, creating ambiguity. If `totalNonFixedHosts` is a required field, it should never fall back to `totalHosts`. The type should clarify intent: either make `totalNonFixedHosts` optional or remove `totalHosts` from the public progress calculation. As-is, the `|| totalHosts` branch in `AvailableTimeSlots.tsx` line 202 silently masks a bug where `totalNonFixedHosts` is 0 and would give a 0-denominator division, but the fallback to `totalHosts` may itself be incorrect for non-fixed-host progress.

Current Code:
export type RoundRobinChunkInfo = {
  totalHosts: number;
  totalNonFixedHosts: number;
  chunkSize: number;
  chunkOffset: number;
  loadedNonFixedHosts: number;
  hasMoreNonFixedHosts: boolean;
  manualChunking: boolean;
};

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



Like Dislike

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Added Round-Robin host chunking to load large teams progressively instead of all at once, improving performance for events with 100+ hosts.
  • Added manual pagination UI with "Load more availability" button and progress indicator.
  • Extended API and platform wrappers to support chunked availability queries with offset control.

Key Changes by Area

Backend/Availability: Added calculateAvailabilityWithRoundRobinChunks() in packages/trpc/server/routers/viewer/slots/util.ts that processes hosts in 20% chunks (max 50) when threshold exceeded, with automatic stop-on-find or manual offset modes.

Frontend/UI: Added useRoundRobinChunking hook and integrated into BookerWebWrapper.tsx and BookerPlatformWrapper.tsx with reset on route changes. Added progress button in AvailableTimeSlots.tsx.

API/Types: Extended slot query inputs with roundRobinManualChunking and roundRobinChunkOffset parameters across tRPC and platform types.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added "Load more availability" button with circular progress indicator for chunked loading
apps/web/modules/bookings/components/Booker.tsx Integrated chunking callback props into booker component
apps/web/modules/bookings/components/BookerWebWrapper.tsx Integrated useRoundRobinChunking hook with reset dependencies on route changes
apps/web/public/static/locales/en/common.json Added i18n strings for chunking UI (note: round_robin_reset_hosts appears unused)
packages/features/bookings/Booker/tests/test-utils.tsx Test utilities updated for chunking support
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook managing chunked host loading state and pagination
packages/features/bookings/Booker/store.ts Extended store with roundRobinChunkSettings and roundRobinChunkInfo state
packages/features/bookings/Booker/types.ts Added onLoadNextRoundRobinChunk callback to wrapper props
packages/features/bookings/Booker/utils/event.ts Utility updates for chunking integration
packages/features/bookings/lib/bookingCreateBodySchema.ts Schema updates for chunking parameters
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Extended to accept round-robin chunking parameters
packages/features/schedules/lib/use-schedule/useSchedule.ts Extended to accept round-robin chunking parameters
packages/lib/types/roundRobinChunkInfo.ts New type for pagination metadata (total hosts, chunk size, hasMoreNonFixedHosts, etc.)
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Added chunking support with rrHostSubsetIds prop handling
packages/platform/atoms/hooks/useAvailableSlots.ts Integrated chunking parameters into available slots query
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added round-robin chunking input parameters
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added round-robin chunking input parameters
packages/trpc/server/routers/viewer/slots/types.ts Extended slot query input types with chunking parameters
packages/trpc/server/routers/viewer/slots/util.test.ts Comprehensive unit tests for chunking logic
packages/trpc/server/routers/viewer/slots/util.ts Core chunking implementation with sequential processing and metadata return

Review Focus Areas

  • Chunking reset logic: Verify resetDeps in BookerWebWrapper.tsx:164-177 correctly resets state on all relevant route changes (indentation issue noted).
  • Theme consistency: Hard-coded colors in AvailableTimeSlots.tsx:215 SVG progress indicator may not adapt to dark mode or theming.
  • Performance: renderLoadMoreButton function in AvailableTimeSlots.tsx:196-237 recreates JSX and recalculates derived values on every render.

Architecture

Design Decisions: Chunking is disabled when RR weights are enabled because weights require full host evaluation. Fixed hosts are always included in every chunk. The 20%/50-host chunk sizing and 100-host threshold are tuned for typical query latency vs. coverage tradeoffs.

Scalability & Extensibility: Manual chunking mode allows platform consumers to implement custom loading patterns. The RoundRobinChunkInfo metadata supports future infinite-scroll or prefetching implementations.

Risks:

  • Intentional: Chunking may return partial availability (stops when slots found in automatic mode). Callers must handle hasMoreNonFixedHosts flag.
  • Unintentional: Unused i18n key adds translation debt. Render function recreation may cause unnecessary re-renders.

Comment on lines +193 to +201
const showLoadMoreButton =
roundRobinChunkInfo?.hasMoreNonFixedHosts && onLoadNextRoundRobinChunk;

const renderLoadMoreButton = () => {
if (!showLoadMoreButton) return null;

const totalLoadedHosts =
roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
roundRobinChunkInfo.loadedNonFixedHosts;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

totalLoadedHosts computation can overflow the actual total. When roundRobinChunkInfo.chunkOffset is 3 and chunkSize is 21, chunkOffset * chunkSize = 63 already larger than the total number of non-fixed hosts that were actually loaded. The issue: chunkOffset is the 0-based index of the current chunk, so previously loaded non-fixed hosts are chunkOffset * chunkSize, but the very first chunk is offset 0, meaning hosts loaded before the current chunk = chunkOffset * chunkSize, plus loadedNonFixedHosts in the current chunk. That formula looks correct: but only when loadedNonFixedHosts refers to hosts in the current chunk alone. Looking at the server code in util.ts, loadedNonFixedHosts: hostChunk.length is indeed per-chunk. So the formula actually skips all intermediate chunks' host counts and is likely to produce a progressPercentage that jumps non-linearly and can exceed 100 before Math.min. While Math.min(100, ...) clamps the display, the underlying counter logic is semantically wrong for non-manual (sequential) chunking after a second automatic batch fires.

Suggested fix
      // chunkOffset is 0-based; hosts loaded up to and including the current chunk:
      const totalLoadedHosts = Math.min(
        (roundRobinChunkInfo.chunkOffset + 1) * roundRobinChunkInfo.chunkSize,
        roundRobinChunkInfo.totalNonFixedHosts || roundRobinChunkInfo.totalHosts || 0
      );
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 193-201
Issue Type: functional-medium
Severity: medium

Issue Description:
`totalLoadedHosts` computation can overflow the actual total. When `roundRobinChunkInfo.chunkOffset` is 3 and `chunkSize` is 21, `chunkOffset * chunkSize` = 63 already larger than the total number of non-fixed hosts that were actually loaded. The issue: `chunkOffset` is the 0-based index of the *current* chunk, so previously loaded non-fixed hosts are `chunkOffset * chunkSize`, but the very first chunk is offset 0, meaning hosts loaded before the current chunk = `chunkOffset * chunkSize`, plus `loadedNonFixedHosts` in the current chunk. That formula looks correct: but only when `loadedNonFixedHosts` refers to hosts in the *current* chunk alone. Looking at the server code in `util.ts`, `loadedNonFixedHosts: hostChunk.length` is indeed per-chunk. So the formula actually skips all intermediate chunks' host counts and is likely to produce a `progressPercentage` that jumps non-linearly and can exceed 100 before `Math.min`. While `Math.min(100, ...)` clamps the display, the underlying counter logic is semantically wrong for non-manual (sequential) chunking after a second automatic batch fires.

Current Code:
      const totalLoadedHosts =
        roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
        roundRobinChunkInfo.loadedNonFixedHosts;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +230 to +234
@Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
@IsBoolean()
@IsOptional()
@ApiHideProperty()
roundRobinManualChunking?: boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Security Medium

The @Transform for roundRobinManualChunking uses (value ? value.toLowerCase() === 'true' : false). When value is the boolean true (already transformed by class-transformer on a JSON body), calling .toLowerCase() on it will throw TypeError: value.toLowerCase is not a function, crashing the request pipeline before validation runs. The existing pattern on other boolean fields in this file uses value && value.toLowerCase() === 'true' which short-circuits on falsy (but that fails the opposite way when value is already false). The correct defensive pattern is to handle both the already-boolean case and the string case.

Also reported at: packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts L114–L118

Suggested fix
  @Transform(({ value }) => {
    if (typeof value === "boolean") return value;
    if (typeof value === "string") return value.toLowerCase() === "true";
    return false;
  })
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/types/slots/slots-2024-04-15/inputs/index.ts
Lines: 230-234
Issue Type: security-medium
Severity: medium

Issue Description:
The `@Transform` for `roundRobinManualChunking` uses `(value ? value.toLowerCase() === 'true' : false)`. When `value` is the boolean `true` (already transformed by class-transformer on a JSON body), calling `.toLowerCase()` on it will throw `TypeError: value.toLowerCase is not a function`, crashing the request pipeline before validation runs. The existing pattern on other boolean fields in this file uses `value && value.toLowerCase() === 'true'` which short-circuits on falsy (but that fails the opposite way when `value` is already `false`). The correct defensive pattern is to handle both the already-boolean case and the string case.

_Also reported at: `packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts` L114–L118_

Current Code:
  @Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

Nitpicks (Low Priority)

Found 4 low-priority suggestions for code improvement

Click to expand nitpicks

apps/web/modules/bookings/components/BookerWebWrapper.tsx (lines 164-177)

Style Low

Inconsistent indentation inside the resetDeps array literal: the closing bracket ] and the outer object closing } are misaligned. The opening resetDeps: [ is at 6-space indent but the inner items are at 8-space indent while the closing ] is at 4-space indent. This is inconsistent with the rest of the file (2-space indentation convention).

Code Suggestion or Comments
resetDeps: [
      props.username,
      props.eventSlug,
      props.entity.orgSlug,
      props.entity.eventTypeId,
      event.data?.id,
    ],
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/BookerWebWrapper.tsx
Lines: 164-177
Issue Type: style-low
Severity: low

Issue Description:
Inconsistent indentation inside the `resetDeps` array literal: the closing bracket `]` and the outer object closing `}` are misaligned. The opening `resetDeps: [` is at 6-space indent but the inner items are at 8-space indent while the closing `]` is at 4-space indent. This is inconsistent with the rest of the file (2-space indentation convention).

Current Code:
    resetDeps: [
      props.username,
      props.eventSlug,
      props.entity.orgSlug,
      props.entity.eventTypeId,
      event.data?.id,
    ],

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



apps/web/public/static/locales/en/common.json (line 586)

Maintainability Low

The key round_robin_reset_hosts (value: "Reset host selection") is added to the locale file but is never referenced anywhere in the changed source files. It appears to be dead/unused i18n string, which adds unnecessary maintenance burden and translation cost if the project ever gets the file translated.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/public/static/locales/en/common.json
Lines: 586-586
Issue Type: maintainability-low
Severity: low

Issue Description:
The key `round_robin_reset_hosts` (value: "Reset host selection") is added to the locale file but is never referenced anywhere in the changed source files. It appears to be dead/unused i18n string, which adds unnecessary maintenance burden and translation cost if the project ever gets the file translated.

Current Code:
  "round_robin_reset_hosts": "Reset host selection",

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



apps/web/modules/bookings/components/AvailableTimeSlots.tsx (line 215)

Maintainability Low

Hard-coded hex colour #FFFFFF and inline rgba(255,255,255,0.35) are embedded in the SVG. The rest of the design system uses Tailwind design tokens (e.g. text-emphasis, bg-default). If the app theme changes (dark mode, white-label), these values will not adapt. They should either use currentColor (for the filled arc) or be defined as CSS variables.

Code Suggestion or Comments
stroke="currentColor"
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 215-215
Issue Type: maintainability-low
Severity: low

Issue Description:
Hard-coded hex colour `#FFFFFF` and inline `rgba(255,255,255,0.35)` are embedded in the SVG. The rest of the design system uses Tailwind design tokens (e.g. `text-emphasis`, `bg-default`). If the app theme changes (dark mode, white-label), these values will not adapt. They should either use `currentColor` (for the filled arc) or be defined as CSS variables.

Current Code:
          stroke="#FFFFFF"

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



apps/web/modules/bookings/components/AvailableTimeSlots.tsx (lines 196-237)

Performance Low

renderLoadMoreButton is a plain function defined inside the render body. It recreates a new JSX tree (including the ProgressIcon SVG) on every render, and the computed values (progressPercentage, circumference, dashArray) are recalculated even when the underlying data has not changed. These should be extracted with useMemo/useCallback or moved outside the component since they only depend on roundRobinChunkInfo, isLoading, and schedule?.isFetching.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 196-237
Issue Type: performance-low
Severity: low

Issue Description:
`renderLoadMoreButton` is a plain function defined inside the render body. It recreates a new JSX tree (including the `ProgressIcon` SVG) on every render, and the computed values (`progressPercentage`, `circumference`, `dashArray`) are recalculated even when the underlying data has not changed. These should be extracted with `useMemo`/`useCallback` or moved outside the component since they only depend on `roundRobinChunkInfo`, `isLoading`, and `schedule?.isFetching`.

Current Code:
  const renderLoadMoreButton = () => {
    if (!showLoadMoreButton) return null;

    const totalLoadedHosts =
      roundRobinChunkInfo.chunkOffset * roundRobinChunkInfo.chunkSize +
      roundRobinChunkInfo.loadedNonFixedHosts;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



Like Dislike

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-ai

codity-ai Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Implements Round Robin chunking for availability loading to improve performance with large teams (100+ hosts). Hosts are processed in chunks (20% of total, max 50) until availability is found, with UI support for manual "load more" progression.
  • Adds useRoundRobinChunking hook and store integration to manage chunked loading state across web and platform booker components.
  • Extends tRPC slots router and Platform API v2 with chunking parameters (roundRobinManualChunking, roundRobinChunkOffset).

Key Changes by Area

Availability Calculation: Added calculateAvailabilityWithRoundRobinChunks() in slots util that processes non-fixed hosts sequentially in dynamic chunks, stopping early when slots are found.

API/Types: Extended GetAvailableSlotsInput schemas for both 2024-04-15 and 2024-09-04 API versions; added RoundRobinChunkInfo type for pagination metadata.

Frontend/UI: "Load more availability" button with progress indicator in AvailableTimeSlots.tsx; hook manages chunk offset and manual loading mode.

Platform: BookerPlatformWrapper.tsx integrates chunking with store context for platform atoms.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added "Load more" button with circular progress indicator for chunk loading
apps/web/modules/bookings/components/Booker.tsx Integrated chunking callback into booking flow
apps/web/modules/bookings/components/BookerWebWrapper.tsx Integrated useRoundRobinChunking hook, passed onLoadNextRoundRobinChunk callback
apps/web/public/static/locales/en/common.json Added translation strings for chunk loading UI
packages/features/bookings/Booker/tests/test-utils.tsx Added mock store values for chunking state
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook for chunked loading state management
packages/features/bookings/Booker/store.ts Added roundRobinChunkSettings and roundRobinChunkInfo to store
packages/features/bookings/Booker/types.ts Added onLoadNextRoundRobinChunk callback to props
packages/features/bookings/Booker/utils/event.ts Updated event utilities for chunking support
packages/features/bookings/lib/bookingCreateBodySchema.ts Extended schema with chunking parameters
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Extended with chunking params; local type intersection (see review note)
packages/features/schedules/lib/use-schedule/useSchedule.ts Added chunking params to UseScheduleWithCacheArgs
packages/lib/types/roundRobinChunkInfo.ts New type definition for chunk pagination metadata
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Integrated chunking hook and store context
packages/platform/atoms/hooks/useAvailableSlots.ts Extended with chunking parameters
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added roundRobinManualChunking and roundRobinChunkOffset to input class
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added chunking params to newer API version
packages/trpc/server/routers/viewer/slots/types.ts Extended tRPC input schema with chunking fields
packages/trpc/server/routers/viewer/slots/util.test.ts Comprehensive tests for chunking logic
packages/trpc/server/routers/viewer/slots/util.ts Core calculateAvailabilityWithRoundRobinChunks implementation

Review Focus Areas

  • Redundant store entry: roundRobinChunkInfo is written to Zustand store but never subscribed; consumers read directly from schedule.data. Consider removing or documenting intentional redundancy.
  • Duplicate type definition: Local GetAvailableSlotsInputWithChunks in useApiV2AvailableSlots.ts intersects with class that now has same fields in platform types. Verify if intersection can be removed.
  • Chunk sizing logic: Confirm dynamic chunk calculation (20% of hosts, max 50, threshold 100) matches product requirements for team size scaling.

Architecture

Design Decisions: Chunking stops at first availability found to minimize calendar API calls. This trades completeness for speed: users may see fewer initial slots but get faster response times. Manual chunking mode allows users to explicitly request more hosts when needed.

Risks:

  • Intentional: Store writes without subscriptions cause minor Zustand overhead. Acceptable if future features plan to use store-based chunk info.
  • Intentional: Hardcoded SVG stroke colors in progress indicator reduce theme adaptability. Acceptable if design system permits.
  • Unintentional: Indentation inconsistency in BookerWebWrapper.tsx:170-176 suggests possible merge conflict or editor misconfiguration.

@codity-ai

codity-ai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Workflow Diagrams

Automatically generated sequence diagrams showing the workflows in this PR

1. Round Robin Chunked Availability Loading Flow

Complex complexity • Components: useRoundRobinChunking hook, BookerPlatformWrapper, BookerWebWrapper

sequenceDiagram
    title: Round Robin Chunked Availability Loading Workflow

    actor User
    participant AvailableTimeSlots as AvailableTimeSlots Component
    participant BookerStore as BookerStore Zustand
    participant useRoundRobinChunking as useRoundRobinChunking Hook
    participant useAvailableSlots as useAvailableSlots Hook
    participant API as Availability API
    participant Database as Database

    Note over User,Database: Initial Load Flow

    User->>BookerStore: Select date/event
    BookerStore->>useRoundRobinChunking: Initialize with default chunkOffset 0
    useRoundRobinChunking->>BookerStore: Set roundRobinChunkSettings
    BookerStore->>useAvailableSlots: Trigger with chunkOffset 0
    useAvailableSlots->>API: GET /slots with roundRobinChunkOffset 0
    API->>Database: Query host availability (first chunk)
    Database-->>API: Return slots + roundRobinChunkInfo
    API-->>useAvailableSlots: Return {slots, roundRobinChunkInfo}
    useAvailableSlots->>BookerStore: Update schedule data
    AvailableTimeSlots->>BookerStore: Read roundRobinChunkInfo
    Note right of AvailableTimeSlots: Check hasMoreNonFixedHosts flag

    alt hasMoreNonFixedHosts is true
        AvailableTimeSlots->>AvailableTimeSlots: Render "Load More" button with progress indicator
        Note right of AvailableTimeSlots: Progress percentage calculated from loaded vs total hosts
    end

    Note over User,Database: User Requests More Availability

    User->>AvailableTimeSlots: Click "Load More Availability" button
    AvailableTimeSlots->>useRoundRobinChunking: Call handleLoadNextRoundRobinChunk
    useRoundRobinChunking->>BookerStore: Update roundRobinChunkSettings.chunkOffset (increment)
    BookerStore->>useAvailableSlots: Detect chunkOffset change, trigger refetch
    useAvailableSlots->>API: GET /slots with new roundRobinChunkOffset
    API->>Database: Query next chunk of hosts availability
    Database-->>API: Return additional slots + updated roundRobinChunkInfo
    API-->>useAvailableSlots: Merge new slots with existing
    useAvailableSlots->>BookerStore: Update schedule data with combined slots
    AvailableTimeSlots->>BookerStore: Re-read roundRobinChunkInfo

    alt hasMoreNonFixedHosts is now false
        AvailableTimeSlots->>AvailableTimeSlots: Hide "Load More" button
        Note right of AvailableTimeSlots: All hosts loaded, show complete availability
    else hasMoreNonFixedHosts still true
        AvailableTimeSlots->>AvailableTimeSlots: Update progress indicator
        Note right of AvailableTimeSlots: Show updated percentage of loaded hosts
    end

    Note over User,Database: Context Change Reset Flow

    alt Event, username, orgSlug, or eventTypeId changes
        useRoundRobinChunking->>useRoundRobinChunking: Detect reset dependency change
        useRoundRobinChunking->>BookerStore: Reset chunkOffset to 0
        BookerStore->>useAvailableSlots: Trigger fresh fetch
        Note right of useRoundRobinChunking: Previous chunk state discarded
    end
Loading

Note: Diagrams show detected patterns only. Complex workflows may require manual review.

Comment on lines +29 to +32
useEffect(() => {
setRoundRobinChunkSettings(null);
setRoundRobinChunkInfo(null);
}, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Robustness Medium

Spreading ...resetDeps into a useEffect dependency array creates a variable-length dep array. React tracks dependency array length between renders and will emit a warning if the count changes. More critically, eslint-plugin-react-hooks/exhaustive-deps cannot statically analyse spread syntax, so the linter silently stops enforcing exhaustiveness for the entire effect: any future accidental omission of a real dep won't be caught. The conventional fix is to flatten the list to a primitive cache-key string so the array length is always 2.

Suggested fix
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, JSON.stringify(resetDeps)]);
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts
Lines: 29-32
Issue Type: robustness-medium
Severity: medium

Issue Description:
Spreading `...resetDeps` into a `useEffect` dependency array creates a variable-length dep array. React tracks dependency array length between renders and will emit a warning if the count changes. More critically, `eslint-plugin-react-hooks/exhaustive-deps` cannot statically analyse spread syntax, so the linter silently stops enforcing exhaustiveness for the entire effect: any future accidental omission of a real dep won't be caught. The conventional fix is to flatten the list to a primitive cache-key string so the array length is always 2.

Current Code:
  }, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +236 to +246
@Transform(({ value }) => {
if (value === undefined || value === null || value === "") {
return undefined;
}
const parsedValue = typeof value === "string" ? parseInt(value, 10) : value;
return Number.isNaN(parsedValue) ? undefined : parsedValue;
})
@IsNumber()
@IsOptional()
@ApiHideProperty()
roundRobinChunkOffset?: number;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

The roundRobinChunkOffset field has no @Min(0) or @IsInt() constraint in the platform API DTO. A caller can supply a negative integer (e.g., -5) and it will pass class-validator without a 400 error. The tRPC path correctly applies .min(0) in the Zod schema, and the server's Math.max(0, roundRobinChunkOffset) clamps the value at runtime: but the platform API endpoint never rejects the invalid value, silently treating it as 0. @Min and @IsInt are already imported in this file.

Also reported at: packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts L120–L130

Suggested fix
  @Transform(({ value }) => {
    if (value === undefined || value === null || value === "") {
      return undefined;
    }
    const parsedValue = typeof value === "string" ? parseInt(value, 10) : value;
    return Number.isNaN(parsedValue) ? undefined : parsedValue;
  })
  @IsNumber()
  @IsInt()
  @Min(0)
  @IsOptional()
  @ApiHideProperty()
  roundRobinChunkOffset?: number;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/types/slots/slots-2024-04-15/inputs/index.ts
Lines: 236-246
Issue Type: functional-medium
Severity: medium

Issue Description:
The `roundRobinChunkOffset` field has no `@Min(0)` or `@IsInt()` constraint in the platform API DTO. A caller can supply a negative integer (e.g., `-5`) and it will pass class-validator without a 400 error. The tRPC path correctly applies `.min(0)` in the Zod schema, and the server's `Math.max(0, roundRobinChunkOffset)` clamps the value at runtime: but the platform API endpoint never rejects the invalid value, silently treating it as 0. `@Min` and `@IsInt` are already imported in this file.

_Also reported at: `packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts` L120–L130_

Current Code:
  @Transform(({ value }) => {
    if (value === undefined || value === null || value === "") {
      return undefined;
    }
    const parsedValue = typeof value === "string" ? parseInt(value, 10) : value;
    return Number.isNaN(parsedValue) ? undefined : parsedValue;
  })
  @IsNumber()
  @IsOptional()
  @ApiHideProperty()
  roundRobinChunkOffset?: number;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

@codity-ai

codity-ai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Nitpicks (Low Priority)

Found 4 low-priority suggestions for code improvement

Click to expand nitpicks

packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts (lines 13-16)

Maintainability Low

The local GetAvailableSlotsInputWithChunks intersection type extends GetAvailableSlotsInput_2024_04_15 with roundRobinManualChunking and roundRobinChunkOffset: but this same PR adds those fields directly to the class in packages/platform/types/slots/slots-2024-04-15/inputs/index.ts. The intersection is now a no-op type alias that will drift from the canonical source of truth if the fields are ever renamed or constrained.

Also reported at: packages/platform/atoms/hooks/useAvailableSlots.ts L15–L18

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts
Lines: 13-16
Issue Type: maintainability-low
Severity: low

Issue Description:
The local `GetAvailableSlotsInputWithChunks` intersection type extends `GetAvailableSlotsInput_2024_04_15` with `roundRobinManualChunking` and `roundRobinChunkOffset`: but this same PR adds those fields directly to the class in `packages/platform/types/slots/slots-2024-04-15/inputs/index.ts`. The intersection is now a no-op type alias that will drift from the canonical source of truth if the fields are ever renamed or constrained.

_Also reported at: `packages/platform/atoms/hooks/useAvailableSlots.ts` L15–L18_

Current Code:
type GetAvailableSlotsInputWithChunks = GetAvailableSlotsInput_2024_04_15 & {
  roundRobinManualChunking?: boolean;
  roundRobinChunkOffset?: number;
};

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



packages/features/bookings/Booker/store.ts (lines 507-508)

Maintainability Low

roundRobinChunkInfo is written into the Zustand store by useRoundRobinChunking on every fetch, but state.roundRobinChunkInfo is never subscribed to anywhere in the codebase: every consumer reads directly from schedule.data?.roundRobinChunkInfo. The store entry causes a redundant Zustand state write (and potential spurious re-renders for any future inadvertent subscriber) while the data is fully available through the schedule query result.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/store.ts
Lines: 507-508
Issue Type: maintainability-low
Severity: low

Issue Description:
`roundRobinChunkInfo` is written into the Zustand store by `useRoundRobinChunking` on every fetch, but `state.roundRobinChunkInfo` is never subscribed to anywhere in the codebase: every consumer reads directly from `schedule.data?.roundRobinChunkInfo`. The store entry causes a redundant Zustand state write (and potential spurious re-renders for any future inadvertent subscriber) while the data is fully available through the schedule query result.

Current Code:
    roundRobinChunkInfo: null,
    setRoundRobinChunkInfo: (info: RoundRobinChunkInfo | null) => set({ roundRobinChunkInfo: info }),

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



apps/web/modules/bookings/components/BookerWebWrapper.tsx (lines 170-176)

Style Low

The resetDeps array items are indented at the same level as the property name rather than one level deeper, and the closing ], is unindented relative to the surrounding object. This breaks the consistent 2-space indentation of the rest of the useRoundRobinChunking call.

Code Suggestion or Comments
resetDeps: [
        props.username,
        props.eventSlug,
        props.entity.orgSlug,
        props.entity.eventTypeId,
        event.data?.id,
      ],
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/BookerWebWrapper.tsx
Lines: 170-176
Issue Type: style-low
Severity: low

Issue Description:
The `resetDeps` array items are indented at the same level as the property name rather than one level deeper, and the closing `],` is unindented relative to the surrounding object. This breaks the consistent 2-space indentation of the rest of the `useRoundRobinChunking` call.

Current Code:
      resetDeps: [
      props.username,
      props.eventSlug,
      props.entity.orgSlug,
      props.entity.eventTypeId,
      event.data?.id,
    ],

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



apps/web/modules/bookings/components/AvailableTimeSlots.tsx (lines 209-222)

Style Low

The progress SVG uses hardcoded stroke="rgba(255,255,255,0.35)" and stroke="#FFFFFF" instead of currentColor. The className="text-emphasis" on the <svg> element already sets the CSS color property, so switching to currentColor for both strokes would make the icon adapt to any primary-button text color variation automatically (including white-labelled deployments that configure a light primary colour).

Code Suggestion or Comments
<svg width="20" height="20" viewBox="0 0 20 20" className="text-emphasis" aria-hidden>
        <circle cx="10" cy="10" r="8" stroke="currentColor" strokeWidth="2" fill="none" strokeOpacity="0.35" />
        <circle
          cx="10"
          cy="10"
          r="8"
          stroke="currentColor"
          strokeWidth="2"
          fill="none"
          strokeDasharray={`${dashArray} ${circumference}`}
          strokeLinecap="round"
          transform="rotate(-90 10 10)"
        />
      </svg>
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: apps/web/modules/bookings/components/AvailableTimeSlots.tsx
Lines: 209-222
Issue Type: style-low
Severity: low

Issue Description:
The progress SVG uses hardcoded `stroke="rgba(255,255,255,0.35)"` and `stroke="#FFFFFF"` instead of `currentColor`. The `className="text-emphasis"` on the `<svg>` element already sets the CSS `color` property, so switching to `currentColor` for both strokes would make the icon adapt to any primary-button text color variation automatically (including white-labelled deployments that configure a light primary colour).

Current Code:
      <svg width="20" height="20" viewBox="0 0 20 20" className="text-emphasis" aria-hidden>
        <circle cx="10" cy="10" r="8" stroke="rgba(255,255,255,0.35)" strokeWidth="2" fill="none" />
        <circle
          cx="10"
          cy="10"
          r="8"
          stroke="#FFFFFF"
          strokeWidth="2"
          fill="none"
          strokeDasharray={`${dashArray} ${circumference}`}
          strokeLinecap="round"
          transform="rotate(-90 10 10)"
        />
      </svg>

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



Like Dislike

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Added Round Robin chunking for large team events (100+ hosts) to improve availability query performance by processing hosts in batches rather than all at once.
  • Added a "Load more" UI with progress indicator so users can manually fetch additional host chunks when initial chunks return no availability.
  • Extended API and frontend hooks to support both automatic and manual chunk navigation with offset-based pagination.

Key Changes by Area

Availability Engine: Added calculateAvailabilityWithRoundRobinChunks() in packages/trpc/server/routers/viewer/slots/util.ts that processes non-fixed hosts in dynamic chunks (20% of total, max 50) until availability is found, with early termination on success.

Frontend State: Extended booker store with roundRobinChunkSettings and roundRobinChunkInfo for tracking chunk progress across renders.

Platform API: Added roundRobinManualChunking and roundRobinChunkOffset parameters to slot query inputs in both legacy and v2 API types.

UI Components: Added useRoundRobinChunking hook and integrated "Load more" button with host count progress in AvailableTimeSlots.tsx.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added "Load more" button with progress indicator for manual chunk loading
apps/web/modules/bookings/components/Booker.tsx Integrated chunking props and callbacks
apps/web/modules/bookings/components/BookerWebWrapper.tsx Added onLoadNextRoundRobinChunk callback integration
apps/web/public/static/locales/en/common.json Added translation keys for chunking UI
packages/features/bookings/Booker/tests/test-utils.tsx Test utilities for chunking scenarios
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook managing chunk state and load progression
packages/features/bookings/Booker/store.ts Extended store with round robin chunk tracking state
packages/features/bookings/Booker/types.ts Added onLoadNextRoundRobinChunk to wrapper props
packages/features/bookings/Booker/utils/event.ts Event utility updates for chunking support
packages/features/bookings/lib/bookingCreateBodySchema.ts Schema updates for chunking parameters
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Added chunking parameters to API v2 slots query
packages/features/schedules/lib/use-schedule/useSchedule.ts Added chunking parameters to schedule hook
packages/lib/types/roundRobinChunkInfo.ts New type for chunk metadata (total, loaded, hasMore)
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Integrated chunking hook and callback
packages/platform/atoms/hooks/useAvailableSlots.ts Added chunking parameter support
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added chunking input parameters
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added chunking input parameters
packages/trpc/server/routers/viewer/slots/types.ts Extended types with RoundRobinChunkInfo
packages/trpc/server/routers/viewer/slots/util.test.ts Added 7 test cases for chunking behavior
packages/trpc/server/routers/viewer/slots/util.ts Core chunking implementation with dynamic sizing

Review Focus Areas

  • Early termination logic in calculateAvailabilityWithRoundRobinChunks when availability is found mid-chunk.
  • State synchronization between useRoundRobinChunking hook and booker store on chunk reset.
  • Edge case: behavior when isRRWeightsEnabled is true (chunking bypassed) versus large team chunking path.

Architecture

Design Decisions: Dynamic chunk sizing (20% of hosts, capped at 50) balances query size against total host count. Sequential processing with early termination prioritizes user-perceived speed over backend parallelism. Manual chunking via offset allows frontend-driven "Load more" without server-side session state.

Scalability & Extensibility: Chunking is intentionally capped at 50 hosts to prevent oversized queries. The 100-host threshold is hardcoded; making this configurable is out of scope. Weight-based routing bypasses chunking entirely since weights require full host set evaluation.

Risks:

  • Intentional: No availability returned until a chunk with slots is processed. Users may see "no slots" briefly before loading completes.
  • Intentional: Manual chunking requires clients to track offset state; server is stateless.
  • Unintentional: Race conditions if multiple "Load more" clicks occur before prior chunk returns.

Comment on lines +29 to +32
useEffect(() => {
setRoundRobinChunkSettings(null);
setRoundRobinChunkInfo(null);
}, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional High

The reset effect spreads resetDeps directly into the dependency array of useEffect, which violates the React hooks rules. The ESLint react-hooks/exhaustive-deps rule does not understand spread syntax in dependency arrays, and more critically the React runtime treats the spread as a series of positional arguments: if resetDeps length ever changes between renders the hook silently breaks (hooks must be called with the same number of arguments every render). Furthermore, including setRoundRobinChunkInfo and setRoundRobinChunkSettings (stable store functions) together with the actual reset deps means the reset fires on every render where the store reference changes (e.g. HMR, context re-initialization). In practice, the effect can fire immediately after the user clicks 'Load more', erasing the roundRobinChunkSettings they just set and preventing the next chunk from ever loading.

Suggested fix
  const resetDepsRef = useRef(resetDeps);
  useEffect(() => {
    resetDepsRef.current = resetDeps;
  });

  useEffect(() => {
    setRoundRobinChunkSettings(null);
    setRoundRobinChunkInfo(null);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, resetDeps); // resetDeps must have a stable length; see useRef pattern above if it can change
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts
Lines: 29-32
Issue Type: functional-high
Severity: high

Issue Description:
The reset effect spreads `resetDeps` directly into the dependency array of `useEffect`, which violates the React hooks rules. The ESLint `react-hooks/exhaustive-deps` rule does not understand spread syntax in dependency arrays, and more critically the React runtime treats the spread as a series of positional arguments: if `resetDeps` length ever changes between renders the hook silently breaks (hooks must be called with the same number of arguments every render). Furthermore, including `setRoundRobinChunkInfo` and `setRoundRobinChunkSettings` (stable store functions) together with the actual reset deps means the reset fires on every render where the store reference changes (e.g. HMR, context re-initialization). In practice, the effect can fire immediately after the user clicks 'Load more', erasing the `roundRobinChunkSettings` they just set and preventing the next chunk from ever loading.

Current Code:
  useEffect(() => {
    setRoundRobinChunkSettings(null);
    setRoundRobinChunkInfo(null);
  }, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +34 to +40
const handleLoadNextRoundRobinChunk = useCallback(() => {
if (!roundRobinChunkInfo?.hasMoreNonFixedHosts || isFetching) return;
const currentOffset = roundRobinChunkSettings?.chunkOffset ?? roundRobinChunkInfo.chunkOffset ?? 0;
setRoundRobinChunkSettings({
manual: true,
chunkOffset: currentOffset + 1,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

The handleLoadNextRoundRobinChunk callback uses roundRobinChunkSettings?.chunkOffset ?? roundRobinChunkInfo.chunkOffset ?? 0 to determine the current offset, but the intent is to advance to the next chunk beyond what the API last returned. When the server responds with chunkOffset: N, the client state (roundRobinChunkSettings) may still hold the previous request offset (N-1) or null (first click). The fallback to roundRobinChunkInfo.chunkOffset is correct for the first click, but on subsequent clicks the stale roundRobinChunkSettings.chunkOffset is used instead of the server-confirmed roundRobinChunkInfo.chunkOffset, causing the offset to be calculated as (N-1) + 1 = N (re-requesting the same chunk) instead of N + 1. The correct base should always be the server-confirmed roundRobinChunkInfo.chunkOffset.

Suggested change
const handleLoadNextRoundRobinChunk = useCallback(() => {
if (!roundRobinChunkInfo?.hasMoreNonFixedHosts || isFetching) return;
const currentOffset = roundRobinChunkSettings?.chunkOffset ?? roundRobinChunkInfo.chunkOffset ?? 0;
setRoundRobinChunkSettings({
manual: true,
chunkOffset: currentOffset + 1,
});
const currentOffset = roundRobinChunkInfo.chunkOffset ?? 0;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts
Lines: 34-40
Issue Type: functional-medium
Severity: medium

Issue Description:
The `handleLoadNextRoundRobinChunk` callback uses `roundRobinChunkSettings?.chunkOffset ?? roundRobinChunkInfo.chunkOffset ?? 0` to determine the current offset, but the intent is to advance to the *next* chunk beyond what the API last returned. When the server responds with `chunkOffset: N`, the client state (`roundRobinChunkSettings`) may still hold the *previous* request offset (N-1) or null (first click). The fallback to `roundRobinChunkInfo.chunkOffset` is correct for the first click, but on subsequent clicks the stale `roundRobinChunkSettings.chunkOffset` is used instead of the server-confirmed `roundRobinChunkInfo.chunkOffset`, causing the offset to be calculated as `(N-1) + 1 = N` (re-requesting the same chunk) instead of `N + 1`. The correct base should always be the server-confirmed `roundRobinChunkInfo.chunkOffset`.

Current Code:
    const currentOffset = roundRobinChunkSettings?.chunkOffset ?? roundRobinChunkInfo.chunkOffset ?? 0;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +1148 to +1162
return chunkResultWithInfo;
}
lastResult = chunkResultWithInfo;
}

if (lastResult) {
return lastResult;
}

const fallbackResult = await calculateForHosts(fixedHosts);
return {
...fallbackResult,
roundRobinChunkInfo: buildChunkInfo({
chunkOffset: 0,
loadedNonFixedHosts: 0,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Performance Medium

In automatic (non-manual) chunking mode, calculateAvailabilityWithRoundRobinChunks calls calculateHostsAndAvailabilities sequentially for every chunk until it finds one with availability. For a 1000-host team with a 50-host chunk size, this means up to 20 sequential calculateHostsAndAvailabilities calls in the hot availability-check path. Each call fetches calendar data and checks busy times for 50+ hosts. With no timeout or early-exit beyond finding the first chunk with results, a worst-case request (no availability at all) will make 20 sequential heavy DB/calendar calls, potentially timing out or causing severe latency for the user.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/trpc/server/routers/viewer/slots/util.ts
Lines: 1148-1162
Issue Type: performance-medium
Severity: medium

Issue Description:
In automatic (non-manual) chunking mode, `calculateAvailabilityWithRoundRobinChunks` calls `calculateHostsAndAvailabilities` sequentially for every chunk until it finds one with availability. For a 1000-host team with a 50-host chunk size, this means up to 20 sequential `calculateHostsAndAvailabilities` calls in the hot availability-check path. Each call fetches calendar data and checks busy times for 50+ hosts. With no timeout or early-exit beyond finding the first chunk with results, a worst-case request (no availability at all) will make 20 sequential heavy DB/calendar calls, potentially timing out or causing severe latency for the user.

Current Code:
    let lastResult: ChunkedAvailabilityResult | null = null;
    for (let index = 0; index < hostChunks.length; index += 1) {
      const hostChunk = hostChunks[index];
      const hostsForChunk = [...hostChunk, ...fixedHosts];
      const chunkResult = await calculateForHosts(hostsForChunk);
      const chunkInfo = buildChunkInfo({

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines 1395 to 1420
@@ -1222,7 +1403,7 @@ export class AvailableSlotsService {
// if start time is not within first two weeks, check if there are any available slots
if (!aggregatedAvailability.length) {
// if no available slots check if first two weeks are available, otherwise fallback
const firstTwoWeeksAvailabilities = await this.calculateHostsAndAvailabilities({
const firstTwoWeeksAvailabilities = await this.calculateAvailabilityWithRoundRobinChunks({
input,
eventType,
hosts: [...eligibleQualifiedRRHosts, ...eligibleFixedHosts],
@@ -1233,12 +1414,7 @@ export class AvailableSlotsService {
silentCalendarFailures,
mode,
});
if (
!getAggregatedAvailability(
firstTwoWeeksAvailabilities.allUsersAvailability,
eventType.schedulingType
).length
) {
if (!firstTwoWeeksAvailabilities.aggregatedAvailability.length) {
diff = 1;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

When the fallback path (hasFallbackRRHosts && diff > 0) is taken, the roundRobinChunkInfo returned to the client reflects the fallback host set (eligibleFallbackRRHosts + eligibleFixedHosts), but the totalHosts / totalNonFixedHosts fields inside buildChunkInfo are captured from the original allHosts array via closure from the outer call. This means the chunk metadata reported to the UI (total hosts, hasMoreNonFixedHosts, etc.) is incorrect for the fallback host set, leading to a 'Load more' button that shows wrong progress and may display 'more availability' when all fallback hosts have already been loaded.

Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/trpc/server/routers/viewer/slots/util.ts
Lines: 1395-1420
Issue Type: functional-medium
Severity: medium

Issue Description:
When the fallback path (`hasFallbackRRHosts && diff > 0`) is taken, the `roundRobinChunkInfo` returned to the client reflects the fallback host set (eligibleFallbackRRHosts + eligibleFixedHosts), but the `totalHosts` / `totalNonFixedHosts` fields inside `buildChunkInfo` are captured from the **original** `allHosts` array via closure from the outer call. This means the chunk metadata reported to the UI (total hosts, hasMoreNonFixedHosts, etc.) is incorrect for the fallback host set, leading to a 'Load more' button that shows wrong progress and may display 'more availability' when all fallback hosts have already been loaded.

Current Code:
        ({
          allUsersAvailability,
          usersWithCredentials,
          currentSeats,
          aggregatedAvailability,
          roundRobinChunkInfo,
        } = await this.calculateAvailabilityWithRoundRobinChunks({
            input,
            eventType,
            hosts: [...eligibleFallbackRRHosts, ...eligibleFixedHosts],
            loggerWithEventDetails,
            startTime,
            endTime,
            bypassBusyCalendarTimes,
            silentCalendarFailures,
            mode,
          }));

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +230 to +234
@Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
@IsBoolean()
@IsOptional()
@ApiHideProperty()
roundRobinManualChunking?: boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Medium

The @Transform for roundRobinManualChunking uses the expression value ? value.toLowerCase() === 'true' : false. This means that if the query string sends roundRobinManualChunking=false (the string "false"), value is truthy, so value.toLowerCase() === 'true' evaluates to false correctly. However, if the value is already a boolean false (when used programmatically), value.toLowerCase() will throw a TypeError because false.toLowerCase is not a function. The same pattern is used for several existing fields (e.g. skipContactOwner) but for new numeric roundRobinChunkOffset the guard correctly handles the boolean case. This is a latent bug that will surface when the value is passed as a boolean rather than a string query param.

Suggested fix
  @Transform(({ value }) => {
    if (typeof value === "boolean") return value;
    if (value === undefined || value === null) return false;
    return String(value).toLowerCase() === "true";
  })
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/types/slots/slots-2024-04-15/inputs/index.ts
Lines: 230-234
Issue Type: functional-medium
Severity: medium

Issue Description:
The `@Transform` for `roundRobinManualChunking` uses the expression `value ? value.toLowerCase() === 'true' : false`. This means that if the query string sends `roundRobinManualChunking=false` (the string `"false"`), `value` is truthy, so `value.toLowerCase() === 'true'` evaluates to `false` correctly. However, if the value is already a boolean `false` (when used programmatically), `value.toLowerCase()` will throw a TypeError because `false.toLowerCase` is not a function. The same pattern is used for several existing fields (e.g. `skipContactOwner`) but for new numeric `roundRobinChunkOffset` the guard correctly handles the boolean case. This is a latent bug that will surface when the value is passed as a boolean rather than a string query param.

Current Code:
  @Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Added Round Robin host chunking for large team events (100+ hosts) to improve availability query performance by processing hosts in batches rather than all at once.
  • Added UI controls for progressive loading with "Load more availability" button and manual pagination.
  • Extended API and platform wrappers to support chunked availability queries with offset-based pagination.

Key Changes by Area

Availability Engine: Added calculateAvailabilityWithRoundRobinChunks in util.ts that processes hosts sequentially in 20% chunks (max 50) until slots are found, with early termination and weight-based ordering preservation.

UI/UX: Added useRoundRobinChunking hook and "Load more availability" button with circular progress indicator in AvailableTimeSlots.tsx.

API/Platform: Extended slot query inputs with roundRobinManualChunking and roundRobinChunkOffset parameters across tRPC and platform API schemas.

State Management: Extended Booker store with roundRobinChunkSettings and roundRobinChunkInfo for pagination tracking.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added "Load more availability" button with progress indicator for chunked loading
apps/web/modules/bookings/components/Booker.tsx Added onLoadNextRoundRobinChunk callback prop to Booker component
apps/web/modules/bookings/components/BookerWebWrapper.tsx Integrated useRoundRobinChunking hook and passed callback to Booker
apps/web/public/static/locales/en/common.json Added i18n strings for Round Robin chunking UI
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook managing chunk state, pagination, and load more functionality
packages/features/bookings/Booker/store.ts Extended store with roundRobinChunkSettings and roundRobinChunkInfo state
packages/features/bookings/Booker/types.ts Updated Booker types for new callback prop
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Added roundRobinManualChunking and roundRobinChunkOffset parameters
packages/features/schedules/lib/use-schedule/useSchedule.ts Added chunking parameters to schedule queries
packages/lib/types/roundRobinChunkInfo.ts New type definition for Round Robin chunk metadata
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Integrated chunking hook and callback for platform wrapper
packages/platform/atoms/hooks/useAvailableSlots.ts Added chunking parameters to platform slot queries
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added chunking parameters to platform API schema
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added chunking parameters to platform API schema
packages/trpc/server/routers/viewer/slots/types.ts Added roundRobinManualChunking and roundRobinChunkOffset to input schema
packages/trpc/server/routers/viewer/slots/util.ts Added calculateAvailabilityWithRoundRobinChunks with dynamic chunk sizing and sequential processing
packages/trpc/server/routers/viewer/slots/util.test.ts Comprehensive tests for chunking logic, manual offsets, and edge cases

Review Focus Areas

  • Early termination logic in calculateAvailabilityWithRoundRobinChunks when slots are found mid-chunk.
  • Interaction between manual chunking mode and automatic sequential chunking in useRoundRobinChunking.
  • Weight-based host ordering preservation when RR weights are enabled (chunking is skipped).

Architecture

Design Decisions: Dynamic chunk sizing (20% of hosts, capped at 50) balances query size against request count. Sequential processing with early termination optimizes for common case where early hosts have availability. Manual chunking mode allows explicit pagination control for UI "load more" pattern.

Scalability & Extensibility: Chunking threshold (100 hosts) and sizing constants are hardcoded. Out of scope: making these configurable per-event-type or tenant.

Risks: Intentional: Weight-based ordering is preserved by disabling chunking when RR weights are enabled, trading performance for fairness. Unintentional: hasMoreNonFixedHosts flag relies on accurate host counting; verify edge cases with filtered/deactivated hosts.

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Added Round-Robin host chunking for availability queries to improve performance with large teams (100+ non-fixed hosts). Hosts are now processed in 20% chunks (max 50) with progressive loading.
  • New UI components let users manually load more hosts when chunked results are incomplete.

Key Changes by Area

Backend/Availability: Added calculateAvailabilityWithRoundRobinChunks() in packages/trpc/server/routers/viewer/slots/util.ts that chunks non-fixed hosts dynamically and returns RoundRobinChunkInfo metadata for pagination.

API/Types: Extended slot query inputs across tRPC and platform APIs (roundRobinManualChunking, roundRobinChunkOffset) and added RoundRobinChunkInfo type with host counts and pagination state.

Frontend/Booker: New useRoundRobinChunking hook manages chunk state with offset tracking. AvailableTimeSlots shows a sticky "Load more" button with progress indicator when hasMoreNonFixedHosts is true.

Platform: BookerPlatformWrapper and BookerWebWrapper integrate chunking with cache invalidation on route changes.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added "Load more availability" button with progress indicator for chunked RR hosts
apps/web/modules/bookings/components/Booker.tsx Updated to support round-robin chunking callbacks
apps/web/modules/bookings/components/BookerWebWrapper.tsx Integrated chunking hook with resetDeps for cache invalidation
apps/web/public/static/locales/en/common.json Added i18n strings for RR chunking UI
packages/features/bookings/Booker/tests/test-utils.tsx Test utilities updated for chunking support
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook for managing chunked loading state and pagination
packages/features/bookings/Booker/store.ts Added roundRobinChunkSettings and roundRobinChunkInfo to booker store
packages/features/bookings/Booker/types.ts Updated types for round-robin chunking support
packages/features/bookings/Booker/utils/event.ts Utility updates for chunking integration
packages/features/bookings/lib/bookingCreateBodySchema.ts Schema updates for chunking parameters
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Extended to accept roundRobinManualChunking and roundRobinChunkOffset
packages/features/schedules/lib/use-schedule/useSchedule.ts Extended to accept chunking parameters
packages/lib/types/roundRobinChunkInfo.ts New type definition for chunk metadata
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Added chunk settings to useAvailableSlots and exposed onLoadNextRoundRobinChunk
packages/platform/atoms/hooks/useAvailableSlots.ts Updated to handle round-robin chunking parameters
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added roundRobinManualChunking and roundRobinChunkOffset inputs
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added chunking inputs for v2 API
packages/trpc/server/routers/viewer/slots/types.ts Added chunking input parameters
packages/trpc/server/routers/viewer/slots/util.test.ts Comprehensive tests for chunking logic
packages/trpc/server/routers/viewer/slots/util.ts Core chunking implementation with calculateAvailabilityWithRoundRobinChunks

Review Focus Areas

  • Chunk size calculation in calculateAvailabilityWithRoundRobinChunks: verify 20%/50 cap logic handles edge cases (101 hosts vs 500 hosts).
  • Cache invalidation in BookerWebWrapper: confirm resetDeps properly clears stale chunk state on route changes.
  • Progress indicator math in AvailableTimeSlots: check percentage calculation when totalHosts includes fixed hosts.

Architecture

Design Decisions: Chunking activates only when non-fixed hosts exceed 100 and RR weights are disabled. This keeps simple cases fast while solving the large-team performance problem. Manual chunking mode gives frontend control over pagination vs. automatic sequential processing.

Scalability & Extensibility: Chunk size scales with team size (20% of hosts) but caps at 50 to prevent oversized queries. The RoundRobinChunkInfo metadata structure supports future extensions like estimated completion time or host priority scores.

Risks:

  • Intentional: Users may see partial availability until they click "Load more". This is acceptable for the performance tradeoff.
  • Unintentional: Fixed hosts are always loaded first. If a large team has many fixed hosts, the "Load more" flow may feel confusing. Review if fixed host count should also influence chunking thresholds.

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Added Round-Robin host chunking to handle 100+ non-fixed hosts by processing in 20% chunks (max 50) instead of all at once.
  • New UI controls let users manually load additional host chunks when initial chunks return no availability.
  • Chunking state persists in the booker store with automatic reset on event changes.

Key Changes by Area

Availability Calculation: Added calculateAvailabilityWithRoundRobinChunks() in util.ts that chunks hosts dynamically and processes sequentially until slots are found. Disabled when RR weights are enabled.

API/Types: Extended Platform API inputs (slots-2024-04-15, slots-2024-09-04) and tRPC types with roundRobinManualChunking and roundRobinChunkOffset parameters.

Frontend State: New useRoundRobinChunking hook manages chunk loading state. AvailableTimeSlots shows progress indicator and "Load more" button with host counts.

Platform Integration: Both BookerPlatformWrapper and BookerWebWrapper integrate chunking hook and pass callbacks through component tree.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added "Load more" button with circular progress and host count display
apps/web/modules/bookings/components/Booker.tsx Forwards onLoadNextRoundRobinChunk prop to AvailableTimeSlots
apps/web/modules/bookings/components/BookerWebWrapper.tsx Integrates useRoundRobinChunking hook
apps/web/public/static/locales/en/common.json Added round_robin_load_next_hosts and round_robin_reset_hosts strings
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook for chunk loading state management
packages/features/bookings/Booker/store.ts Added roundRobinChunkSettings and roundRobinChunkInfo to store
packages/features/schedules/lib/use-schedule/useSchedule.ts Passes chunking params to slot queries
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Includes chunking params in cache key
packages/lib/types/roundRobinChunkInfo.ts New RoundRobinChunkInfo type definition
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Integrates useRoundRobinChunking hook
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added chunking parameters to input type
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added chunking parameters to input type
packages/trpc/server/routers/viewer/slots/types.ts Extended tRPC input schema with chunking fields
packages/trpc/server/routers/viewer/slots/util.ts Core chunking logic with calculateAvailabilityWithRoundRobinChunks
packages/trpc/server/routers/viewer/slots/util.test.ts Unit tests for chunking logic

Review Focus Areas

  • Chunk size calculation in util.ts when host count is near threshold boundaries.
  • State reset logic in useRoundRobinChunking when event identifiers change.
  • Cache key invalidation in useApiV2AvailableSlots when chunk offset changes.

Architecture

Design Decisions: Sequential chunk processing prioritizes early termination when availability is found. This trades worst-case latency (all chunks) for typical-case speed. Manual chunking is exposed to UI rather than auto-loading to prevent excessive backend calls when users are unlikely to book far-future slots.

Scalability & Extensibility: Chunk sizing is intentionally capped at 50 hosts to bound single-request latency. The 20% ratio provides reasonable granularity without excessive round trips for 100-500 host teams. Out of scope: adaptive chunk sizing based on historical availability patterns.

Risks:

  • Intentional: Fixed hosts are duplicated across every chunk. This is correct for availability but increases processing slightly.
  • Intentional: RR weights disable chunking entirely. This is a product tradeoff (accurate weights vs. performance).
  • Unintentional: Manual chunk offset could exceed total chunks if frontend/store state drifts from backend calculation.

@chay2199

chay2199 commented Jun 6, 2026

Copy link
Copy Markdown
Author

@codity review

@codity-chait

codity-chait Bot commented Jun 6, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Implements Round-Robin host chunking to improve performance for events with 100+ non-fixed hosts by processing availability in batches (20% of hosts, max 50 per chunk) instead of all at once.
  • Adds manual chunk navigation with a "Load more availability" button showing progress (loaded/total hosts) when more hosts remain.
  • Extends platform API and booker store to support chunked loading state across web and platform wrappers.

Key Changes by Area

Availability Engine: New calculateAvailabilityWithRoundRobinChunks() in util.ts handles automatic sequential chunking with early termination when availability found, plus manual offset-based chunking via query params.

API/Types: Added roundRobinManualChunking and roundRobinChunkOffset to slot query schemas (TRPC and Platform APIs v2024-04-15, v2024-09-04).

Frontend/UI: New useRoundRobinChunking hook manages loading state; AvailableTimeSlots.tsx renders sticky progress button; BookerPlatformWrapper.tsx exposes onLoadNextRoundRobinChunk callback.

State Management: Extended booker store with roundRobinChunkSettings and roundRobinChunkInfo for cross-component coordination.

Files Changed

File Changes Summary
apps/web/modules/bookings/components/AvailableTimeSlots.tsx Added "Load more availability" button with progress indicator
apps/web/modules/bookings/components/Booker.tsx Integrated chunking hook and pass-through to time slots
apps/web/modules/bookings/components/BookerWebWrapper.tsx Connected round-robin chunk settings to store
apps/web/public/static/locales/en/common.json Added translation keys for chunking UI
packages/features/bookings/Booker/tests/test-utils.tsx Updated test utilities for chunking state
packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts New hook for chunk loading state and callbacks
packages/features/bookings/Booker/store.ts Added roundRobinChunkSettings and roundRobinChunkInfo to store
packages/features/bookings/Booker/types.ts Extended types for chunk settings
packages/features/bookings/Booker/utils/event.ts Updated event utilities for chunking support
packages/features/bookings/lib/bookingCreateBodySchema.ts Schema updates for chunking params
packages/features/schedules/lib/use-schedule/useApiV2AvailableSlots.ts Passes chunk params to API v2 slots
packages/features/schedules/lib/use-schedule/useSchedule.ts Passes roundRobinManualChunking and roundRobinChunkOffset to queries
packages/lib/types/roundRobinChunkInfo.ts New type definition for chunk metadata
packages/platform/atoms/booker/BookerPlatformWrapper.tsx Integrated chunking hook, exposed onLoadNextRoundRobinChunk
packages/platform/atoms/hooks/useAvailableSlots.ts Added chunk params to slot fetching
packages/platform/types/slots/slots-2024-04-15/inputs/index.ts Added manual chunking input types
packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts Added manual chunking input types for v2024-09-04
packages/trpc/server/routers/viewer/slots/types.ts Added chunking params to slot query schema
packages/trpc/server/routers/viewer/slots/util.test.ts Comprehensive tests for chunking logic
packages/trpc/server/routers/viewer/slots/util.ts Core chunking implementation with calculateAvailabilityWithRoundRobinChunks

Review Focus Areas

  • Chunk size logic in util.ts:68-80: Verify 20%/50-max sizing handles edge cases (e.g., 101 hosts → 21 per chunk, not 20).
  • Early termination vs. full scan: Sequential processing stops at first chunk with availability. Confirm this matches product intent for "find any slot" vs. "find optimal slot".
  • State sync between manual and automatic modes: roundRobinManualChunking flag switches behaviors. Check that platform and web wrappers handle mode transitions correctly.

Architecture

Design Decisions

  • Chunking activates only when non-fixed hosts exceed 100 and RR weights are disabled. This avoids complexity in weighted scenarios where host ordering matters more.
  • Sequential automatic chunking prioritizes speed (early termination) over completeness. Manual mode gives users control to explore more hosts when initial chunks lack availability.
  • 20%/50-max sizing balances query count vs. per-query load. Capped at 50 to prevent single query timeouts.

Scalability & Extensibility

  • RoundRobinChunkInfo metadata structure supports future pagination UIs (e.g., "showing hosts 1-20 of 150").
  • Platform API versioning (v2024-04-15, v2024-09-04) ensures backward compatibility. New params are optional.

Risks

  • Intentional: Early termination may hide better availability in later chunks. This is acceptable for the "find any slot" use case but should be documented if users expect full host coverage.
  • Unintentional: hasMoreNonFixedHosts calculation depends on accurate totalNonFixedHosts from initial query. Verify this count remains stable across chunk requests (hosts added/removed mid-session could desync UI).

useEffect(() => {
setRoundRobinChunkSettings(null);
setRoundRobinChunkInfo(null);
}, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Critical

Spreading resetDeps (a variable-length array) into the dependency array violates React's Rules of Hooks, which require dependency arrays to have a constant number of elements across renders. This causes React to silently skip effect cleanup or retain stale closures when resetDeps length changes, and breaks ESLint's exhaustive-deps rule. The fix is to include resetDeps as a single dependency rather than spreading it.

Suggested change
}, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);
}, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, resetDeps]);
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/features/bookings/Booker/components/hooks/useRoundRobinChunking.ts
Lines: 32-32
Issue Type: functional-critical
Severity: critical

Issue Description:
Spreading `resetDeps` (a variable-length array) into the dependency array violates React's Rules of Hooks, which require dependency arrays to have a constant number of elements across renders. This causes React to silently skip effect cleanup or retain stale closures when `resetDeps` length changes, and breaks ESLint's exhaustive-deps rule. The fix is to include `resetDeps` as a single dependency rather than spreading it.

Current Code:
  }, [setRoundRobinChunkInfo, setRoundRobinChunkSettings, ...resetDeps]);

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Comment on lines +114 to +118
@Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
@IsBoolean()
@IsOptional()
@ApiHideProperty()
roundRobinManualChunking?: boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional High

The @Transform decorator on line 114 calls value.toLowerCase() without type-checking, causing a TypeError when value is a boolean true from JSON input. While the decorator attempts to handle truthy values, it doesn't account for non-string truthy values like native booleans. This crashes the request when the API receives roundRobinManualChunking: true as a JSON boolean instead of a string.

Suggested change
@Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
@IsBoolean()
@IsOptional()
@ApiHideProperty()
roundRobinManualChunking?: boolean;
@Transform(({ value }) => (typeof value === "string" ? value.toLowerCase() === "true" : Boolean(value)))
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts
Lines: 114-118
Issue Type: functional-high
Severity: high

Issue Description:
The `@Transform` decorator on line 114 calls `value.toLowerCase()` without type-checking, causing a TypeError when `value` is a boolean `true` from JSON input. While the decorator attempts to handle truthy values, it doesn't account for non-string truthy values like native booleans. This crashes the request when the API receives `roundRobinManualChunking: true` as a JSON boolean instead of a string.

Current Code:
  @Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional Critical

The @Transform decorator calls value.toLowerCase() on any truthy value without checking its type first. When a native boolean true is sent in the JSON request body (not a string), value.toLowerCase is undefined, causing a TypeError that crashes the request handler. The fix must handle both string and boolean inputs by checking the type before calling string methods.

Suggested change
@Transform(({ value }) => (typeof value === 'string' ? value.toLowerCase() === 'true' : !!value))
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/types/slots/slots-2024-04-15/inputs/index.ts
Lines: 197-201
Issue Type: functional-critical
Severity: critical

Issue Description:
The `@Transform` decorator calls `value.toLowerCase()` on any truthy value without checking its type first. When a native boolean `true` is sent in the JSON request body (not a string), `value.toLowerCase` is undefined, causing a `TypeError` that crashes the request handler. The fix must handle both string and boolean inputs by checking the type before calling string methods.

Current Code:
  @Transform(({ value }) => (value ? value.toLowerCase() === "true" : false))
  @IsBoolean()
  @IsOptional()
  @ApiHideProperty()
  roundRobinManualChunking?: boolean;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Functional High

The roundRobinChunkOffset field is validated only with @IsNumber(), allowing negative values and floats to pass validation, whereas the tRPC schema enforces .int().min(0). When a float (e.g., 1.5) or negative value reaches the server, using it as an array index into hostChunks silently returns undefined, causing an empty chunk to be returned instead of rejecting the invalid input. This creates a data validation inconsistency between client and server schemas, leading to unexpected behavior.

Also reported at: packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts L71–L81

Suggested fix
  @Transform(({ value }) => {
      if (value === undefined || value === null || value === "") {
        return undefined;
      }
      const parsedValue = typeof value === "string" ? parseInt(value, 10) : value;
      return Number.isNaN(parsedValue) ? undefined : parsedValue;
    })
    @IsNumber()
    @IsInt()
    @Min(0)
    @IsOptional()
    @ApiHideProperty()
    roundRobinChunkOffset?: number;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert bash developer with deep knowledge of security, performance, and best practices.

### Context

File: packages/platform/types/slots/slots-2024-04-15/inputs/index.ts
Lines: 114-124
Issue Type: functional-high
Severity: high

Issue Description:
The `roundRobinChunkOffset` field is validated only with `@IsNumber()`, allowing negative values and floats to pass validation, whereas the tRPC schema enforces `.int().min(0)`. When a float (e.g., `1.5`) or negative value reaches the server, using it as an array index into `hostChunks` silently returns `undefined`, causing an empty chunk to be returned instead of rejecting the invalid input. This creates a data validation inconsistency between client and server schemas, leading to unexpected behavior.

_Also reported at: `packages/platform/types/slots/slots-2024-09-04/inputs/get-slots.input.ts` L71–L81_

Current Code:
  @Transform(({ value }) => {
    if (value === undefined || value === null || value === "") {
      return undefined;
    }
    const parsedValue = typeof value === "string" ? parseInt(value, 10) : value;
    return Number.isNaN(parsedValue) ? undefined : parsedValue;
  })
  @IsNumber()
  @IsOptional()
  @ApiHideProperty()
  roundRobinChunkOffset?: number;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike Create Issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants