Improve type safety and remove unnecessary store operations (#18622)

## Summary
This PR improves type safety across the codebase by replacing generic
`any` types with proper TypeScript types, removes unnecessary record
store operations, and adds TODO comments for future refactoring of
useEffect hooks.

## Key Changes

### Type Safety Improvements
- **SettingsAgentTurnDetail.tsx**: Replaced `any` type annotations with
proper `AgentMessage` type from generated GraphQL types
- **useCreateManyRecords.ts**: Added `RecordGqlNode` type for better
type safety when handling mutation responses
- **useLazyFindOneRecord.ts**: Replaced generic `Record<string, any>`
with `Record<string, RecordGqlNode>` for improved type checking

### Removed Unnecessary Operations
- **EventCardCalendarEvent.tsx**: Removed unused
`useUpsertRecordsInStore` hook and its associated useEffect that was
upserting calendar event records to the store
- **EventCardMessage.tsx**: Removed unused `useUpsertRecordsInStore`
hook and its associated useEffect that was upserting message records to
the store

### Conditional Query Execution
- **useLoadCurrentUser.ts**: Made the `FindAllCoreViewsDocument` query
conditional - only executes when `isOnAWorkspace` is true, preventing
unnecessary queries for users not on a workspace

### Documentation
- Added TODO comments in multiple files (`useAgentChatData.ts`,
`useWorkspaceFromInviteHash.ts`, `useGetPublicWorkspaceDataByDomain.ts`,
`useFindManyRecords.ts`, `useSingleRecordPickerPerformSearch.ts`)
referencing PR #18584 for future refactoring of useEffect hooks to avoid
unnecessary re-renders

## Implementation Details
- The removal of store upsert operations suggests these records are
already being managed elsewhere or the operations were redundant
- Type improvements maintain backward compatibility while providing
better IDE support and compile-time checking
- Conditional query execution reduces unnecessary network requests and
improves performance for non-workspace users

https://claude.ai/code/session_01YQErkoHotMvM6VL3JkWAqV

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Félix Malfait
2026-03-13 17:14:56 +01:00
committed by GitHub
parent b470cb21a1
commit 4b6c8d52e5
11 changed files with 37 additions and 35 deletions
@@ -20,6 +20,7 @@ import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useU
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { computeOptimisticRecordFromInput } from '@/object-record/utils/computeOptimisticRecordFromInput';
import { dispatchObjectRecordOperationBrowserEvent } from '@/browser-event/utils/dispatchObjectRecordOperationBrowserEvent';
import { type RecordGqlNode } from '@/object-record/graphql/types/RecordGqlNode';
import { getCreateManyRecordsMutationResponseField } from '@/object-record/utils/getCreateManyRecordsMutationResponseField';
import { sanitizeRecordInput } from '@/object-record/utils/sanitizeRecordInput';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
@@ -195,7 +196,7 @@ export const useCreateManyRecords = <
},
},
update: (cache, { data }) => {
const records = (data as Record<string, any>)?.[
const records = (data as Record<string, RecordGqlNode[]> | null)?.[
mutationResponseField
];
@@ -254,8 +255,9 @@ export const useCreateManyRecords = <
});
return (
(createdObjects.data as Record<string, any>)?.[mutationResponseField] ??
[]
(createdObjects.data as Record<string, RecordGqlNode[]> | null)?.[
mutationResponseField
] ?? []
);
};
@@ -103,6 +103,7 @@ export const useFindManyRecords = <T extends ObjectRecord = ObjectRecord>({
client: apolloCoreClient,
});
// TODO: Refactor these useEffects to avoid unnecessary re-renders (see PR #18584 review)
useEffect(() => {
if (data) {
handleFindManyRecordsCompleted(data);
@@ -5,6 +5,7 @@ import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient
import { type ObjectMetadataItemIdentifier } from '@/object-metadata/types/ObjectMetadataItemIdentifier';
import { getRecordFromRecordNode } from '@/object-record/cache/utils/getRecordFromRecordNode';
import { useGenerateDepthRecordGqlFieldsFromObject } from '@/object-record/graphql/record-gql-fields/hooks/useGenerateDepthRecordGqlFieldsFromObject';
import { type RecordGqlNode } from '@/object-record/graphql/types/RecordGqlNode';
import { type RecordGqlOperationGqlRecordFields } from 'twenty-shared/types';
import { useFindOneRecordQuery } from '@/object-record/hooks/useFindOneRecordQuery';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
@@ -58,7 +59,9 @@ export const useLazyFindOneRecord = <T extends ObjectRecord = ObjectRecord>({
}).retain();
if (result.data) {
const record = getRecordFromRecordNode<T>({
recordNode: (result.data as Record<string, any>)[objectNameSingular],
recordNode: (result.data as Record<string, RecordGqlNode>)[
objectNameSingular
],
});
onCompleted?.(record);
}
@@ -66,6 +69,9 @@ export const useLazyFindOneRecord = <T extends ObjectRecord = ObjectRecord>({
called,
error,
loading,
record: (data as Record<string, any>)?.[objectNameSingular] || undefined,
record:
(data as Record<string, RecordGqlNode> | undefined)?.[
objectNameSingular
] || undefined,
};
};
@@ -72,6 +72,7 @@ export const useSingleRecordPickerPerformSearch = ({
[selectedRecords, filteredSelectedRecords, recordsToSelect],
);
// TODO: Refactor this useEffect to avoid unnecessary re-renders (see PR #18584 review)
useEffect(() => {
allSearchRecords.forEach((searchRecord) => {
store.set(