Deprecate nullable syncableEntity (#17279)
# Introduction As we've been identifying both standard and custom entities for all the metadata that had standard We now still need to identify all custom entities enforcing them to have an `applicationId` and `universalIdentifier` In this PR we've removed the `SyncableEntityRequired` in favor requiring props directly in the `SyncableEntity` Which means that all metadata in db will now expect non nullable applicationId and universalIdentifier across the whole application Will add some type cleanup later in https://github.com/twentyhq/twenty/pull/17277
This commit is contained in:
+2
-2
@@ -14,7 +14,7 @@ import {
|
||||
DEFAULT_SMART_MODEL,
|
||||
ModelId,
|
||||
} from 'src/engine/metadata-modules/ai/ai-models/constants/ai-models.const';
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity('agent')
|
||||
@Index('IDX_AGENT_ID_DELETED_AT', ['id', 'deletedAt'])
|
||||
@@ -23,7 +23,7 @@ import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/synca
|
||||
where: '"deletedAt" IS NULL',
|
||||
})
|
||||
export class AgentEntity
|
||||
extends SyncableEntityRequired
|
||||
extends SyncableEntity
|
||||
implements Required<AgentEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ import {
|
||||
} from 'typeorm';
|
||||
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
export enum CommandMenuItemAvailabilityType {
|
||||
GLOBAL = 'GLOBAL',
|
||||
@@ -28,7 +28,7 @@ export enum CommandMenuItemAvailabilityType {
|
||||
'availabilityObjectMetadataId',
|
||||
])
|
||||
export class CommandMenuItemEntity
|
||||
extends SyncableEntityRequired
|
||||
extends SyncableEntity
|
||||
implements Required<CommandMenuItemEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
|
||||
+2
-2
@@ -30,7 +30,7 @@ import { FieldPermissionEntity } from 'src/engine/metadata-modules/object-permis
|
||||
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
|
||||
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity('fieldMetadata')
|
||||
@Check(
|
||||
@@ -56,7 +56,7 @@ import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/synca
|
||||
export class FieldMetadataEntity<
|
||||
TFieldMetadataType extends FieldMetadataType = FieldMetadataType,
|
||||
>
|
||||
extends SyncableEntityRequired
|
||||
extends SyncableEntity
|
||||
implements Required<FieldMetadataEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
|
||||
+3
-1
@@ -11,9 +11,11 @@ export const fromCreateRowLevelPermissionPredicateGroupInputToFlatRowLevelPermis
|
||||
createRowLevelPermissionPredicateGroupInput:
|
||||
rawCreateRowLevelPermissionPredicateGroupInput,
|
||||
workspaceId,
|
||||
workspaceCustomApplicationId,
|
||||
}: {
|
||||
createRowLevelPermissionPredicateGroupInput: CreateRowLevelPermissionPredicateGroupInput;
|
||||
workspaceId: string;
|
||||
workspaceCustomApplicationId: string;
|
||||
}): FlatRowLevelPermissionPredicateGroup => {
|
||||
const sanitizedInput = (
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties as unknown as (
|
||||
@@ -55,6 +57,6 @@ export const fromCreateRowLevelPermissionPredicateGroupInputToFlatRowLevelPermis
|
||||
positionInRowLevelPermissionPredicateGroup:
|
||||
createRowLevelPermissionPredicateGroupInput.positionInRowLevelPermissionPredicateGroup ??
|
||||
null,
|
||||
applicationId: null,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
};
|
||||
};
|
||||
|
||||
+3
-1
@@ -11,9 +11,11 @@ export const fromCreateRowLevelPermissionPredicateInputToFlatRowLevelPermissionP
|
||||
createRowLevelPermissionPredicateInput:
|
||||
rawCreateRowLevelPermissionPredicateInput,
|
||||
workspaceId,
|
||||
workspaceCustomApplicationId,
|
||||
}: {
|
||||
createRowLevelPermissionPredicateInput: CreateRowLevelPermissionPredicateInput;
|
||||
workspaceId: string;
|
||||
workspaceCustomApplicationId: string;
|
||||
}): FlatRowLevelPermissionPredicate => {
|
||||
const sanitizedInput = (
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties as unknown as (
|
||||
@@ -67,6 +69,6 @@ export const fromCreateRowLevelPermissionPredicateInputToFlatRowLevelPermissionP
|
||||
workspaceMemberSubFieldName:
|
||||
createRowLevelPermissionPredicateInput.workspaceMemberSubFieldName ??
|
||||
null,
|
||||
applicationId: null,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
};
|
||||
};
|
||||
|
||||
+2
-2
@@ -6,11 +6,11 @@ import {
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity('frontComponent')
|
||||
export class FrontComponentEntity
|
||||
extends SyncableEntityRequired
|
||||
extends SyncableEntity
|
||||
implements Required<FrontComponentEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ import {
|
||||
import { IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-field-metadata.entity';
|
||||
import { IndexType } from 'src/engine/metadata-modules/index-metadata/types/indexType.types';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Unique('IDX_INDEX_METADATA_NAME_WORKSPACE_ID_OBJECT_METADATA_ID_UNIQUE', [
|
||||
'name',
|
||||
@@ -28,7 +28,7 @@ import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/synca
|
||||
])
|
||||
@Entity('indexMetadata')
|
||||
export class IndexMetadataEntity
|
||||
extends SyncableEntityRequired
|
||||
extends SyncableEntity
|
||||
implements Required<IndexMetadataEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ import { type ObjectStandardOverridesDTO } from 'src/engine/metadata-modules/obj
|
||||
import { FieldPermissionEntity } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.entity';
|
||||
import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity('objectMetadata')
|
||||
@Unique('IDX_OBJECT_METADATA_NAME_SINGULAR_WORKSPACE_ID_UNIQUE', [
|
||||
@@ -32,7 +32,7 @@ import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/synca
|
||||
])
|
||||
@Index('IDX_OBJECT_METADATA_DATA_SOURCE_ID', ['dataSourceId'])
|
||||
export class ObjectMetadataEntity
|
||||
extends SyncableEntityRequired
|
||||
extends SyncableEntity
|
||||
implements Required<ObjectMetadataEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
|
||||
@@ -15,14 +15,11 @@ import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-fla
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
|
||||
import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity';
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity('role')
|
||||
@Unique('IDX_ROLE_LABEL_WORKSPACE_ID_UNIQUE', ['label', 'workspaceId'])
|
||||
export class RoleEntity
|
||||
extends SyncableEntityRequired
|
||||
implements Required<RoleEntity>
|
||||
{
|
||||
export class RoleEntity extends SyncableEntity implements Required<RoleEntity> {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
|
||||
+2
@@ -3,6 +3,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
|
||||
import { BillingModule } from 'src/engine/core-modules/billing/billing.module';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
|
||||
@@ -24,6 +25,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
WorkspaceMigrationModule,
|
||||
BillingModule,
|
||||
ApplicationModule,
|
||||
],
|
||||
providers: [
|
||||
RowLevelPermissionPredicateService,
|
||||
|
||||
+9
@@ -7,6 +7,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { BillingEntitlementKey } from 'src/engine/core-modules/billing/enums/billing-entitlement-key.enum';
|
||||
import { BillingService } from 'src/engine/core-modules/billing/services/billing.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
@@ -42,6 +43,7 @@ export class RowLevelPermissionPredicateGroupService {
|
||||
@InjectRepository(RowLevelPermissionPredicateGroupEntity)
|
||||
private readonly rowLevelPermissionPredicateGroupRepository: Repository<RowLevelPermissionPredicateGroupEntity>,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
) {}
|
||||
|
||||
async createOne({
|
||||
@@ -52,12 +54,19 @@ export class RowLevelPermissionPredicateGroupService {
|
||||
workspaceId: string;
|
||||
}): Promise<RowLevelPermissionPredicateGroupDTO> {
|
||||
await this.hasRowLevelPermissionFeatureOrThrow(workspaceId);
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
const flatGroupToCreate =
|
||||
fromCreateRowLevelPermissionPredicateGroupInputToFlatRowLevelPermissionPredicateGroupToCreate(
|
||||
{
|
||||
createRowLevelPermissionPredicateGroupInput,
|
||||
workspaceId,
|
||||
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
+23
-2
@@ -6,6 +6,7 @@ import { ConfigService } from '@nestjs/config';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { BillingEntitlementKey } from 'src/engine/core-modules/billing/enums/billing-entitlement-key.enum';
|
||||
import { BillingService } from 'src/engine/core-modules/billing/services/billing.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
@@ -47,6 +48,7 @@ export class RowLevelPermissionPredicateService {
|
||||
private readonly workspaceCacheService: WorkspaceCacheService,
|
||||
private readonly billingService: BillingService,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
) {}
|
||||
|
||||
async createOne({
|
||||
@@ -58,11 +60,18 @@ export class RowLevelPermissionPredicateService {
|
||||
}): Promise<RowLevelPermissionPredicateDTO> {
|
||||
await this.hasRowLevelPermissionFeatureOrThrow(workspaceId);
|
||||
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
const flatPredicateToCreate =
|
||||
fromCreateRowLevelPermissionPredicateInputToFlatRowLevelPermissionPredicateToCreate(
|
||||
{
|
||||
createRowLevelPermissionPredicateInput,
|
||||
workspaceId,
|
||||
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -322,6 +331,12 @@ export class RowLevelPermissionPredicateService {
|
||||
|
||||
const { roleId, objectMetadataId, predicates, predicateGroups } = input;
|
||||
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
const {
|
||||
flatRowLevelPermissionPredicateMaps,
|
||||
flatRowLevelPermissionPredicateGroupMaps,
|
||||
@@ -366,6 +381,7 @@ export class RowLevelPermissionPredicateService {
|
||||
objectMetadataId,
|
||||
workspaceId,
|
||||
flatRowLevelPermissionPredicateGroupMaps,
|
||||
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
|
||||
});
|
||||
|
||||
const { predicatesToCreate, predicatesToUpdate, predicatesToDelete } =
|
||||
@@ -376,6 +392,7 @@ export class RowLevelPermissionPredicateService {
|
||||
objectMetadataId,
|
||||
workspaceId,
|
||||
flatRowLevelPermissionPredicateMaps,
|
||||
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
|
||||
});
|
||||
|
||||
await this.runUpsertMigration({
|
||||
@@ -435,6 +452,7 @@ export class RowLevelPermissionPredicateService {
|
||||
objectMetadataId,
|
||||
workspaceId,
|
||||
flatRowLevelPermissionPredicateGroupMaps,
|
||||
workspaceCustomApplicationId,
|
||||
}: {
|
||||
existingGroups: FlatRowLevelPermissionPredicateGroup[];
|
||||
inputGroups: RowLevelPermissionPredicateGroupInput[];
|
||||
@@ -442,6 +460,7 @@ export class RowLevelPermissionPredicateService {
|
||||
objectMetadataId: string;
|
||||
workspaceId: string;
|
||||
flatRowLevelPermissionPredicateGroupMaps: FlatEntityMaps<FlatRowLevelPermissionPredicateGroup>;
|
||||
workspaceCustomApplicationId: string;
|
||||
}): {
|
||||
groupsToCreate: FlatRowLevelPermissionPredicateGroup[];
|
||||
groupsToUpdate: FlatRowLevelPermissionPredicateGroup[];
|
||||
@@ -488,7 +507,7 @@ export class RowLevelPermissionPredicateService {
|
||||
updatedAt: createdAt,
|
||||
deletedAt: null,
|
||||
universalIdentifier: groupId,
|
||||
applicationId: null,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -515,6 +534,7 @@ export class RowLevelPermissionPredicateService {
|
||||
objectMetadataId,
|
||||
workspaceId,
|
||||
flatRowLevelPermissionPredicateMaps,
|
||||
workspaceCustomApplicationId,
|
||||
}: {
|
||||
existingPredicates: FlatRowLevelPermissionPredicate[];
|
||||
inputPredicates: RowLevelPermissionPredicateInput[];
|
||||
@@ -522,6 +542,7 @@ export class RowLevelPermissionPredicateService {
|
||||
objectMetadataId: string;
|
||||
workspaceId: string;
|
||||
flatRowLevelPermissionPredicateMaps: FlatEntityMaps<FlatRowLevelPermissionPredicate>;
|
||||
workspaceCustomApplicationId: string;
|
||||
}): {
|
||||
predicatesToCreate: FlatRowLevelPermissionPredicate[];
|
||||
predicatesToUpdate: FlatRowLevelPermissionPredicate[];
|
||||
@@ -583,7 +604,7 @@ export class RowLevelPermissionPredicateService {
|
||||
updatedAt: createdAt,
|
||||
deletedAt: null,
|
||||
universalIdentifier: predicateId,
|
||||
applicationId: null,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ import {
|
||||
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity({ name: 'viewField', schema: 'core' })
|
||||
@Index('IDX_VIEW_FIELD_WORKSPACE_ID_VIEW_ID', ['workspaceId', 'viewId'])
|
||||
@@ -29,7 +29,7 @@ import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/synca
|
||||
},
|
||||
)
|
||||
export class ViewFieldEntity
|
||||
extends SyncableEntityRequired
|
||||
extends SyncableEntity
|
||||
implements Required<ViewFieldEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
|
||||
+2
-2
@@ -16,14 +16,14 @@ import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/
|
||||
import { ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity';
|
||||
import { type ViewFilterValue } from 'src/engine/metadata-modules/view-filter/types/view-filter-value.type';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity({ name: 'viewFilter', schema: 'core' })
|
||||
@Index('IDX_VIEW_FILTER_WORKSPACE_ID_VIEW_ID', ['workspaceId', 'viewId'])
|
||||
@Index('IDX_VIEW_FILTER_VIEW_ID', ['viewId'])
|
||||
@Index('IDX_VIEW_FILTER_FIELD_METADATA_ID', ['fieldMetadataId'])
|
||||
export class ViewFilterEntity
|
||||
extends SyncableEntityRequired
|
||||
extends SyncableEntity
|
||||
implements Required<ViewFilterEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
|
||||
+2
-2
@@ -12,13 +12,13 @@ import {
|
||||
} from 'typeorm';
|
||||
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity({ name: 'viewGroup', schema: 'core' })
|
||||
@Index('IDX_VIEW_GROUP_WORKSPACE_ID_VIEW_ID', ['workspaceId', 'viewId'])
|
||||
@Index('IDX_VIEW_GROUP_VIEW_ID', ['viewId'])
|
||||
export class ViewGroupEntity
|
||||
extends SyncableEntityRequired
|
||||
extends SyncableEntity
|
||||
implements Required<ViewGroupEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
|
||||
+42
-1
@@ -3,6 +3,7 @@ import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
import { type Repository } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
|
||||
import { ViewSortDirection } from 'src/engine/metadata-modules/view-sort/enums/view-sort-direction';
|
||||
import {
|
||||
@@ -18,6 +19,7 @@ import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage
|
||||
describe('ViewSortService', () => {
|
||||
let viewSortService: ViewSortService;
|
||||
let viewSortRepository: Repository<ViewSortEntity>;
|
||||
let applicationService: ApplicationService;
|
||||
|
||||
const mockViewSort = {
|
||||
id: 'view-sort-id',
|
||||
@@ -51,6 +53,12 @@ describe('ViewSortService', () => {
|
||||
flushGraphQLOperation: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: ApplicationService,
|
||||
useValue: {
|
||||
findWorkspaceTwentyStandardAndCustomApplicationOrThrow: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
@@ -58,6 +66,7 @@ describe('ViewSortService', () => {
|
||||
viewSortRepository = module.get<Repository<ViewSortEntity>>(
|
||||
getRepositoryToken(ViewSortEntity),
|
||||
);
|
||||
applicationService = module.get<ApplicationService>(ApplicationService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
@@ -151,12 +160,26 @@ describe('ViewSortService', () => {
|
||||
};
|
||||
|
||||
it('should create a view sort successfully', async () => {
|
||||
const mockApplicationId = 'application-id';
|
||||
|
||||
jest
|
||||
.spyOn(
|
||||
applicationService,
|
||||
'findWorkspaceTwentyStandardAndCustomApplicationOrThrow',
|
||||
)
|
||||
.mockResolvedValue({
|
||||
workspaceCustomFlatApplication: { id: mockApplicationId },
|
||||
} as any);
|
||||
jest.spyOn(viewSortRepository, 'create').mockReturnValue(mockViewSort);
|
||||
jest.spyOn(viewSortRepository, 'save').mockResolvedValue(mockViewSort);
|
||||
|
||||
const result = await viewSortService.create(validViewSortData);
|
||||
|
||||
expect(viewSortRepository.create).toHaveBeenCalledWith(validViewSortData);
|
||||
expect(viewSortRepository.create).toHaveBeenCalledWith({
|
||||
...validViewSortData,
|
||||
universalIdentifier: expect.any(String),
|
||||
applicationId: mockApplicationId,
|
||||
});
|
||||
expect(viewSortRepository.save).toHaveBeenCalledWith(mockViewSort);
|
||||
expect(result).toEqual(mockViewSort);
|
||||
});
|
||||
@@ -182,6 +205,15 @@ describe('ViewSortService', () => {
|
||||
it('should throw exception when viewId is missing', async () => {
|
||||
const invalidData = { ...validViewSortData, viewId: undefined };
|
||||
|
||||
jest
|
||||
.spyOn(
|
||||
applicationService,
|
||||
'findWorkspaceTwentyStandardAndCustomApplicationOrThrow',
|
||||
)
|
||||
.mockResolvedValue({
|
||||
workspaceCustomFlatApplication: { id: 'application-id' },
|
||||
} as any);
|
||||
|
||||
await expect(viewSortService.create(invalidData)).rejects.toThrow(
|
||||
new ViewSortException(
|
||||
generateViewSortExceptionMessage(
|
||||
@@ -200,6 +232,15 @@ describe('ViewSortService', () => {
|
||||
it('should throw exception when fieldMetadataId is missing', async () => {
|
||||
const invalidData = { ...validViewSortData, fieldMetadataId: undefined };
|
||||
|
||||
jest
|
||||
.spyOn(
|
||||
applicationService,
|
||||
'findWorkspaceTwentyStandardAndCustomApplicationOrThrow',
|
||||
)
|
||||
.mockResolvedValue({
|
||||
workspaceCustomFlatApplication: { id: 'application-id' },
|
||||
} as any);
|
||||
|
||||
await expect(viewSortService.create(invalidData)).rejects.toThrow(
|
||||
new ViewSortException(
|
||||
generateViewSortExceptionMessage(
|
||||
|
||||
+16
-1
@@ -3,7 +3,9 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
|
||||
import {
|
||||
ViewSortException,
|
||||
@@ -15,12 +17,14 @@ import {
|
||||
import { FIND_ALL_CORE_VIEWS_GRAPHQL_OPERATION } from 'src/engine/metadata-modules/view/constants/find-all-core-views-graphql-operation.constant';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
|
||||
// TODO migrate to v2
|
||||
@Injectable()
|
||||
export class ViewSortService {
|
||||
constructor(
|
||||
@InjectRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: Repository<ViewSortEntity>,
|
||||
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
) {}
|
||||
|
||||
async findByWorkspaceId(workspaceId: string): Promise<ViewSortEntity[]> {
|
||||
@@ -78,6 +82,13 @@ export class ViewSortService {
|
||||
);
|
||||
}
|
||||
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{
|
||||
workspaceId: viewSortData.workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (!isDefined(viewSortData.viewId)) {
|
||||
throw new ViewSortException(
|
||||
generateViewSortExceptionMessage(
|
||||
@@ -106,7 +117,11 @@ export class ViewSortService {
|
||||
);
|
||||
}
|
||||
|
||||
const viewSort = this.viewSortRepository.create(viewSortData);
|
||||
const viewSort = this.viewSortRepository.create({
|
||||
...viewSortData,
|
||||
universalIdentifier: v4(),
|
||||
applicationId: workspaceCustomFlatApplication.id,
|
||||
});
|
||||
|
||||
const savedViewSort = await this.viewSortRepository.save(viewSort);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
import { ViewPermissionsModule } from 'src/engine/metadata-modules/view-permissions/view-permissions.module';
|
||||
import { ViewSortController } from 'src/engine/metadata-modules/view-sort/controllers/view-sort.controller';
|
||||
@@ -16,6 +17,7 @@ import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/
|
||||
PermissionsModule,
|
||||
WorkspaceCacheStorageModule,
|
||||
ViewPermissionsModule,
|
||||
ApplicationModule,
|
||||
],
|
||||
controllers: [ViewSortController],
|
||||
providers: [ViewSortService, ViewSortResolver],
|
||||
|
||||
@@ -27,7 +27,7 @@ import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
|
||||
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
|
||||
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
|
||||
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
|
||||
import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/syncable-entity-required.interface';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
// We could refactor this type to be dynamic to view type
|
||||
@Entity({ name: 'view', schema: 'core' })
|
||||
@@ -46,10 +46,7 @@ import { SyncableEntityRequired } from 'src/engine/workspace-manager/types/synca
|
||||
'CHK_VIEW_CALENDAR_INTEGRITY',
|
||||
`("type" != 'CALENDAR' OR ("calendarLayout" IS NOT NULL AND "calendarFieldMetadataId" IS NOT NULL))`,
|
||||
)
|
||||
export class ViewEntity
|
||||
extends SyncableEntityRequired
|
||||
implements Required<ViewEntity>
|
||||
{
|
||||
export class ViewEntity extends SyncableEntity implements Required<ViewEntity> {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user