Maintain INDEX view system side effects on deactivated views (#23590)
# Introduction Follow-up on https://github.com/twentyhq/twenty/pull/23585#discussion_r3683701472. Two INDEX view side-effect handlers bailed out when the view had `isActive: false`. This drops those gates. # Why `isActive: false` on a view has exactly one writer: the delete path, when `isCallerOverridingEntity` is true (`from-delete-view-input-to-flat-view-or-throw.util.ts`, `view.service.ts`). It is not in `FLAT_VIEW_EDITABLE_PROPERTIES`, so nothing else sets it. So the flag means "the workspace deleted an engine-owned view, and since the engine owns the row we deactivate instead of hard-deleting". It is a workspace override of a row we still own, not a signal the row is gone (that is `deletedAt`). Which makes it precisely the state where the engine must keep maintaining its own rows: the row still exists, still belongs to the engine, and is expected to be consistent whenever the override is lifted. Skipping the side effect instead left the view permanently incomplete, with no repair path. The gates were inherited from the candidate-view scan removed in the same commit as these handlers were introduced (`compute-flat-view-fields-from-fields-widgets.util.ts`, #23081). There, `!view.isActive` filtered which of many views were candidates. Transplanted into handlers that resolve *the* one deterministic engine-owned INDEX view identifier, the same predicate stops meaning "is this a candidate" and starts meaning "silently skip the system side effect". # Changes - `fieldIndexViewFieldOnCreate`: create the INDEX view field even when the view is deactivated. - `objectIndexViewLabelIdentifierOnUpdate`: reconcile the label identifier view field even when the view is deactivated. `deletedAt` gates are unchanged in both. The `should noop when the object has no active INDEX view` spec case is inverted accordingly. # Follow-up Both handlers also drop inactive view fields when computing positions, while `FlatViewFieldValidatorService` builds its `otherFlatViewFields` with no `isActive` filter. An inactive view field below all active ones would make a handler emit a label identifier position the validator then rejects. Unreachable today (view fields are only ever soft-deleted, never deactivated), so left out of this PR.
This commit is contained in:
+16
-2
@@ -585,7 +585,7 @@ describe('FieldIndexViewFieldOnCreateSideEffectHandlerService', () => {
|
||||
expect(result.status).toBe('noop');
|
||||
});
|
||||
|
||||
it('should noop when the object has no active INDEX view', () => {
|
||||
it('should emit a view field on a deactivated INDEX view', () => {
|
||||
const result = handler.buildSideEffects(
|
||||
buildArgs({
|
||||
triggerFieldMetadata: PRIORITY_FIELD,
|
||||
@@ -602,7 +602,21 @@ describe('FieldIndexViewFieldOnCreateSideEffectHandlerService', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.status).toBe('noop');
|
||||
expect(result.status).toBe('success');
|
||||
|
||||
if (result.status !== 'success') {
|
||||
throw new Error('expected success');
|
||||
}
|
||||
|
||||
const viewFields = Object.values(
|
||||
result.operations.viewField?.flatEntityToCreate ?? {},
|
||||
);
|
||||
|
||||
expect(viewFields).toHaveLength(1);
|
||||
expect(viewFields[0].viewUniversalIdentifier).toBe(
|
||||
DERIVED_INDEX_VIEW_UNIVERSAL_IDENTIFIER,
|
||||
);
|
||||
expect(viewFields[0].isVisible).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
-1
@@ -183,7 +183,6 @@ export class FieldIndexViewFieldOnCreateSideEffectHandlerService extends Metadat
|
||||
|
||||
if (
|
||||
!isDefined(existingIndexFlatView) ||
|
||||
!existingIndexFlatView.isActive ||
|
||||
isDefined(existingIndexFlatView.deletedAt)
|
||||
) {
|
||||
return undefined;
|
||||
|
||||
-1
@@ -80,7 +80,6 @@ export class ObjectIndexViewLabelIdentifierOnUpdateSideEffectHandlerService exte
|
||||
if (
|
||||
!isDefined(indexFlatView) ||
|
||||
indexFlatView.isSystemSideEffect !== true ||
|
||||
!indexFlatView.isActive ||
|
||||
isDefined(indexFlatView.deletedAt)
|
||||
) {
|
||||
return { status: 'noop' };
|
||||
|
||||
Reference in New Issue
Block a user