@adobe/spacecat-shared-data-access 3.46.0 → 3.48.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +1 -3
  3. package/package.json +4 -4
  4. package/src/models/api-key/api-key.schema.js +0 -6
  5. package/src/models/audit/audit.schema.js +1 -7
  6. package/src/models/audit-url/audit-url.model.js +1 -1
  7. package/src/models/audit-url/audit-url.schema.js +0 -4
  8. package/src/models/base/entity.registry.js +2 -2
  9. package/src/models/base/index.d.ts +1 -1
  10. package/src/models/base/schema.builder.js +1 -3
  11. package/src/models/base/schema.js +3 -3
  12. package/src/models/configuration/configuration.collection.js +1 -1
  13. package/src/models/configuration/configuration.model.js +1 -1
  14. package/src/models/configuration/configuration.schema.js +1 -1
  15. package/src/models/consumer/consumer.schema.js +0 -6
  16. package/src/models/entitlement/entitlement.model.js +1 -0
  17. package/src/models/entitlement/entitlement.schema.js +0 -6
  18. package/src/models/entitlement/index.d.ts +1 -1
  19. package/src/models/experiment/experiment.schema.js +0 -6
  20. package/src/models/fix-entity/fix-entity.schema.js +0 -6
  21. package/src/models/fix-entity-suggestion/fix-entity-suggestion.schema.js +0 -6
  22. package/src/models/geo-experiment/geo-experiment.collection.js +22 -0
  23. package/src/models/geo-experiment/geo-experiment.model.js +37 -3
  24. package/src/models/geo-experiment/geo-experiment.schema.js +2 -1
  25. package/src/models/geo-experiment/index.d.ts +1 -0
  26. package/src/models/import-job/import-job.schema.js +0 -6
  27. package/src/models/import-url/import-url.schema.js +0 -6
  28. package/src/models/key-event/key-event.schema.js +0 -6
  29. package/src/models/latest-audit/latest-audit.schema.js +1 -7
  30. package/src/models/opportunity/opportunity.schema.js +0 -6
  31. package/src/models/organization/organization.schema.js +0 -6
  32. package/src/models/page-citability/page-citability.schema.js +0 -6
  33. package/src/models/page-intent/README.md +1 -1
  34. package/src/models/page-intent/page-intent.schema.js +0 -6
  35. package/src/models/plg-onboarding/index.d.ts +14 -1
  36. package/src/models/plg-onboarding/plg-onboarding.model.js +6 -0
  37. package/src/models/plg-onboarding/plg-onboarding.schema.js +19 -6
  38. package/src/models/project/project.schema.js +0 -6
  39. package/src/models/report/report.schema.js +0 -6
  40. package/src/models/scrape-job/scrape-job.schema.js +0 -6
  41. package/src/models/scrape-url/scrape-url.schema.js +0 -6
  42. package/src/models/sentiment-guideline/sentiment-guideline.schema.js +0 -4
  43. package/src/models/sentiment-topic/sentiment-topic.schema.js +0 -4
  44. package/src/models/site/site.schema.js +0 -6
  45. package/src/models/site-candidate/site-candidate.schema.js +0 -6
  46. package/src/models/site-enrollment/site-enrollment.schema.js +0 -6
  47. package/src/models/site-top-form/site-top-form.schema.js +0 -6
  48. package/src/models/site-top-page/site-top-page.schema.js +0 -6
  49. package/src/models/suggestion/suggestion.schema.js +0 -6
  50. package/src/models/trial-user/trial-user.schema.js +0 -6
  51. package/src/models/trial-user-activity/trial-user-activity.schema.js +0 -6
  52. package/migration.sh +0 -137
  53. package/src/readme.md +0 -463
package/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ ## [@adobe/spacecat-shared-data-access-v3.48.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v3.47.0...@adobe/spacecat-shared-data-access-v3.48.0) (2026-04-08)
2
+
3
+ ### Features
4
+
5
+ * **data-access:** add INACTIVE status, reviews field, and REVIEW_DECISIONS to PlgOnboarding ([#1516](https://github.com/adobe/spacecat-shared/issues/1516)) ([8f038e9](https://github.com/adobe/spacecat-shared/commit/8f038e93287da51acf0e586f3e786aeb00d4a0d3))
6
+
7
+ ## [@adobe/spacecat-shared-data-access-v3.47.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v3.46.0...@adobe/spacecat-shared-data-access-v3.47.0) (2026-04-07)
8
+
9
+ ### Features
10
+
11
+ * add PRE_ONBOARD tier to entitlement model ([#1514](https://github.com/adobe/spacecat-shared/issues/1514)) ([bc4e8f3](https://github.com/adobe/spacecat-shared/commit/bc4e8f36549ab1fe6a03d39d7dec6b4b1f67d229))
12
+
13
+ ### Bug Fixes
14
+
15
+ * **data-access:** remove stale ElectroDB/DynamoDB v2 references ([#1509](https://github.com/adobe/spacecat-shared/issues/1509)) ([ddd180f](https://github.com/adobe/spacecat-shared/commit/ddd180fb5350a14a04583f7c55f89873ed3a3929))
16
+ * update geo experiment schema for experimentation engine ([#1512](https://github.com/adobe/spacecat-shared/issues/1512)) ([58315cd](https://github.com/adobe/spacecat-shared/commit/58315cd973c373b399429bf11ff1b958d3cfe9c8))
17
+
1
18
  ## [@adobe/spacecat-shared-data-access-v3.46.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v3.45.2...@adobe/spacecat-shared-data-access-v3.46.0) (2026-04-07)
2
19
 
3
20
  ### Features
package/README.md CHANGED
@@ -1,11 +1,9 @@
1
- # Spacecat Shared Data Access (v3)
1
+ # Spacecat Shared Data Access
2
2
 
3
3
  `@adobe/spacecat-shared-data-access` is the shared data-access layer used by Spacecat services.
4
4
 
5
- This package is **v3 Postgres-first**:
6
5
  - Primary datastore: **Postgres via PostgREST** (`@supabase/postgrest-js`)
7
6
  - Optional secondary datastore: **S3** (for `Configuration`)
8
- - No ElectroDB/DynamoDB runtime dependency in v3 behavior
9
7
 
10
8
  ## Installation
11
9
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-data-access",
3
- "version": "3.46.0",
3
+ "version": "3.48.0",
4
4
  "description": "Shared modules of the Spacecat Services - Data Access",
5
5
  "type": "module",
6
6
  "engines": {
@@ -10,9 +10,9 @@
10
10
  "main": "src/index.js",
11
11
  "types": "src/index.d.ts",
12
12
  "scripts": {
13
- "test:it": "npm run test:it:legacy && npm run test:it:postgrest",
14
- "test:it:legacy": "IT_SEED_MODE=none mocha --require ./test/it/fixtures.js --spec \"test/it/**/*.test.js\" --ignore \"test/it/postgrest/**/*.test.js\"",
15
- "test:it:postgrest": "IT_SEED_MODE=tenant-sql mocha --require ./test/it/fixtures.js --spec \"test/it/postgrest/**/*.test.js\"",
13
+ "test:it": "npm run test:it:self-seeded && npm run test:it:tenant-seeded",
14
+ "test:it:self-seeded": "IT_SEED_MODE=none mocha --require ./test/it/fixtures.js --spec \"test/it/**/*.test.js\" --ignore \"test/it/postgrest/**/*.test.js\"",
15
+ "test:it:tenant-seeded": "IT_SEED_MODE=tenant-sql mocha --require ./test/it/fixtures.js --spec \"test/it/postgrest/**/*.test.js\"",
16
16
  "test": "c8 mocha --spec \"test/unit/**/*.test.js\"",
17
17
  "test:debug": "mocha --inspect-brk --require ./test/setup-env.js --spec \"test/unit/**/*.test.js\"",
18
18
  "test:debug:config": "mocha --inspect-brk --require ./test/setup-env.js --spec \"test/unit/models/site/config.test.js\"",
@@ -18,12 +18,6 @@ import SchemaBuilder from '../base/schema.builder.js';
18
18
  import ApiKey from './api-key.model.js';
19
19
  import ApiKeyCollection from './api-key.collection.js';
20
20
 
21
- /*
22
- Schema Doc: https://electrodb.dev/en/modeling/schema/
23
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
24
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
25
- */
26
-
27
21
  const schema = new SchemaBuilder(ApiKey, ApiKeyCollection)
28
22
  .addAttribute('hashedApiKey', {
29
23
  type: 'string',
@@ -18,12 +18,6 @@ import SchemaBuilder from '../base/schema.builder.js';
18
18
  import Audit from './audit.model.js';
19
19
  import AuditCollection from './audit.collection.js';
20
20
 
21
- /*
22
- Schema Doc: https://electrodb.dev/en/modeling/schema/
23
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
24
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
25
- */
26
-
27
21
  const schema = new SchemaBuilder(Audit, AuditCollection)
28
22
  .addReference('belongs_to', 'Site', ['auditType', 'auditedAt'])
29
23
  .addReference('has_one', 'LatestAudit', ['auditType'], { required: false })
@@ -35,7 +29,7 @@ const schema = new SchemaBuilder(Audit, AuditCollection)
35
29
  required: true,
36
30
  validate: (value) => isNonEmptyObject(value) || isArray(value),
37
31
  set: (value, attributes) => {
38
- // as the electroDb validate function does not provide access to the model instance
32
+ // as the validate function does not provide access to the model instance
39
33
  // we need to call the validate function from the model on setting the value
40
34
  Audit.validateAuditResult(value, attributes.auditType);
41
35
  return value;
@@ -79,7 +79,7 @@ class AuditUrl extends BaseModel {
79
79
 
80
80
  /**
81
81
  * Generates the composite keys for the AuditUrl model.
82
- * Required for ElectroDB operations with composite primary key (siteId + url).
82
+ * Required for operations with composite primary key (siteId + url).
83
83
  * @returns {Object} - The composite keys.
84
84
  */
85
85
  generateCompositeKeys() {
@@ -19,10 +19,6 @@ import AuditUrl from './audit-url.model.js';
19
19
  import AuditUrlCollection from './audit-url.collection.js';
20
20
 
21
21
  /*
22
- Schema Doc: https://electrodb.dev/en/modeling/schema/
23
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
24
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
25
-
26
22
  Data Access Patterns:
27
23
  1. Get all URLs for a site: allBySiteId(siteId)
28
24
  2. Get all URLs for a site by byCustomer: allBySiteIdAndByCustomer(siteId, byCustomer) - uses GSI
@@ -172,7 +172,7 @@ class EntityRegistry {
172
172
 
173
173
  static getEntities() {
174
174
  return Object.keys(this.entities).reduce((acc, key) => {
175
- acc[key] = this.entities[key].schema.toElectroDBSchema();
175
+ acc[key] = this.entities[key].schema.toSchema();
176
176
  return acc;
177
177
  }, {});
178
178
  }
@@ -186,7 +186,7 @@ class EntityRegistry {
186
186
  }
187
187
  }
188
188
 
189
- // Register ElectroDB-based entities only (Configuration is handled separately)
189
+ // Register entities (Configuration is handled separately via S3)
190
190
  EntityRegistry.registerEntity(ApiKeySchema, ApiKeyCollection);
191
191
  EntityRegistry.registerEntity(AsyncJobSchema, AsyncJobCollection);
192
192
  EntityRegistry.registerEntity(ContactSalesLeadSchema, ContactSalesLeadCollection);
@@ -121,7 +121,7 @@ export interface Schema {
121
121
  getServiceName(): string;
122
122
  getVersion(): number;
123
123
  toAccessorConfigs(): object[];
124
- toElectroDBSchema(): object;
124
+ toSchema(): object;
125
125
  }
126
126
 
127
127
  export interface SchemaBuilder {
@@ -39,9 +39,7 @@ const ID_ATTRIBUTE_DATA = {
39
39
  postgrestField: 'id',
40
40
  required: true,
41
41
  readOnly: true,
42
- // https://electrodb.dev/en/modeling/attributes/#default
43
42
  default: () => crypto.randomUUID(),
44
- // https://electrodb.dev/en/modeling/attributes/#attribute-validation
45
43
  validate: (value) => isValidUUID(value),
46
44
  };
47
45
 
@@ -141,7 +139,7 @@ class SchemaBuilder {
141
139
  // will be populated by build() from rawIndexes
142
140
  this.indexes = {};
143
141
 
144
- // this is not part of the ElectroDB schema spec, but we use it to store reference data
142
+ // this is not part of the standard schema spec, but we use it to store reference data
145
143
  this.references = [];
146
144
 
147
145
  this.#initialize();
@@ -365,12 +365,12 @@ class Schema {
365
365
  }
366
366
 
367
367
  /**
368
- * Transforms the stored schema model into a format directly usable by ElectroDB.
368
+ * Transforms the stored schema model into a serializable format.
369
369
  * Here, you could do any final adjustments or transformations needed before returning.
370
370
  *
371
- * @returns {object} ElectroDB-compatible schema.
371
+ * @returns {object} Serialized schema.
372
372
  */
373
- toElectroDBSchema() {
373
+ toSchema() {
374
374
  return {
375
375
  model: {
376
376
  entity: this.getModelName(),
@@ -24,7 +24,7 @@ const S3_CONFIG_KEY = 'config/spacecat/global-config.json';
24
24
 
25
25
  /**
26
26
  * ConfigurationCollection - A standalone collection class for managing Configuration entities.
27
- * Unlike other collections, this does not use ElectroDB or DynamoDB.
27
+ * Unlike other collections, this uses S3 instead of PostgREST.
28
28
  * Configuration is stored as a versioned JSON object in S3.
29
29
  *
30
30
  * @class ConfigurationCollection
@@ -18,7 +18,7 @@ import { Entitlement } from '../entitlement/index.js';
18
18
  /**
19
19
  * Configuration - A standalone class representing the global Configuration entity.
20
20
  * This is a singleton entity stored in S3 with versioning.
21
- * Unlike other entities, Configuration does not use ElectroDB or DynamoDB.
21
+ * Unlike other entities, Configuration uses S3 instead of PostgREST.
22
22
  *
23
23
  * @class Configuration
24
24
  */
@@ -13,7 +13,7 @@
13
13
  /**
14
14
  * Configuration Schema
15
15
  *
16
- * Unlike other entities, Configuration does not use ElectroDB and is stored in S3.
16
+ * Unlike other entities, Configuration is stored in S3 instead of PostgREST.
17
17
  * Validation is handled by Joi schemas defined below.
18
18
  */
19
19
 
@@ -16,12 +16,6 @@ import SchemaBuilder from '../base/schema.builder.js';
16
16
  import Consumer from './consumer.model.js';
17
17
  import ConsumerCollection from './consumer.collection.js';
18
18
 
19
- /*
20
- Schema Doc: https://electrodb.dev/en/modeling/schema/
21
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
22
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
23
- */
24
-
25
19
  const schema = new SchemaBuilder(Consumer, ConsumerCollection)
26
20
  .addAttribute('clientId', {
27
21
  type: 'string',
@@ -26,6 +26,7 @@ class Entitlement extends BaseModel {
26
26
  FREE_TRIAL: 'FREE_TRIAL',
27
27
  PAID: 'PAID',
28
28
  PLG: 'PLG',
29
+ PRE_ONBOARD: 'PRE_ONBOARD',
29
30
  };
30
31
 
31
32
  static PRODUCT_CODES = {
@@ -14,12 +14,6 @@ import SchemaBuilder from '../base/schema.builder.js';
14
14
  import Entitlement from './entitlement.model.js';
15
15
  import EntitlementCollection from './entitlement.collection.js';
16
16
 
17
- /*
18
- Schema Doc: https://electrodb.dev/en/modeling/schema/
19
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
20
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
21
- */
22
-
23
17
  const schema = new SchemaBuilder(Entitlement, EntitlementCollection)
24
18
  // Reference to Organization (many-to-one relationship)
25
19
  .addReference('belongs_to', 'Organization')
@@ -15,7 +15,7 @@ import type {
15
15
  } from '../index';
16
16
 
17
17
  export type EntitlementStatus = 'ACTIVE' | 'SUSPENDED' | 'ENDED';
18
- export type EntitlementTier = 'FREE_TRIAL' | 'PAID' | 'PLG';
18
+ export type EntitlementTier = 'FREE_TRIAL' | 'PAID' | 'PLG' | 'PRE_ONBOARD';
19
19
  export type EntitlementProductCode = 'LLMO' | 'ASO' | 'ACO';
20
20
 
21
21
  export interface Entitlement extends BaseModel {
@@ -20,12 +20,6 @@ import SchemaBuilder from '../base/schema.builder.js';
20
20
  import Experiment from './experiment.model.js';
21
21
  import ExperimentCollection from './experiment.collection.js';
22
22
 
23
- /*
24
- Schema Doc: https://electrodb.dev/en/modeling/schema/
25
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
26
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
27
- */
28
-
29
23
  const schema = new SchemaBuilder(Experiment, ExperimentCollection)
30
24
  .addReference('belongs_to', 'Site', ['expId', 'url', 'updatedAt'])
31
25
  .addAttribute('conversionEventName', {
@@ -17,12 +17,6 @@ import FixEntity from './fix-entity.model.js';
17
17
  import FixEntityCollection from './fix-entity.collection.js';
18
18
  import Suggestion from '../suggestion/suggestion.model.js';
19
19
 
20
- /*
21
- Schema Doc: https://electrodb.dev/en/modeling/schema/
22
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
23
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
24
- */
25
-
26
20
  const schema = new SchemaBuilder(FixEntity, FixEntityCollection)
27
21
  .addReference('has_many', 'FixEntitySuggestion', ['updatedAt'], { removeDependents: true })
28
22
  .addReference('belongs_to', 'Opportunity', ['status'])
@@ -14,12 +14,6 @@ import SchemaBuilder from '../base/schema.builder.js';
14
14
  import FixEntitySuggestion from './fix-entity-suggestion.model.js';
15
15
  import FixEntitySuggestionCollection from './fix-entity-suggestion.collection.js';
16
16
 
17
- /*
18
- Schema Doc: https://electrodb.dev/en/modeling/schema/
19
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
20
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
21
- */
22
-
23
17
  const schema = new SchemaBuilder(FixEntitySuggestion, FixEntitySuggestionCollection)
24
18
  .withPrimaryPartitionKeys(['suggestionId'])
25
19
  .withPrimarySortKeys(['fixEntityId'])
@@ -12,6 +12,7 @@
12
12
 
13
13
  import { hasText } from '@adobe/spacecat-shared-utils';
14
14
  import BaseCollection from '../base/base.collection.js';
15
+ import GeoExperiment from './geo-experiment.model.js';
15
16
 
16
17
  class GeoExperimentCollection extends BaseCollection {
17
18
  static COLLECTION_NAME = 'GeoExperimentCollection';
@@ -38,6 +39,27 @@ class GeoExperimentCollection extends BaseCollection {
38
39
  cursor: result.cursor,
39
40
  };
40
41
  }
42
+
43
+ /**
44
+ * Gets all geo experiments that are currently active (GENERATING_BASELINE or IN_PROGRESS).
45
+ * Used by the experimentation engine to discover which experiments to process on each cron tick.
46
+ *
47
+ * @param {object} [options={}] - Query options (limit, cursor, order).
48
+ * @returns {Promise<GeoExperiment[]>} Array of active experiments.
49
+ */
50
+ async allActive(options = {}) {
51
+ const activeStatuses = [
52
+ GeoExperiment.STATUSES.GENERATING_BASELINE,
53
+ GeoExperiment.STATUSES.IN_PROGRESS,
54
+ ];
55
+ return this.all(
56
+ {},
57
+ {
58
+ ...options,
59
+ where: (attrs, op) => op.in(attrs.status, activeStatuses),
60
+ },
61
+ );
62
+ }
41
63
  }
42
64
 
43
65
  export default GeoExperimentCollection;
@@ -29,13 +29,47 @@ class GeoExperiment extends BaseModel {
29
29
  };
30
30
 
31
31
  static PHASES = {
32
- PRE_ANALYSIS_SUBMITTED: 'pre_analysis_submitted',
32
+ PRE_ANALYSIS_STARTED: 'pre_analysis_started',
33
33
  PRE_ANALYSIS_DONE: 'pre_analysis_done',
34
34
  DEPLOYMENT_STARTED: 'deployment_started',
35
- DEPLOYMENT_COMPLETED: 'deployment_completed',
36
- POST_ANALYSIS_SUBMITTED: 'post_analysis_submitted',
35
+ DEPLOYMENT_DONE: 'deployment_done',
36
+ POST_ANALYSIS_STARTED: 'post_analysis_started',
37
37
  POST_ANALYSIS_DONE: 'post_analysis_done',
38
38
  };
39
+
40
+ /**
41
+ * Name of the environment variable that holds per-strategy schedule configuration.
42
+ * The value is a JSON string keyed by strategy type, each with 'pre' and 'post' phase configs.
43
+ * Both the API service (writes config into experiment metadata) and the experimentation engine
44
+ * (reads config from metadata) reference this constant so the name stays in sync.
45
+ *
46
+ * @type {string}
47
+ */
48
+ static SCHEDULE_CONFIG_ENV_VAR = 'EXPERIMENT_SCHEDULE_CONFIG';
49
+
50
+ /**
51
+ * Well-known keys used within a GeoExperiment's metadata object.
52
+ * Centralised here so all consumers reference the same key names.
53
+ *
54
+ * @type {{ SCHEDULE_CONFIG: string }}
55
+ */
56
+ static METADATA_KEYS = {
57
+ SCHEDULE_CONFIG: 'scheduleConfig',
58
+ };
59
+
60
+ /**
61
+ * Field names within a schedule config block (pre or post phase).
62
+ * Both the API service (writes) and the experimentation engine (reads) import
63
+ * these so a rename in one place propagates automatically to the other.
64
+ *
65
+ * @type {{ CRON_EXPRESSION: string, EXPIRY_MS: string, PLATFORMS: string, PROVIDER_IDS: string }}
66
+ */
67
+ static SCHEDULE_CONFIG_KEYS = {
68
+ CRON_EXPRESSION: 'cronExpression',
69
+ EXPIRY_MS: 'expiryMs',
70
+ PLATFORMS: 'platforms',
71
+ PROVIDER_IDS: 'providerIds',
72
+ };
39
73
  }
40
74
 
41
75
  export default GeoExperiment;
@@ -43,8 +43,9 @@ const schema = new SchemaBuilder(GeoExperiment, GeoExperimentCollection)
43
43
  required: true,
44
44
  })
45
45
  .addAttribute('phase', {
46
- type: Object.values(GeoExperiment.PHASES),
46
+ type: 'string',
47
47
  required: true,
48
+ validate: (value) => hasText(value),
48
49
  })
49
50
  .addAttribute('suggestionIds', {
50
51
  type: 'list',
@@ -68,4 +68,5 @@ export interface GeoExperimentCollection extends BaseCollection<GeoExperiment> {
68
68
  opportunityId: string,
69
69
  options?: QueryOptions,
70
70
  ): Promise<GeoExperiment | null>;
71
+ allActive(options?: QueryOptions): Promise<GeoExperiment[]>;
71
72
  }
@@ -72,12 +72,6 @@ const validateOptions = (options) => {
72
72
  return true;
73
73
  };
74
74
 
75
- /*
76
- Schema Doc: https://electrodb.dev/en/modeling/schema/
77
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
78
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
79
- */
80
-
81
75
  const schema = new SchemaBuilder(ImportJob, ImportJobCollection)
82
76
  .addReference('has_many', 'ImportUrls')
83
77
  .addAttribute('baseURL', {
@@ -19,12 +19,6 @@ import ImportUrl from './import-url.model.js';
19
19
  import ImportUrlCollection from './import-url.collection.js';
20
20
  import { ImportJob } from '../import-job/index.js';
21
21
 
22
- /*
23
- Schema Doc: https://electrodb.dev/en/modeling/schema/
24
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
25
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
26
- */
27
-
28
22
  const schema = new SchemaBuilder(ImportUrl, ImportUrlCollection)
29
23
  .withRecordExpiry(ImportUrl.IMPORT_URL_EXPIRES_IN_DAYS)
30
24
  .addReference('belongs_to', 'ImportJob', ['status'])
@@ -18,12 +18,6 @@ import SchemaBuilder from '../base/schema.builder.js';
18
18
  import KeyEvent from './key-event.model.js';
19
19
  import KeyEventCollection from './key-event.collection.js';
20
20
 
21
- /*
22
- Schema Doc: https://electrodb.dev/en/modeling/schema/
23
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
24
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
25
- */
26
-
27
21
  const schema = new SchemaBuilder(KeyEvent, KeyEventCollection)
28
22
  .addReference('belongs_to', 'Site', ['time'])
29
23
  .addAttribute('name', {
@@ -19,12 +19,6 @@ import SchemaBuilder from '../base/schema.builder.js';
19
19
  import LatestAudit from './latest-audit.model.js';
20
20
  import LatestAuditCollection from './latest-audit.collection.js';
21
21
 
22
- /*
23
- Schema Doc: https://electrodb.dev/en/modeling/schema/
24
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
25
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
26
- */
27
-
28
22
  const schema = new SchemaBuilder(LatestAudit, LatestAuditCollection)
29
23
  .withPrimaryPartitionKeys(['siteId'])
30
24
  .withPrimarySortKeys(['auditType'])
@@ -39,7 +33,7 @@ const schema = new SchemaBuilder(LatestAudit, LatestAuditCollection)
39
33
  required: true,
40
34
  validate: (value) => isNonEmptyObject(value) || isArray(value),
41
35
  set: (value, attributes) => {
42
- // as the electroDb validate function does not provide access to the model instance
36
+ // as the validate function does not provide access to the model instance
43
37
  // we need to call the validate function from the model on setting the value
44
38
  Audit.validateAuditResult(value, attributes.auditType);
45
39
  return value;
@@ -18,12 +18,6 @@ import SchemaBuilder from '../base/schema.builder.js';
18
18
  import Opportunity from './opportunity.model.js';
19
19
  import OpportunityCollection from './opportunity.collection.js';
20
20
 
21
- /*
22
- Schema Doc: https://electrodb.dev/en/modeling/schema/
23
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
24
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
25
- */
26
-
27
21
  const schema = new SchemaBuilder(Opportunity, OpportunityCollection)
28
22
  .addReference('belongs_to', 'Site', ['status', 'updatedAt'])
29
23
  .addReference('belongs_to', 'Audit', ['updatedAt'], { required: false })
@@ -19,12 +19,6 @@ import SchemaBuilder from '../base/schema.builder.js';
19
19
  import Organization from './organization.model.js';
20
20
  import OrganizationCollection from './organization.collection.js';
21
21
 
22
- /*
23
- Schema Doc: https://electrodb.dev/en/modeling/schema/
24
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
25
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
26
- */
27
-
28
22
  const schema = new SchemaBuilder(Organization, OrganizationCollection)
29
23
  // this will add an attribute 'organizationId' as well as an index 'byOrganizationId'
30
24
  .addReference('has_many', 'Sites')
@@ -16,12 +16,6 @@ import SchemaBuilder from '../base/schema.builder.js';
16
16
  import PageCitability from './page-citability.model.js';
17
17
  import PageCitabilityCollection from './page-citability.collection.js';
18
18
 
19
- /*
20
- Schema: https://electrodb.dev/en/modeling/schema/
21
- Attributes: https://electrodb.dev/en/modeling/attributes/
22
- Indexes: https://electrodb.dev/en/modeling/indexes/
23
- */
24
-
25
19
  const schema = new SchemaBuilder(PageCitability, PageCitabilityCollection)
26
20
  // link back to Site entity
27
21
  .addReference('belongs_to', 'Site')
@@ -25,7 +25,7 @@ The `PageIntent` entity persists each page’s metadata. Key attributes include:
25
25
  - `TRANSACTIONAL`
26
26
  - `COMMERCIAL`
27
27
  - **`topic`** (string) – arbitrary topic label for the page.
28
- - **`createdAt`, `updatedAt`** (ISO timestamp) – automatically maintained by ElectroDB.
28
+ - **`createdAt`, `updatedAt`** (ISO timestamp) – automatically maintained by the framework.
29
29
 
30
30
  ## Best Practices
31
31
 
@@ -16,12 +16,6 @@ import SchemaBuilder from '../base/schema.builder.js';
16
16
  import PageIntent from './page-intent.model.js';
17
17
  import PageIntentCollection from './page-intent.collection.js';
18
18
 
19
- /*
20
- Schema: https://electrodb.dev/en/modeling/schema/
21
- Attributes: https://electrodb.dev/en/modeling/attributes/
22
- Indexes: https://electrodb.dev/en/modeling/indexes/
23
- */
24
-
25
19
  const schema = new SchemaBuilder(PageIntent, PageIntentCollection)
26
20
  // link back to Site entity
27
21
  .addReference('belongs_to', 'Site')
@@ -18,7 +18,18 @@ export type PlgOnboardingStatus =
18
18
  | 'ONBOARDED'
19
19
  | 'ERROR'
20
20
  | 'WAITING_FOR_IP_ALLOWLISTING'
21
- | 'WAITLISTED';
21
+ | 'WAITLISTED'
22
+ | 'INACTIVE';
23
+
24
+ export type PlgOnboardingReviewDecision = 'BYPASSED' | 'UPHELD';
25
+
26
+ export interface PlgOnboardingReview {
27
+ reason: string;
28
+ decision: PlgOnboardingReviewDecision;
29
+ reviewedBy: string;
30
+ reviewedAt: string;
31
+ justification: string;
32
+ }
22
33
 
23
34
  export interface PlgOnboarding extends BaseModel {
24
35
  getImsOrgId(): string;
@@ -31,6 +42,7 @@ export interface PlgOnboarding extends BaseModel {
31
42
  getError(): object | null;
32
43
  getBotBlocker(): object | null;
33
44
  getWaitlistReason(): string | null;
45
+ getReviews(): PlgOnboardingReview[] | null;
34
46
  getCompletedAt(): string | null;
35
47
  setStatus(status: PlgOnboardingStatus): PlgOnboarding;
36
48
  setSiteId(siteId: string): PlgOnboarding;
@@ -39,6 +51,7 @@ export interface PlgOnboarding extends BaseModel {
39
51
  setError(error: object): PlgOnboarding;
40
52
  setBotBlocker(botBlocker: object): PlgOnboarding;
41
53
  setWaitlistReason(waitlistReason: string): PlgOnboarding;
54
+ setReviews(reviews: PlgOnboardingReview[]): PlgOnboarding;
42
55
  setCompletedAt(completedAt: string): PlgOnboarding;
43
56
  }
44
57
 
@@ -33,6 +33,12 @@ class PlgOnboarding extends BaseModel {
33
33
  ERROR: 'ERROR',
34
34
  WAITING_FOR_IP_ALLOWLISTING: 'WAITING_FOR_IP_ALLOWLISTING',
35
35
  WAITLISTED: 'WAITLISTED',
36
+ INACTIVE: 'INACTIVE',
37
+ };
38
+
39
+ static REVIEW_DECISIONS = {
40
+ BYPASSED: 'BYPASSED',
41
+ UPHELD: 'UPHELD',
36
42
  };
37
43
  }
38
44
 
@@ -17,12 +17,6 @@ import SchemaBuilder from '../base/schema.builder.js';
17
17
  import PlgOnboarding from './plg-onboarding.model.js';
18
18
  import PlgOnboardingCollection from './plg-onboarding.collection.js';
19
19
 
20
- /*
21
- Schema Doc: https://electrodb.dev/en/modeling/schema/
22
- Attribute Doc: https://electrodb.dev/en/modeling/attributes/
23
- Indexes Doc: https://electrodb.dev/en/modeling/indexes/
24
- */
25
-
26
20
  const schema = new SchemaBuilder(PlgOnboarding, PlgOnboardingCollection)
27
21
  .addAttribute('imsOrgId', {
28
22
  type: 'string',
@@ -86,6 +80,25 @@ const schema = new SchemaBuilder(PlgOnboarding, PlgOnboardingCollection)
86
80
  type: 'string',
87
81
  required: false,
88
82
  })
83
+ .addAttribute('reviews', {
84
+ type: 'list',
85
+ required: false,
86
+ items: {
87
+ type: 'map',
88
+ properties: {
89
+ reason: { type: 'string' },
90
+ decision: { type: 'string' },
91
+ reviewedBy: { type: 'string' },
92
+ reviewedAt: { type: 'string' },
93
+ justification: { type: 'string' },
94
+ },
95
+ },
96
+ validate: (value) => {
97
+ if (!Array.isArray(value)) return false;
98
+ const valid = Object.values(PlgOnboarding.REVIEW_DECISIONS);
99
+ return value.every((r) => valid.includes(r.decision) && isIsoDate(r.reviewedAt));
100
+ },
101
+ })
89
102
  .addAttribute('completedAt', {
90
103
  type: 'string',
91
104
  validate: (value) => !value || isIsoDate(value),