Separate system operations from core objects in GraphQL endpoints (#12977)

Moves system-level operations (auth, billing, admin) to use the
/metadata endpoint instead of /graphql.

This cleans up the endpoint separation so /graphql is purely for core
objects (Company, People, etc.) and /metadata handles all system
operations.

Part of prep work for webhook/API key core migration.
This commit is contained in:
nitin
2025-07-01 21:59:32 +05:30
committed by GitHub
parent 76c517aa29
commit d2ddd6f473
229 changed files with 9425 additions and 8804 deletions
@@ -14,9 +14,9 @@ import isPropValid from '@emotion/is-prop-valid';
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useGetSsoIdentityProvidersQuery } from '~/generated/graphql';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
import { IconKey } from 'twenty-ui/display';
import { useGetSsoIdentityProvidersQuery } from '~/generated-metadata/graphql';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
const StyledLink = styled(Link, {
shouldForwardProp: (prop) => isPropValid(prop) && prop !== 'isDisabled',
@@ -7,17 +7,19 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { useRecoilState, useRecoilValue } from 'recoil';
import { AuthProviders } from '~/generated-metadata/graphql';
import { useUpdateWorkspaceMutation } from '~/generated/graphql';
import { capitalize } from 'twenty-shared/utils';
import { ConnectedAccountProvider } from 'twenty-shared/types';
import { Card } from 'twenty-ui/layout';
import { capitalize } from 'twenty-shared/utils';
import {
IconGoogle,
IconLink,
IconMicrosoft,
IconPassword,
} from 'twenty-ui/display';
import { Card } from 'twenty-ui/layout';
import {
AuthProviders,
useUpdateWorkspaceMutation,
} from '~/generated-metadata/graphql';
const StyledSettingsSecurityOptionsList = styled.div`
display: flex;
@@ -3,19 +3,19 @@ import { Link, useNavigate } from 'react-router-dom';
import { SettingsPath } from '@/types/SettingsPath';
import { SettingsCard } from '@/settings/components/SettingsCard';
import { SettingsListCard } from '@/settings/components/SettingsListCard';
import { SettingsSecurityApprovedAccessDomainRowDropdownMenu } from '@/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainRowDropdownMenu';
import { SettingsSecurityApprovedAccessDomainValidationEffect } from '@/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect';
import { approvedAccessDomainsState } from '@/settings/security/states/ApprovedAccessDomainsState';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { useRecoilState } from 'recoil';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
import { SettingsListCard } from '@/settings/components/SettingsListCard';
import { approvedAccessDomainsState } from '@/settings/security/states/ApprovedAccessDomainsState';
import { SettingsSecurityApprovedAccessDomainRowDropdownMenu } from '@/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainRowDropdownMenu';
import { SettingsSecurityApprovedAccessDomainValidationEffect } from '@/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect';
import { useGetApprovedAccessDomainsQuery } from '~/generated/graphql';
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
import { IconAt, IconMailCog, Status } from 'twenty-ui/display';
import { useGetApprovedAccessDomainsQuery } from '~/generated-metadata/graphql';
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
const StyledLink = styled(Link)`
text-decoration: none;
@@ -10,7 +10,7 @@ import { isDefined } from 'twenty-shared/utils';
import { IconDotsVertical, IconTrash } from 'twenty-ui/display';
import { LightIconButton } from 'twenty-ui/input';
import { MenuItem } from 'twenty-ui/navigation';
import { useDeleteApprovedAccessDomainMutation } from '~/generated/graphql';
import { useDeleteApprovedAccessDomainMutation } from '~/generated-metadata/graphql';
type SettingsSecurityApprovedAccessDomainRowDropdownMenuProps = {
approvedAccessDomain: UnwrapRecoilValue<typeof approvedAccessDomainsState>[0];
@@ -1,9 +1,9 @@
import { useEffect } from 'react';
import { useValidateApprovedAccessDomainMutation } from '~/generated/graphql';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { useSearchParams } from 'react-router-dom';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import { isDefined } from 'twenty-shared/utils';
import { useValidateApprovedAccessDomainMutation } from '~/generated-metadata/graphql';
export const SettingsSecurityApprovedAccessDomainValidationEffect = () => {
const [validateApprovedAccessDomainMutation] =
@@ -1,22 +1,21 @@
/* @license Enterprise */
import { renderHook } from '@testing-library/react';
import { ReactNode } from 'react';
import { RecoilRoot } from 'recoil';
import { useCreateSSOIdentityProvider } from '@/settings/security/hooks/useCreateSSOIdentityProvider';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
const mutationOIDCCallSpy = jest.fn();
const mutationSAMLCallSpy = jest.fn();
jest.mock('~/generated/graphql', () => ({
jest.mock('~/generated-metadata/graphql', () => ({
useCreateOidcIdentityProviderMutation: () => [mutationOIDCCallSpy],
useCreateSamlIdentityProviderMutation: () => [mutationSAMLCallSpy],
}));
const Wrapper = ({ children }: { children: ReactNode }) => (
<RecoilRoot>{children}</RecoilRoot>
);
const Wrapper = getJestMetadataAndApolloMocksWrapper({
apolloMocks: [],
});
describe('useCreateSSOIdentityProvider', () => {
afterEach(() => {
@@ -1,20 +1,19 @@
/* @license Enterprise */
import { renderHook } from '@testing-library/react';
import { ReactNode } from 'react';
import { RecoilRoot } from 'recoil';
import { useDeleteSSOIdentityProvider } from '@/settings/security/hooks/useDeleteSSOIdentityProvider';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
const mutationDeleteSSOIDPCallSpy = jest.fn();
jest.mock('~/generated/graphql', () => ({
jest.mock('~/generated-metadata/graphql', () => ({
useDeleteSsoIdentityProviderMutation: () => [mutationDeleteSSOIDPCallSpy],
}));
const Wrapper = ({ children }: { children: ReactNode }) => (
<RecoilRoot>{children}</RecoilRoot>
);
const Wrapper = getJestMetadataAndApolloMocksWrapper({
apolloMocks: [],
});
describe('useDeleteSsoIdentityProvider', () => {
afterEach(() => {
@@ -22,10 +21,11 @@ describe('useDeleteSsoIdentityProvider', () => {
});
it('delete SSO identity provider', async () => {
const params = { identityProviderId: 'test' };
renderHook(
() => {
const { deleteSSOIdentityProvider } = useDeleteSSOIdentityProvider();
deleteSSOIdentityProvider({ identityProviderId: 'test' });
deleteSSOIdentityProvider(params);
},
{ wrapper: Wrapper },
);
@@ -33,7 +33,7 @@ describe('useDeleteSsoIdentityProvider', () => {
expect(mutationDeleteSSOIDPCallSpy).toHaveBeenCalledWith({
onCompleted: expect.any(Function),
variables: {
input: { identityProviderId: 'test' },
input: params,
},
});
});
@@ -1,25 +1,24 @@
/* @license Enterprise */
import { renderHook } from '@testing-library/react';
import { ReactNode } from 'react';
import { RecoilRoot } from 'recoil';
import { useUpdateSSOIdentityProvider } from '@/settings/security/hooks/useUpdateSSOIdentityProvider';
import { SsoIdentityProviderStatus } from '~/generated/graphql';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
const mutationEditSSOIDPCallSpy = jest.fn();
jest.mock('~/generated/graphql', () => {
const actual = jest.requireActual('~/generated/graphql');
jest.mock('~/generated-metadata/graphql', () => {
const actual = jest.requireActual('~/generated-metadata/graphql');
return {
...actual,
useEditSsoIdentityProviderMutation: () => [mutationEditSSOIDPCallSpy],
SsoIdentityProviderStatus: actual.SsoIdentityProviderStatus,
};
});
const Wrapper = ({ children }: { children: ReactNode }) => (
<RecoilRoot>{children}</RecoilRoot>
);
const Wrapper = getJestMetadataAndApolloMocksWrapper({
apolloMocks: [],
});
describe('useEditSsoIdentityProvider', () => {
afterEach(() => {
@@ -7,7 +7,7 @@ import {
CreateSamlIdentityProviderMutationVariables,
useCreateOidcIdentityProviderMutation,
useCreateSamlIdentityProviderMutation,
} from '~/generated/graphql';
} from '~/generated-metadata/graphql';
export const useCreateSSOIdentityProvider = () => {
const [createOidcIdentityProviderMutation] =
@@ -5,7 +5,7 @@ import { useSetRecoilState } from 'recoil';
import {
DeleteSsoIdentityProviderMutationVariables,
useDeleteSsoIdentityProviderMutation,
} from '~/generated/graphql';
} from '~/generated-metadata/graphql';
export const useDeleteSSOIdentityProvider = () => {
const [deleteSsoIdentityProviderMutation] =
@@ -5,7 +5,7 @@ import { useSetRecoilState } from 'recoil';
import {
EditSsoIdentityProviderMutationVariables,
useEditSsoIdentityProviderMutation,
} from '~/generated/graphql';
} from '~/generated-metadata/graphql';
export const useUpdateSSOIdentityProvider = () => {
const [editSsoIdentityProviderMutation] =