Skip to content

Fix: multi-select default values validation #12271

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

abdulrahmancodes
Copy link
Contributor

@abdulrahmancodes abdulrahmancodes commented May 24, 2025

Screen.Recording.2025-05-24.at.11.25.18.AM.mov

Closes #12277

…thod for validating multi-select default values.
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

This PR fixes validation issues with multi-select default values in the field metadata system, specifically addressing the inability to remove defaulted option values for standard objects.

  • Added separate validation logic for multi-select fields in packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata-validation.service.ts
  • Implemented validation to ensure all multi-select default values exist within the options array
  • Added support for handling null/empty default values in multi-select fields
  • Enhanced type safety with stricter validation checks for field metadata options

1 file(s) reviewed, no comment(s)
Edit PR Review Bot Settings | Greptile

Copy link
Contributor

github-actions bot commented May 24, 2025

🚀 Preview Environment Ready!

Your preview environment is available at: http://bore.pub:5378

This environment will automatically shut down when the PR is closed or after 5 hours.

Copy link
Contributor

@prastoin prastoin left a comment

Choose a reason for hiding this comment

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

Hey @abdulrahmancodes ! Hope you're doing great, thanks for your contribution.
In a nutshell what you've done is great and works ! but IMO we should go deeper and integrate tho other existing service

I think such refactor is very prone to TDD.
That's why I would recommend starting by writing twenty-server integration tests in the first place, we can have a call where we could describe each tests use case we wanna cover through the defaultValue validation

Main review points:

  • Moving the enum fieldMetadataType ( SELECT | MULTI_SELECT | RATING ) validation logic in FieldMetadataEnumValidationService/
  • defaultValue key should be trimmed using trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties ( see existing usage I think we could merge the defaultValue within the prepareCustomFieldMetadataOptions)
  • Adding integrations tests to for each raised exceptions in update-create-one-field-metadata-select-tests-cases.ts

// @ts-expect-error legacy noImplicitAny
enumOptions.some((option) => option.to === formattedDefaultValue))
) {
if (isValid) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: Would rather throw an exception if invalid as early return

fieldType === FieldMetadataType.SELECT ||
fieldType === FieldMetadataType.MULTI_SELECT
) {
if (fieldType === FieldMetadataType.SELECT) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Remark: If the default value validation is only scoped to ENUM field metadata type ( SELECT || MULTI_SELECT || RATING ) then can moove this in the FieldMetadataEnumValidationService

Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: Using switch statement

Copy link
Contributor

Choose a reason for hiding this comment

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

Question: unsure what we should do about the RATING fieldMetadata type, to be determined

return false;
}

const enumOptions = options.map((option) => option.value);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Please follow the validator pattern from the FieldMetadataEnumValidationService that makes the following assertions more explicit IMO

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: The defaultValue should also be validate through the value validators and trimmer too


return (
enumOptions.includes(formattedValue) ||
// @ts-expect-error legacy noImplicitAny
Copy link
Contributor

Choose a reason for hiding this comment

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

Request: This @ts-expect-error is inaccurate, the related error is not an implicit any

to does not exist on string, from my understanding the below some always returns false

      enumOptions.some((option) => option.to === formattedValue)

const enumOptions = options.map((option) => option.value);
private validateMultiSelectDefaultValue(
options: FieldMetadataOptions<T>,
defaultValues: FieldMetadataDefaultValue<T>,
Copy link
Contributor

@prastoin prastoin May 25, 2025

Choose a reason for hiding this comment

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

Note: We should refactor the FieldMetadataDefaultValue as is imo too verbose
Create accurately named and exported abstraction for each ternary occurence that could be used here for example

export type FieldMetadataDefaultValue<
  T extends FieldMetadataType = FieldMetadataType,
> =
  IsExactly<T, FieldMetadataType> extends true
    ? ExtractValueType<UnionOfValues<FieldMetadataDefaultValueMapping>> | null
    : T extends keyof FieldMetadataDefaultValueMapping
      ? ExtractValueType<FieldMetadataDefaultValueMapping[T]> | null
      : never;

…ming and validation for default values. Introduced a utility function to sanitize input and updated validation logic for both single and multi-select default values.
Copy link
Contributor

github-actions bot commented May 25, 2025

TODOs/FIXMEs:

  • // TODO: Determine if RATING should be handled here: packages/twenty-server/src/engine/metadata-modules/field-metadata/services/field-metadata-enum-validation.service.ts

Generated by 🚫 dangerJS against 1ecc096

@prastoin
Copy link
Contributor

Hey @abdulrahmancodes please let me know once you would like me to review your PR

@abdulrahmancodes
Copy link
Contributor Author

Hey @abdulrahmancodes please let me know once you would like me to review your PR

Hey @prastoin ! Sure. Will let you know as soon as I'm done with the changes.

Copy link
Contributor

@prastoin prastoin left a comment

Choose a reason for hiding this comment

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

Hey hijacking this ! Left a concern regarding tests cases for multi-select, please let me know if you would be up for some sync peer to peer on this section

},
},
{
title: 'should fail with duplicate multi-select default values',
Copy link
Contributor

Choose a reason for hiding this comment

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

Praise: Nice

@@ -123,6 +124,46 @@ const successfulTestCases: UpdateCreateFieldMetadataSelectTestCase[] = [
},
},
},
{
Copy link
Contributor

Choose a reason for hiding this comment

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

Remark: I agree that I've missed testing the multi-select over there, I'm afraid that mixing SELECT and MULTI_SELECT specific scoped tests cases becomes hardly maintainable.
Would you be up to do some peer on this section ? From my point of view I would see commonTestCases between SELECT MULTI_SELECT and afterwards dedicated tests file with their own jest hooks implementation etc.

@abdulrahmancodes
Copy link
Contributor Author

Hey @prastoin ! Sure, happy to sync on this, just let me know when works for you.

@prastoin
Copy link
Contributor

Hey @prastoin ! Sure, happy to sync on this, just let me know when works for you.

Reaching out on discord in order to plan the best schedule for both of us !

@abdulrahmancodes abdulrahmancodes force-pushed the fix/multi-select-default-value-validation branch from 95fe946 to 454c1fb Compare May 28, 2025 07:50
@@ -94,6 +94,22 @@ describe('trim-and-remove-duplicated-whitespaces-from-object-string-properties',
expected: { name: ' John Doe ', description: 'this is a test' },
},
},
{
title: 'should strip quotes from string properties',
Copy link
Contributor

@prastoin prastoin May 28, 2025

Choose a reason for hiding this comment

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

Request: We should not, doing so will break below queries. its required for the defaultValue to be formatted as 'Option'
Related issue twentyhq/core-team-issues#941

@prastoin
Copy link
Contributor

Update

Had a call with @abdulrahmancodes, we should implement dedicated defaultValue validation for multiSelect ( as he's done within the PR ) but expecting a stringified string and not an array ( see latest commit in wip )

We should create a new test suite that will handle the MULTI_SELECT specific success and failing tests cases.
We concluded that common tests should agnostic of the fieldMetadataType

The validation enum typing should be scoped to the MULTI_SELECT RATING SELECT entities in order to infer the correct input typing

Actions

  • @prastoin I will give this PR a further look within few hours !
  • @abdulrahmancodes you can if you want implement the specific tests cases for the MULTI_SELECT following the TDD pattern

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

Successfully merging this pull request may close these issues.

Unable to update default values for multi-select fields
3 participants