feat: health check enum (#3913)

* feat: health check enum

* fix: cleaner if condition
This commit is contained in:
Jérémy M
2024-02-12 17:32:05 +01:00
committed by GitHub
parent b0b033aec9
commit 35fce6a6b4
3 changed files with 67 additions and 21 deletions

View File

@ -1,11 +1,13 @@
import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity'; import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity';
export type EnumFieldMetadataUnionType =
| FieldMetadataType.RATING
| FieldMetadataType.SELECT
| FieldMetadataType.MULTI_SELECT;
export const isEnumFieldMetadataType = ( export const isEnumFieldMetadataType = (
type: FieldMetadataType, type: FieldMetadataType,
): type is ): type is EnumFieldMetadataUnionType => {
| FieldMetadataType.RATING
| FieldMetadataType.SELECT
| FieldMetadataType.MULTI_SELECT => {
return ( return (
type === FieldMetadataType.RATING || type === FieldMetadataType.RATING ||
type === FieldMetadataType.SELECT || type === FieldMetadataType.SELECT ||

View File

@ -10,7 +10,10 @@ import {
import { FieldMetadataDefaultValue } from 'src/metadata/field-metadata/interfaces/field-metadata-default-value.interface'; import { FieldMetadataDefaultValue } from 'src/metadata/field-metadata/interfaces/field-metadata-default-value.interface';
import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service';
import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity'; import {
FieldMetadataEntity,
FieldMetadataType,
} from 'src/metadata/field-metadata/field-metadata.entity';
import { fieldMetadataTypeToColumnType } from 'src/metadata/workspace-migration/utils/field-metadata-type-to-column-type.util'; import { fieldMetadataTypeToColumnType } from 'src/metadata/workspace-migration/utils/field-metadata-type-to-column-type.util';
import { serializeTypeDefaultValue } from 'src/metadata/field-metadata/utils/serialize-type-default-value.util'; import { serializeTypeDefaultValue } from 'src/metadata/field-metadata/utils/serialize-type-default-value.util';
@ -122,17 +125,17 @@ export class DatabaseStructureService {
})); }));
} }
getPostgresDataType( getPostgresDataType(fieldMetadata: FieldMetadataEntity): string {
fieldMetadataType: FieldMetadataType, const typeORMType = fieldMetadataTypeToColumnType(fieldMetadata.type);
fieldMetadataName: string,
objectMetadataNameSingular: string,
): string {
const typeORMType = fieldMetadataTypeToColumnType(fieldMetadataType);
const mainDataSource = this.typeORMService.getMainDataSource(); const mainDataSource = this.typeORMService.getMainDataSource();
// TODO: remove special case for enum type, should we include this to fieldMetadataTypeToColumnType? // Compute enum name to compare data type properly
if (typeORMType === 'enum') { if (typeORMType === 'enum') {
return `${objectMetadataNameSingular}_${fieldMetadataName}_enum`; const objectName = fieldMetadata.object?.nameSingular;
const prefix = fieldMetadata.isCustom ? '_' : '';
const fieldName = fieldMetadata.name;
return `${objectName}_${prefix}${fieldName}_enum`;
} }
return mainDataSource.driver.normalizeType({ return mainDataSource.driver.normalizeType({

View File

@ -6,6 +6,7 @@ import {
} from 'src/workspace/workspace-health/interfaces/workspace-health-issue.interface'; } from 'src/workspace/workspace-health/interfaces/workspace-health-issue.interface';
import { WorkspaceTableStructure } from 'src/workspace/workspace-health/interfaces/workspace-table-definition.interface'; import { WorkspaceTableStructure } from 'src/workspace/workspace-health/interfaces/workspace-table-definition.interface';
import { WorkspaceHealthOptions } from 'src/workspace/workspace-health/interfaces/workspace-health-options.interface'; import { WorkspaceHealthOptions } from 'src/workspace/workspace-health/interfaces/workspace-health-options.interface';
import { FieldMetadataDefaultValue } from 'src/metadata/field-metadata/interfaces/field-metadata-default-value.interface';
import { import {
FieldMetadataEntity, FieldMetadataEntity,
@ -16,8 +17,12 @@ import { DatabaseStructureService } from 'src/workspace/workspace-health/service
import { validName } from 'src/workspace/workspace-health/utils/valid-name.util'; import { validName } from 'src/workspace/workspace-health/utils/valid-name.util';
import { compositeDefinitions } from 'src/metadata/field-metadata/composite-types'; import { compositeDefinitions } from 'src/metadata/field-metadata/composite-types';
import { validateDefaultValueForType } from 'src/metadata/field-metadata/utils/validate-default-value-for-type.util'; import { validateDefaultValueForType } from 'src/metadata/field-metadata/utils/validate-default-value-for-type.util';
import { isEnumFieldMetadataType } from 'src/metadata/field-metadata/utils/is-enum-field-metadata-type.util'; import {
EnumFieldMetadataUnionType,
isEnumFieldMetadataType,
} from 'src/metadata/field-metadata/utils/is-enum-field-metadata-type.util';
import { validateOptionsForType } from 'src/metadata/field-metadata/utils/validate-options-for-type.util'; import { validateOptionsForType } from 'src/metadata/field-metadata/utils/validate-options-for-type.util';
import { serializeDefaultValue } from 'src/metadata/field-metadata/utils/serialize-default-value';
@Injectable() @Injectable()
export class FieldMetadataHealthService { export class FieldMetadataHealthService {
@ -118,11 +123,8 @@ export class FieldMetadataHealthService {
const issues: WorkspaceHealthIssue[] = []; const issues: WorkspaceHealthIssue[] = [];
const columnName = fieldMetadata.targetColumnMap.value; const columnName = fieldMetadata.targetColumnMap.value;
const dataType = this.databaseStructureService.getPostgresDataType( const dataType =
fieldMetadata.type, this.databaseStructureService.getPostgresDataType(fieldMetadata);
fieldMetadata.name,
fieldMetadata.object?.nameSingular,
);
const defaultValue = this.databaseStructureService.getPostgresDefault( const defaultValue = this.databaseStructureService.getPostgresDefault(
fieldMetadata.type, fieldMetadata.type,
@ -144,6 +146,8 @@ export class FieldMetadataHealthService {
return issues; return issues;
} }
const columnDefaultValue = columnStructure.columnDefault?.split('::')?.[0];
// Check if column data type is the same // Check if column data type is the same
if (columnStructure.dataType !== dataType) { if (columnStructure.dataType !== dataType) {
issues.push({ issues.push({
@ -167,8 +171,27 @@ export class FieldMetadataHealthService {
if ( if (
defaultValue && defaultValue &&
columnStructure.columnDefault && columnDefaultValue &&
!columnStructure.columnDefault.startsWith(defaultValue) isEnumFieldMetadataType(fieldMetadata.type)
) {
const enumValues = fieldMetadata.options?.map((option) =>
serializeDefaultValue(option.value),
);
if (!enumValues.includes(columnDefaultValue)) {
issues.push({
type: WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_NOT_VALID,
fieldMetadata,
columnStructure,
message: `Column ${columnName} default value is not in the enum values "${columnDefaultValue}" NOT IN "${enumValues}"`,
});
}
}
if (
defaultValue &&
columnDefaultValue &&
columnDefaultValue !== defaultValue
) { ) {
issues.push({ issues.push({
type: WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_CONFLICT, type: WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_CONFLICT,
@ -314,6 +337,24 @@ export class FieldMetadataHealthService {
}); });
} }
if (
isEnumFieldMetadataType(fieldMetadata.type) &&
fieldMetadata.defaultValue
) {
const enumValues = fieldMetadata.options?.map((option) => option.value);
const metadataDefaultValue = (
fieldMetadata.defaultValue as FieldMetadataDefaultValue<EnumFieldMetadataUnionType>
)?.value;
if (metadataDefaultValue && !enumValues.includes(metadataDefaultValue)) {
issues.push({
type: WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_NOT_VALID,
fieldMetadata,
message: `Column default value is not in the enum values "${metadataDefaultValue}" NOT IN "${enumValues}"`,
});
}
}
return issues; return issues;
} }