Skip to content

Conversation

hariombalhara
Copy link
Member

@hariombalhara hariombalhara commented Jul 25, 2025

What does this PR do?

  • Fixes PR-296 (Linear issue number - should be visible at the bottom of the GitHub issue description)
image

Video Demo (if applicable):

After the fix: https://www.loom.com/share/8ab462f3d9c44641996e7d7ec9a3bdc3
Before the fix: https://www.loom.com/share/4b6684ddd75d469c87319e079b076c45

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?

See loom.

Earlier, if a multiselect form field was provided with multiple options and that field is selected as 'Value of Field', there was an intentional error

Copy link

linear bot commented Jul 25, 2025

PRI-296

Copy link
Contributor

coderabbitai bot commented Jul 25, 2025

Walkthrough

This set of changes introduces significant refactoring and new functionality related to the processing of RAQB (Rule-based Attribute Query Builder) queries. The core logic for resolving query values is centralized in a new resolveQueryValue module, which replaces attribute option IDs with their labels and substitutes field template variables with actual dynamic field values. Utility functions for case-insensitive string handling are added. Extensive new and refactored test suites are provided to cover a wide range of scenarios and edge cases for this logic. Documentation is enhanced with a detailed JSON example for the query value schema. No public API signatures are broken; new exports are added for the new functionality.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Complexity: The changes span multiple files with high-complexity logic, including deep recursive transformations, dynamic value resolution, and comprehensive test coverage for numerous edge cases. The introduction of new modules and significant refactoring of existing test suites require careful review for correctness and regression risks.
  • Scope: New modules, utility functions, and extensive test additions, along with documentation updates.
  • Estimated review time: Approximately 45 minutes for a thorough human review.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • PR-296: Entity not found: Issue - Could not find referenced Issue.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch hariom/pri-296-attribute-routing-error-with-value-of-field-when-the-field

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted.

Details:

No release type found in pull request title "Passing tests and fixed". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

@keithwillcode keithwillcode added core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO labels Jul 25, 2025
@hariombalhara hariombalhara changed the title Passing tests and fixed feat: Support multiple options when used with Value of Field Jul 25, 2025
Comment on lines -20 to -52
function getFieldResponseValueAsLabel({
field,
fieldResponseValue,
}: {
fieldResponseValue: dynamicFieldValueOperandsResponse[keyof dynamicFieldValueOperandsResponse]["value"];
field: {
type: string;
options?: {
id: string | null;
label: string;
}[];
};
}) {
if (!field.options) {
return fieldResponseValue;
}

const valueArray = fieldResponseValue instanceof Array ? fieldResponseValue : [fieldResponseValue];

const chosenOptions = valueArray.map((idOrLabel) => {
const foundOptionById = field.options?.find((option) => {
return option.id === idOrLabel;
});
if (foundOptionById) {
return {
label: foundOptionById.label,
id: foundOptionById.id,
};
} else {
return {
label: idOrLabel.toString(),
id: null,
};
Copy link
Member Author

@hariombalhara hariombalhara Jul 28, 2025

Choose a reason for hiding this comment

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

This and all other deleted code here is actually moved to resolveQueryValue.ts or utils.ts

…ute-routing-error-with-value-of-field-when-the-field
* Replace attribute option Ids with the attribute option label(compatible to be matched with form field value)
*/
const replaceAttributeOptionIdsWithOptionLabel = ({
queryValue,
Copy link
Member Author

@hariombalhara hariombalhara Jul 28, 2025

Choose a reason for hiding this comment

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

This fn came from raqbUtils with the difference that it now accepts queryValue and returned updated queryValue instead of accepting queryValueString and returning back updated string. It builds queryValueString itself

This change ensures that we pass a typed queryValue and get typed queryValue in return

Comment on lines 50 to 71
const nonNumberFieldResponseValue =
typeof fieldResponseValue === "number" ? fieldResponseValue.toString() : fieldResponseValue;

if (!field.options) {
return nonNumberFieldResponseValue;
}

if (nonNumberFieldResponseValue instanceof Array) {
return nonNumberFieldResponseValue.map(transformValue);
}

return transformValue(nonNumberFieldResponseValue);

function transformValue(idOrLabel: string) {
const foundOptionById = field.options?.find((option) => {
return option.id === idOrLabel;
});
if (foundOptionById) {
return foundOptionById.label;
} else {
return idOrLabel.toString();
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This fn also comes from raqbUtils with the change that it now never returns a number type which was unexpected as label can't be a number.

Also, earlier it was returning an array regardless of whether the fieldResponseValue was an array or string, now it returns array for array and string for string, making the function do its job well.

* // Returns: '{"value": [["delhi", "mumbai"]], "operator": "multiselect_some_in"}'
* ```
*/
export const resolveQueryValue = ({
Copy link
Member Author

Choose a reason for hiding this comment

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

This fn replaces the earlier replaceFieldTemplateVariableWithOptionLabel which was working on queryValueString and it now works on queryValue as an object(which is the original form).

It was required because string regex replacement can't handle all the scenarios.

Copy link
Member Author

@hariombalhara hariombalhara Jul 28, 2025

Choose a reason for hiding this comment

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

Also, this fn itself calls replaceAttributeOptionIdsWithOptionLabel now, instead of letting the caller do it first before calling this fn.

This makes the job of this fn focussed on resolving the query value which involves.

  1. Repacing optionId with optionLabel
  2. Replacing {field:FIELD_ID} with the field's response

This fn is now being unit tested well.

value: [[Option1OfAttribute1.id, Option2OfAttribute1.id]],
operator: "multiselect_some_in",
valueType: ["multiselect"],
it("should handle field template mixed with regular values in multiselect array", async () => {
Copy link
Member Author

@hariombalhara hariombalhara Jul 28, 2025

Choose a reason for hiding this comment

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

This is a new test.

]);
});
describe("with `Value of field`", () => {
it("when 'Any in'(multiselect_some_in) option is selected and more than one option is used in attribute and more than one option is selected in the field", async () => {
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a new test

Comment on lines +293 to +305
describe("with a SINGLE_SELECT attribute", () => {
it("when a static option is selected, troubleshooter should be null by default", async () => {
const Option1OfAttribute1 = { id: "opt1", value: "Option 1", slug: "option-1" };
const Attribute1 = {
id: "attr1",
name: "Attribute 1",
type: "SINGLE_SELECT" as const,
slug: "attribute-1",
options: [Option1OfAttribute1],
};

mockAttributesScenario({
attributes: [Attribute1],
teamMembersWithAttributeOptionValuePerAttribute: [
{ userId: 1, attributes: { [Attribute1.id]: Option1OfAttribute1.value } },
],
});
mockAttributesScenario({
attributes: [Attribute1],
Copy link
Member Author

Choose a reason for hiding this comment

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

A lot of restructuring of tests.

Copy link

vercel bot commented Jul 28, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
cal ⬜️ Ignored (Inspect) Jul 30, 2025 1:59pm
cal-eu ⬜️ Ignored (Inspect) Jul 30, 2025 1:59pm

@hariombalhara hariombalhara self-assigned this Jul 28, 2025
@hariombalhara hariombalhara changed the title feat: Support multiple options when used with Value of Field feat: Support an array response for a field when used as Value of Field Jul 28, 2025
@hariombalhara hariombalhara marked this pull request as ready for review July 28, 2025 09:57
@graphite-app graphite-app bot requested a review from a team July 28, 2025 09:57
@hariombalhara hariombalhara added the High priority Created by Linear-GitHub Sync label Jul 28, 2025
@dosubot dosubot bot added the ✨ feature New feature or request label Jul 28, 2025
Copy link

graphite-app bot commented Jul 28, 2025

Graphite Automations

"Add consumer team as reviewer" took an action on this PR • (07/28/25)

1 reviewer was added to this PR based on Keith Williams's automation.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/lib/raqb/resolveQueryValue.ts (1)

156-167: Consider using a more robust regex pattern for field template validation

The current string manipulation approach for field template detection works but could be more robust.

-  const isFieldTemplate = (str: string): boolean => {
-    const trimmedStr = str.trim();
-    return trimmedStr.startsWith("{field:") && trimmedStr.endsWith("}");
-  };
-
-  // Extract field ID from template string
-  const extractFieldId = (template: string): string | null => {
-    const trimmedTemplate = template.trim();
-    if (!isFieldTemplate(trimmedTemplate)) return null;
-    // Remove {field: and } to get the ID
-    return trimmedTemplate.slice(7, -1);
-  };
+  const FIELD_TEMPLATE_REGEX = /^\s*\{field:([^}]+)\}\s*$/;
+  
+  const isFieldTemplate = (str: string): boolean => {
+    return FIELD_TEMPLATE_REGEX.test(str);
+  };
+
+  // Extract field ID from template string
+  const extractFieldId = (template: string): string | null => {
+    const match = template.match(FIELD_TEMPLATE_REGEX);
+    return match ? match[1] : null;
+  };
packages/lib/raqb/raqbUtils.test.ts (1)

1703-1719: Consider adding assertion for error logging in null query test

While the test handles null input gracefully, it would be valuable to verify that appropriate error logging occurs.

Consider using a spy to verify error logging:

+  const loggerSpy = vi.spyOn(logger, 'error');
   const result = resolveQueryValue({
     queryValue: invalidQueryValue,
     // ... rest of params
   });

   expect(result).toBeNull();
+  // Optionally verify error was logged
+  expect(loggerSpy).toHaveBeenCalled();
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee073cd and e954268.

📒 Files selected for processing (7)
  • packages/lib/raqb/findTeamMembersMatchingAttributeLogic.test.ts (3 hunks)
  • packages/lib/raqb/raqbUtils.test.ts (2 hunks)
  • packages/lib/raqb/raqbUtils.ts (4 hunks)
  • packages/lib/raqb/resolveQueryValue.test.ts (1 hunks)
  • packages/lib/raqb/resolveQueryValue.ts (1 hunks)
  • packages/lib/raqb/utils.ts (1 hunks)
  • packages/lib/raqb/zod.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code. Functions like .add, .diff, .isBefore, and .isAfter are slow, especially in timezone mode. Prefer .utc() for better performance. Where possible, replace with native Date and direct .valueOf() comparisons for faster execution. Recommend using native methods or Day.js .utc() consistently in hot paths like loops.

Files:

  • packages/lib/raqb/utils.ts
  • packages/lib/raqb/zod.ts
  • packages/lib/raqb/resolveQueryValue.ts
  • packages/lib/raqb/raqbUtils.ts
  • packages/lib/raqb/raqbUtils.test.ts
  • packages/lib/raqb/resolveQueryValue.test.ts
  • packages/lib/raqb/findTeamMembersMatchingAttributeLogic.test.ts
🧠 Learnings (2)
packages/lib/raqb/raqbUtils.ts (5)

Learnt from: eunjae-lee
PR: #22106
File: packages/lib/server/service/insightsRouting.ts:367-368
Timestamp: 2025-07-15T13:02:17.403Z
Learning: In the InsightsRoutingService (packages/lib/server/service/insightsRouting.ts), multi-select filter data is already validated by zod before reaching the buildFormFieldSqlCondition method, so null/undefined values are not present in filterValue.data arrays and don't need to be filtered out.

Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-21T13:54:11.770Z
Learning: Applies to backend/**/*.{ts,tsx} : For Prisma queries: Never use Includes - use select.

Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-21T13:54:11.770Z
Learning: Applies to backend/**/*.{ts,tsx} : For Prisma queries: Only select data you need.

Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-21T13:54:11.770Z
Learning: Applies to backend/**/*.{ts,tsx} : For Prisma queries: Select selects only the fields you specify explicitly.

Learnt from: eunjae-lee
PR: #22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.

packages/lib/raqb/raqbUtils.test.ts (1)

Learnt from: eunjae-lee
PR: #22106
File: packages/lib/server/service/insightsRouting.ts:367-368
Timestamp: 2025-07-15T13:02:17.403Z
Learning: In the InsightsRoutingService (packages/lib/server/service/insightsRouting.ts), multi-select filter data is already validated by zod before reaching the buildFormFieldSqlCondition method, so null/undefined values are not present in filterValue.data arrays and don't need to be filtered out.

🧬 Code Graph Analysis (1)
packages/lib/raqb/raqbUtils.ts (1)
packages/lib/raqb/resolveQueryValue.ts (1)
  • resolveQueryValue (137-267)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze Build / analyze
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (20)
packages/lib/raqb/utils.ts (1)

1-9: LGTM!

The caseInsensitive utility function is well-implemented with proper TypeScript conditional return types, maintaining the input structure while converting to lowercase.

packages/lib/raqb/zod.ts (1)

87-119: Helpful documentation addition!

The JSON example clearly illustrates the expected structure of raqbQueryValueSchema, including nested groups, rules, and field templates. This will aid developers in understanding the complex query value format.

packages/lib/raqb/findTeamMembersMatchingAttributeLogic.test.ts (3)

50-50: Good addition of attributeId to options.

Adding attributeId to the option objects is necessary for the attribute resolution logic to work correctly.


293-795: Excellent test organization and coverage!

The restructured tests with nested describe blocks for SINGLE_SELECT and MULTI_SELECT attributes provide clear organization and comprehensive coverage of:

  • Static option selection
  • Dynamic "Value of field" resolution
  • Complex multiselect scenarios with mixed field templates and fixed values
  • Edge cases with array handling

The test scenarios effectively validate the new resolveQueryValue functionality.


1214-1252: Good edge case coverage for non-existent option IDs.

This test ensures the system gracefully handles invalid option IDs by returning no matches rather than throwing errors.

packages/lib/raqb/resolveQueryValue.test.ts (4)

11-152: Well-structured test data builders!

The helper functions (createQueryValueRule, createAttributesQueryValue, etc.) provide a clean and maintainable way to create test scenarios, reducing boilerplate and improving test readability.


211-581: Comprehensive coverage of attribute option ID conversion!

These tests thoroughly validate the conversion of attribute option IDs to lowercase labels, covering:

  • Single and multiple option conversions
  • Mixed arrays with field templates
  • Special characters preservation
  • Edge cases with missing attributes

The tests effectively verify the critical functionality for field matching.


1154-1181: Good performance consideration with large arrays.

Testing with 100-item arrays ensures the implementation handles large datasets efficiently.


1621-1654: Excellent stack overflow prevention test!

Testing with 100 levels of nesting ensures the recursive implementation won't cause stack overflow issues in production.

packages/lib/raqb/raqbUtils.ts (2)

160-166: Clean refactoring to use centralized resolveQueryValue!

The simplified implementation delegates the complex logic of attribute option ID resolution and field template processing to the dedicated resolveQueryValue function, improving maintainability and separation of concerns.


223-223: Good addition of resolveQueryValue to exports.

Exposing resolveQueryValue through the acrossQueryValueCompatiblity object allows external modules to use this functionality when needed.

packages/lib/raqb/resolveQueryValue.ts (3)

47-77: LGTM!

The function correctly handles field response value transformation with proper type conversions and array handling.


200-227: Array flattening implementation correctly supports multiselect fields

The flattening behavior for field templates that resolve to arrays (lines 213-217) properly addresses the PR objective of supporting array responses for multiselect fields when used as "Value of Field".


251-267: Good error handling with comprehensive logging

The error handling provides detailed context for debugging including field counts and response keys.

packages/lib/raqb/raqbUtils.test.ts (6)

12-18: Well-structured test setup with appropriate mocking

The mock for getFieldResponseValueAsLabel appropriately simplifies testing by returning values as-is, allowing focus on the core logic of resolveQueryValue.


20-163: Excellent test data builders improve test maintainability

The test data builders (createQueryValueRule, createAttributesQueryValue, etc.) provide a clean API for creating test scenarios, making tests more readable and maintainable.


281-645: Comprehensive test coverage for attribute option ID replacement

The test suite thoroughly covers attribute ID replacement scenarios including edge cases like special characters, empty arrays, and complex nested structures.


759-799: Critical test validates array field template resolution

This test specifically validates the PR's core objective - when multiple field templates are used in a multiselect context and one resolves to an array while another to a single value, they are properly combined into a flat array.


1286-1313: Good performance consideration with large array test

Testing with a 100-item array ensures the implementation handles large datasets efficiently.


1560-1595: Excellent edge case coverage for empty responses

The tests properly verify that field templates remain unchanged when responses are missing, ensuring graceful degradation.

Copy link
Member

@alishaz-polymath alishaz-polymath left a comment

Choose a reason for hiding this comment

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

LGTM 🙏

Copy link
Contributor

@anikdhabal anikdhabal left a comment

Choose a reason for hiding this comment

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

Looks good

@hariombalhara hariombalhara enabled auto-merge (squash) July 30, 2025 13:59
@hariombalhara hariombalhara disabled auto-merge July 30, 2025 13:59
@hariombalhara hariombalhara enabled auto-merge (squash) July 30, 2025 13:59
@hariombalhara hariombalhara merged commit 016a966 into main Jul 30, 2025
56 of 60 checks passed
@hariombalhara hariombalhara deleted the hariom/pri-296-attribute-routing-error-with-value-of-field-when-the-field branch July 30, 2025 15:07
Copy link
Contributor

E2E results are ready!

devin-ai-integration bot pushed a commit that referenced this pull request Jul 31, 2025
…eld` (#22740)

* Passing tests and fixed

* self review addressed adn more tests
anikdhabal added a commit that referenced this pull request Jul 31, 2025
* fix: resolve username constraint violation in removeMember

- Update username to - format when removing users from organizations
- Fix unique constraint violation on (username, organizationId) when organizationId is null
- Add test case to verify username format change and successful removal
- Fix skipped test by adding proper imports and removing describe.skip

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* test: update removeMember test to verify constraint violation scenario

- Create two users with same username (one with null orgId, one with orgId)
- Verify removing org user updates username without unique constraint error
- Test ensures username gets updated to - format

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* test: add comprehensive unit tests for handleInstantMeeting

- Revert previous removeMember changes
- Add full test coverage for instant meeting functionality
- Test team validation, booking creation, token generation
- Test webhook triggers and browser notifications
- Mock external dependencies for isolated unit tests
- Translation issue to be addressed in future iteration

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* update

* Update handleInstantMeeting.test.ts

* fix: redir parameter for connect atoms (#22815)

* encode redirect url to make sure it has all parameters

* add changesets

* feat: Support an array response for a field when used as `Value of Field` (#22740)

* Passing tests and fixed

* self review addressed adn more tests

* fix: flaky e2e (#22819)

* fix: merge working hours when adjacent (#21912)

* fix: Adjacency issue when working hours connect over multiple days

* Add tests to validate the new merging of day end logic

* Update to correct annotation.

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Implement subsequent date ranges for date overrides also

* The map needs to be updated on successful resolve.

* test: add failing test for overlapping ranges with same end time

Demonstrates bug where overlapping working hour ranges (6:00-10:00 and 8:00-10:00)
lose the earlier portion (6:00-8:00), showing only 8:00 and 9:00 slots
instead of all 4 slots (6:00, 7:00, 8:00, 9:00).

Related to Carina's comment on PR #21912.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: properly merge overlapping ranges with same end time

Fixes bug where overlapping working hour ranges with the same end time
(e.g., 6:00-10:00 and 8:00-10:00) would lose the earlier portion of the
first range. The merging logic now correctly preserves the earliest
start time when ranges overlap and share the same end time.

This ensures all expected time slots are available (6:00, 7:00, 8:00, 9:00)
instead of losing the earlier slots (6:00, 7:00).

Resolves the issue identified in Carina's comment on PR #21912.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* perf: optimize overlapping range detection from O(n²) to O(n)

Replaces Object.keys().find() with Map-based lookup for ranges with same end time.
This optimization handles 2000+ date ranges efficiently, reducing complexity from
4M operations to linear time while maintaining the same merging behavior.

Performance improvement for high-volume event types with many availability ranges.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: Improving Booking Visibility at Month-End (#22770)

* remove first weeks and add last

* fix added last week

* prefetch availability of next month

* don't switch month

* On hover show month

* only show new UI in monthly view

* show month tooldtip only when needed

* show month on first day of month

* remove isFirstDayOfNextMonth

* fix prefetching next month

* fix datePicker tests

* preventMonthSwitching in monthly view

* add tests

* code clean up

* code clean up

* code clena up for ooo days

* push first day of month

* remove bg color for the month badge

* fix text colour

* remove not needed

* use object param

* revert: use object param

* use object param

* fix DatePicker tests

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Sean Brydon <sean@cal.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>

* chore: Refactor logs (#22824)

* Refactor logs

* Add specific info to log

* fix: Errors in org onboarding in some edge cases (#22711)

* Automatically enable migration of a team that conflicts with Orgs slug

* Allow changing the orgs slug and name if user goes back and changes it

* avoid crashing on some scenarios

* Revert "Allow changing the orgs slug and name if user goes back and changes it"

This reverts commit f8872b0.

* fix: handle unpublished teams gracefully in org migration

- Change 'No oldSlug for team' from error to warning for unpublished teams
- Keep 'No slug for team' as error since org onboarding ensures teams have names
- Add test for migrating unpublished teams without oldSlug
- Add clarifying comments about when each condition can occur

* feat: enable PBAC checking on organization settings page (#22467)

* refactor: convert checkBookingLimits to class service with dependency injection (#22768)

* refactor: convert checkBookingLimits to class service with dependency injection

- Create CheckBookingLimitsService class following AvailableSlotsService pattern
- Add countBookingsByEventTypeAndDateRange method to BookingRepository
- Move direct prisma calls from service to repository layer
- Implement dependency injection with proper DI tokens and modules
- Update all usage points to use the new service through DI
- Maintain backward compatibility with error-throwing wrapper functions
- Update tests to use the new service pattern
- Resolve TODO comment in AvailableSlotsService for DI integration

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: DI CheckBookingLimitsService in v2 slots service

* chore: bump libraries

* chore: create getCheckBookingLimitsService

* refactor: convert checkBookingAndDurationLimits to service class with DI

- Create CheckBookingAndDurationLimitsService class following DI pattern
- Add DI tokens and module for the new service
- Update booking-limits container to provide the new service
- Refactor handleNewBooking.ts to use service through DI
- Maintain backward compatibility with deprecated function export
- Preserve all existing functionality while improving code organization

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: CheckBookingAndDurationLimitsService

* chore: bump platform libs

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: morgan@cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>

* fix: Return empty available days if error querying calendar (#22828)

* Return a busy block placeholder if calendar throws an error

* Refactor `getCalendarsEvents` to return an object with a success prop

* Throw error in `getBusyTimes` if failed to fetch calendar availability

* Return empty available days if error getting busy times

* yeet.

* Type fix

* Fix type error in getLuckyUsers

* Type fixes

* Type fix

* Type fix

* Fix test

* Fix test mocks

* Refactor calendars.service to use new calendarBusyTimesQuery

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* chore: release v5.5.9

* include mobile layout (#22836)

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* test: fix handleInstantMeeting test with setupAndTeardown and proper mocking

- Add setupAndTeardown() for proper test environment setup
- Use mockNoTranslations() to fix translation function mocking
- Simplify NextApiRequest mock to resolve TypeScript errors
- Both test cases now pass successfully

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix typo

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Sean Brydon <sean@cal.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: morgan@cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO ✨ feature New feature or request High priority Created by Linear-GitHub Sync ready-for-e2e
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants