From 1c5f3ef5fa0ac217d2eb98d25b472474568ad7a1 Mon Sep 17 00:00:00 2001 From: Etienne <45695613+etiennejouan@users.noreply.github.com> Date: Mon, 24 Mar 2025 13:42:51 +0100 Subject: [PATCH] clean searchResolvers in server (#11114) Introduces break in change - remove search... resolvers - rename globalSearch to search - rename searchRecord.objectSingularName > objectNameSingular closes https://github.com/twentyhq/core-team-issues/issues/643 --- .../src/generated-metadata/graphql.ts | 41 ++--- .../twenty-front/src/generated/graphql.tsx | 58 +++---- .../__stories__/CommandMenu.stories.tsx | 4 +- .../queries/{globalSearch.ts => search.ts} | 8 +- .../hooks/useCommandMenuSearchRecords.tsx | 20 +-- ...SearchRecordAsSingleRecordPickerRecord.ts} | 12 +- .../hooks/useObjectRecordSearchRecords.ts | 15 +- .../MultipleRecordPickerMenuItemContent.tsx | 4 +- .../useMultipleRecordPickerPerformSearch.ts | 22 +-- .../searchRecordStoreComponentFamilyState.ts | 4 +- .../hooks/useFilteredSearchRecordQuery.ts | 8 +- .../components/RoleAssignment.tsx | 4 +- ...ssignmentWorkspaceMemberPickerDropdown.tsx | 4 +- ...ntWorkspaceMemberPickerDropdownContent.tsx | 6 +- .../twenty-front/src/testing/graphqlMocks.ts | 59 ++----- ...ector-on-note-and-task-entities.command.ts | 8 +- .../0-43-upgrade-version-command.module.ts | 4 +- .../graphql-query-runner.module.ts | 2 - .../interfaces/base-resolver-service.ts | 1 - .../graphql-query-search-resolver.service.ts | 158 ------------------ .../types/workspace-query-hook.type.ts | 5 +- .../constants/resolver-method-names.ts | 1 - .../factories/factories.ts | 3 - .../factories/search-resolver-factory.ts | 43 ----- .../workspace-resolvers-builder.interface.ts | 9 - .../workspace-resolver-builder.service.ts | 3 - .../workspace-resolver.factory.ts | 3 - .../factories/root-type.factory.ts | 1 - .../utils/get-resolver-args.util.ts | 15 -- .../engine/core-modules/core-engine.module.ts | 4 +- .../mockObjectMetadataItemsWithFieldMaps.ts | 0 .../__tests__/search.service.spec.ts} | 30 ++-- ...ts-limit-by-object-without-search-terms.ts | 0 .../standard-objects-by-priority-rank.ts | 0 .../dtos/object-record-filter-input.ts | 0 .../dtos/search-args.ts} | 4 +- .../dtos/search-record-dto.ts} | 6 +- .../exceptions/search.exception.ts} | 6 +- .../filters/search-api-exception.filter.ts} | 8 +- .../search.module.ts} | 8 +- .../search.resolver.ts} | 63 ++++--- .../services/search.service.ts} | 32 ++-- .../records-with-object-metadata-item.ts | 0 .../__tests__/format-search-terms.spec.ts | 2 +- .../utils/format-search-terms.ts | 0 .../object-metadata/object-metadata.module.ts | 4 +- .../object-metadata.service.ts | 8 +- .../search-vector.module.ts} | 8 +- .../search-vector.service.ts} | 2 +- .../engine/utils/get-resolver-name.util.ts | 2 - .../search-resolver.integration-spec.ts} | 37 ++-- ...factory.util.ts => search-factory.util.ts} | 16 +- 52 files changed, 236 insertions(+), 529 deletions(-) rename packages/twenty-front/src/modules/command-menu/graphql/queries/{globalSearch.ts => search.ts} (83%) rename packages/twenty-front/src/modules/object-metadata/utils/{formatGlobalSearchRecordAsSingleRecordPickerRecord.ts => formatSearchRecordAsSingleRecordPickerRecord.ts} (63%) delete mode 100644 packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts delete mode 100644 packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/search-resolver-factory.ts rename packages/twenty-server/src/engine/core-modules/{global-search => search}/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts (100%) rename packages/twenty-server/src/engine/core-modules/{global-search/__tests__/global-search.service.spec.ts => search/__tests__/search.service.spec.ts} (87%) rename packages/twenty-server/src/engine/core-modules/{global-search => search}/constants/results-limit-by-object-without-search-terms.ts (100%) rename packages/twenty-server/src/engine/core-modules/{global-search => search}/constants/standard-objects-by-priority-rank.ts (100%) rename packages/twenty-server/src/engine/core-modules/{global-search => search}/dtos/object-record-filter-input.ts (100%) rename packages/twenty-server/src/engine/core-modules/{global-search/dtos/global-search-args.ts => search/dtos/search-args.ts} (89%) rename packages/twenty-server/src/engine/core-modules/{global-search/dtos/global-search-record-dto.ts => search/dtos/search-record-dto.ts} (83%) rename packages/twenty-server/src/engine/core-modules/{global-search/exceptions/global-search.exception.ts => search/exceptions/search.exception.ts} (65%) rename packages/twenty-server/src/engine/core-modules/{global-search/filters/global-search-api-exception.filter.ts => search/filters/search-api-exception.filter.ts} (52%) rename packages/twenty-server/src/engine/core-modules/{global-search/global-search.module.ts => search/search.module.ts} (51%) rename packages/twenty-server/src/engine/core-modules/{global-search/global-search.resolver.ts => search/search.resolver.ts} (62%) rename packages/twenty-server/src/engine/core-modules/{global-search/services/global-search.service.ts => search/services/search.service.ts} (88%) rename packages/twenty-server/src/engine/core-modules/{global-search => search}/types/records-with-object-metadata-item.ts (100%) rename packages/twenty-server/src/engine/core-modules/{global-search => search}/utils/__tests__/format-search-terms.spec.ts (80%) rename packages/twenty-server/src/engine/core-modules/{global-search => search}/utils/format-search-terms.ts (100%) rename packages/twenty-server/src/engine/metadata-modules/{search/search.module.ts => search-vector/search-vector.module.ts} (78%) rename packages/twenty-server/src/engine/metadata-modules/{search/search.service.ts => search-vector/search-vector.service.ts} (99%) rename packages/twenty-server/test/integration/graphql/suites/{global-search/global-search-resolver.integration-spec.ts => search/search-resolver.integration-spec.ts} (87%) rename packages/twenty-server/test/integration/graphql/utils/{global-search-factory.util.ts => search-factory.util.ts} (79%) diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 6db6c27cc..c6398f32c 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -707,16 +707,6 @@ export type GetServerlessFunctionSourceCodeInput = { version?: Scalars['String']['input']; }; -export type GlobalSearchRecord = { - __typename?: 'GlobalSearchRecord'; - imageUrl?: Maybe; - label: Scalars['String']['output']; - objectSingularName: Scalars['String']['output']; - recordId: Scalars['String']['output']; - tsRank: Scalars['Float']['output']; - tsRankCD: Scalars['Float']['output']; -}; - export enum HealthIndicatorId { app = 'app', connectedAccount = 'connectedAccount', @@ -934,6 +924,7 @@ export type Mutation = { updateOneField: Field; updateOneObject: Object; updateOneRemoteServer: RemoteServer; + updateOneRole: Role; updateOneServerlessFunction: ServerlessFunction; updatePasswordViaResetToken: InvalidatePassword; updateWorkflowVersionStep: WorkflowAction; @@ -1481,13 +1472,13 @@ export type Query = { getTimelineCalendarEventsFromPersonId: TimelineCalendarEventsWithTotal; getTimelineThreadsFromCompanyId: TimelineThreadsWithTotal; getTimelineThreadsFromPersonId: TimelineThreadsWithTotal; - globalSearch: Array; index: Index; indexMetadatas: IndexConnection; object: Object; objects: ObjectConnection; plans: Array; relationMetadata: RelationMetadataConnection; + search: Array; validatePasswordResetToken: ValidatePasswordResetToken; }; @@ -1593,15 +1584,6 @@ export type QueryGetTimelineThreadsFromPersonIdArgs = { }; -export type QueryGlobalSearchArgs = { - excludedObjectNameSingulars?: InputMaybe>; - filter?: InputMaybe; - includedObjectNameSingulars?: InputMaybe>; - limit: Scalars['Int']['input']; - searchInput: Scalars['String']['input']; -}; - - export type QueryIndexArgs = { id: Scalars['UUID']['input']; }; @@ -1629,6 +1611,15 @@ export type QueryRelationMetadataArgs = { }; +export type QuerySearchArgs = { + excludedObjectNameSingulars?: InputMaybe>; + filter?: InputMaybe; + includedObjectNameSingulars?: InputMaybe>; + limit: Scalars['Int']['input']; + searchInput: Scalars['String']['input']; +}; + + export type QueryValidatePasswordResetTokenArgs = { passwordResetToken: Scalars['String']['input']; }; @@ -1827,6 +1818,16 @@ export enum SsoIdentityProviderStatus { Inactive = 'Inactive' } +export type SearchRecord = { + __typename?: 'SearchRecord'; + imageUrl?: Maybe; + label: Scalars['String']['output']; + objectNameSingular: Scalars['String']['output']; + recordId: Scalars['String']['output']; + tsRank: Scalars['Float']['output']; + tsRankCD: Scalars['Float']['output']; +}; + export type SendInvitationsOutput = { __typename?: 'SendInvitationsOutput'; errors: Array; diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index 9028ae457..5a92c3868 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -643,16 +643,6 @@ export type GetServerlessFunctionSourceCodeInput = { version?: Scalars['String']; }; -export type GlobalSearchRecord = { - __typename?: 'GlobalSearchRecord'; - imageUrl?: Maybe; - label: Scalars['String']; - objectSingularName: Scalars['String']; - recordId: Scalars['String']; - tsRank: Scalars['Float']; - tsRankCD: Scalars['Float']; -}; - export enum HealthIndicatorId { app = 'app', connectedAccount = 'connectedAccount', @@ -1368,12 +1358,12 @@ export type Query = { getTimelineCalendarEventsFromPersonId: TimelineCalendarEventsWithTotal; getTimelineThreadsFromCompanyId: TimelineThreadsWithTotal; getTimelineThreadsFromPersonId: TimelineThreadsWithTotal; - globalSearch: Array; index: Index; indexMetadatas: IndexConnection; object: Object; objects: ObjectConnection; plans: Array; + search: Array; validatePasswordResetToken: ValidatePasswordResetToken; }; @@ -1453,7 +1443,7 @@ export type QueryGetTimelineThreadsFromPersonIdArgs = { }; -export type QueryGlobalSearchArgs = { +export type QuerySearchArgs = { excludedObjectNameSingulars?: InputMaybe>; filter?: InputMaybe; includedObjectNameSingulars?: InputMaybe>; @@ -1646,6 +1636,16 @@ export enum SsoIdentityProviderStatus { Inactive = 'Inactive' } +export type SearchRecord = { + __typename?: 'SearchRecord'; + imageUrl?: Maybe; + label: Scalars['String']; + objectNameSingular: Scalars['String']; + recordId: Scalars['String']; + tsRank: Scalars['Float']; + tsRankCD: Scalars['Float']; +}; + export type SendInvitationsOutput = { __typename?: 'SendInvitationsOutput'; errors: Array; @@ -2456,7 +2456,7 @@ export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>; export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, isMultiWorkspaceEnabled: boolean, isEmailVerificationRequired: boolean, defaultSubdomain?: string | null, frontDomain: string, debugMode: boolean, analyticsEnabled: boolean, isAttachmentPreviewEnabled: boolean, chromeExtensionId?: string | null, canManageFeatureFlags: boolean, isMicrosoftMessagingEnabled: boolean, isMicrosoftCalendarEnabled: boolean, isGoogleMessagingEnabled: boolean, isGoogleCalendarEnabled: boolean, billing: { __typename?: 'Billing', isBillingEnabled: boolean, billingUrl?: string | null, trialPeriods: Array<{ __typename?: 'BillingTrialPeriodDTO', duration: number, isCreditCardRequired: boolean }> }, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean, microsoft: boolean, sso: Array<{ __typename?: 'SSOIdentityProvider', id: string, name: string, type: IdentityProviderType, status: SsoIdentityProviderStatus, issuer: string }> }, support: { __typename?: 'Support', supportDriver: string, supportFrontChatId?: string | null }, sentry: { __typename?: 'Sentry', dsn?: string | null, environment?: string | null, release?: string | null }, captcha: { __typename?: 'Captcha', provider?: CaptchaDriverType | null, siteKey?: string | null }, api: { __typename?: 'ApiConfig', mutationMaximumAffectedRecords: number }, publicFeatureFlags: Array<{ __typename?: 'PublicFeatureFlag', key: FeatureFlagKey, metadata: { __typename?: 'PublicFeatureFlagMetadata', label: string, description: string, imagePath: string } }> } }; -export type GlobalSearchQueryVariables = Exact<{ +export type SearchQueryVariables = Exact<{ searchInput: Scalars['String']; limit: Scalars['Int']; excludedObjectNameSingulars?: InputMaybe | Scalars['String']>; @@ -2465,7 +2465,7 @@ export type GlobalSearchQueryVariables = Exact<{ }>; -export type GlobalSearchQuery = { __typename?: 'Query', globalSearch: Array<{ __typename?: 'GlobalSearchRecord', recordId: string, objectSingularName: string, label: string, imageUrl?: string | null, tsRankCD: number, tsRank: number }> }; +export type SearchQuery = { __typename?: 'Query', search: Array<{ __typename?: 'SearchRecord', recordId: string, objectNameSingular: string, label: string, imageUrl?: string | null, tsRankCD: number, tsRank: number }> }; export type SkipSyncEmailOnboardingStepMutationVariables = Exact<{ [key: string]: never; }>; @@ -4145,9 +4145,9 @@ export function useGetClientConfigLazyQuery(baseOptions?: Apollo.LazyQueryHookOp export type GetClientConfigQueryHookResult = ReturnType; export type GetClientConfigLazyQueryHookResult = ReturnType; export type GetClientConfigQueryResult = Apollo.QueryResult; -export const GlobalSearchDocument = gql` - query GlobalSearch($searchInput: String!, $limit: Int!, $excludedObjectNameSingulars: [String!], $includedObjectNameSingulars: [String!], $filter: ObjectRecordFilterInput) { - globalSearch( +export const SearchDocument = gql` + query Search($searchInput: String!, $limit: Int!, $excludedObjectNameSingulars: [String!], $includedObjectNameSingulars: [String!], $filter: ObjectRecordFilterInput) { + search( searchInput: $searchInput limit: $limit excludedObjectNameSingulars: $excludedObjectNameSingulars @@ -4155,7 +4155,7 @@ export const GlobalSearchDocument = gql` filter: $filter ) { recordId - objectSingularName + objectNameSingular label imageUrl tsRankCD @@ -4165,16 +4165,16 @@ export const GlobalSearchDocument = gql` `; /** - * __useGlobalSearchQuery__ + * __useSearchQuery__ * - * To run a query within a React component, call `useGlobalSearchQuery` and pass it any options that fit your needs. - * When your component renders, `useGlobalSearchQuery` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useSearchQuery` and pass it any options that fit your needs. + * When your component renders, `useSearchQuery` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useGlobalSearchQuery({ + * const { data, loading, error } = useSearchQuery({ * variables: { * searchInput: // value for 'searchInput' * limit: // value for 'limit' @@ -4184,17 +4184,17 @@ export const GlobalSearchDocument = gql` * }, * }); */ -export function useGlobalSearchQuery(baseOptions: Apollo.QueryHookOptions) { +export function useSearchQuery(baseOptions: Apollo.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(GlobalSearchDocument, options); + return Apollo.useQuery(SearchDocument, options); } -export function useGlobalSearchLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { +export function useSearchLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(GlobalSearchDocument, options); + return Apollo.useLazyQuery(SearchDocument, options); } -export type GlobalSearchQueryHookResult = ReturnType; -export type GlobalSearchLazyQueryHookResult = ReturnType; -export type GlobalSearchQueryResult = Apollo.QueryResult; +export type SearchQueryHookResult = ReturnType; +export type SearchLazyQueryHookResult = ReturnType; +export type SearchQueryResult = Apollo.QueryResult; export const SkipSyncEmailOnboardingStepDocument = gql` mutation SkipSyncEmailOnboardingStep { skipSyncEmailOnboardingStep { diff --git a/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx b/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx index 42a02de0b..130399297 100644 --- a/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx @@ -164,10 +164,10 @@ export const NoResultsSearchFallback: Story = { parameters: { msw: { handlers: [ - graphql.query('GlobalSearch', () => { + graphql.query('Search', () => { return HttpResponse.json({ data: { - globalSearch: [], + search: [], }, }); }), diff --git a/packages/twenty-front/src/modules/command-menu/graphql/queries/globalSearch.ts b/packages/twenty-front/src/modules/command-menu/graphql/queries/search.ts similarity index 83% rename from packages/twenty-front/src/modules/command-menu/graphql/queries/globalSearch.ts rename to packages/twenty-front/src/modules/command-menu/graphql/queries/search.ts index 4407502b0..6b4019d8a 100644 --- a/packages/twenty-front/src/modules/command-menu/graphql/queries/globalSearch.ts +++ b/packages/twenty-front/src/modules/command-menu/graphql/queries/search.ts @@ -1,14 +1,14 @@ import gql from 'graphql-tag'; -export const globalSearch = gql` - query GlobalSearch( +export const search = gql` + query Search( $searchInput: String! $limit: Int! $excludedObjectNameSingulars: [String!] $includedObjectNameSingulars: [String!] $filter: ObjectRecordFilterInput ) { - globalSearch( + search( searchInput: $searchInput limit: $limit excludedObjectNameSingulars: $excludedObjectNameSingulars @@ -16,7 +16,7 @@ export const globalSearch = gql` filter: $filter ) { recordId - objectSingularName + objectNameSingular label imageUrl tsRankCD diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuSearchRecords.tsx b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuSearchRecords.tsx index 169fd5804..efb48f433 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuSearchRecords.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuSearchRecords.tsx @@ -5,17 +5,17 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi import { t } from '@lingui/core/macro'; import { useMemo } from 'react'; import { useRecoilValue } from 'recoil'; +import { capitalize } from 'twenty-shared/utils'; import { Avatar } from 'twenty-ui'; import { useDebounce } from 'use-debounce'; -import { useGlobalSearchQuery } from '~/generated/graphql'; -import { capitalize } from 'twenty-shared/utils'; +import { useSearchQuery } from '~/generated/graphql'; export const useCommandMenuSearchRecords = () => { const commandMenuSearch = useRecoilValue(commandMenuSearchState); const [deferredCommandMenuSearch] = useDebounce(commandMenuSearch, 300); - const { data: globalSearchData, loading } = useGlobalSearchQuery({ + const { data: searchData, loading } = useSearchQuery({ variables: { searchInput: deferredCommandMenuSearch ?? '', limit: MAX_SEARCH_RESULTS, @@ -26,17 +26,17 @@ export const useCommandMenuSearchRecords = () => { const { openRecordInCommandMenu } = useOpenRecordInCommandMenu(); const commands = useMemo(() => { - return (globalSearchData?.globalSearch ?? []).map((searchRecord) => { + return (searchData?.search ?? []).map((searchRecord) => { const command = { id: searchRecord.recordId, label: searchRecord.label, - description: capitalize(searchRecord.objectSingularName), - to: `object/${searchRecord.objectSingularName}/${searchRecord.recordId}`, + description: capitalize(searchRecord.objectNameSingular), + to: `object/${searchRecord.objectNameSingular}/${searchRecord.recordId}`, shouldCloseCommandMenuOnClick: true, Icon: () => ( { }; if ( [CoreObjectNameSingular.Task, CoreObjectNameSingular.Note].includes( - searchRecord.objectSingularName as CoreObjectNameSingular, + searchRecord.objectNameSingular as CoreObjectNameSingular, ) ) { return { ...command, to: '', onCommandClick: () => { - searchRecord.objectSingularName === 'task' + searchRecord.objectNameSingular === 'task' ? openRecordInCommandMenu({ recordId: searchRecord.recordId, objectNameSingular: CoreObjectNameSingular.Task, @@ -69,7 +69,7 @@ export const useCommandMenuSearchRecords = () => { } return command; }); - }, [globalSearchData, openRecordInCommandMenu]); + }, [searchData, openRecordInCommandMenu]); return { loading, diff --git a/packages/twenty-front/src/modules/object-metadata/utils/formatGlobalSearchRecordAsSingleRecordPickerRecord.ts b/packages/twenty-front/src/modules/object-metadata/utils/formatSearchRecordAsSingleRecordPickerRecord.ts similarity index 63% rename from packages/twenty-front/src/modules/object-metadata/utils/formatGlobalSearchRecordAsSingleRecordPickerRecord.ts rename to packages/twenty-front/src/modules/object-metadata/utils/formatSearchRecordAsSingleRecordPickerRecord.ts index 1d38d6a78..1bfd9baaf 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/formatGlobalSearchRecordAsSingleRecordPickerRecord.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/formatSearchRecordAsSingleRecordPickerRecord.ts @@ -1,23 +1,23 @@ import { getAvatarType } from '@/object-metadata/utils/getAvatarType'; import { getBasePathToShowPage } from '@/object-metadata/utils/getBasePathToShowPage'; import { SingleRecordPickerRecord } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerRecord'; -import { GlobalSearchRecord } from '~/generated/graphql'; +import { SearchRecord } from '~/generated/graphql'; -export const formatGlobalSearchRecordAsSingleRecordPickerRecord = ( - searchRecord: GlobalSearchRecord, +export const formatSearchRecordAsSingleRecordPickerRecord = ( + searchRecord: SearchRecord, ): SingleRecordPickerRecord => { return { id: searchRecord.recordId, name: searchRecord.label, avatarUrl: searchRecord.imageUrl ?? undefined, - avatarType: getAvatarType(searchRecord.objectSingularName), + avatarType: getAvatarType(searchRecord.objectNameSingular), linkToShowPage: getBasePathToShowPage({ - objectNameSingular: searchRecord.objectSingularName, + objectNameSingular: searchRecord.objectNameSingular, }) + searchRecord.recordId, record: { id: searchRecord.recordId, - __typename: searchRecord.objectSingularName, + __typename: searchRecord.objectNameSingular, }, }; }; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useObjectRecordSearchRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/useObjectRecordSearchRecords.ts index f07abb3e2..89a3ef52c 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useObjectRecordSearchRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useObjectRecordSearchRecords.ts @@ -7,12 +7,9 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { WatchQueryFetchPolicy } from '@apollo/client'; import { useMemo } from 'react'; import { useRecoilValue } from 'recoil'; -import { - ObjectRecordFilterInput, - useGlobalSearchQuery, -} from '~/generated/graphql'; -import { logError } from '~/utils/logError'; import { isDefined } from 'twenty-shared/utils'; +import { ObjectRecordFilterInput, useSearchQuery } from '~/generated/graphql'; +import { logError } from '~/utils/logError'; export type UseSearchRecordsParams = ObjectMetadataItemIdentifier & { limit?: number; @@ -38,7 +35,7 @@ export const useObjectRecordSearchRecords = ({ const { enqueueSnackBar } = useSnackBar(); - const { data, loading, error, previousData } = useGlobalSearchQuery({ + const { data, loading, error, previousData } = useSearchQuery({ skip: skip || !objectMetadataItem || @@ -53,11 +50,11 @@ export const useObjectRecordSearchRecords = ({ fetchPolicy: fetchPolicy, onError: (error) => { logError( - `useGlobalSearchRecords for "${objectMetadataItem.namePlural}" error : ` + + `useSearchRecords for "${objectMetadataItem.namePlural}" error : ` + error, ); enqueueSnackBar( - `Error during useGlobalSearchRecords for "${objectMetadataItem.namePlural}", ${error.message}`, + `Error during useSearchRecords for "${objectMetadataItem.namePlural}", ${error.message}`, { variant: SnackBarVariant.Error, }, @@ -68,7 +65,7 @@ export const useObjectRecordSearchRecords = ({ const effectiveData = loading ? previousData : data; const searchRecords = useMemo( - () => effectiveData?.globalSearch || [], + () => effectiveData?.search || [], [effectiveData], ); diff --git a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItemContent.tsx b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItemContent.tsx index 45711b25c..84a051292 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItemContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItemContent.tsx @@ -12,7 +12,7 @@ import { SelectableItem } from '@/ui/layout/selectable-list/components/Selectabl import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList'; import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2'; -import { GlobalSearchRecord } from '~/generated-metadata/graphql'; +import { SearchRecord } from '~/generated-metadata/graphql'; export const StyledSelectableItem = styled(SelectableItem)` height: 100%; @@ -20,7 +20,7 @@ export const StyledSelectableItem = styled(SelectableItem)` `; type MultipleRecordPickerMenuItemContentProps = { - searchRecord: GlobalSearchRecord; + searchRecord: SearchRecord; objectMetadataItem: ObjectMetadataItem; onChange: (morphItem: RecordPickerPickableMorphItem) => void; }; diff --git a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerPerformSearch.ts b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerPerformSearch.ts index c6bf068e0..c2c15052a 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerPerformSearch.ts +++ b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerPerformSearch.ts @@ -1,5 +1,5 @@ import { MAX_SEARCH_RESULTS } from '@/command-menu/constants/MaxSearchResults'; -import { globalSearch } from '@/command-menu/graphql/queries/globalSearch'; +import { search } from '@/command-menu/graphql/queries/search'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { usePerformCombinedFindManyRecords } from '@/object-record/multiple-objects/hooks/usePerformCombinedFindManyRecords'; import { multipleRecordPickerPickableMorphItemsComponentState } from '@/object-record/record-picker/multiple-record-picker/states/multipleRecordPickerPickableMorphItemsComponentState'; @@ -10,8 +10,8 @@ import { RecordPickerPickableMorphItem } from '@/object-record/record-picker/typ import { ApolloClient, useApolloClient } from '@apollo/client'; import { isNonEmptyArray } from '@sniptt/guards'; import { useRecoilCallback } from 'recoil'; -import { GlobalSearchRecord } from '~/generated-metadata/graphql'; import { capitalize, isDefined } from 'twenty-shared/utils'; +import { SearchRecord } from '~/generated-metadata/graphql'; export const useMultipleRecordPickerPerformSearch = () => { const client = useApolloClient(); @@ -117,23 +117,23 @@ export const useMultipleRecordPickerPerformSearch = () => { const morphItems = [ ...updatedPickedMorphItems, ...searchRecordsFilteredOnPickedRecordsWithoutDuplicates.map( - ({ recordId, objectSingularName }) => ({ + ({ recordId, objectNameSingular }) => ({ isMatchingSearchFilter: true, isSelected: true, objectMetadataId: searchableObjectMetadataItems.find( (objectMetadata) => - objectMetadata.nameSingular === objectSingularName, + objectMetadata.nameSingular === objectNameSingular, )?.id, recordId, }), ), ...searchRecordsExcludingPickedRecordsWithoutDuplicates.map( - ({ recordId, objectSingularName }) => ({ + ({ recordId, objectNameSingular }) => ({ isMatchingSearchFilter: true, isSelected: false, objectMetadataId: searchableObjectMetadataItems.find( (objectMetadata) => - objectMetadata.nameSingular === objectSingularName, + objectMetadata.nameSingular === objectNameSingular, )?.id, recordId, }), @@ -168,8 +168,8 @@ export const useMultipleRecordPickerPerformSearch = () => { .map(({ nameSingular }) => { const recordIdsForMetadataItem = searchRecords .filter( - ({ objectSingularName }) => - objectSingularName === nameSingular, + ({ objectNameSingular }) => + objectNameSingular === nameSingular, ) .map(({ recordId }) => recordId); @@ -251,14 +251,14 @@ const performSearchQueries = async ({ searchFilter: string; searchableObjectMetadataItems: ObjectMetadataItem[]; pickedRecordIds: string[]; -}): Promise<[GlobalSearchRecord[], GlobalSearchRecord[]]> => { +}): Promise<[SearchRecord[], SearchRecord[]]> => { if (searchableObjectMetadataItems.length === 0) { return [[], []]; } const searchRecords = async (filter: any) => { const { data } = await client.query({ - query: globalSearch, + query: search, variables: { searchInput: searchFilter, includedObjectNameSingulars: searchableObjectMetadataItems.map( @@ -268,7 +268,7 @@ const performSearchQueries = async ({ limit: MAX_SEARCH_RESULTS, }, }); - return data.globalSearch; + return data.search; }; const searchRecordsExcludingPickedRecords = await searchRecords( diff --git a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/states/searchRecordStoreComponentFamilyState.ts b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/states/searchRecordStoreComponentFamilyState.ts index 6dfebda23..9253f1a92 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/states/searchRecordStoreComponentFamilyState.ts +++ b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/states/searchRecordStoreComponentFamilyState.ts @@ -1,11 +1,11 @@ import { MultipleRecordPickerComponentInstanceContext } from '@/object-record/record-picker/multiple-record-picker/states/contexts/MultipleRecordPickerComponentInstanceContext'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2'; -import { GlobalSearchRecord } from '~/generated-metadata/graphql'; +import { SearchRecord } from '~/generated-metadata/graphql'; export const searchRecordStoreComponentFamilyState = createComponentFamilyStateV2< - (GlobalSearchRecord & { record?: ObjectRecord }) | undefined, + (SearchRecord & { record?: ObjectRecord }) | undefined, string >({ key: 'searchRecordStoreComponentFamilyState', diff --git a/packages/twenty-front/src/modules/search/hooks/useFilteredSearchRecordQuery.ts b/packages/twenty-front/src/modules/search/hooks/useFilteredSearchRecordQuery.ts index 30bf5c2b9..0ba012515 100644 --- a/packages/twenty-front/src/modules/search/hooks/useFilteredSearchRecordQuery.ts +++ b/packages/twenty-front/src/modules/search/hooks/useFilteredSearchRecordQuery.ts @@ -1,4 +1,4 @@ -import { formatGlobalSearchRecordAsSingleRecordPickerRecord } from '@/object-metadata/utils/formatGlobalSearchRecordAsSingleRecordPickerRecord'; +import { formatSearchRecordAsSingleRecordPickerRecord } from '@/object-metadata/utils/formatSearchRecordAsSingleRecordPickerRecord'; import { DEFAULT_SEARCH_REQUEST_LIMIT } from '@/object-record/constants/DefaultSearchRequestLimit'; import { useObjectRecordSearchRecords } from '@/object-record/hooks/useObjectRecordSearchRecords'; import { SingleRecordPickerRecord } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerRecord'; @@ -57,13 +57,13 @@ export const useFilteredSearchRecordQuery = ({ return { selectedRecords: selectedRecords - .map(formatGlobalSearchRecordAsSingleRecordPickerRecord) + .map(formatSearchRecordAsSingleRecordPickerRecord) .filter(isDefined), filteredSelectedRecords: filteredSelectedRecords - .map(formatGlobalSearchRecordAsSingleRecordPickerRecord) + .map(formatSearchRecordAsSingleRecordPickerRecord) .filter(isDefined), recordsToSelect: recordsToSelect - .map(formatGlobalSearchRecordAsSingleRecordPickerRecord) + .map(formatSearchRecordAsSingleRecordPickerRecord) .filter(isDefined), loading: recordsToSelectLoading || diff --git a/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignment.tsx b/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignment.tsx index 696e7e4c1..514967714 100644 --- a/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignment.tsx +++ b/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignment.tsx @@ -22,8 +22,8 @@ import { TooltipDelay, } from 'twenty-ui'; import { - GlobalSearchRecord, Role, + SearchRecord, WorkspaceMember, } from '~/generated-metadata/graphql'; import { @@ -134,7 +134,7 @@ export const RoleAssignment = ({ role }: RoleAssignmentProps) => { }; const handleSelectWorkspaceMember = ( - workspaceMemberSearchRecord: GlobalSearchRecord, + workspaceMemberSearchRecord: SearchRecord, ) => { const existingRole = workspaceMemberRoleMap.get( workspaceMemberSearchRecord.recordId, diff --git a/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdown.tsx b/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdown.tsx index d4398fea6..f29cac2b3 100644 --- a/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdown.tsx +++ b/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdown.tsx @@ -6,11 +6,11 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; import { ChangeEvent, useState } from 'react'; -import { GlobalSearchRecord } from '~/generated-metadata/graphql'; +import { SearchRecord } from '~/generated-metadata/graphql'; type RoleAssignmentWorkspaceMemberPickerDropdownProps = { excludedWorkspaceMemberIds: string[]; - onSelect: (workspaceMemberSearchRecord: GlobalSearchRecord) => void; + onSelect: (workspaceMemberSearchRecord: SearchRecord) => void; }; export const RoleAssignmentWorkspaceMemberPickerDropdown = ({ diff --git a/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdownContent.tsx b/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdownContent.tsx index 812e76ab1..ec64a4840 100644 --- a/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdownContent.tsx +++ b/packages/twenty-front/src/modules/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdownContent.tsx @@ -1,12 +1,12 @@ import { t } from '@lingui/core/macro'; import { MenuItem, MenuItemAvatar } from 'twenty-ui'; -import { GlobalSearchRecord } from '~/generated-metadata/graphql'; +import { SearchRecord } from '~/generated-metadata/graphql'; type RoleAssignmentWorkspaceMemberPickerDropdownContentProps = { loading: boolean; searchFilter: string; - filteredWorkspaceMembers: GlobalSearchRecord[]; - onSelect: (workspaceMemberSearchRecord: GlobalSearchRecord) => void; + filteredWorkspaceMembers: SearchRecord[]; + onSelect: (workspaceMemberSearchRecord: SearchRecord) => void; }; export const RoleAssignmentWorkspaceMemberPickerDropdownContent = ({ diff --git a/packages/twenty-front/src/testing/graphqlMocks.ts b/packages/twenty-front/src/testing/graphqlMocks.ts index f16b465f7..6de1f22d9 100644 --- a/packages/twenty-front/src/testing/graphqlMocks.ts +++ b/packages/twenty-front/src/testing/graphqlMocks.ts @@ -182,41 +182,41 @@ export const graphqlMocks = { }, }); }), - graphql.query('GlobalSearch', () => { + graphql.query('Search', () => { return HttpResponse.json({ data: { - globalSearch: [ + search: [ { - __typename: 'GlobalSearchRecordDTO', + __typename: 'SearchRecordDTO', recordId: '20202020-2d40-4e49-8df4-9c6a049191de', - objectSingularName: 'person', + objectNameSingular: 'person', label: 'Louis Duss', imageUrl: '', tsRankCD: 0.2, tsRank: 0.12158542, }, { - __typename: 'GlobalSearchRecordDTO', + __typename: 'SearchRecordDTO', recordId: '20202020-3ec3-4fe3-8997-b76aa0bfa408', - objectSingularName: 'company', + objectNameSingular: 'company', label: 'Linkedin', imageUrl: 'https://twenty-icons.com/linkedin.com', tsRankCD: 0.2, tsRank: 0.12158542, }, { - __typename: 'GlobalSearchRecordDTO', + __typename: 'SearchRecordDTO', recordId: '20202020-3f74-492d-a101-2a70f50a1645', - objectSingularName: 'company', + objectNameSingular: 'company', label: 'Libeo', imageUrl: 'https://twenty-icons.com/libeo.io', tsRankCD: 0.2, tsRank: 0.12158542, }, { - __typename: 'GlobalSearchRecordDTO', + __typename: 'SearchRecordDTO', recordId: '20202020-ac73-4797-824e-87a1f5aea9e0', - objectSingularName: 'person', + objectNameSingular: 'person', label: 'Sylvie Palmer', imageUrl: '', tsRankCD: 0.1, @@ -226,45 +226,6 @@ export const graphqlMocks = { }, }); }), - graphql.query('CombinedSearchRecords', () => { - return HttpResponse.json({ - data: { - searchOpportunities: { - edges: [], - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - startCursor: null, - endCursor: null, - }, - }, - searchCompanies: { - edges: companiesMock.slice(0, 3).map((company) => ({ - node: company, - cursor: null, - })), - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - startCursor: null, - endCursor: null, - }, - }, - searchPeople: { - edges: peopleMock.slice(0, 3).map((person) => ({ - node: person, - cursor: null, - })), - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - startCursor: null, - endCursor: null, - }, - }, - }, - }); - }), graphql.query('FindManyViews', ({ variables }) => { const objectMetadataId = variables.filter?.objectMetadataId?.eq; const viewType = variables.filter?.type?.eq; diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/0-43/0-43-migrate-search-vector-on-note-and-task-entities.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/0-43/0-43-migrate-search-vector-on-note-and-task-entities.command.ts index 6e0e5bbed..af6a80db5 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/0-43/0-43-migrate-search-vector-on-note-and-task-entities.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/0-43/0-43-migrate-search-vector-on-note-and-task-entities.command.ts @@ -10,7 +10,7 @@ import { import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { SearchService } from 'src/engine/metadata-modules/search/search.service'; +import { SearchVectorService } from 'src/engine/metadata-modules/search-vector/search-vector.service'; import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service'; import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service'; @@ -30,7 +30,7 @@ export class MigrateSearchVectorOnNoteAndTaskEntitiesCommand extends ActiveOrSus protected readonly featureFlagRepository: Repository, @InjectRepository(ObjectMetadataEntity, 'metadata') protected readonly objectMetadataRepository: Repository, - private readonly searchService: SearchService, + private readonly searchVectorService: SearchVectorService, private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService, private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService, ) { @@ -57,7 +57,7 @@ export class MigrateSearchVectorOnNoteAndTaskEntitiesCommand extends ActiveOrSus }); if (!options.dryRun) { - await this.searchService.updateSearchVector( + await this.searchVectorService.updateSearchVector( noteObjectMetadata.id, SEARCH_FIELDS_FOR_NOTES, workspaceId, @@ -74,7 +74,7 @@ export class MigrateSearchVectorOnNoteAndTaskEntitiesCommand extends ActiveOrSus }); if (!options.dryRun) { - await this.searchService.updateSearchVector( + await this.searchVectorService.updateSearchVector( taskObjectMetadata.id, SEARCH_FIELDS_FOR_TASKS, workspaceId, diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/0-43/0-43-upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/0-43/0-43-upgrade-version-command.module.ts index cf7419da5..97110d3e0 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/0-43/0-43-upgrade-version-command.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/0-43/0-43-upgrade-version-command.module.ts @@ -10,7 +10,7 @@ import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.e import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { SearchModule } from 'src/engine/metadata-modules/search/search.module'; +import { SearchVectorModule } from 'src/engine/metadata-modules/search-vector/search-vector.module'; import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; @@ -23,7 +23,7 @@ import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/wor 'metadata', ), WorkspaceDataSourceModule, - SearchModule, + SearchVectorModule, WorkspaceMigrationRunnerModule, WorkspaceMetadataVersionModule, ], diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-runner.module.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-runner.module.ts index 53fa7f76d..8342959b1 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-runner.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-runner.module.ts @@ -14,7 +14,6 @@ import { GraphqlQueryFindManyResolverService } from 'src/engine/api/graphql/grap import { GraphqlQueryFindOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service'; import { GraphqlQueryRestoreManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service'; import { GraphqlQueryRestoreOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-one-resolver.service'; -import { GraphqlQuerySearchResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service'; import { GraphqlQueryUpdateManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service'; import { GraphqlQueryUpdateOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-one-resolver.service'; import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service'; @@ -35,7 +34,6 @@ const graphqlQueryResolvers = [ GraphqlQueryFindOneResolverService, GraphqlQueryRestoreManyResolverService, GraphqlQueryRestoreOneResolverService, - GraphqlQuerySearchResolverService, GraphqlQueryUpdateManyResolverService, GraphqlQueryUpdateOneResolverService, ]; diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service.ts index 28944f449..2bc8aadbb 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service.ts @@ -245,7 +245,6 @@ export abstract class GraphqlQueryBaseResolverService< case RESOLVER_METHOD_NAMES.FIND_MANY: case RESOLVER_METHOD_NAMES.FIND_ONE: case RESOLVER_METHOD_NAMES.FIND_DUPLICATES: - case RESOLVER_METHOD_NAMES.SEARCH: return PermissionsOnAllObjectRecords.READ_ALL_OBJECT_RECORDS; case RESOLVER_METHOD_NAMES.CREATE_MANY: case RESOLVER_METHOD_NAMES.CREATE_ONE: diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts deleted file mode 100644 index a6e3e555b..000000000 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { Brackets } from 'typeorm'; -import { isDefined } from 'twenty-shared/utils'; - -import { - GraphqlQueryBaseResolverService, - GraphqlQueryResolverExecutionArgs, -} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service'; -import { - ObjectRecord, - ObjectRecordFilter, - OrderByDirection, -} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface'; -import { IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface'; -import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; -import { SearchResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; - -import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/constants/query-max-records.constant'; -import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; -import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; -import { formatSearchTerms } from 'src/engine/core-modules/global-search/utils/format-search-terms'; -import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants'; -import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; - -@Injectable() -export class GraphqlQuerySearchResolverService extends GraphqlQueryBaseResolverService< - SearchResolverArgs, - IConnection -> { - async resolve( - executionArgs: GraphqlQueryResolverExecutionArgs, - featureFlagsMap: Record, - ): Promise> { - const { authContext, objectMetadataMaps, objectMetadataItemWithFieldMaps } = - executionArgs.options; - - const typeORMObjectRecordsParser = - new ObjectRecordsToGraphqlConnectionHelper( - objectMetadataMaps, - featureFlagsMap, - ); - - if (!isDefined(executionArgs.args.searchInput)) { - return typeORMObjectRecordsParser.createConnection({ - objectRecords: [], - objectName: objectMetadataItemWithFieldMaps.nameSingular, - take: 0, - totalCount: 0, - order: [{ id: OrderByDirection.AscNullsFirst }], - hasNextPage: false, - hasPreviousPage: false, - }); - } - - const searchTerms = formatSearchTerms( - executionArgs.args.searchInput, - 'and', - ); - const searchTermsOr = formatSearchTerms( - executionArgs.args.searchInput, - 'or', - ); - - const limit = executionArgs.args?.limit ?? QUERY_MAX_RECORDS; - - const queryBuilder = executionArgs.repository.createQueryBuilder( - objectMetadataItemWithFieldMaps.nameSingular, - ); - - executionArgs.graphqlQueryParser.applyFilterToBuilder( - queryBuilder, - objectMetadataItemWithFieldMaps.nameSingular, - executionArgs.args.filter ?? ({} as ObjectRecordFilter), - ); - - const countQueryBuilder = queryBuilder.clone(); - - const resultsQueryBuilder = - searchTerms !== '' - ? queryBuilder - .andWhere( - new Brackets((qb) => { - qb.where( - `"${SEARCH_VECTOR_FIELD.name}" @@ to_tsquery('simple', :searchTerms)`, - { searchTerms }, - ).orWhere( - `"${SEARCH_VECTOR_FIELD.name}" @@ to_tsquery('simple', :searchTermsOr)`, - { searchTermsOr }, - ); - }), - ) - .orderBy( - `ts_rank_cd("${SEARCH_VECTOR_FIELD.name}", to_tsquery(:searchTerms))`, - 'DESC', - ) - .addOrderBy( - `ts_rank("${SEARCH_VECTOR_FIELD.name}", to_tsquery(:searchTermsOr))`, - 'DESC', - ) - .setParameter('searchTerms', searchTerms) - .setParameter('searchTermsOr', searchTermsOr) - .take(limit) - : queryBuilder - .andWhere( - new Brackets((qb) => { - qb.where(`"${SEARCH_VECTOR_FIELD.name}" IS NOT NULL`); - }), - ) - .take(limit); - - const resultsWithTsVector = - (await resultsQueryBuilder.getMany()) as ObjectRecord[]; - - const objectRecords = formatResult( - resultsWithTsVector, - objectMetadataItemWithFieldMaps, - objectMetadataMaps, - ); - - const totalCount = isDefined( - executionArgs.graphqlQuerySelectedFieldsResult.aggregate.totalCount, - ) - ? await countQueryBuilder.getCount() - : 0; - const order = undefined; - - if (executionArgs.graphqlQuerySelectedFieldsResult.relations) { - await this.processNestedRelationsHelper.processNestedRelations({ - objectMetadataMaps, - parentObjectMetadataItem: objectMetadataItemWithFieldMaps, - parentObjectRecords: objectRecords, - relations: executionArgs.graphqlQuerySelectedFieldsResult.relations, - aggregate: executionArgs.graphqlQuerySelectedFieldsResult.aggregate, - limit, - authContext, - dataSource: executionArgs.dataSource, - isNewRelationEnabled: - featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled], - }); - } - - return typeORMObjectRecordsParser.createConnection({ - objectRecords: objectRecords ?? [], - objectName: objectMetadataItemWithFieldMaps.nameSingular, - take: limit, - totalCount, - order, - hasNextPage: false, - hasPreviousPage: false, - }); - } - - async validate( - _args: SearchResolverArgs, - _options: WorkspaceQueryRunnerOptions, - ): Promise {} -} diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type.ts index 034c73bda..b75c939d1 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type.ts @@ -9,7 +9,6 @@ import { FindManyResolverArgs, FindOneResolverArgs, RestoreManyResolverArgs, - SearchResolverArgs, UpdateManyResolverArgs, UpdateOneResolverArgs, } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; @@ -43,6 +42,4 @@ export type WorkspacePreQueryHookPayload = T extends 'createMany' ? DestroyManyResolverArgs : T extends 'destroyOne' ? DestroyOneResolverArgs - : T extends 'search' - ? SearchResolverArgs - : never; + : never; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names.ts index 15fde4c0a..3a529bea4 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names.ts @@ -2,7 +2,6 @@ export const RESOLVER_METHOD_NAMES = { FIND_MANY: 'findMany', FIND_ONE: 'findOne', FIND_DUPLICATES: 'findDuplicates', - SEARCH: 'search', CREATE_MANY: 'createMany', CREATE_ONE: 'createOne', UPDATE_MANY: 'updateMany', diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/factories.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/factories.ts index 7c951ad5b..4c08455ec 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/factories.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/factories.ts @@ -2,7 +2,6 @@ import { DestroyManyResolverFactory } from 'src/engine/api/graphql/workspace-res import { DestroyOneResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/destroy-one-resolver.factory'; import { RestoreManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/restore-many-resolver.factory'; import { RestoreOneResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/restore-one-resolver.factory'; -import { SearchResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/search-resolver-factory'; import { UpdateManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory'; import { CreateManyResolverFactory } from './create-many-resolver.factory'; @@ -28,7 +27,6 @@ export const workspaceResolverBuilderFactories = [ DestroyManyResolverFactory, RestoreOneResolverFactory, RestoreManyResolverFactory, - SearchResolverFactory, ]; export const workspaceResolverBuilderMethodNames = { @@ -36,7 +34,6 @@ export const workspaceResolverBuilderMethodNames = { FindManyResolverFactory.methodName, FindOneResolverFactory.methodName, FindDuplicatesResolverFactory.methodName, - SearchResolverFactory.methodName, ], mutations: [ CreateManyResolverFactory.methodName, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/search-resolver-factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/search-resolver-factory.ts deleted file mode 100644 index 60a7eb2b8..000000000 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/search-resolver-factory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { - Resolver, - SearchResolverArgs, -} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; - -import { GraphqlQuerySearchResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service'; -import { RESOLVER_METHOD_NAMES } from 'src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names'; - -@Injectable() -export class SearchResolverFactory - implements WorkspaceResolverBuilderFactoryInterface -{ - public static methodName = RESOLVER_METHOD_NAMES.SEARCH; - - constructor( - private readonly graphqlQueryRunnerService: GraphqlQuerySearchResolverService, - ) {} - - create(context: WorkspaceSchemaBuilderContext): Resolver { - const internalContext = context; - - return async (_source, args, _context, info) => { - const options: WorkspaceQueryRunnerOptions = { - authContext: internalContext.authContext, - info, - objectMetadataMaps: internalContext.objectMetadataMaps, - objectMetadataItemWithFieldMaps: - internalContext.objectMetadataItemWithFieldMaps, - }; - - return await this.graphqlQueryRunnerService.execute( - args, - options, - SearchResolverFactory.methodName, - ); - }; - } -} diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts index d216dfda6..95bea5de1 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts @@ -48,14 +48,6 @@ export interface FindDuplicatesResolverArgs< data?: Data[]; } -export interface SearchResolverArgs< - Filter extends ObjectRecordFilter = ObjectRecordFilter, -> { - searchInput?: string; - filter?: Filter; - limit?: number; -} - export interface CreateOneResolverArgs< Data extends Partial = Partial, > { @@ -135,6 +127,5 @@ export type ResolverArgs = | FindOneResolverArgs | RestoreManyResolverArgs | RestoreOneResolverArgs - | SearchResolverArgs | UpdateManyResolverArgs | UpdateOneResolverArgs; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.service.ts index 92dc9087f..8fe346ca5 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.service.ts @@ -6,7 +6,6 @@ import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/work import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { FindDuplicatesResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/find-duplicates-resolver.factory'; -import { SearchResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/search-resolver-factory'; @Injectable() export class WorkspaceResolverBuilderService { @@ -19,8 +18,6 @@ export class WorkspaceResolverBuilderService { switch (methodName) { case FindDuplicatesResolverFactory.methodName: return isDefined(objectMetadata.duplicateCriteria); - case SearchResolverFactory.methodName: - return objectMetadata.isSearchable; default: return true; } diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts index deca77c7f..43c083d45 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts @@ -7,7 +7,6 @@ import { DestroyManyResolverFactory } from 'src/engine/api/graphql/workspace-res import { DestroyOneResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/destroy-one-resolver.factory'; import { RestoreManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/restore-many-resolver.factory'; import { RestoreOneResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/restore-one-resolver.factory'; -import { SearchResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/search-resolver-factory'; import { UpdateManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory'; import { WorkspaceResolverBuilderService } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.service'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; @@ -45,7 +44,6 @@ export class WorkspaceResolverFactory { private readonly restoreOneResolverFactory: RestoreOneResolverFactory, private readonly restoreManyResolverFactory: RestoreManyResolverFactory, private readonly destroyManyResolverFactory: DestroyManyResolverFactory, - private readonly searchResolverFactory: SearchResolverFactory, private readonly workspaceResolverBuilderService: WorkspaceResolverBuilderService, ) {} @@ -69,7 +67,6 @@ export class WorkspaceResolverFactory { ['findOne', this.findOneResolverFactory], ['restoreMany', this.restoreManyResolverFactory], ['restoreOne', this.restoreOneResolverFactory], - ['search', this.searchResolverFactory], ['updateMany', this.updateManyResolverFactory], ['updateOne', this.updateOneResolverFactory], ]); diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts index 8c1f86625..de9170476 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts @@ -138,7 +138,6 @@ export class RootTypeFactory { switch (methodName) { case 'findMany': case 'findDuplicates': - case 'search': return ObjectTypeDefinitionKind.Connection; default: return ObjectTypeDefinitionKind.Plain; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts index 990d77f4a..421c68346 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts @@ -144,21 +144,6 @@ export const getResolverArgs = ( isNullable: false, }, }; - case 'search': - return { - searchInput: { - type: GraphQLString, - isNullable: true, - }, - limit: { - type: GraphQLInt, - isNullable: true, - }, - filter: { - kind: InputTypeDefinitionKind.Filter, - isNullable: true, - }, - }; default: throw new Error(`Unknown resolver type: ${type}`); } diff --git a/packages/twenty-server/src/engine/core-modules/core-engine.module.ts b/packages/twenty-server/src/engine/core-modules/core-engine.module.ts index fdb8aac9d..fcbf7cc19 100644 --- a/packages/twenty-server/src/engine/core-modules/core-engine.module.ts +++ b/packages/twenty-server/src/engine/core-modules/core-engine.module.ts @@ -22,7 +22,6 @@ import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature- import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module'; import { fileStorageModuleFactory } from 'src/engine/core-modules/file-storage/file-storage.module-factory'; import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service'; -import { GlobalSearchModule } from 'src/engine/core-modules/global-search/global-search.module'; import { HealthModule } from 'src/engine/core-modules/health/health.module'; import { LabModule } from 'src/engine/core-modules/lab/lab.module'; import { LLMChatModelModule } from 'src/engine/core-modules/llm-chat-model/llm-chat-model.module'; @@ -38,6 +37,7 @@ import { OpenApiModule } from 'src/engine/core-modules/open-api/open-api.module' import { PostgresCredentialsModule } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.module'; import { RedisClientModule } from 'src/engine/core-modules/redis-client/redis-client.module'; import { RedisClientService } from 'src/engine/core-modules/redis-client/redis-client.service'; +import { SearchModule } from 'src/engine/core-modules/search/search.module'; import { serverlessModuleFactory } from 'src/engine/core-modules/serverless/serverless-module.factory'; import { ServerlessModule } from 'src/engine/core-modules/serverless/serverless.module'; import { WorkspaceSSOModule } from 'src/engine/core-modules/sso/sso.module'; @@ -121,7 +121,7 @@ import { FileModule } from './file/file.module'; useFactory: serverlessModuleFactory, inject: [EnvironmentService, FileStorageService], }), - GlobalSearchModule, + SearchModule, ], exports: [ AnalyticsModule, diff --git a/packages/twenty-server/src/engine/core-modules/global-search/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts b/packages/twenty-server/src/engine/core-modules/search/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts similarity index 100% rename from packages/twenty-server/src/engine/core-modules/global-search/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts rename to packages/twenty-server/src/engine/core-modules/search/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts diff --git a/packages/twenty-server/src/engine/core-modules/global-search/__tests__/global-search.service.spec.ts b/packages/twenty-server/src/engine/core-modules/search/__tests__/search.service.spec.ts similarity index 87% rename from packages/twenty-server/src/engine/core-modules/global-search/__tests__/global-search.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/search/__tests__/search.service.spec.ts index ac652feea..fe2b63db2 100644 --- a/packages/twenty-server/src/engine/core-modules/global-search/__tests__/global-search.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/search/__tests__/search.service.spec.ts @@ -1,17 +1,17 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { mockObjectMetadataItemsWithFieldMaps } from 'src/engine/core-modules/global-search/__mocks__/mockObjectMetadataItemsWithFieldMaps'; -import { GlobalSearchService } from 'src/engine/core-modules/global-search/services/global-search.service'; +import { mockObjectMetadataItemsWithFieldMaps } from 'src/engine/core-modules/search/__mocks__/mockObjectMetadataItemsWithFieldMaps'; +import { SearchService } from 'src/engine/core-modules/search/services/search.service'; -describe('GlobalSearchService', () => { - let service: GlobalSearchService; +describe('SearchService', () => { + let service: SearchService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [GlobalSearchService], + providers: [SearchService], }).compile(); - service = module.get(GlobalSearchService); + service = module.get(SearchService); }); it('should be defined', () => { @@ -103,7 +103,7 @@ describe('GlobalSearchService', () => { it('should sort the search object results by tsRankCD', () => { const objectResults = [ { - objectSingularName: 'person', + objectNameSingular: 'person', tsRankCD: 2, tsRank: 1, recordId: '', @@ -111,7 +111,7 @@ describe('GlobalSearchService', () => { imageUrl: '', }, { - objectSingularName: 'company', + objectNameSingular: 'company', tsRankCD: 1, tsRank: 1, recordId: '', @@ -119,7 +119,7 @@ describe('GlobalSearchService', () => { imageUrl: '', }, { - objectSingularName: 'regular-custom-object', + objectNameSingular: 'regular-custom-object', tsRankCD: 3, tsRank: 1, recordId: '', @@ -138,7 +138,7 @@ describe('GlobalSearchService', () => { it('should sort the search object results by tsRank, if tsRankCD is the same', () => { const objectResults = [ { - objectSingularName: 'person', + objectNameSingular: 'person', tsRankCD: 1, tsRank: 1, recordId: '', @@ -146,7 +146,7 @@ describe('GlobalSearchService', () => { imageUrl: '', }, { - objectSingularName: 'company', + objectNameSingular: 'company', tsRankCD: 1, tsRank: 2, recordId: '', @@ -154,7 +154,7 @@ describe('GlobalSearchService', () => { imageUrl: '', }, { - objectSingularName: 'regular-custom-object', + objectNameSingular: 'regular-custom-object', tsRankCD: 1, tsRank: 3, recordId: '', @@ -173,7 +173,7 @@ describe('GlobalSearchService', () => { it('should sort the search object results by priority rank, if tsRankCD and tsRank are the same', () => { const objectResults = [ { - objectSingularName: 'company', + objectNameSingular: 'company', tsRankCD: 1, tsRank: 1, recordId: '', @@ -181,7 +181,7 @@ describe('GlobalSearchService', () => { imageUrl: '', }, { - objectSingularName: 'person', + objectNameSingular: 'person', tsRankCD: 1, tsRank: 1, recordId: '', @@ -189,7 +189,7 @@ describe('GlobalSearchService', () => { imageUrl: '', }, { - objectSingularName: 'regular-custom-object', + objectNameSingular: 'regular-custom-object', tsRankCD: 1, tsRank: 1, recordId: '', diff --git a/packages/twenty-server/src/engine/core-modules/global-search/constants/results-limit-by-object-without-search-terms.ts b/packages/twenty-server/src/engine/core-modules/search/constants/results-limit-by-object-without-search-terms.ts similarity index 100% rename from packages/twenty-server/src/engine/core-modules/global-search/constants/results-limit-by-object-without-search-terms.ts rename to packages/twenty-server/src/engine/core-modules/search/constants/results-limit-by-object-without-search-terms.ts diff --git a/packages/twenty-server/src/engine/core-modules/global-search/constants/standard-objects-by-priority-rank.ts b/packages/twenty-server/src/engine/core-modules/search/constants/standard-objects-by-priority-rank.ts similarity index 100% rename from packages/twenty-server/src/engine/core-modules/global-search/constants/standard-objects-by-priority-rank.ts rename to packages/twenty-server/src/engine/core-modules/search/constants/standard-objects-by-priority-rank.ts diff --git a/packages/twenty-server/src/engine/core-modules/global-search/dtos/object-record-filter-input.ts b/packages/twenty-server/src/engine/core-modules/search/dtos/object-record-filter-input.ts similarity index 100% rename from packages/twenty-server/src/engine/core-modules/global-search/dtos/object-record-filter-input.ts rename to packages/twenty-server/src/engine/core-modules/search/dtos/object-record-filter-input.ts diff --git a/packages/twenty-server/src/engine/core-modules/global-search/dtos/global-search-args.ts b/packages/twenty-server/src/engine/core-modules/search/dtos/search-args.ts similarity index 89% rename from packages/twenty-server/src/engine/core-modules/global-search/dtos/global-search-args.ts rename to packages/twenty-server/src/engine/core-modules/search/dtos/search-args.ts index bcb2fd667..d6cb1ce78 100644 --- a/packages/twenty-server/src/engine/core-modules/global-search/dtos/global-search-args.ts +++ b/packages/twenty-server/src/engine/core-modules/search/dtos/search-args.ts @@ -2,10 +2,10 @@ import { ArgsType, Field, Int } from '@nestjs/graphql'; import { IsArray, IsInt, IsOptional, IsString } from 'class-validator'; -import { ObjectRecordFilterInput } from 'src/engine/core-modules/global-search/dtos/object-record-filter-input'; +import { ObjectRecordFilterInput } from 'src/engine/core-modules/search/dtos/object-record-filter-input'; @ArgsType() -export class GlobalSearchArgs { +export class SearchArgs { @Field(() => String) @IsString() searchInput: string; diff --git a/packages/twenty-server/src/engine/core-modules/global-search/dtos/global-search-record-dto.ts b/packages/twenty-server/src/engine/core-modules/search/dtos/search-record-dto.ts similarity index 83% rename from packages/twenty-server/src/engine/core-modules/global-search/dtos/global-search-record-dto.ts rename to packages/twenty-server/src/engine/core-modules/search/dtos/search-record-dto.ts index 9e642bfa5..15568b6b9 100644 --- a/packages/twenty-server/src/engine/core-modules/global-search/dtos/global-search-record-dto.ts +++ b/packages/twenty-server/src/engine/core-modules/search/dtos/search-record-dto.ts @@ -2,8 +2,8 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { IsNotEmpty, IsNumber, IsString } from 'class-validator'; -@ObjectType('GlobalSearchRecord') -export class GlobalSearchRecordDTO { +@ObjectType('SearchRecord') +export class SearchRecordDTO { @Field(() => String) @IsString() @IsNotEmpty() @@ -12,7 +12,7 @@ export class GlobalSearchRecordDTO { @Field(() => String) @IsString() @IsNotEmpty() - objectSingularName: string; + objectNameSingular: string; @Field(() => String) @IsString() diff --git a/packages/twenty-server/src/engine/core-modules/global-search/exceptions/global-search.exception.ts b/packages/twenty-server/src/engine/core-modules/search/exceptions/search.exception.ts similarity index 65% rename from packages/twenty-server/src/engine/core-modules/global-search/exceptions/global-search.exception.ts rename to packages/twenty-server/src/engine/core-modules/search/exceptions/search.exception.ts index 6bac7cc84..72b88d200 100644 --- a/packages/twenty-server/src/engine/core-modules/global-search/exceptions/global-search.exception.ts +++ b/packages/twenty-server/src/engine/core-modules/search/exceptions/search.exception.ts @@ -1,12 +1,12 @@ import { CustomException } from 'src/utils/custom-exception'; -export class GlobalSearchException extends CustomException { - constructor(message: string, code: GlobalSearchExceptionCode) { +export class SearchException extends CustomException { + constructor(message: string, code: SearchExceptionCode) { super(message, code); } } -export enum GlobalSearchExceptionCode { +export enum SearchExceptionCode { METADATA_CACHE_VERSION_NOT_FOUND = 'METADATA_CACHE_VERSION_NOT_FOUND', LABEL_IDENTIFIER_FIELD_NOT_FOUND = 'LABEL_IDENTIFIER_FIELD_NOT_FOUND', OBJECT_METADATA_MAP_NOT_FOUND = 'OBJECT_METADATA_MAP_NOT_FOUND', diff --git a/packages/twenty-server/src/engine/core-modules/global-search/filters/global-search-api-exception.filter.ts b/packages/twenty-server/src/engine/core-modules/search/filters/search-api-exception.filter.ts similarity index 52% rename from packages/twenty-server/src/engine/core-modules/global-search/filters/global-search-api-exception.filter.ts rename to packages/twenty-server/src/engine/core-modules/search/filters/search-api-exception.filter.ts index 275c09e9d..d8f0c13c8 100644 --- a/packages/twenty-server/src/engine/core-modules/global-search/filters/global-search-api-exception.filter.ts +++ b/packages/twenty-server/src/engine/core-modules/search/filters/search-api-exception.filter.ts @@ -1,13 +1,13 @@ import { Catch, ExceptionFilter } from '@nestjs/common'; -import { GlobalSearchException } from 'src/engine/core-modules/global-search/exceptions/global-search.exception'; import { InternalServerError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; +import { SearchException } from 'src/engine/core-modules/search/exceptions/search.exception'; -@Catch(GlobalSearchException) -export class GlobalSearchApiExceptionFilter implements ExceptionFilter { +@Catch(SearchException) +export class SearchApiExceptionFilter implements ExceptionFilter { constructor() {} - catch(exception: GlobalSearchException) { + catch(exception: SearchException) { switch (exception.code) { default: throw new InternalServerError(exception.message); diff --git a/packages/twenty-server/src/engine/core-modules/global-search/global-search.module.ts b/packages/twenty-server/src/engine/core-modules/search/search.module.ts similarity index 51% rename from packages/twenty-server/src/engine/core-modules/global-search/global-search.module.ts rename to packages/twenty-server/src/engine/core-modules/search/search.module.ts index 06b805e72..4557f2fc4 100644 --- a/packages/twenty-server/src/engine/core-modules/global-search/global-search.module.ts +++ b/packages/twenty-server/src/engine/core-modules/search/search.module.ts @@ -1,12 +1,12 @@ import { Module } from '@nestjs/common'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; -import { GlobalSearchResolver } from 'src/engine/core-modules/global-search/global-search.resolver'; -import { GlobalSearchService } from 'src/engine/core-modules/global-search/services/global-search.service'; +import { SearchResolver } from 'src/engine/core-modules/search/search.resolver'; +import { SearchService } from 'src/engine/core-modules/search/services/search.service'; import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module'; @Module({ imports: [WorkspaceCacheStorageModule, FeatureFlagModule], - providers: [GlobalSearchResolver, GlobalSearchService], + providers: [SearchResolver, SearchService], }) -export class GlobalSearchModule {} +export class SearchModule {} diff --git a/packages/twenty-server/src/engine/core-modules/global-search/global-search.resolver.ts b/packages/twenty-server/src/engine/core-modules/search/search.resolver.ts similarity index 62% rename from packages/twenty-server/src/engine/core-modules/global-search/global-search.resolver.ts rename to packages/twenty-server/src/engine/core-modules/search/search.resolver.ts index 1b8bd8ab9..e138d51d5 100644 --- a/packages/twenty-server/src/engine/core-modules/global-search/global-search.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/search/search.resolver.ts @@ -6,16 +6,16 @@ import chunk from 'lodash.chunk'; import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; -import { GlobalSearchArgs } from 'src/engine/core-modules/global-search/dtos/global-search-args'; -import { GlobalSearchRecordDTO } from 'src/engine/core-modules/global-search/dtos/global-search-record-dto'; +import { SearchArgs } from 'src/engine/core-modules/search/dtos/search-args'; +import { SearchRecordDTO } from 'src/engine/core-modules/search/dtos/search-record-dto'; import { - GlobalSearchException, - GlobalSearchExceptionCode, -} from 'src/engine/core-modules/global-search/exceptions/global-search.exception'; -import { GlobalSearchApiExceptionFilter } from 'src/engine/core-modules/global-search/filters/global-search-api-exception.filter'; -import { GlobalSearchService } from 'src/engine/core-modules/global-search/services/global-search.service'; -import { RecordsWithObjectMetadataItem } from 'src/engine/core-modules/global-search/types/records-with-object-metadata-item'; -import { formatSearchTerms } from 'src/engine/core-modules/global-search/utils/format-search-terms'; + SearchException, + SearchExceptionCode, +} from 'src/engine/core-modules/search/exceptions/search.exception'; +import { SearchApiExceptionFilter } from 'src/engine/core-modules/search/filters/search-api-exception.filter'; +import { SearchService } from 'src/engine/core-modules/search/services/search.service'; +import { RecordsWithObjectMetadataItem } from 'src/engine/core-modules/search/types/records-with-object-metadata-item'; +import { formatSearchTerms } from 'src/engine/core-modules/search/utils/format-search-terms'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager'; @@ -23,18 +23,18 @@ import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage const OBJECT_METADATA_ITEMS_CHUNK_SIZE = 5; -@Resolver(() => [GlobalSearchRecordDTO]) -@UseFilters(GlobalSearchApiExceptionFilter) -export class GlobalSearchResolver { +@Resolver(() => [SearchRecordDTO]) +@UseFilters(SearchApiExceptionFilter) +export class SearchResolver { constructor( private readonly workspaceCacheStorageService: WorkspaceCacheStorageService, private readonly twentyORMManager: TwentyORMManager, - private readonly globalSearchService: GlobalSearchService, + private readonly searchService: SearchService, private readonly featureFlagService: FeatureFlagService, ) {} - @Query(() => [GlobalSearchRecordDTO]) - async globalSearch( + @Query(() => [SearchRecordDTO]) + async search( @AuthWorkspace() workspace: Workspace, @Args() { @@ -43,15 +43,15 @@ export class GlobalSearchResolver { filter, includedObjectNameSingulars, excludedObjectNameSingulars, - }: GlobalSearchArgs, + }: SearchArgs, ) { const currentCacheVersion = await this.workspaceCacheStorageService.getMetadataVersion(workspace.id); if (currentCacheVersion === undefined) { - throw new GlobalSearchException( + throw new SearchException( 'Metadata cache version not found', - GlobalSearchExceptionCode.METADATA_CACHE_VERSION_NOT_FOUND, + SearchExceptionCode.METADATA_CACHE_VERSION_NOT_FOUND, ); } @@ -62,9 +62,9 @@ export class GlobalSearchResolver { ); if (!objectMetadataMaps) { - throw new GlobalSearchException( + throw new SearchException( `Object metadata map not found for workspace ${workspace.id} and metadata version ${currentCacheVersion}`, - GlobalSearchExceptionCode.OBJECT_METADATA_MAP_NOT_FOUND, + SearchExceptionCode.OBJECT_METADATA_MAP_NOT_FOUND, ); } @@ -76,7 +76,7 @@ export class GlobalSearchResolver { ); const filteredObjectMetadataItems = - this.globalSearchService.filterObjectMetadataItems({ + this.searchService.filterObjectMetadataItems({ objectMetadataItemWithFieldMaps, includedObjectNameSingulars: includedObjectNameSingulars ?? [], excludedObjectNameSingulars: excludedObjectNameSingulars ?? [], @@ -99,16 +99,15 @@ export class GlobalSearchResolver { return { objectMetadataItem, - records: - await this.globalSearchService.buildSearchQueryAndGetRecords({ - entityManager: repository, - objectMetadataItem, - featureFlagMap, - searchTerms: formatSearchTerms(searchInput, 'and'), - searchTermsOr: formatSearchTerms(searchInput, 'or'), - limit, - filter: filter ?? ({} as ObjectRecordFilter), - }), + records: await this.searchService.buildSearchQueryAndGetRecords({ + entityManager: repository, + objectMetadataItem, + featureFlagMap, + searchTerms: formatSearchTerms(searchInput, 'and'), + searchTermsOr: formatSearchTerms(searchInput, 'or'), + limit, + filter: filter ?? ({} as ObjectRecordFilter), + }), }; }), ); @@ -116,7 +115,7 @@ export class GlobalSearchResolver { allRecordsWithObjectMetadataItems.push(...recordsWithObjectMetadataItems); } - return this.globalSearchService.computeSearchObjectResults( + return this.searchService.computeSearchObjectResults( allRecordsWithObjectMetadataItems, limit, ); diff --git a/packages/twenty-server/src/engine/core-modules/global-search/services/global-search.service.ts b/packages/twenty-server/src/engine/core-modules/search/services/search.service.ts similarity index 88% rename from packages/twenty-server/src/engine/core-modules/global-search/services/global-search.service.ts rename to packages/twenty-server/src/engine/core-modules/search/services/search.service.ts index 6803867ed..3f6554108 100644 --- a/packages/twenty-server/src/engine/core-modules/global-search/services/global-search.service.ts +++ b/packages/twenty-server/src/engine/core-modules/search/services/search.service.ts @@ -8,22 +8,22 @@ import { ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/int import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser'; -import { RESULTS_LIMIT_BY_OBJECT_WITHOUT_SEARCH_TERMS } from 'src/engine/core-modules/global-search/constants/results-limit-by-object-without-search-terms'; -import { STANDARD_OBJECTS_BY_PRIORITY_RANK } from 'src/engine/core-modules/global-search/constants/standard-objects-by-priority-rank'; -import { GlobalSearchRecordDTO } from 'src/engine/core-modules/global-search/dtos/global-search-record-dto'; -import { ObjectRecordFilterInput } from 'src/engine/core-modules/global-search/dtos/object-record-filter-input'; +import { RESULTS_LIMIT_BY_OBJECT_WITHOUT_SEARCH_TERMS } from 'src/engine/core-modules/search/constants/results-limit-by-object-without-search-terms'; +import { STANDARD_OBJECTS_BY_PRIORITY_RANK } from 'src/engine/core-modules/search/constants/standard-objects-by-priority-rank'; +import { ObjectRecordFilterInput } from 'src/engine/core-modules/search/dtos/object-record-filter-input'; +import { SearchRecordDTO } from 'src/engine/core-modules/search/dtos/search-record-dto'; import { - GlobalSearchException, - GlobalSearchExceptionCode, -} from 'src/engine/core-modules/global-search/exceptions/global-search.exception'; -import { RecordsWithObjectMetadataItem } from 'src/engine/core-modules/global-search/types/records-with-object-metadata-item'; + SearchException, + SearchExceptionCode, +} from 'src/engine/core-modules/search/exceptions/search.exception'; +import { RecordsWithObjectMetadataItem } from 'src/engine/core-modules/search/types/records-with-object-metadata-item'; import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants'; import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps'; import { generateObjectMetadataMaps } from 'src/engine/metadata-modules/utils/generate-object-metadata-maps.util'; import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository'; @Injectable() -export class GlobalSearchService { +export class SearchService { filterObjectMetadataItems({ objectMetadataItemWithFieldMaps, includedObjectNameSingulars, @@ -143,9 +143,9 @@ export class GlobalSearchService { objectMetadataItem: ObjectMetadataItemWithFieldMaps, ) { if (!objectMetadataItem.labelIdentifierFieldMetadataId) { - throw new GlobalSearchException( + throw new SearchException( 'Label identifier field not found', - GlobalSearchExceptionCode.LABEL_IDENTIFIER_FIELD_NOT_FOUND, + SearchExceptionCode.LABEL_IDENTIFIER_FIELD_NOT_FOUND, ); } @@ -217,7 +217,7 @@ export class GlobalSearchService { return records.map((record) => { return { recordId: record.id, - objectSingularName: objectMetadataItem.nameSingular, + objectNameSingular: objectMetadataItem.nameSingular, label: this.getLabelIdentifierValue(record, objectMetadataItem), imageUrl: this.getImageIdentifierValue(record, objectMetadataItem), tsRankCD: record.tsRankCD, @@ -230,9 +230,7 @@ export class GlobalSearchService { return this.sortSearchObjectResults(searchRecords).slice(0, limit); } - sortSearchObjectResults( - searchObjectResultsWithRank: GlobalSearchRecordDTO[], - ) { + sortSearchObjectResults(searchObjectResultsWithRank: SearchRecordDTO[]) { return searchObjectResultsWithRank.sort((a, b) => { if (a.tsRankCD !== b.tsRankCD) { return b.tsRankCD - a.tsRankCD; @@ -243,8 +241,8 @@ export class GlobalSearchService { } return ( - (STANDARD_OBJECTS_BY_PRIORITY_RANK[b.objectSingularName] || 0) - - (STANDARD_OBJECTS_BY_PRIORITY_RANK[a.objectSingularName] || 0) + (STANDARD_OBJECTS_BY_PRIORITY_RANK[b.objectNameSingular] || 0) - + (STANDARD_OBJECTS_BY_PRIORITY_RANK[a.objectNameSingular] || 0) ); }); } diff --git a/packages/twenty-server/src/engine/core-modules/global-search/types/records-with-object-metadata-item.ts b/packages/twenty-server/src/engine/core-modules/search/types/records-with-object-metadata-item.ts similarity index 100% rename from packages/twenty-server/src/engine/core-modules/global-search/types/records-with-object-metadata-item.ts rename to packages/twenty-server/src/engine/core-modules/search/types/records-with-object-metadata-item.ts diff --git a/packages/twenty-server/src/engine/core-modules/global-search/utils/__tests__/format-search-terms.spec.ts b/packages/twenty-server/src/engine/core-modules/search/utils/__tests__/format-search-terms.spec.ts similarity index 80% rename from packages/twenty-server/src/engine/core-modules/global-search/utils/__tests__/format-search-terms.spec.ts rename to packages/twenty-server/src/engine/core-modules/search/utils/__tests__/format-search-terms.spec.ts index 6ae8c09b5..8ca204cd1 100644 --- a/packages/twenty-server/src/engine/core-modules/global-search/utils/__tests__/format-search-terms.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/search/utils/__tests__/format-search-terms.spec.ts @@ -1,4 +1,4 @@ -import { formatSearchTerms } from 'src/engine/core-modules/global-search/utils/format-search-terms'; +import { formatSearchTerms } from 'src/engine/core-modules/search/utils/format-search-terms'; describe('formatSearchTerms', () => { it('should format the search terms', () => { diff --git a/packages/twenty-server/src/engine/core-modules/global-search/utils/format-search-terms.ts b/packages/twenty-server/src/engine/core-modules/search/utils/format-search-terms.ts similarity index 100% rename from packages/twenty-server/src/engine/core-modules/global-search/utils/format-search-terms.ts rename to packages/twenty-server/src/engine/core-modules/search/utils/format-search-terms.ts diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts index 19044486a..006cb53c1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts @@ -27,7 +27,7 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { RemoteTableRelationsModule } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table-relations/remote-table-relations.module'; -import { SearchModule } from 'src/engine/metadata-modules/search/search.module'; +import { SearchVectorModule } from 'src/engine/metadata-modules/search-vector/search-vector.module'; import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module'; import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; @@ -54,7 +54,7 @@ import { UpdateObjectPayload } from './dtos/update-object.input'; WorkspaceMigrationRunnerModule, WorkspaceMetadataVersionModule, RemoteTableRelationsModule, - SearchModule, + SearchVectorModule, IndexMetadataModule, FeatureFlagModule, PermissionsModule, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts index ba5468573..929b6bf0e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts @@ -31,7 +31,7 @@ import { validateObjectMetadataInputNamesOrThrow, } from 'src/engine/metadata-modules/object-metadata/utils/validate-object-metadata-input.util'; import { RemoteTableRelationsService } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table-relations/remote-table-relations.service'; -import { SearchService } from 'src/engine/metadata-modules/search/search.service'; +import { SearchVectorService } from 'src/engine/metadata-modules/search-vector/search-vector.service'; import { validateNameAndLabelAreSyncOrThrow } from 'src/engine/metadata-modules/utils/validate-name-and-label-are-sync-or-throw.util'; import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; @@ -56,7 +56,7 @@ export class ObjectMetadataService extends TypeOrmQueryService, diff --git a/packages/twenty-server/src/engine/utils/get-resolver-name.util.ts b/packages/twenty-server/src/engine/utils/get-resolver-name.util.ts index c4b140ad2..2a77019a2 100644 --- a/packages/twenty-server/src/engine/utils/get-resolver-name.util.ts +++ b/packages/twenty-server/src/engine/utils/get-resolver-name.util.ts @@ -41,8 +41,6 @@ export const getResolverName = ( case 'restoreMany': return `restore${pascalCase(objectMetadata.namePlural)}`; - case 'search': - return `search${pascalCase(objectMetadata.namePlural)}`; default: throw new Error(`Unknown resolver type: ${type}`); } diff --git a/packages/twenty-server/test/integration/graphql/suites/global-search/global-search-resolver.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/search/search-resolver.integration-spec.ts similarity index 87% rename from packages/twenty-server/test/integration/graphql/suites/global-search/global-search-resolver.integration-spec.ts rename to packages/twenty-server/test/integration/graphql/suites/search/search-resolver.integration-spec.ts index 6c7017062..e3fa26a52 100644 --- a/packages/twenty-server/test/integration/graphql/suites/global-search/global-search-resolver.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/search/search-resolver.integration-spec.ts @@ -4,12 +4,12 @@ import { OBJECT_MODEL_COMMON_FIELDS } from 'test/integration/constants/object-mo import { PERSON_GQL_FIELDS } from 'test/integration/constants/person-gql-fields.constants'; import { destroyManyOperationFactory } from 'test/integration/graphql/utils/destroy-many-operation-factory.util'; import { destroyOneOperationFactory } from 'test/integration/graphql/utils/destroy-one-operation-factory.util'; -import { - globalSearchFactory, - GlobalSearchFactoryParams, -} from 'test/integration/graphql/utils/global-search-factory.util'; import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util'; import { performCreateManyOperation } from 'test/integration/graphql/utils/perform-create-many-operation.utils'; +import { + SearchFactoryParams, + searchFactory, +} from 'test/integration/graphql/utils/search-factory.util'; import { LISTING_NAME_PLURAL, LISTING_NAME_SINGULAR, @@ -19,9 +19,9 @@ import { deleteOneObjectMetadataItem } from 'test/integration/metadata/suites/ob import { findManyObjectsMetadataItems } from 'test/integration/metadata/suites/object-metadata/utils/find-many-objects-metadata-items.util'; import { EachTestingContext } from 'twenty-shared/testing'; -import { GlobalSearchRecordDTO } from 'src/engine/core-modules/global-search/dtos/global-search-record-dto'; +import { SearchRecordDTO } from 'src/engine/core-modules/search/dtos/search-record-dto'; -describe('GlobalSearchResolver', () => { +describe('SearchResolver', () => { let listingObjectMetadataId: { objectMetadataId: string }; const [firstPerson, secondPerson, thirdPerson] = [ { id: randomUUID(), name: { firstName: 'searchInput1' } }, @@ -40,13 +40,8 @@ describe('GlobalSearchResolver', () => { { id: randomUUID(), name: 'searchInput2' }, ]; - const hasSearchRecord = ( - globalSearch: GlobalSearchRecordDTO[], - recordId: string, - ) => { - return globalSearch.some( - (item: GlobalSearchRecordDTO) => item.recordId === recordId, - ); + const hasSearchRecord = (search: SearchRecordDTO[], recordId: string) => { + return search.some((item: SearchRecordDTO) => item.recordId === recordId); }; beforeAll(async () => { @@ -127,7 +122,7 @@ describe('GlobalSearchResolver', () => { }); const testsUseCases: EachTestingContext<{ - input: GlobalSearchFactoryParams; + input: SearchFactoryParams; eval: { definedRecordIds: string[]; undefinedRecordIds: string[]; @@ -202,24 +197,24 @@ describe('GlobalSearchResolver', () => { ]; it.each(testsUseCases)('$title', async ({ context }) => { - const graphqlOperation = globalSearchFactory(context.input); + const graphqlOperation = searchFactory(context.input); const response = await makeGraphqlAPIRequest(graphqlOperation); expect(response.body.data).toBeDefined(); - expect(response.body.data.globalSearch).toBeDefined(); + expect(response.body.data.search).toBeDefined(); - const globalSearch = response.body.data.globalSearch; + const search = response.body.data.search; context.eval.definedRecordIds.length > 0 - ? expect(globalSearch).not.toHaveLength(0) - : expect(globalSearch).toHaveLength(0); + ? expect(search).not.toHaveLength(0) + : expect(search).toHaveLength(0); context.eval.definedRecordIds.forEach((recordId) => { - expect(hasSearchRecord(globalSearch, recordId)).toBeTruthy(); + expect(hasSearchRecord(search, recordId)).toBeTruthy(); }); context.eval.undefinedRecordIds.forEach((recordId) => { - expect(hasSearchRecord(globalSearch, recordId)).toBeFalsy(); + expect(hasSearchRecord(search, recordId)).toBeFalsy(); }); }); }); diff --git a/packages/twenty-server/test/integration/graphql/utils/global-search-factory.util.ts b/packages/twenty-server/test/integration/graphql/utils/search-factory.util.ts similarity index 79% rename from packages/twenty-server/test/integration/graphql/utils/global-search-factory.util.ts rename to packages/twenty-server/test/integration/graphql/utils/search-factory.util.ts index 9b1d496b2..75e365778 100644 --- a/packages/twenty-server/test/integration/graphql/utils/global-search-factory.util.ts +++ b/packages/twenty-server/test/integration/graphql/utils/search-factory.util.ts @@ -1,29 +1,29 @@ import gql from 'graphql-tag'; -import { ObjectRecordFilterInput } from 'src/engine/core-modules/global-search/dtos/object-record-filter-input'; +import { ObjectRecordFilterInput } from 'src/engine/core-modules/search/dtos/object-record-filter-input'; -export type GlobalSearchFactoryParams = { +export type SearchFactoryParams = { searchInput: string; excludedObjectNameSingulars?: string[]; includedObjectNameSingulars?: string[]; filter?: ObjectRecordFilterInput; }; -export const globalSearchFactory = ({ +export const searchFactory = ({ searchInput, excludedObjectNameSingulars, includedObjectNameSingulars, filter, -}: GlobalSearchFactoryParams) => ({ +}: SearchFactoryParams) => ({ query: gql` - query GlobalSearch( + query Search( $searchInput: String! $limit: Int! $excludedObjectNameSingulars: [String!] $includedObjectNameSingulars: [String!] $filter: ObjectRecordFilterInput ) { - globalSearch( + search( searchInput: $searchInput limit: $limit excludedObjectNameSingulars: $excludedObjectNameSingulars @@ -31,7 +31,7 @@ export const globalSearchFactory = ({ filter: $filter ) { recordId - objectSingularName + objectNameSingular label imageUrl tsRankCD @@ -41,7 +41,7 @@ export const globalSearchFactory = ({ `, variables: { searchInput, - limit: 30, + limit: 50, excludedObjectNameSingulars, includedObjectNameSingulars, filter,