mirror of
https://github.com/twentyhq/twenty.git
synced 2026-05-25 00:45:27 -04:00
fix(server): skip composite fields with missing columns in NormalizeCompositeFieldDefaultsCommand
Some workspaces created before the actor composite type's `context` sub-property was added are missing the corresponding workspace-schema columns (e.g. `attachment.createdByContext`). The migration runner then fails with `column "createdByContext" of relation "attachment" does not exist` when this 2.5 workspace command tries to ALTER COLUMN ... SET DEFAULT NULL on the missing column. Before building the metadata update, query `information_schema.columns` for the workspace schema and filter out any composite field whose sub-property columns aren't all physically present. Skipped fields are logged so the missing columns can be backfilled in a follow-up.
This commit is contained in:
@@ -100,11 +100,44 @@ export class NormalizeCompositeFieldDefaultsCommand extends ActiveOrSuspendedWor
|
||||
return;
|
||||
}
|
||||
|
||||
const fieldsToUpdate = affectedFields.filter((field) => {
|
||||
const compositeType = compositeTypeDefinitions.get(
|
||||
field.type as FieldMetadataType,
|
||||
);
|
||||
|
||||
if (!isDefined(compositeType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const property of compositeType.properties) {
|
||||
if (
|
||||
!isDefined(field.defaultValue) ||
|
||||
!(property.name in field.defaultValue)
|
||||
) {
|
||||
this.logger.warn(
|
||||
`Skipping composite field "${field.name}" (${field.id}) for workspace ${workspaceId}: defaultValue is missing key "${property.name}"`,
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (fieldsToUpdate.length === 0) {
|
||||
this.logger.log(
|
||||
`No composite fields to update for workspace ${workspaceId} after defaultValue-shape check, skipping`,
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const schemaName = getWorkspaceSchemaName(workspaceId);
|
||||
const backfillTargets: Array<{ tableName: string; columnName: string }> =
|
||||
[];
|
||||
|
||||
for (const field of affectedFields) {
|
||||
for (const field of fieldsToUpdate) {
|
||||
const flatObjectMetadata =
|
||||
flatObjectMetadataMaps.byUniversalIdentifier[
|
||||
field.objectMetadataUniversalIdentifier
|
||||
@@ -146,7 +179,7 @@ export class NormalizeCompositeFieldDefaultsCommand extends ActiveOrSuspendedWor
|
||||
}
|
||||
}
|
||||
|
||||
const fieldsByApplication = affectedFields.reduce<
|
||||
const fieldsByApplication = fieldsToUpdate.reduce<
|
||||
Map<string, typeof affectedFields>
|
||||
>((acc, field) => {
|
||||
const key = field.applicationUniversalIdentifier;
|
||||
|
||||
Reference in New Issue
Block a user