diff --git a/packages/spacecat-shared-data-access/src/models/suggestion/suggestion.data-schemas.js b/packages/spacecat-shared-data-access/src/models/suggestion/suggestion.data-schemas.js index 4fef62dd1..fe43019fb 100644 --- a/packages/spacecat-shared-data-access/src/models/suggestion/suggestion.data-schemas.js +++ b/packages/spacecat-shared-data-access/src/models/suggestion/suggestion.data-schemas.js @@ -135,16 +135,17 @@ export const DATA_SCHEMAS = { pageviews: Joi.number().optional(), clsCount: Joi.number().optional(), ttfbCount: Joi.number().optional(), - lcp: Joi.number().optional(), + lcp: Joi.number().allow(null).optional(), inpCount: Joi.number().optional(), inp: Joi.number().optional(), - ttfb: Joi.number().optional(), - cls: Joi.number().optional(), + ttfb: Joi.number().allow(null).optional(), + cls: Joi.number().allow(null).optional(), lcpCount: Joi.number().optional(), organic: Joi.number().optional(), }).unknown(true), ).required(), issues: Joi.array().items(Joi.object()).required(), + jiraLink: Joi.string().uri().allow(null).optional(), aggregationKey: Joi.string().allow(null).optional(), }).unknown(true), projections: { diff --git a/packages/spacecat-shared-data-access/test/unit/models/suggestion/suggestion.model.test.js b/packages/spacecat-shared-data-access/test/unit/models/suggestion/suggestion.model.test.js index 475503bd5..ac169c8f0 100644 --- a/packages/spacecat-shared-data-access/test/unit/models/suggestion/suggestion.model.test.js +++ b/packages/spacecat-shared-data-access/test/unit/models/suggestion/suggestion.model.test.js @@ -184,6 +184,62 @@ describe('SuggestionModel', () => { Suggestion.validateData({ anything: 'goes' }, 'unknown-type'); }).to.not.throw(); }); + + // Verification: CWV suggestion data (suggestion.data object only) vs DATA_SCHEMAS['cwv'] + describe('CWV opportunity type', () => { + it('passes when url-type has type, url (uri), metrics, and issues', () => { + const suggestionData = { + type: 'url', + url: 'https://www.example.com/page', + pageviews: 11620, + organic: 2400, + metrics: [ + { + deviceType: 'mobile', + pageviews: 6200, + lcp: 2701, + cls: 0.001, + ttfb: 682, + }, + { + deviceType: 'desktop', + pageviews: 3600, + lcp: null, + cls: null, + ttfb: null, + }, + ], + issues: [], + }; + expect(() => Suggestion.validateData(suggestionData, 'cwv')).to.not.throw(); + }); + + it('fails when issues is missing (schema requires issues array)', () => { + const suggestionData = { + type: 'url', + url: 'https://www.example.com/page', + pageviews: 11620, + metrics: [{ deviceType: 'mobile', lcp: 2701 }], + }; + expect(() => Suggestion.validateData(suggestionData, 'cwv')).to.throw(); + }); + + it('fails when group-type has pattern but no url (schema requires url)', () => { + const suggestionData = { + type: 'group', + name: 'Some pages', + pattern: 'https://www.aem.live/home/*', + pageviews: 9620, + organic: 1900, + metrics: [ + { deviceType: 'desktop', lcp: 2099, cls: 0.011 }, + { deviceType: 'mobile', lcp: 2454, cls: 0.27 }, + ], + issues: [], + }; + expect(() => Suggestion.validateData(suggestionData, 'cwv')).to.throw(); + }); + }); }); }); });