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';
export type EnumFieldMetadataUnionType =
| FieldMetadataType.RATING
| FieldMetadataType.SELECT
| FieldMetadataType.MULTI_SELECT;
export const isEnumFieldMetadataType = (
type: FieldMetadataType,
): type is
| FieldMetadataType.RATING
| FieldMetadataType.SELECT
| FieldMetadataType.MULTI_SELECT => {
): type is EnumFieldMetadataUnionType => {
return (
type === FieldMetadataType.RATING ||
type === FieldMetadataType.SELECT ||

View File

@ -10,7 +10,10 @@ import {
import { FieldMetadataDefaultValue } from 'src/metadata/field-metadata/interfaces/field-metadata-default-value.interface';
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 { serializeTypeDefaultValue } from 'src/metadata/field-metadata/utils/serialize-type-default-value.util';
@ -122,17 +125,17 @@ export class DatabaseStructureService {
}));
}
getPostgresDataType(
fieldMetadataType: FieldMetadataType,
fieldMetadataName: string,
objectMetadataNameSingular: string,
): string {
const typeORMType = fieldMetadataTypeToColumnType(fieldMetadataType);
getPostgresDataType(fieldMetadata: FieldMetadataEntity): string {
const typeORMType = fieldMetadataTypeToColumnType(fieldMetadata.type);
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') {
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({

View File

@ -6,6 +6,7 @@ import {
} from 'src/workspace/workspace-health/interfaces/workspace-health-issue.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 { FieldMetadataDefaultValue } from 'src/metadata/field-metadata/interfaces/field-metadata-default-value.interface';
import {
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 { compositeDefinitions } from 'src/metadata/field-metadata/composite-types';
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 { serializeDefaultValue } from 'src/metadata/field-metadata/utils/serialize-default-value';
@Injectable()
export class FieldMetadataHealthService {
@ -118,11 +123,8 @@ export class FieldMetadataHealthService {
const issues: WorkspaceHealthIssue[] = [];
const columnName = fieldMetadata.targetColumnMap.value;
const dataType = this.databaseStructureService.getPostgresDataType(
fieldMetadata.type,
fieldMetadata.name,
fieldMetadata.object?.nameSingular,
);
const dataType =
this.databaseStructureService.getPostgresDataType(fieldMetadata);
const defaultValue = this.databaseStructureService.getPostgresDefault(
fieldMetadata.type,
@ -144,6 +146,8 @@ export class FieldMetadataHealthService {
return issues;
}
const columnDefaultValue = columnStructure.columnDefault?.split('::')?.[0];
// Check if column data type is the same
if (columnStructure.dataType !== dataType) {
issues.push({
@ -167,8 +171,27 @@ export class FieldMetadataHealthService {
if (
defaultValue &&
columnStructure.columnDefault &&
!columnStructure.columnDefault.startsWith(defaultValue)
columnDefaultValue &&
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({
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;
}