@adobe/spacecat-shared-data-access 2.82.0 → 2.83.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # [@adobe/spacecat-shared-data-access-v2.83.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.83.0...@adobe/spacecat-shared-data-access-v2.83.1) (2025-11-14)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Add a dummy code ([#1128](https://github.com/adobe/spacecat-shared/issues/1128)) ([7d8a6d8](https://github.com/adobe/spacecat-shared/commit/7d8a6d829303f2710dd7363d05a511a7ddfbb0d0))
7
+
8
+ # [@adobe/spacecat-shared-data-access-v2.83.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.82.0...@adobe/spacecat-shared-data-access-v2.83.0) (2025-11-14)
9
+
10
+
11
+ ### Features
12
+
13
+ * Add top-level brandProfile to Site Config with versioning and hash; tests and fixtures ([#1125](https://github.com/adobe/spacecat-shared/issues/1125)) ([6dcd3f8](https://github.com/adobe/spacecat-shared/commit/6dcd3f848d0dcc7303a9778ee86fc334166e2b68))
14
+ * added a new type reporting for fix entity ([#1121](https://github.com/adobe/spacecat-shared/issues/1121)) ([47f44b8](https://github.com/adobe/spacecat-shared/commit/47f44b81f073bdf1801746fb9e348a661f3a3fc5))
15
+
1
16
  # [@adobe/spacecat-shared-data-access-v2.82.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.81.0...@adobe/spacecat-shared-data-access-v2.82.0) (2025-11-13)
2
17
 
3
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-data-access",
3
- "version": "2.82.0",
3
+ "version": "2.83.1",
4
4
  "description": "Shared modules of the Spacecat Services - Data Access",
5
5
  "type": "module",
6
6
  "engines": {
@@ -29,9 +29,12 @@ class FixEntity extends BaseModel {
29
29
  ROLLED_BACK: 'ROLLED_BACK', // the fix has been rolled_back
30
30
  };
31
31
 
32
+ // reporting is a new origin which is used
33
+ // to denote the fix entities created by the reporting team
32
34
  static ORIGINS = {
33
35
  SPACECAT: 'spacecat',
34
36
  ASO: 'aso',
37
+ REPORTING: 'reporting',
35
38
  };
36
39
 
37
40
  async getSuggestions() {
@@ -10,7 +10,10 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
+ import { isNonEmptyObject } from '@adobe/spacecat-shared-utils';
14
+ import crypto from 'crypto';
13
15
  import Joi from 'joi';
16
+
14
17
  import { getLogger } from '../../util/logger-registry.js';
15
18
 
16
19
  export const IMPORT_TYPES = {
@@ -269,6 +272,21 @@ export const configSchema = Joi.object({
269
272
  brandId: Joi.string().required(),
270
273
  userId: Joi.string().required(),
271
274
  }).optional(),
275
+ brandProfile: Joi.object({
276
+ // functional metadata
277
+ version: Joi.number().integer().min(0),
278
+ updatedAt: Joi.string().isoDate(),
279
+ contentHash: Joi.string(),
280
+ // generic top-level content containers (non-strict)
281
+ discovery: Joi.any(),
282
+ clustering: Joi.any(),
283
+ competitive_context: Joi.any(),
284
+ main_profile: Joi.any(),
285
+ sub_brands: Joi.any(),
286
+ confidence_score: Joi.any(),
287
+ pages_considered: Joi.any(),
288
+ diversity_assessment: Joi.any(),
289
+ }).unknown(true).optional(),
272
290
  fetchConfig: Joi.object({
273
291
  headers: Joi.object().pattern(Joi.string(), Joi.string()),
274
292
  overrideBaseURL: Joi.string().uri().optional(),
@@ -414,6 +432,7 @@ export const Config = (data = {}) => {
414
432
  self.getLatestMetrics = (type) => state?.handlers?.[type]?.latestMetrics;
415
433
  self.getFetchConfig = () => state?.fetchConfig;
416
434
  self.getBrandConfig = () => state?.brandConfig;
435
+ self.getBrandProfile = () => state?.brandProfile;
417
436
  self.getCdnLogsConfig = () => state?.cdnLogsConfig;
418
437
  self.getLlmoConfig = () => state?.llmo;
419
438
  self.getLlmoDataFolder = () => state?.llmo?.dataFolder;
@@ -630,6 +649,48 @@ export const Config = (data = {}) => {
630
649
  state.brandConfig = brandConfig;
631
650
  };
632
651
 
652
+ /**
653
+ * Updates the top-level brandProfile with versioning and content hashing.
654
+ * Version is incremented only if the meaningful content changes.
655
+ * @param {object} newProfile
656
+ */
657
+ self.updateBrandProfile = (newProfile = {}) => {
658
+ const prior = state.brandProfile || {};
659
+ // compute hash over all content except functional fields
660
+ const stripFunctional = (p) => {
661
+ if (!isNonEmptyObject(p)) return {};
662
+ const {
663
+ /* eslint-disable no-unused-vars */
664
+ version, updatedAt, contentHash, ...rest
665
+ } = p;
666
+ return rest;
667
+ };
668
+ const meaningful = stripFunctional(newProfile);
669
+ const contentHash = crypto.createHash('sha256')
670
+ .update(JSON.stringify(meaningful))
671
+ .digest('hex');
672
+
673
+ if (prior?.contentHash === contentHash) {
674
+ state.brandProfile = {
675
+ ...prior,
676
+ ...newProfile,
677
+ contentHash: prior.contentHash,
678
+ version: prior.version,
679
+ updatedAt: prior.updatedAt,
680
+ };
681
+ return;
682
+ }
683
+
684
+ const version = (prior?.version || 0) + 1;
685
+ state.brandProfile = {
686
+ ...prior,
687
+ ...meaningful,
688
+ version,
689
+ contentHash,
690
+ updatedAt: new Date().toISOString(),
691
+ };
692
+ };
693
+
633
694
  self.enableImport = (type, config = {}) => {
634
695
  if (!IMPORT_TYPE_SCHEMAS[type]) {
635
696
  throw new Error(`Unknown import type: ${type}`);
@@ -691,6 +752,7 @@ Config.toDynamoItem = (config) => ({
691
752
  imports: config.getImports(),
692
753
  fetchConfig: config.getFetchConfig(),
693
754
  brandConfig: config.getBrandConfig(),
755
+ brandProfile: config.getBrandProfile(),
694
756
  cdnLogsConfig: config.getCdnLogsConfig(),
695
757
  llmo: config.getLlmoConfig(),
696
758
  tokowakaConfig: config.getTokowakaConfig(),
@@ -29,6 +29,7 @@ class Suggestion extends BaseModel {
29
29
  FIXED: 'FIXED',
30
30
  ERROR: 'ERROR',
31
31
  OUTDATED: 'OUTDATED',
32
+ PENDING_VALIDATION: 'PENDING_VALIDATION',
32
33
  };
33
34
 
34
35
  static TYPES = {
@@ -40,7 +41,7 @@ class Suggestion extends BaseModel {
40
41
  CONFIG_UPDATE: 'CONFIG_UPDATE',
41
42
  };
42
43
 
43
- // add your customized methods here
44
+ // add your customized method here
44
45
  }
45
46
 
46
47
  export default Suggestion;