Skip to content

Commit dd5889b

Browse files
fix: @W-19837693: Address the code review for delete case of OS and FC
Changes: - Handle the delete use case with multiple versions of OS and FC - Added test cases - Updated the messages TODO: - Update the labels for CX review
1 parent 74b2499 commit dd5889b

File tree

6 files changed

+500
-106
lines changed

6 files changed

+500
-106
lines changed

messages/assess.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"duplicatedDrName": "Data Mapper with duplicate name found in this org. Rename your Data Mapper and try again.",
2121
"duplicatedOSName": "Omniscript with duplicate name, type, subtype, or language found in this org. Modify your Omniscript and try again.",
2222
"duplicatedName": "Duplicated name %s",
23-
"lowerVersionDuplicateOmniscriptName": "A %s with name \"%s\" will not be migrated because lower version of same %s is marked as duplicate, which could lead to conflicts during migration.",
23+
"lowerVersionDuplicateOmniscriptName": "A %s with name \"%s\" will not be migrated because lower version of same %s will be marked as duplicate, which could lead to conflicts during migration.",
2424
"errorWhileActivatingOs": "We couldn't activate your %s:",
2525
"errorWhileActivatingCard": "We couldn't activate your Flexcard:",
2626
"errorWhileUploadingCard": "We couldn't deploy your Flexcard to your org. Review these errors:",
@@ -39,10 +39,10 @@
3939
"processingDataRaptor": "Processing Data Mapper: %s",
4040
"processingOmniScript": "Processing Omniscript: %s",
4141
"foundDataRaptorsToAssess": "Found %s Data Mappers to assess.",
42-
"foundOmniScriptsToAssess": "Found %s Omniscripts to assess",
42+
"foundOmniScriptsToAssess": "Found %s %s to assess",
4343
"foundGlobalAutoNumbersToAssess": "Found %s Omni Global Auto Numbers to assess.",
4444
"startingDataRaptorAssessment": "Starting Data Mapper assessment",
45-
"startingOmniScriptAssessment": "Starting Omniscript assessment",
45+
"startingOmniScriptAssessment": "Starting %s assessment",
4646
"startingGlobalAutoNumberAssessment": "Starting Omni Global Auto Number assessment",
4747
"allVersionsInfo": "All versions: %s",
4848
"assessmentInitialization": "Assessment process started. Using namespace: %s",
@@ -98,7 +98,7 @@
9898
"integrationProcedureNameChangeMessage": "The Integration Procedure %s will be renamed to %s during migration.",
9999
"integrationProcedureManualUpdateMessage": "All references to %s in this Integration Procedure must be manually updated after migration.",
100100
"duplicateCardNameMessage": "A Flexcard with the same name \"%s\" already exists after name cleaning, which could lead to conflicts during migration.",
101-
"lowerVersionDuplicateCardNameMessage": "A Flexcard with the name \"%s\" will not be migrated because lower version of same card is marked as duplicate, which could lead to conflicts during migration.",
101+
"lowerVersionDuplicateCardNameMessage": "A Flexcard with the name \"%s\" will not be migrated because lower version of same card will be marked as duplicate, which could lead to conflicts during migration.",
102102
"startingCustomLabelAssessment": "Starting Custom Label assessment",
103103
"assessedCustomLabelsCount": "Found %s labels that need attention out of %s total",
104104
"customLabelAssessmentCompleted": "Custom Label assessment completed",

messages/migrate.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
"couldNotTruncate": "We couldn't clear all %s records.",
2020
"couldNotTruncateOmnniProcess": "We couldn't clear all records of your %s because the %s is referenced in an Omniscript or a Flexcard.",
2121
"invalidOrRepeatingOmniscriptElementNames": "Omniscript with invalid or duplicate element names found. Rename your Omniscript elements and try again.",
22-
"lowerVersionDuplicateCardName": "Flexcard with name %s can't be migrated because lower version of same card is marked as duplicate. Rename your Flexcard and try again.",
22+
"lowerVersionDuplicateCardName": "Flexcard with name %s can't be migrated because lower version of same card is probable duplicate. Rename your Flexcard and try again.",
2323
"duplicatedCardName": "Flexcard with duplicate name %s found in this org. Rename your Flexcard and try again.",
2424
"duplicatedDrName": "Data Mapper with duplicate name found in this org. Rename your Data Mapper and try again.",
2525
"duplicatedOSName": "Omniscript with duplicate name, type, subtype, or language found in this org. Modify your Omniscript and try again.",
26-
"lowerVersionDuplicateOSName": "%s with name %s can't be migrated because lower version of same %s is marked as duplicate. Rename your %s and try again.",
26+
"lowerVersionDuplicateOSName": "%s with name %s can't be migrated because lower version of same %s is probable duplicate. Rename your %s and try again.",
2727
"errorWhileActivatingOs": "We couldn't activate your %s:",
2828
"errorWhileActivatingCard": "We couldn't activate your Flexcard:",
2929
"errorWhileUploadingCard": "We couldn't deploy your Flexcard to your org. Review these errors:",

src/migration/flexcard.ts

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ export class CardMigrationTool extends BaseMigrationTool implements MigrationToo
165165
const progressBar = createProgressBar('Assessing', 'Flexcards');
166166
progressBar.start(flexCards.length, progressCounter);
167167
const uniqueNames = new Set<string>();
168-
const dupFlexCardNames: Set<string> = new Set<string>();
168+
const dupFlexCardNames: Map<string, string> = new Map<string, string>();
169169

170170
// Now process each OmniScript and its elements
171171
for (const flexCard of flexCards) {
@@ -200,7 +200,7 @@ export class CardMigrationTool extends BaseMigrationTool implements MigrationToo
200200
private async processFlexCard(
201201
flexCard: AnyJson,
202202
uniqueNames: Set<string>,
203-
dupFlexCardNames: Set<String>
203+
dupFlexCardNames: Map<string, string>
204204
): Promise<FlexCardAssessmentInfo> {
205205
const flexCardName = flexCard['Name'];
206206
Logger.info(this.messages.getMessage('processingFlexCard', [flexCardName]));
@@ -235,24 +235,30 @@ export class CardMigrationTool extends BaseMigrationTool implements MigrationToo
235235
}
236236

237237
// Check for duplicate names (include version when allVersions is true)
238-
// A Set that can only store original flexcard names to avoid conflicts with cleaned name
239238
const uniqueCleanedName = this.allVersions ? `${cleanedName}_${version}` : cleanedName;
240-
if (uniqueNames.has(uniqueCleanedName) || dupFlexCardNames.has(originalName)) {
241-
// Add the original flexcard name to the set
242-
if (this.allVersions && !dupFlexCardNames.has(originalName)) {
243-
dupFlexCardNames.add(originalName);
244-
}
245-
if (uniqueNames.has(uniqueCleanedName)) {
246-
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('duplicateCardNameMessage', [uniqueCleanedName]));
247-
} else {
239+
240+
// Check for exact duplicate (same name + same version)
241+
if (uniqueNames.has(uniqueCleanedName)) {
242+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('duplicateCardNameMessage', [uniqueCleanedName]));
243+
assessmentStatus = getUpdatedAssessmentStatus(assessmentStatus, 'Needs manual intervention');
244+
}
245+
// Check for naming conflict: different original names cleaning to same name
246+
else if (this.allVersions && dupFlexCardNames.has(cleanedName)) {
247+
const existingOriginalName = dupFlexCardNames.get(cleanedName);
248+
// Only flag if the original names are different (indicates a naming conflict)
249+
if (existingOriginalName !== originalName) {
248250
flexCardAssessmentInfo.warnings.push(
249251
this.messages.getMessage('lowerVersionDuplicateCardNameMessage', [uniqueCleanedName])
250252
);
253+
assessmentStatus = getUpdatedAssessmentStatus(assessmentStatus, 'Needs manual intervention');
251254
}
252-
assessmentStatus = getUpdatedAssessmentStatus(assessmentStatus, 'Needs manual intervention');
253255
}
254256

257+
// Add to tracking structures
255258
uniqueNames.add(uniqueCleanedName);
259+
if (this.allVersions && !dupFlexCardNames.has(cleanedName)) {
260+
dupFlexCardNames.set(cleanedName, originalName);
261+
}
256262

257263
// Check for author name changes
258264
const originalAuthor = flexCard[this.namespacePrefix + 'Author__c'];
@@ -738,7 +744,8 @@ export class CardMigrationTool extends BaseMigrationTool implements MigrationToo
738744
const cardsUploadInfo = new Map<string, UploadRecordResult>();
739745
const originalRecords = new Map<string, any>();
740746
const uniqueNames = new Set<string>();
741-
const dupFlexCardNames: Set<string> = new Set<string>();
747+
// Map to track cleanedName -> originalName for duplicate detection
748+
const dupFlexCardNames: Map<string, string> = new Map<string, string>();
742749

743750
let progressCounter = 0;
744751
progressBar.start(cards.length, progressCounter);
@@ -760,7 +767,7 @@ export class CardMigrationTool extends BaseMigrationTool implements MigrationToo
760767
cardsUploadInfo: Map<string, UploadRecordResult>,
761768
originalRecords: Map<string, any>,
762769
uniqueNames: Set<string>,
763-
dupFlexCardNames: Set<String>
770+
dupFlexCardNames: Map<string, string>
764771
) {
765772
const recordId = card['Id'];
766773

@@ -802,22 +809,31 @@ export class CardMigrationTool extends BaseMigrationTool implements MigrationToo
802809
? `${transformedCard['Name']}_${transformedCard['VersionNumber']}`
803810
: transformedCard['Name'];
804811

805-
if (uniqueNames.has(uniqueCheckName) || dupFlexCardNames.has(transformedCard['Name'])) {
806-
if (this.allVersions && !dupFlexCardNames.has(transformedCard['Name'])) {
807-
dupFlexCardNames.add(transformedCard['Name']);
808-
}
809-
// change error message
810-
if (uniqueNames.has(uniqueCheckName)) {
811-
this.setRecordErrors(card, this.messages.getMessage('duplicatedCardName', [uniqueCheckName]));
812-
} else {
813-
this.setRecordErrors(card, this.messages.getMessage('lowerVersionDuplicateCardName', [uniqueCheckName]));
814-
}
812+
const originalCardName = card['Name'];
813+
const cleanedCardName = transformedCard['Name'];
814+
815+
// Check for exact duplicate (same name + same version)
816+
if (uniqueNames.has(uniqueCheckName)) {
817+
this.setRecordErrors(card, this.messages.getMessage('duplicatedCardName', [uniqueCheckName]));
815818
originalRecords.set(recordId, card);
816819
return;
817820
}
821+
// Check for naming conflict: different original names cleaning to same name
822+
else if (this.allVersions && dupFlexCardNames.has(cleanedCardName)) {
823+
const existingOriginalName = dupFlexCardNames.get(cleanedCardName);
824+
// Only flag if the original names are different (indicates a naming conflict)
825+
if (existingOriginalName !== originalCardName) {
826+
this.setRecordErrors(card, this.messages.getMessage('lowerVersionDuplicateCardName', [uniqueCheckName]));
827+
originalRecords.set(recordId, card);
828+
return;
829+
}
830+
}
818831

819-
// Save the name for duplicated names check (with version if allVersions is true)
832+
// Add to tracking structures
820833
uniqueNames.add(uniqueCheckName);
834+
if (this.allVersions && !dupFlexCardNames.has(cleanedCardName)) {
835+
dupFlexCardNames.set(cleanedCardName, originalCardName);
836+
}
821837

822838
// Create a map of the original records
823839
originalRecords.set(recordId, card);

src/migration/omniscript.ts

Lines changed: 76 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat
238238
const ipAssessmentInfos: IPAssessmentInfo[] = [];
239239

240240
// Create a set to store existing OmniScript names and also extract DataRaptor and FlexCard names
241-
const duplicateOmniscriptNames = new Set<string>();
241+
// Map to track cleanedName (without version) -> originalName (without version) for duplicate detection
242+
const duplicateOmniscriptNames: Map<string, string> = new Map<string, string>();
242243
const existingOmniscriptNames = new Set<string>();
243244
const existingDataRaptorNames = new Set(dataRaptorAssessmentInfos.map((info) => info.name));
244245
const existingFlexCardNames = new Set(flexCardAssessmentInfos.map((info) => info.name));
@@ -359,7 +360,7 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat
359360
existingOmniscriptNames: Set<string>,
360361
existingDataRaptorNames: Set<string>,
361362
existingFlexCardNames: Set<string>,
362-
duplicateOmniscriptNames: Set<string>
363+
duplicateOmniscriptNames: Map<string, string>
363364
): Promise<OSAssessmentInfo> {
364365
const elements = await this.getAllElementsForOmniScript(omniscript['Id']);
365366

@@ -570,47 +571,43 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat
570571
);
571572
assessmentStatus = 'Warnings';
572573
}
573-
// Duplicate check logic:
574-
// - When allVersions=false: check without version (using recordNameWithoutVersion)
575-
// - When allVersions=true: check with version (using recordName)
574+
// Duplicate check logic using Map to track originalName -> cleanedName
575+
// This allows us to detect both exact duplicates and name cleaning conflicts
576576
const nameToCheck = this.allVersions ? recordName : recordNameWithoutVersion;
577577

578-
if (existingOmniscriptNames.has(nameToCheck) || duplicateOmniscriptNames.has(recordNameWithoutVersion)) {
579-
// Mark the base name as duplicate for subsequent versions when allVersions=true
580-
if (this.allVersions && !duplicateOmniscriptNames.has(recordNameWithoutVersion)) {
581-
duplicateOmniscriptNames.add(recordNameWithoutVersion);
582-
}
583-
584-
// Message selection logic:
585-
// - When allVersions=false: always use "duplicatedName" (comparing without version)
586-
// - When allVersions=true:
587-
// - If exact match in existingOmniscriptNames (same name+version): use "duplicatedName"
588-
// - If base name in duplicateOmniscriptNames (different version): use "lowerVersionDuplicateOmniscriptName"
589-
let shouldUseDuplicatedNameMessage = false;
590-
591-
if (!this.allVersions) {
592-
// allVersions=false: always use duplicatedName message
593-
shouldUseDuplicatedNameMessage = true;
594-
} else {
595-
// allVersions=true: use duplicatedName only if exact match (same name+version)
596-
shouldUseDuplicatedNameMessage = existingOmniscriptNames.has(recordName);
597-
}
598-
599-
if (shouldUseDuplicatedNameMessage) {
600-
warnings.push(this.messages.getMessage('duplicatedName', [recordName]));
601-
} else {
578+
// Get the original name parts (before cleaning)
579+
const originalType = omniscript[this.namespacePrefix + 'Type__c'];
580+
const originalSubType = omniscript[this.namespacePrefix + 'SubType__c'];
581+
const originalLanguage = omniscript[this.namespacePrefix + 'Language__c'] || '';
582+
const originalNameWithoutVersion = originalLanguage
583+
? `${originalType}_${originalSubType}_${originalLanguage}`
584+
: `${originalType}_${originalSubType}`;
585+
586+
// Check for exact duplicate (same name + version)
587+
if (existingOmniscriptNames.has(nameToCheck)) {
588+
warnings.push(this.messages.getMessage('duplicatedName', [recordName]));
589+
assessmentStatus = 'Needs manual intervention';
590+
}
591+
// Check for naming conflict: different original names cleaning to same name
592+
else if (this.allVersions && duplicateOmniscriptNames.has(recordNameWithoutVersion)) {
593+
const existingOriginalName = duplicateOmniscriptNames.get(recordNameWithoutVersion);
594+
// Only flag if the original names are different (indicates a naming conflict)
595+
if (existingOriginalName !== originalNameWithoutVersion) {
602596
warnings.push(
603597
this.messages.getMessage('lowerVersionDuplicateOmniscriptName', [
604598
this.getName(true),
605599
recordName,
606600
this.getName(true),
607601
])
608602
);
603+
assessmentStatus = 'Needs manual intervention';
609604
}
605+
}
610606

611-
assessmentStatus = 'Needs manual intervention';
612-
} else {
613-
existingOmniscriptNames.add(nameToCheck);
607+
// Add to tracking structures
608+
existingOmniscriptNames.add(nameToCheck);
609+
if (this.allVersions && !duplicateOmniscriptNames.has(recordNameWithoutVersion)) {
610+
duplicateOmniscriptNames.set(recordNameWithoutVersion, originalNameWithoutVersion);
614611
}
615612

616613
// Add warning for duplicate element names within the same OmniScript
@@ -736,7 +733,8 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat
736733
populateRegexForFunctionMetadata(functionDefinitionMetadata);
737734

738735
const duplicatedNames = new Set<string>();
739-
const duplicateOmniscriptNames = new Set<string>();
736+
// Map to track cleanedName (without version) -> originalName (without version) for duplicate detection
737+
const duplicateOmniscriptNames: Map<string, string> = new Map<string, string>();
740738

741739
// Variables to be returned After Migration
742740
let originalOsRecords = new Map<string, any>();
@@ -1048,24 +1046,17 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat
10481046
'_1';
10491047
}
10501048

1051-
if (duplicatedNames.has(mappedOsName) || duplicateOmniscriptNames.has(mappedOsNameWithoutVersion)) {
1052-
originalOsRecords.set(recordId, omniscript);
1053-
if (this.allVersions && !duplicateOmniscriptNames.has(mappedOsNameWithoutVersion)) {
1054-
duplicateOmniscriptNames.add(mappedOsNameWithoutVersion);
1055-
}
1056-
1057-
let warningMessage: string;
1058-
if (duplicatedNames.has(mappedOsName)) {
1059-
warningMessage = this.messages.getMessage('duplicatedOSName', [this.getName(true), mappedOsName]);
1060-
} else {
1061-
warningMessage = this.messages.getMessage('lowerVersionDuplicateOSName', [
1062-
this.getName(true),
1063-
mappedOsName,
1064-
this.getName(true),
1065-
this.getName(true),
1066-
]);
1067-
}
1068-
1049+
// Get original name parts for tracking
1050+
const originalType = omniscript[this.namespacePrefix + 'Type__c'];
1051+
const originalSubType = omniscript[this.namespacePrefix + 'SubType__c'];
1052+
const originalLanguage = omniscript[this.namespacePrefix + 'Language__c'] || '';
1053+
const originalNameWithoutVersion = originalLanguage
1054+
? `${originalType}_${originalSubType}_${originalLanguage}`
1055+
: `${originalType}_${originalSubType}`;
1056+
1057+
// Check for exact duplicate (same name + same version)
1058+
if (duplicatedNames.has(mappedOsName)) {
1059+
const warningMessage = this.messages.getMessage('duplicatedOSName', [this.getName(true), mappedOsName]);
10691060
const skippedResponse: UploadRecordResult = {
10701061
referenceId: recordId,
10711062
id: '',
@@ -1077,8 +1068,35 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat
10771068
skipped: true,
10781069
};
10791070
osUploadInfo.set(recordId, skippedResponse);
1071+
originalOsRecords.set(recordId, omniscript);
10801072
continue;
10811073
}
1074+
// Check for naming conflict: different original names cleaning to same name
1075+
else if (this.allVersions && duplicateOmniscriptNames.has(mappedOsNameWithoutVersion)) {
1076+
const existingOriginalName = duplicateOmniscriptNames.get(mappedOsNameWithoutVersion);
1077+
// Only flag if the original names are different (indicates a naming conflict)
1078+
if (existingOriginalName !== originalNameWithoutVersion) {
1079+
const warningMessage = this.messages.getMessage('lowerVersionDuplicateOSName', [
1080+
this.getName(true),
1081+
mappedOsName,
1082+
this.getName(true),
1083+
this.getName(true),
1084+
]);
1085+
const skippedResponse: UploadRecordResult = {
1086+
referenceId: recordId,
1087+
id: '',
1088+
success: false,
1089+
hasErrors: false,
1090+
errors: [],
1091+
warnings: [warningMessage],
1092+
newName: '',
1093+
skipped: true,
1094+
};
1095+
osUploadInfo.set(recordId, skippedResponse);
1096+
originalOsRecords.set(recordId, omniscript);
1097+
continue;
1098+
}
1099+
}
10821100

10831101
// Save the mapped record
10841102
mappedRecords.push(mappedOmniScript);
@@ -1128,8 +1146,14 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat
11281146
'_1';
11291147
}
11301148
// Always set the new name to show the migrated name
1131-
// Add the processednew name to the duplicated set
1149+
// Add the processed new name to the duplicated set
11321150
duplicatedNames.add(mappedOsName);
1151+
1152+
// Add to map for tracking naming conflicts (only when allVersions=true)
1153+
if (this.allVersions && !duplicateOmniscriptNames.has(mappedOsNameWithoutVersion)) {
1154+
duplicateOmniscriptNames.set(mappedOsNameWithoutVersion, originalNameWithoutVersion);
1155+
}
1156+
11331157
osUploadResponse.newName = mappedOsName;
11341158

11351159
// Only add warning if the name was actually modified

0 commit comments

Comments
 (0)