Conversation
|
🚀 Preview Environment Ready! Your preview environment is available at: http://bore.pub:64319 This environment will automatically shut down when the PR is closed or after 5 hours. |
packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFields.ts
Show resolved
Hide resolved
There was a problem hiding this comment.
Greptile Overview
Greptile Summary
This PR introduces a batch creation endpoint for view fields to solve race condition issues when creating views with multiple fields in production with the v2 flag enabled.
Key Changes
- Backend: Added
createManyCoreViewFieldsmutation in the resolver that only works whenIS_WORKSPACE_MIGRATION_V2_ENABLEDfeature flag is active - Backend Service: Refactored
ViewFieldV2Service.createOneto internally use the newcreateManymethod, implementing proper batch processing with validation - Frontend: Updated
usePersistViewFieldhook to use the batch mutation in v2 while maintaining backward compatibility with v1 througholdCreateViewFields - Frontend Usage: Updated
useSaveCurrentViewFieldsanduseCreateViewFromCurrentViewto use the new{ inputs: [...] }signature - Tests: Added comprehensive test coverage for both successful and failing scenarios, including edge case of empty input arrays
Implementation Approach
The solution implements a progressive enhancement pattern:
- In v1 (flag disabled): Frontend continues to use sequential individual mutations via
oldCreateViewFields - In v2 (flag enabled): Frontend uses the new batch endpoint, backend processes all fields in a single transaction
This eliminates race conditions by ensuring all view fields are created atomically in a single database transaction when using v2.
Confidence Score: 5/5
- This PR is safe to merge with minimal risk
- The implementation is well-structured with proper feature flag gating, maintains backward compatibility with v1, includes comprehensive test coverage for both success and error cases, and follows established patterns in the codebase. The refactoring of
createOneto usecreateManyinternally is a clean approach that reduces code duplication. - No files require special attention
Important Files Changed
File Analysis
| Filename | Score | Overview |
|---|---|---|
| packages/twenty-server/src/engine/metadata-modules/view-field/resolvers/view-field.resolver.ts | 5/5 | Adds createManyCoreViewFields mutation with proper feature flag check; delegates to v2 service correctly |
| packages/twenty-server/src/engine/metadata-modules/view-field/services/view-field-v2.service.ts | 5/5 | Refactored createOne to use createMany, adds proper batch creation logic with validation and error handling |
| packages/twenty-front/src/modules/views/hooks/internal/usePersistViewField.ts | 5/5 | Refactored to use batch mutation in v2, maintains backward compatibility with v1 using oldCreateViewFields |
| packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFields.ts | 5/5 | Updated to use new batch mutation signature with inputs wrapper object |
| packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts | 5/5 | Updated to use new batch mutation signature with inputs wrapper object |
Sequence Diagram
sequenceDiagram
participant Frontend as Frontend (usePersistViewField)
participant Resolver as ViewFieldResolver
participant FeatureFlag as FeatureFlagService
participant V2Service as ViewFieldV2Service
participant Cache as FlatEntityMapsCacheService
participant Migration as MigrationValidateBuildAndRunService
participant DB as Database
Frontend->>Resolver: createManyCoreViewFields(inputs)
Resolver->>FeatureFlag: isFeatureEnabled(IS_WORKSPACE_MIGRATION_V2_ENABLED)
FeatureFlag-->>Resolver: enabled/disabled
alt V2 Not Enabled
Resolver-->>Frontend: throw ViewFieldException
else V2 Enabled
Resolver->>V2Service: createMany(createViewFieldInputs, workspaceId)
alt Empty inputs
V2Service-->>Resolver: return []
else Has inputs
V2Service->>Cache: getOrRecomputeManyOrAllFlatEntityMaps()
Cache-->>V2Service: existing flat entity maps
V2Service->>V2Service: transform inputs to flatViewFieldsToCreate
V2Service->>V2Service: computeFlatEntityMapsFromTo()
V2Service->>Migration: validateBuildAndRunWorkspaceMigration()
Migration->>Migration: validate view fields
Migration->>DB: run migration
DB-->>Migration: success/error
alt Validation errors
Migration-->>V2Service: validation errors
V2Service-->>Resolver: throw WorkspaceMigrationBuilderExceptionV2
Resolver-->>Frontend: error
else Success
Migration-->>V2Service: success
V2Service->>Cache: getOrRecomputeManyOrAllFlatEntityMaps()
Cache-->>V2Service: recomputed maps with new entities
V2Service->>V2Service: findManyFlatEntityByIdInFlatEntityMapsOrThrow()
V2Service-->>Resolver: created ViewFieldDTOs[]
Resolver-->>Frontend: created ViewFieldDTOs[]
Frontend->>Frontend: triggerViewFieldOptimisticEffect()
end
end
end
13 files reviewed, no comments
ee93988 to
55d3a8b
Compare
|
Will update test tomorrow |
|
Temporarily updated the coverage lines expectations in twenty front as added lines that aims to be removed after v2 activation |
Weiko
left a comment
There was a problem hiding this comment.
LGTM @prastoin FYI we should do the same with Kanban, I believe we run N createCoreViewGroup (@charlesBochet FYI)
|
Nice catch will create a dedicated PR |
# Introduction Same as #15576 but for view groups creation When creating a kanban view with v2 flag activated in production result in race condition due to request being slow and //. That's why we're introducing a batch create on view group here closing twentyhq/core-team-issues#1847 ## In v2 - batch create view group endpoint is available - frontend will target the new endpoint ## In v1 - batch create view group endpoint is not available - frontend will stick to old fake batch view group creation loop ## Gallery ### v2 <img width="1796" height="486" alt="image" src="https://github.com/user-attachments/assets/932cfe9f-85f1-41cc-a1c4-72a4b5d5a256" /> ### v1 <img width="1852" height="966" alt="image" src="https://github.com/user-attachments/assets/8aa9df11-cdea-4b12-ae60-118cdf5e257b" />
Issues attributed to commits in this pull requestThis pull request was merged and Sentry observed the following issues: |
Introduction
When creating a view with v2 flag activated in production result in race condition due to request being slow and //.
That's why we're introducing a batch create on view field here
closing twentyhq/core-team-issues#1836
In v2
In v1
Polish