@adobe/spacecat-shared-data-access 1.53.1 → 1.54.0

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,10 @@
1
+ # [@adobe/spacecat-shared-data-access-v1.54.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v1.53.1...@adobe/spacecat-shared-data-access-v1.54.0) (2024-11-20)
2
+
3
+
4
+ ### Features
5
+
6
+ * opportunity & suggestion model (+electrodb) ([#447](https://github.com/adobe/spacecat-shared/issues/447)) ([91cf931](https://github.com/adobe/spacecat-shared/commit/91cf931facbc7f13a6fe6eebe71f2948a4ec007e))
7
+
1
8
  # [@adobe/spacecat-shared-data-access-v1.53.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v1.53.0...@adobe/spacecat-shared-data-access-v1.53.1) (2024-11-16)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-data-access",
3
- "version": "1.53.1",
3
+ "version": "1.54.0",
4
4
  "description": "Shared modules of the Spacecat Services - Data Access",
5
5
  "type": "module",
6
6
  "engines": {
@@ -16,6 +16,7 @@
16
16
  "clean": "rm -rf package-lock.json node_modules"
17
17
  },
18
18
  "mocha": {
19
+ "require": "test/setup-env.js",
19
20
  "reporter": "mocha-multi-reporters",
20
21
  "reporter-options": "configFile=.mocha-multi.json"
21
22
  },
@@ -38,6 +39,8 @@
38
39
  "@aws-sdk/client-dynamodb": "3.693.0",
39
40
  "@aws-sdk/lib-dynamodb": "3.693.0",
40
41
  "@types/joi": "17.2.3",
42
+ "aws-xray-sdk": "3.10.2",
43
+ "electrodb": "3.0.1",
41
44
  "joi": "17.13.3",
42
45
  "uuid": "11.0.3"
43
46
  },
package/src/index.d.ts CHANGED
@@ -892,6 +892,10 @@ export interface DataAccess {
892
892
  getExperiments: (siteId: string, experimentId?: string) => Promise<Experiment[]>;
893
893
  getExperiment: (siteId: string, experimentId: string, url: string) => Promise<Experiment | null>;
894
894
  upsertExperiment: (experimentData: object) => Promise<Experiment>;
895
+
896
+ // electro-based entities
897
+ Opportunity: object,
898
+ Suggestion: object,
895
899
  }
896
900
 
897
901
  interface DataAccessConfig {
@@ -930,3 +934,5 @@ export function createDataAccess(
930
934
  config: DataAccessConfig,
931
935
  logger: object,
932
936
  ): DataAccess;
937
+
938
+ export type * from './v2/index.d.ts';
package/src/index.js CHANGED
@@ -14,6 +14,7 @@ import { createDataAccess } from './service/index.js';
14
14
 
15
15
  export { ImportJobStatus, ImportUrlStatus, ImportOptions } from './models/importer/import-constants.js';
16
16
 
17
+ const TABLE_NAME_DATA = 'spacecat-services-data-dev';
17
18
  const TABLE_NAME_AUDITS = 'spacecat-services-audits-dev';
18
19
  const TABLE_NAME_KEY_EVENTS = 'spacecat-services-key-events';
19
20
  const TABLE_NAME_LATEST_AUDITS = 'spacecat-services-latest-audits-dev';
@@ -52,6 +53,7 @@ export default function dataAccessWrapper(fn) {
52
53
  const { log } = context;
53
54
 
54
55
  const {
56
+ DYNAMO_TABLE_NAME_DATA = TABLE_NAME_DATA,
55
57
  DYNAMO_TABLE_NAME_AUDITS = TABLE_NAME_AUDITS,
56
58
  DYNAMO_TABLE_NAME_KEY_EVENTS = TABLE_NAME_KEY_EVENTS,
57
59
  DYNAMO_TABLE_NAME_LATEST_AUDITS = TABLE_NAME_LATEST_AUDITS,
@@ -82,6 +84,7 @@ export default function dataAccessWrapper(fn) {
82
84
  } = context.env;
83
85
 
84
86
  context.dataAccess = createDataAccess({
87
+ tableNameData: DYNAMO_TABLE_NAME_DATA,
85
88
  tableNameAudits: DYNAMO_TABLE_NAME_AUDITS,
86
89
  tableNameKeyEvents: DYNAMO_TABLE_NAME_KEY_EVENTS,
87
90
  tableNameLatestAudits: DYNAMO_TABLE_NAME_LATEST_AUDITS,
@@ -118,3 +121,5 @@ export default function dataAccessWrapper(fn) {
118
121
  return fn(request, context);
119
122
  };
120
123
  }
124
+
125
+ export * from './v2/index.js';
@@ -11,6 +11,17 @@
11
11
  */
12
12
 
13
13
  import { createClient } from '@adobe/spacecat-shared-dynamo';
14
+ import { DynamoDB } from '@aws-sdk/client-dynamodb';
15
+ import { DynamoDBDocument } from '@aws-sdk/lib-dynamodb';
16
+ import AWSXray from 'aws-xray-sdk';
17
+ import { Service } from 'electrodb';
18
+
19
+ import ModelFactory from '../v2/models/model.factory.js';
20
+ import OpportunityCollection from '../v2/models/opportunity.collection.js';
21
+ import SuggestionCollection from '../v2/models/suggestion.collection.js';
22
+ import OpportunitySchema from '../v2/schema/opportunity.schema.js';
23
+ import SuggestionSchema from '../v2/schema/suggestion.schema.js';
24
+
14
25
  import { auditFunctions } from './audits/index.js';
15
26
  import { keyEventFunctions } from './key-events/index.js';
16
27
  import { siteFunctions } from './sites/index.js';
@@ -23,6 +34,36 @@ import { importUrlFunctions } from './import-url/index.js';
23
34
  import { experimentFunctions } from './experiments/index.js';
24
35
  import { apiKeyFunctions } from './api-key/index.js';
25
36
 
37
+ const createRawClient = () => {
38
+ const dbClient = AWSXray.captureAWSv3Client(new DynamoDB());
39
+ return DynamoDBDocument.from(dbClient, {
40
+ marshallOptions: {
41
+ convertEmptyValues: true,
42
+ removeUndefinedValues: true,
43
+ },
44
+ });
45
+ };
46
+
47
+ const createElectroService = (client, config, log) => {
48
+ const { tableNameData: table } = config;
49
+ /* c8 ignore start */
50
+ const logger = (event) => {
51
+ log.debug(JSON.stringify(event, null, 4));
52
+ };
53
+ /* c8 ignore end */
54
+ return new Service(
55
+ {
56
+ opportunity: OpportunitySchema,
57
+ suggestion: SuggestionSchema,
58
+ },
59
+ {
60
+ client,
61
+ table,
62
+ logger,
63
+ },
64
+ );
65
+ };
66
+
26
67
  /**
27
68
  * Creates a data access object.
28
69
  *
@@ -51,6 +92,14 @@ export const createDataAccess = (config, log = console) => {
51
92
  const experimentFuncs = experimentFunctions(dynamoClient, config, log);
52
93
  const apiKeyFuncs = apiKeyFunctions(dynamoClient, config, log);
53
94
 
95
+ // electro-based data access objects
96
+ const rawClient = createRawClient();
97
+ const electroService = createElectroService(rawClient, config, log);
98
+ const modelFactory = new ModelFactory(electroService, log);
99
+
100
+ const Opportunity = modelFactory.getCollection(OpportunityCollection.name);
101
+ const Suggestion = modelFactory.getCollection(SuggestionCollection.name);
102
+
54
103
  return {
55
104
  ...auditFuncs,
56
105
  ...keyEventFuncs,
@@ -63,5 +112,8 @@ export const createDataAccess = (config, log = console) => {
63
112
  ...importUrlFuncs,
64
113
  ...experimentFuncs,
65
114
  ...apiKeyFuncs,
115
+ // electro-based data access objects
116
+ Opportunity,
117
+ Suggestion,
66
118
  };
67
119
  };
@@ -0,0 +1,13 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ export type ValidationError = Error
@@ -0,0 +1,15 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import ValidationError from './validation.error.js';
14
+
15
+ export { ValidationError };
@@ -0,0 +1,13 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ export default class ValidationError extends Error {}
@@ -0,0 +1,15 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ export type * from './errors/index.d.ts';
14
+ export type * from './models/index.d.ts';
15
+ export type * from './util/index.d.ts';
@@ -0,0 +1,15 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ export * from './errors/index.js';
14
+ export * from './models/index.js';
15
+ export * from './util/index.js';
@@ -0,0 +1,118 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { isNonEmptyObject } from '@adobe/spacecat-shared-utils';
14
+
15
+ import { guardId } from '../util/guards.js';
16
+
17
+ /**
18
+ * BaseCollection - A base class for managing collections of entities in the application.
19
+ * This class uses ElectroDB to interact with entities and provides common functionality
20
+ * for data operations.
21
+ *
22
+ * @class BaseCollection
23
+ */
24
+ class BaseCollection {
25
+ /**
26
+ * Constructs an instance of BaseCollection.
27
+ * @constructor
28
+ * @param {Object} electroService - The ElectroDB service used for managing entities.
29
+ * @param {Object} modelFactory - A factory for creating model instances.
30
+ * @param {Class} clazz - The model class that represents the entity.
31
+ * @param {Object} log - A logger for capturing logging information.
32
+ */
33
+ constructor(electroService, modelFactory, clazz, log) {
34
+ this.electroService = electroService;
35
+ this.modelFactory = modelFactory;
36
+ this.clazz = clazz;
37
+ this.entityName = this.clazz.name.toLowerCase();
38
+ this.entity = electroService.entities[this.entityName];
39
+ this.idName = `${this.entityName}Id`;
40
+ this.log = log;
41
+ }
42
+
43
+ /**
44
+ * Creates an instance of a model from a record.
45
+ * @protected
46
+ * @param {Object} record - The record containing data to create the model instance.
47
+ * @returns {BaseModel|null} - Returns an instance of the model class if the data is valid,
48
+ * otherwise null.
49
+ */
50
+ _createInstance(record) {
51
+ if (!isNonEmptyObject(record?.data)) {
52
+ this.log.warn(`Failed to create instance of [${this.entityName}]: record is empty`);
53
+ return null;
54
+ }
55
+ // eslint-disable-next-line new-cap
56
+ return new this.clazz(
57
+ this.electroService,
58
+ this.modelFactory,
59
+ record.data,
60
+ this.log,
61
+ );
62
+ }
63
+
64
+ /**
65
+ * Creates instances of models from a set of records.
66
+ * @protected
67
+ * @param {Object} records - The records containing data to create the model instances.
68
+ * @returns {Array<BaseModel>} - An array of instances of the model class.
69
+ */
70
+ _createInstances(records) {
71
+ if (!Array.isArray(records?.data)) {
72
+ this.log.warn(`Failed to create instances of [${this.entityName}]: records are empty`);
73
+ return [];
74
+ }
75
+ return records.data.map((record) => this._createInstance({ data: record }));
76
+ }
77
+
78
+ /**
79
+ * Finds an entity by its ID.
80
+ * @async
81
+ * @param {string} id - The unique identifier of the entity to be found.
82
+ * @returns {Promise<BaseModel|null>} - A promise that resolves to an instance of
83
+ * the model if found, otherwise null.
84
+ * @throws {Error} - Throws an error if the ID is not provided.
85
+ */
86
+ async findById(id) {
87
+ guardId(this.idName, id, this.entityName);
88
+
89
+ const record = await this.entity.get({ [this.idName]: id }).go();
90
+
91
+ return this._createInstance(record);
92
+ }
93
+
94
+ /**
95
+ * Creates a new entity in the collection.
96
+ * @async
97
+ * @param {Object} data - The data for the entity to be created.
98
+ * @returns {Promise<BaseModel>} - A promise that resolves to the created model instance.
99
+ * @throws {Error} - Throws an error if the data is invalid or if the creation process fails.
100
+ */
101
+ async create(data) {
102
+ if (!isNonEmptyObject(data)) {
103
+ this.log.error(`Failed to create [${this.entityName}]: data is required`);
104
+ throw new Error(`Failed to create [${this.entityName}]: data is required`);
105
+ }
106
+
107
+ try {
108
+ // todo: validate associations
109
+ const record = await this.entity.create(data).go();
110
+ return this._createInstance(record);
111
+ } catch (error) {
112
+ this.log.error(`Failed to create [${this.entityName}]`, error);
113
+ throw error;
114
+ }
115
+ }
116
+ }
117
+
118
+ export default BaseCollection;
@@ -0,0 +1,127 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import Patcher from '../util/patcher.js';
14
+
15
+ /**
16
+ * Base - A base class for representing individual entities in the application.
17
+ * Provides common functionality for entity management, including fetching, updating,
18
+ * and deleting records.
19
+ *
20
+ * @class BaseModel
21
+ */
22
+ class BaseModel {
23
+ /**
24
+ * Constructs an instance of BaseModel.
25
+ * @constructor
26
+ * @param {Object} electroService - The ElectroDB service used for managing entities.
27
+ * @param {Object} modelFactory - A factory for creating model instances.
28
+ * @param {Object} record - The initial data for the entity instance.
29
+ * @param {Object} log - A logger for capturing logging information.
30
+ */
31
+ constructor(electroService, modelFactory, record, log) {
32
+ this.modelFactory = modelFactory;
33
+ this.record = record;
34
+ this.entityName = this.constructor.name.toLowerCase();
35
+ this.entity = electroService.entities[this.entityName];
36
+ this.idName = `${this.entityName}Id`;
37
+ this.log = log;
38
+
39
+ this.patcher = new Patcher(this.entity, this.record);
40
+ this.associationsCache = {};
41
+ }
42
+
43
+ /**
44
+ * Gets the association of the model by querying another related model. Retrieved
45
+ * associations are cached to avoid redundant queries.
46
+ * @protected
47
+ * @async
48
+ * @param {string} modelName - The name of the related model.
49
+ * @param {string} method - The method to use for querying the related model.
50
+ * @param {...*} args - Additional arguments to be passed to the method.
51
+ * @returns {Promise<Object>} - A promise that resolves to the associated model instance.
52
+ */
53
+ async _getAssociation(modelName, method, ...args) {
54
+ const cache = this.associationsCache;
55
+
56
+ cache[modelName] = cache[modelName] || {};
57
+
58
+ if (!(method in cache[modelName])) {
59
+ cache[modelName][method] = await this.modelFactory.getCollection(modelName)[method](...args);
60
+ }
61
+
62
+ return cache[modelName][method];
63
+ }
64
+
65
+ /**
66
+ * Gets the ID of the current entity.
67
+ * @returns {string} - The unique identifier of the entity.
68
+ */
69
+ getId() {
70
+ return this.record[this.idName];
71
+ }
72
+
73
+ /**
74
+ * Gets the creation timestamp of the current entity.
75
+ * @returns {string} - The ISO string representing when the entity was created.
76
+ */
77
+ getCreatedAt() {
78
+ return new Date(this.record.createdAt).toISOString();
79
+ }
80
+
81
+ /**
82
+ * Gets the update timestamp of the current entity.
83
+ * @returns {string} - The ISO string representing when the entity was last updated.
84
+ */
85
+ getUpdatedAt() {
86
+ return new Date(this.record.updatedAt).toISOString();
87
+ }
88
+
89
+ /**
90
+ * Removes the current entity from the database.
91
+ * @async
92
+ * @returns {Promise<BaseModel>} - A promise that resolves to the current instance of the entity
93
+ * after it has been removed.
94
+ * @throws {Error} - Throws an error if the removal fails.
95
+ */
96
+ async remove() {
97
+ try {
98
+ // todo: remove dependents (child associations)
99
+ await this.entity.remove({ [this.idName]: this.getId() }).go();
100
+ return this;
101
+ } catch (error) {
102
+ this.log.error('Failed to remove record', error);
103
+ throw error;
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Saves the current entity to the database. This method must be called after making changes
109
+ * to the entity via their respective setter methods.
110
+ * @async
111
+ * @returns {Promise<BaseModel>} - A promise that resolves to the current instance of the entity
112
+ * after it has been saved.
113
+ * @throws {Error} - Throws an error if the save operation fails.
114
+ */
115
+ async save() {
116
+ // todo: validate associations
117
+ try {
118
+ await this.patcher.save();
119
+ return this;
120
+ } catch (error) {
121
+ this.log.error('Failed to save record', error);
122
+ throw error;
123
+ }
124
+ }
125
+ }
126
+
127
+ export default BaseModel;
@@ -0,0 +1,100 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ /**
14
+ * Interface representing a base model for interacting with a data entity.
15
+ */
16
+ export interface BaseModel {
17
+ getId(): string;
18
+ getCreatedAt(): string;
19
+ getUpdatedAt(): string;
20
+ remove(): Promise<this>;
21
+ save(): Promise<this>;
22
+ }
23
+
24
+ /**
25
+ * Interface representing an Opportunity model, extending BaseModel.
26
+ */
27
+ export interface Opportunity extends BaseModel {
28
+ // eslint-disable-next-line no-use-before-define
29
+ getSuggestions(): Promise<Suggestion[]>;
30
+ getSiteId(): string;
31
+ setSiteId(siteId: string): Opportunity;
32
+ getAuditId(): string;
33
+ setAuditId(auditId: string): Opportunity;
34
+ getRunbook(): string;
35
+ setRunbook(runbook: string): Opportunity;
36
+ getGuidance(): string;
37
+ setGuidance(guidance: string): Opportunity;
38
+ getTitle(): string;
39
+ setTitle(title: string): Opportunity;
40
+ getDescription(): string;
41
+ setDescription(description: string): Opportunity;
42
+ getType(): string;
43
+ getStatus(): string;
44
+ setStatus(status: string): Opportunity;
45
+ getOrigin(): string;
46
+ setOrigin(origin: string): Opportunity;
47
+ getTags(): string[];
48
+ setTags(tags: string[]): Opportunity;
49
+ getData(): object;
50
+ setData(data: object): Opportunity;
51
+ }
52
+
53
+ /**
54
+ * Interface representing a Suggestion model, extending BaseModel.
55
+ */
56
+ export interface Suggestion extends BaseModel {
57
+ getOpportunity(): Promise<Opportunity>;
58
+ getOpportunityId(): string;
59
+ setOpportunityId(opportunityId: string): Suggestion;
60
+ getType(): string;
61
+ getStatus(): string;
62
+ setStatus(status: string): Suggestion;
63
+ getRank(): number;
64
+ setRank(rank: number): Suggestion;
65
+ getData(): object;
66
+ setData(data: object): Suggestion;
67
+ getKpiDeltas(): object;
68
+ setKpiDeltas(kpiDeltas: object): Suggestion;
69
+ }
70
+
71
+ /**
72
+ * Interface representing a base collection for interacting with data entities.
73
+ */
74
+ export interface BaseCollection<T extends BaseModel> {
75
+ findById(id: string): Promise<T>;
76
+ create(data: object): Promise<T>;
77
+ }
78
+
79
+ /**
80
+ * Interface representing the Opportunity collection, extending BaseCollection.
81
+ */
82
+ export interface OpportunityCollection extends BaseCollection<Opportunity> {
83
+ allBySiteId(siteId: string): Promise<Opportunity[]>;
84
+ allBySiteIdAndStatus(siteId: string, status: string): Promise<Opportunity[]>;
85
+ }
86
+
87
+ /**
88
+ * Interface representing the Suggestion collection, extending BaseCollection.
89
+ */
90
+ export interface SuggestionCollection extends BaseCollection<Suggestion> {
91
+ allByOpportunityId(opportunityId: string): Promise<Suggestion[]>;
92
+ allByOpportunityIdAndStatus(opportunityId: string, status: string): Promise<Suggestion[]>;
93
+ }
94
+
95
+ /**
96
+ * Interface representing the Model Factory for creating and managing model collections.
97
+ */
98
+ export interface ModelFactory {
99
+ getCollection<T extends BaseModel>(collectionName: string): BaseCollection<T>;
100
+ }
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import ModelFactory from './model.factory.js';
14
+ import BaseModel from './base.model.js';
15
+ import Opportunity from './opportunity.model.js';
16
+ import OpportunityCollection from './opportunity.collection.js';
17
+ import Suggestion from './suggestion.model.js';
18
+ import SuggestionCollection from './suggestion.collection.js';
19
+
20
+ export {
21
+ ModelFactory,
22
+ BaseModel,
23
+ Opportunity,
24
+ OpportunityCollection,
25
+ Suggestion,
26
+ SuggestionCollection,
27
+ };