@adobe/spacecat-shared-data-access 3.23.0 → 3.25.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 (29) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +2 -2
  3. package/src/models/access-grant-log/access-grant-log.collection.js +26 -0
  4. package/src/models/access-grant-log/access-grant-log.model.js +31 -0
  5. package/src/models/access-grant-log/access-grant-log.schema.js +62 -0
  6. package/src/models/access-grant-log/index.d.ts +37 -0
  7. package/src/models/access-grant-log/index.js +15 -0
  8. package/src/models/base/base.model.js +14 -0
  9. package/src/models/base/entity.registry.js +12 -0
  10. package/src/models/index.d.ts +2 -0
  11. package/src/models/index.js +4 -0
  12. package/src/models/sentiment-topic/index.d.ts +0 -9
  13. package/src/models/sentiment-topic/sentiment-topic.schema.js +0 -19
  14. package/src/models/site/site.schema.js +5 -0
  15. package/src/models/site-ims-org-access/index.d.ts +65 -0
  16. package/src/models/site-ims-org-access/index.js +15 -0
  17. package/src/models/site-ims-org-access/site-ims-org-access.collection.js +190 -0
  18. package/src/models/site-ims-org-access/site-ims-org-access.model.js +32 -0
  19. package/src/models/site-ims-org-access/site-ims-org-access.schema.js +63 -0
  20. package/src/models/suggestion-grant/index.d.ts +30 -0
  21. package/src/models/suggestion-grant/index.js +19 -0
  22. package/src/models/suggestion-grant/suggestion-grant.collection.js +177 -0
  23. package/src/models/suggestion-grant/suggestion-grant.model.js +26 -0
  24. package/src/models/suggestion-grant/suggestion-grant.schema.js +74 -0
  25. package/src/models/token/index.js +19 -0
  26. package/src/models/token/token.collection.js +71 -0
  27. package/src/models/token/token.model.js +36 -0
  28. package/src/models/token/token.schema.js +57 -0
  29. package/src/util/postgrest.utils.js +1 -0
@@ -0,0 +1,71 @@
1
+ /*
2
+ * Copyright 2025 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 { hasText, getTokenGrantConfig } from '@adobe/spacecat-shared-utils';
14
+
15
+ import BaseCollection from '../base/base.collection.js';
16
+ import DataAccessError from '../../errors/data-access.error.js';
17
+
18
+ /**
19
+ * TokenCollection - Manages Token entities (per-site, per-tokenType, per-cycle).
20
+ * Uses PostgREST table `tokens`.
21
+ *
22
+ * @class TokenCollection
23
+ * @extends BaseCollection
24
+ */
25
+ class TokenCollection extends BaseCollection {
26
+ static COLLECTION_NAME = 'TokenCollection';
27
+
28
+ /**
29
+ * Finds a Token for the current cycle by siteId and tokenType. The cycle is
30
+ * derived from the token-grant-config's cycleFormat. If no token exists for
31
+ * the current cycle and options.createIfNotFound is true, creates one. The
32
+ * token total is the minimum of options.total (if supplied) and the config
33
+ * tokensPerCycle, clamped to at least 1.
34
+ *
35
+ * @param {string} siteId - Site ID (UUID).
36
+ * @param {string} tokenType - Token type (e.g. grant_cwv,
37
+ * grant_broken_backlinks).
38
+ * @param {Object} [options={}] - Options.
39
+ * @param {boolean} [options.createIfNotFound=false] - If true, create a token when none exists.
40
+ * @param {number} [options.total] - Optional supplied total;
41
+ * actual total is min(options.total, config.tokensPerCycle), at least 1.
42
+ * @returns {Promise<import('./token.model.js').default|null>} Token instance
43
+ * (existing or newly created), or null when none exists and createIfNotFound is false.
44
+ */
45
+ async findBySiteIdAndTokenType(siteId, tokenType, options = {}) {
46
+ if (!hasText(siteId) || !hasText(tokenType)) {
47
+ throw new DataAccessError('TokenCollection.findBySiteIdAndTokenType: siteId and tokenType are required');
48
+ }
49
+ const config = getTokenGrantConfig(tokenType);
50
+ if (!config) {
51
+ throw new DataAccessError(`TokenCollection.findBySiteIdAndTokenType: no token grant config for tokenType: ${tokenType}`);
52
+ }
53
+ const { currentCycle: cycle } = config;
54
+ const existing = await this.findByIndexKeys({ siteId, tokenType, cycle }, { limit: 1 });
55
+ if (existing || options.createIfNotFound !== true) {
56
+ return existing || null;
57
+ }
58
+ const total = options.total != null
59
+ ? Math.max(1, Math.min(Number(options.total), config.tokensPerCycle))
60
+ : config.tokensPerCycle;
61
+ return this.create({
62
+ siteId,
63
+ tokenType,
64
+ cycle,
65
+ total,
66
+ used: 0,
67
+ });
68
+ }
69
+ }
70
+
71
+ export default TokenCollection;
@@ -0,0 +1,36 @@
1
+ /*
2
+ * Copyright 2025 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 BaseModel from '../base/base.model.js';
14
+
15
+ /**
16
+ * Token - Tracks token allocation and consumption per site, token type (opportunity type),
17
+ * and cycle. Used to enforce per-opportunity monthly (or cycle) limits for granted suggestions.
18
+ *
19
+ * @class Token
20
+ * @extends BaseModel
21
+ */
22
+ class Token extends BaseModel {
23
+ static ENTITY_NAME = 'Token';
24
+
25
+ /**
26
+ * Returns the number of tokens remaining in this cycle (total - used).
27
+ * @returns {number}
28
+ */
29
+ getRemaining() {
30
+ const total = this.getTotal();
31
+ const used = this.getUsed();
32
+ return Math.max(0, total - used);
33
+ }
34
+ }
35
+
36
+ export default Token;
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Copyright 2025 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 { isValidUUID } from '@adobe/spacecat-shared-utils';
14
+
15
+ import SchemaBuilder from '../base/schema.builder.js';
16
+ import Token from './token.model.js';
17
+ import TokenCollection from './token.collection.js';
18
+
19
+ /*
20
+ * Token entity: per-site, per-tokenType (opportunity type), per-cycle token allocation.
21
+ * Postgres table: tokens with primary key id, unique (site_id, token_type, cycle).
22
+ * Data access: findBySiteIdAndTokenType(siteId, tokenType).
23
+ * Consume: one token per grant_suggestions call (whole list of IDs)
24
+ * via SuggestionGrantCollection.grantSuggestions().
25
+ */
26
+
27
+ const schema = new SchemaBuilder(Token, TokenCollection)
28
+ .addIndex({ composite: ['siteId', 'tokenType'] }, { composite: ['cycle'] })
29
+ .addAttribute('siteId', {
30
+ type: 'string',
31
+ required: true,
32
+ readOnly: true,
33
+ validate: (value) => isValidUUID(value),
34
+ postgrestField: 'site_id',
35
+ })
36
+ .addAttribute('tokenType', {
37
+ type: 'string',
38
+ required: true,
39
+ postgrestField: 'token_type',
40
+ })
41
+ .addAttribute('cycle', {
42
+ type: 'string',
43
+ required: true,
44
+ readOnly: true,
45
+ })
46
+ .addAttribute('total', {
47
+ type: 'number',
48
+ required: true,
49
+ readOnly: true,
50
+ })
51
+ .addAttribute('used', {
52
+ type: 'number',
53
+ required: true,
54
+ default: 0,
55
+ });
56
+
57
+ export default schema.build();
@@ -16,6 +16,7 @@ const DEFAULT_PAGE_SIZE = 1000;
16
16
 
17
17
  const ENTITY_TABLE_OVERRIDES = {
18
18
  LatestAudit: 'audits',
19
+ SuggestionGrant: 'suggestion_grants',
19
20
  };
20
21
 
21
22
  const camelToSnake = (value) => value.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase();