feat: health check enum (#3913)
* feat: health check enum * fix: cleaner if condition
This commit is contained in:
@ -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 ||
|
||||||
|
|||||||
@ -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({
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user