Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 1
fix(personalize,import): fix CT linking failure from empty-audience experiences and missing variant entry data file #280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
9cf9514b8585ccb5301108dcd10abf088a2a6596a6ea05a5eFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,5 @@ | ||
| import { join, resolve } from 'path'; | ||
| import { existsSync } from 'fs'; | ||
| import values from 'lodash/values'; | ||
| import cloneDeep from 'lodash/cloneDeep'; | ||
| import { sanitizePath, log, handleAndLogError } from '@contentstack/cli-utilities'; | ||
| import { PersonalizationAdapter, fsUtil, lookUpAudiences, lookUpEvents } from '../utils'; | ||
| import { | ||
| @@ -119,10 +117,12 @@ export default class Experiences extends PersonalizationAdapter<ImportConfig> { | ||
| const experiences = fsUtil.readFile(this.experiencesPath, true) as ExperienceStruct[]; | ||
| log.info(`Found ${experiences.length} experiences to import`, this.config.context); | ||
| const experienceUidsWithVariants = new Set<string>(); | ||
| for (const experience of experiences) { | ||
| const { uid, ...restExperienceData } = experience; | ||
| log.debug(`Processing experience: ${uid}`, this.config.context); | ||
| //check whether reference audience exists or not that referenced in variations having __type equal to AudienceBasedVariation & targeting | ||
| let experienceReqObj: CreateExperienceInput = lookUpAudiences(restExperienceData, this.audiencesUid); | ||
| //check whether events exists or not that referenced in metrics | ||
| @@ -135,7 +135,9 @@ export default class Experiences extends PersonalizationAdapter<ImportConfig> { | ||
| try { | ||
| // import versions of experience | ||
| await this.importExperienceVersions(expRes, uid); | ||
| if (await this.importExperienceVersions(expRes, uid)) { | ||
| experienceUidsWithVariants.add(expRes.uid); | ||
| } | ||
| } catch (error) { | ||
| handleAndLogError(error, this.config.context, `Failed to import experience versions for ${expRes.uid}`); | ||
| } | ||
| @@ -145,7 +147,7 @@ export default class Experiences extends PersonalizationAdapter<ImportConfig> { | ||
| log.success('Experiences created successfully', this.config.context); | ||
| log.info('Validating variant and variant group creation',this.config.context); | ||
| this.pendingVariantAndVariantGrpForExperience = values(cloneDeep(this.experiencesUidMapper)); | ||
| this.pendingVariantAndVariantGrpForExperience = Array.from(experienceUidsWithVariants); | ||
| const jobRes = await this.validateVariantGroupAndVariantsCreated(); | ||
| fsUtil.writeFile(this.cmsVariantPath, this.cmsVariants); | ||
| fsUtil.writeFile(this.cmsVariantGroupPath, this.cmsVariantGroups); | ||
| @@ -175,7 +177,7 @@ export default class Experiences extends PersonalizationAdapter<ImportConfig> { | ||
| /** | ||
| * function import experience versions from a JSON file and creates them in the project. | ||
| */ | ||
| async importExperienceVersions(experience: ExperienceStruct, oldExperienceUid: string) { | ||
| async importExperienceVersions(experience: ExperienceStruct, oldExperienceUid: string): Promise<boolean> { | ||
| log.debug(`Importing versions for experience: ${oldExperienceUid}`, this.config.context); | ||
| const versionsPath = resolve( | ||
| @@ -186,33 +188,39 @@ export default class Experiences extends PersonalizationAdapter<ImportConfig> { | ||
| if (!existsSync(versionsPath)) { | ||
| log.debug(`No versions file found for experience: ${oldExperienceUid}`, this.config.context); | ||
| return; | ||
| return false; | ||
| } | ||
| const versions = fsUtil.readFile(versionsPath, true) as ExperienceStruct[]; | ||
| log.debug(`Found ${versions.length} versions for experience: ${oldExperienceUid}`, this.config.context); | ||
| const versionMap: Record<string, CreateExperienceVersionInput | undefined> = { | ||
| ACTIVE: undefined, | ||
| DRAFT: undefined, | ||
| PAUSE: undefined, | ||
| }; | ||
| const HANDLED_STATUSES = new Set(['ACTIVE', 'DRAFT', 'PAUSE']); | ||
| const versionMap: { ACTIVE?: CreateExperienceVersionInput; DRAFT?: CreateExperienceVersionInput; PAUSE?: CreateExperienceVersionInput } = {}; | ||
| // Process each version and map them by status | ||
| versions.forEach((version) => { | ||
| let versionReqObj = lookUpAudiences(version, this.audiencesUid) as CreateExperienceVersionInput; | ||
| versionReqObj = lookUpEvents(version, this.eventsUid) as CreateExperienceVersionInput; | ||
| versionReqObj = lookUpEvents(versionReqObj, this.eventsUid) as CreateExperienceVersionInput; | ||
| if (versionReqObj && versionReqObj.status && (versionReqObj.variants?.length ?? 0) > 0) { | ||
| versionMap[versionReqObj.status] = versionReqObj; | ||
| if (!HANDLED_STATUSES.has(versionReqObj.status)) { | ||
| log.warn(`Skipping version with unrecognized status "${versionReqObj.status}" — expected one of ACTIVE, DRAFT, PAUSE`, this.config.context); | ||
| return; | ||
| } | ||
| versionMap[versionReqObj.status as 'ACTIVE' | 'DRAFT' | 'PAUSE'] = versionReqObj; | ||
| log.debug(`Mapped version with status: ${versionReqObj.status}`, this.config.context); | ||
| } else if (versionReqObj?.status && !(versionReqObj.variants?.length ?? 0)) { | ||
| log.warn(`Skipping version ${versionReqObj.status}: no valid variants (all had unmapped Lytics audiences)`, this.config.context); | ||
| log.warn(`Skipping version ${versionReqObj.status}: no valid variants after audience/event mapping`, this.config.context); | ||
| } | ||
| }); | ||
| if (!Object.values(versionMap).some((v) => v !== undefined)) { | ||
| return false; | ||
| } | ||
| // Prioritize updating or creating versions based on the order: ACTIVE -> DRAFT -> PAUSE | ||
| return await this.handleVersionUpdateOrCreate(experience, versionMap); | ||
| await this.handleVersionUpdateOrCreate(experience, versionMap); | ||
cs-raj marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| return true; | ||
| } | ||
| // Helper method to handle version update or creation logic | ||
| @@ -333,6 +341,10 @@ export default class Experiences extends PersonalizationAdapter<ImportConfig> { | ||
| log.debug(`Attaching ${updatedContentTypes.length} content types to experience: ${newExpUid}`, this.config.context); | ||
| const { variant_groups: [variantGroup] = [] } = | ||
| (await this.getVariantGroup({ experienceUid: newExpUid })) || {}; | ||
| if (!variantGroup) { | ||
| log.warn(`No variant group found for experience: ${newExpUid} — skipping CT attachment`, this.config.context); | ||
| return; | ||
| } | ||
| variantGroup.content_types = updatedContentTypes; | ||
| // Update content types detail in the new experience asynchronously | ||
| return await this.updateVariantGroup(variantGroup); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -85,7 +85,7 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp | ||
| log.debug(`Checking for variant entry data file: ${filePath}`, this.config.context); | ||
| if (!existsSync(filePath)) { | ||
| log.warn(`Variant entry data file not found at path: ${filePath}`, this.config.context); | ||
| log.debug(`No variant entries to import (data-for-variant-entry.json not found at: ${filePath})`, this.config.context); | ||
| return; | ||
cs-raj marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.