@adobe/spacecat-shared-athena-client 1.2.5 → 1.3.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-athena-client-v1.3.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-athena-client-v1.3.0...@adobe/spacecat-shared-athena-client-v1.3.1) (2025-09-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **deps:** update external fixes ([#920](https://github.com/adobe/spacecat-shared/issues/920)) ([1a6b1e1](https://github.com/adobe/spacecat-shared/commit/1a6b1e1ac9531a41c86406ada4bd4ab903307fdc))
7
+
8
+ # [@adobe/spacecat-shared-athena-client-v1.3.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-athena-client-v1.2.5...@adobe/spacecat-shared-athena-client-v1.3.0) (2025-08-20)
9
+
10
+
11
+ ### Features
12
+
13
+ * add query by month and other fixes ([#917](https://github.com/adobe/spacecat-shared/issues/917)) ([57e4144](https://github.com/adobe/spacecat-shared/commit/57e41443bfdcf9068251f6656e5c0cfcebf32d21))
14
+ * add threshold for pageviews ([#923](https://github.com/adobe/spacecat-shared/issues/923)) ([5b989cd](https://github.com/adobe/spacecat-shared/commit/5b989cd7c38ac946609143ed5402d2ff1600c581))
15
+
1
16
  # [@adobe/spacecat-shared-athena-client-v1.2.5](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-athena-client-v1.2.4...@adobe/spacecat-shared-athena-client-v1.2.5) (2025-08-09)
2
17
 
3
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-athena-client",
3
- "version": "1.2.5",
3
+ "version": "1.3.1",
4
4
  "description": "Shared modules of the Spacecat Services - AWS Athena Client",
5
5
  "type": "module",
6
6
  "engines": {
@@ -35,14 +35,14 @@
35
35
  "access": "public"
36
36
  },
37
37
  "dependencies": {
38
- "@aws-sdk/client-athena": "3.864.0",
39
- "@adobe/spacecat-shared-utils": "1.43.0"
38
+ "@aws-sdk/client-athena": "3.883.0",
39
+ "@adobe/spacecat-shared-utils": "1.48.0"
40
40
  },
41
41
  "devDependencies": {
42
- "chai": "5.2.1",
43
- "chai-as-promised": "8.0.1",
42
+ "chai": "5.3.3",
43
+ "chai-as-promised": "8.0.2",
44
44
  "sinon": "20.0.0",
45
- "sinon-chai": "4.0.0",
45
+ "sinon-chai": "4.0.1",
46
46
  "typescript": "5.9.2"
47
47
  }
48
48
  }
@@ -9,7 +9,7 @@
9
9
  * OF ANY KIND, either express or implied. See the License for the specific language
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
- import { getDateRanges } from '@adobe/spacecat-shared-utils';
12
+ import { getTemporalCondition } from '@adobe/spacecat-shared-utils';
13
13
  import { getTrafficAnalysisTemplate } from './traffic-analysis-template.js';
14
14
 
15
15
  /**
@@ -33,6 +33,7 @@ export function getTrafficAnalysisQueryPlaceholders() {
33
33
  'dimensionColumnsPrefixed',
34
34
  'groupBy',
35
35
  'pageTypeCase',
36
+ 'pageViewThreshold',
36
37
  'siteId',
37
38
  'tableName',
38
39
  'temporalCondition',
@@ -66,6 +67,7 @@ export function buildPageTypeCase(pageTypes, column) {
66
67
  *
67
68
  * @param {Object} params - Input parameters.
68
69
  * @param {number} params.week - The ISO week number (1–53).
70
+ * @param {number} params.month - Month number (1-12).
69
71
  * @param {number} params.year - The year (e.g. 2025).
70
72
  * @param {string} params.siteId - UUID of the site.
71
73
  * @param {string[]} [params.dimensions] - Dimensions to group by (e.g. ['utm_campaign', 'device']).
@@ -74,10 +76,12 @@ export function buildPageTypeCase(pageTypes, column) {
74
76
  * @param {Object|null} [params.pageTypes=null] - Optional pageType rules for CASE generation.
75
77
  * @param {string[]|null} [params.trfTypes] - Traffic type to filter by before
76
78
  * grouping (e.g ['paid']).
79
+ * @param {number} [params.pageViewThreshold=1000] - Minimum total pageviews for a path to include.
77
80
  * @returns {Object} Template values for SQL generation.
78
81
  */
79
82
  export function getTrafficAnalysisQueryPlaceholdersFilled({
80
83
  week,
84
+ month,
81
85
  year,
82
86
  siteId,
83
87
  dimensions,
@@ -85,9 +89,15 @@ export function getTrafficAnalysisQueryPlaceholdersFilled({
85
89
  pageTypes = null,
86
90
  pageTypeMatchColumn = 'path',
87
91
  trfTypes = null,
92
+ temporalCondition = null,
93
+ pageViewThreshold = 1000,
88
94
  }) {
89
- if (!week || !year || !siteId || !tableName) {
90
- throw new Error('Missing required parameters: week, year, siteId, or tableName');
95
+ if (!siteId || !tableName) {
96
+ throw new Error('Missing required parameters: siteId, or tableName');
97
+ }
98
+
99
+ if (!temporalCondition && ((!week && !month) || !year)) {
100
+ throw new Error('Missing required parameters: week, month or year');
91
101
  }
92
102
 
93
103
  if (!Array.isArray(dimensions) || dimensions.length === 0) {
@@ -97,10 +107,10 @@ export function getTrafficAnalysisQueryPlaceholdersFilled({
97
107
  const dimensionColumns = dimensions.join(', ');
98
108
  const dimensionColumnsPrefixed = dimensions.map((col) => `a.${col}`).join(', ');
99
109
 
100
- const dateRanges = getDateRanges(week, year);
101
- const temporalCondition = dateRanges
102
- .map((r) => `(year=${r.year} AND month=${r.month} AND week=${week})`)
103
- .join(' OR ');
110
+ let tempCondition = null;
111
+ if (!temporalCondition) {
112
+ tempCondition = getTemporalCondition({ week, month, year });
113
+ }
104
114
 
105
115
  let pageTypeCase = 'NULL as page_type';
106
116
  if (dimensions.includes('page_type') && pageTypes) {
@@ -119,8 +129,9 @@ export function getTrafficAnalysisQueryPlaceholdersFilled({
119
129
  dimensionColumns,
120
130
  dimensionColumnsPrefixed,
121
131
  tableName,
122
- temporalCondition,
132
+ temporalCondition: tempCondition,
123
133
  pageTypeCase,
124
134
  trfTypeCondition,
135
+ pageViewThreshold,
125
136
  };
126
137
  }
@@ -20,6 +20,7 @@
20
20
  * @param {string} params.groupBy - Group by clause
21
21
  * @param {string} params.dimensionColumnsPrefixed - Prefixed dimension columns
22
22
  * @param {string} params.pageTypeCase - Page type case statement
23
+ * @param {number} params.pageViewThreshold - Minimum total pageviews for path to include
23
24
  * @returns {string} The SQL query string
24
25
  */
25
26
  export function getTrafficAnalysisTemplate({
@@ -31,9 +32,21 @@ export function getTrafficAnalysisTemplate({
31
32
  groupBy,
32
33
  dimensionColumnsPrefixed,
33
34
  pageTypeCase,
35
+ pageViewThreshold,
34
36
  }) {
35
37
  return `
36
- WITH raw AS (
38
+ WITH min_totals AS (
39
+ SELECT
40
+ path AS min_key,
41
+ CAST(SUM(pageviews) AS BIGINT) AS total_pageviews
42
+ FROM ${tableName}
43
+ WHERE siteid = '${siteId}'
44
+ AND (${temporalCondition})
45
+ AND ${trfTypeCondition}
46
+ GROUP BY path
47
+ HAVING SUM(pageviews) >= ${pageViewThreshold}
48
+ ),
49
+ raw AS (
37
50
  SELECT
38
51
  path,
39
52
  ${pageTypeCase},
@@ -55,8 +68,9 @@ WITH raw AS (
55
68
  lcp,
56
69
  cls,
57
70
  inp
58
- FROM ${tableName}
59
- WHERE siteid = '${siteId}'
71
+ FROM ${tableName} m
72
+ JOIN min_totals t ON m.path = t.min_key
73
+ WHERE m.siteid = '${siteId}'
60
74
  AND (${temporalCondition})
61
75
  AND ${trfTypeCondition}
62
76
  ),
@@ -85,7 +99,7 @@ SELECT
85
99
  CAST(a.clicks AS DOUBLE) / NULLIF(a.row_count, 0) AS click_rate,
86
100
  CAST(a.engagements AS DOUBLE) / NULLIF(a.row_count, 0) AS engagement_rate,
87
101
  1 - CAST(a.engagements AS DOUBLE) / NULLIF(a.row_count, 0) AS bounce_rate,
88
- a.engaged_scroll,
102
+ CAST(a.engaged_scroll AS DOUBLE) / NULLIF(a.row_count, 0) AS engaged_scroll_rate,
89
103
  a.p70_scroll,
90
104
  a.p70_lcp,
91
105
  a.p70_cls,
@@ -28,7 +28,7 @@ export const TrafficDataResponseDto = {
28
28
  * click_rate: number,
29
29
  * engagement_rate: number,
30
30
  * bounce_rate: number,
31
- * engaged_scroll: number,
31
+ * engaged_scroll_rate: number,
32
32
  * p70_scroll: number,
33
33
  * }} JSON object.
34
34
  */
@@ -45,7 +45,7 @@ export const TrafficDataResponseDto = {
45
45
  click_rate: data.click_rate,
46
46
  engagement_rate: data.engagement_rate,
47
47
  bounce_rate: data.bounce_rate,
48
- engaged_scroll: data.engaged_scroll,
48
+ engaged_scroll_rate: data.engaged_scroll_rate,
49
49
  p70_scroll: data.p70_scroll,
50
50
  }),
51
51
  };