Skip to content

Commit 5b4e5fb

Browse files
authored
Updated tinybird config to use site_uuid setting (#23886)
ref https://linear.app/ghost/issue/PROD-197/ghost-site-uuid-implementation Currently traffic analytics uses the configured value from `tinybird:stats:id` for the `site_uuid` when querying Tinybird. Now that we have a `site_uuid` settings key persisted in the database, we should switch to using this value as the source of truth, rather than passing it via config. This change switches to using the `site_uuid` setting if the value isn't provided via config, which allows us to override the `site_uuid` to e.g. that of a staging site with real data for local testing. Once we make it easier to generate fake data for local development, we should remove this logic, and strictly use the `site_uuid` in the settings table. Until then, this allows us to switch over to using the `site_uuid` in production, while still allowing overrides for local development.
1 parent 4e4ad66 commit 5b4e5fb

File tree

6 files changed

+48
-13
lines changed

6 files changed

+48
-13
lines changed

ghost/core/core/server/data/tinybird/readme.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ Sample config:
1515
"tracker": {
1616
"endpoint": "https://e.ghost.org/tb/web_analytics",
1717
"token": "xxxxx",
18-
"id": "local-ghost",
1918
"datasource": "analytics_events",
2019
"local": {
2120
"enabled": true,
@@ -27,7 +26,6 @@ Sample config:
2726
"stats": {
2827
"endpoint": "https://api.tinybird.co",
2928
"token": "xxxxx",
30-
"id": "local-ghost",
3129
"local": {
3230
"enabled": true,
3331
"token": "xxxxx",

ghost/core/core/server/services/public-config/config.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const {isPlainObject} = require('lodash');
22
const config = require('../../../shared/config');
3+
const settingsCache = require('../../../shared/settings-cache');
34
const labs = require('../../../shared/labs');
45
const databaseInfo = require('../../data/db/info');
56
const ghostVersion = require('@tryghost/version');
@@ -26,7 +27,12 @@ module.exports = function getConfigProperties() {
2627

2728
// WIP tinybird stats feature - it's entirely config driven instead of using an alpha flag for now
2829
if (config.get('tinybird') && config.get('tinybird:stats')) {
29-
configProperties.stats = config.get('tinybird:stats');
30+
const statsConfig = config.get('tinybird:stats');
31+
const siteUuid = statsConfig.id || settingsCache.get('site_uuid');
32+
configProperties.stats = {
33+
...statsConfig,
34+
id: siteUuid
35+
};
3036
}
3137

3238
return configProperties;

ghost/core/core/server/services/stats/StatsService.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,14 @@ class StatsService {
227227
let tinybirdClient = null;
228228
const config = deps.config || require('../../../shared/config');
229229
const request = deps.request || require('../../lib/request-external');
230+
const settingsCache = deps.settingsCache || require('../../../shared/settings-cache');
230231

231232
// Only create the client if Tinybird is configured
232233
if (config.get('tinybird') && config.get('tinybird:stats')) {
233234
tinybirdClient = tinybird.create({
234235
config,
235-
request
236+
request,
237+
settingsCache
236238
});
237239
}
238240

ghost/core/core/server/services/stats/utils/tinybird.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ const logging = require('@tryghost/logging');
55
* @param {object} deps - Configuration and request dependencies
66
* @param {object} deps.config - Ghost configuration
77
* @param {object} deps.request - HTTP request client
8+
* @param {object} deps.settingsCache - Settings cache client
89
* @returns {Object} Tinybird client with methods
910
*/
10-
const create = ({config, request}) => {
11+
const create = ({config, request, settingsCache}) => {
1112
/**
1213
* Builds a Tinybird API request
1314
* @param {string} pipeName - The name of the Tinybird pipe to query
@@ -22,6 +23,10 @@ const create = ({config, request}) => {
2223
*/
2324
const buildRequest = (pipeName, options = {}) => {
2425
const statsConfig = config.get('tinybird:stats');
26+
// Use tinybird:stats:id if provided, otherwise use site_uuid from settings cache
27+
// Allows overriding site_uuid via config
28+
// This is temporary until we have a proper way to use mock data locally
29+
const siteUuid = statsConfig.id || settingsCache.get('site_uuid');
2530
const localEnabled = statsConfig?.local?.enabled ?? false;
2631
const endpoint = localEnabled ? statsConfig.local.endpoint : statsConfig.endpoint;
2732
const token = localEnabled ? statsConfig.local.token : statsConfig.token;
@@ -35,7 +40,7 @@ const create = ({config, request}) => {
3540

3641
// Use snake_case for query parameters as expected by Tinybird API
3742
const searchParams = {
38-
site_uuid: statsConfig.id
43+
site_uuid: siteUuid
3944
};
4045

4146
// todo: refactor all uses to simply pass options through

ghost/core/test/unit/server/services/public-config/config.test.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const assert = require('assert/strict');
22
const configUtils = require('../../../../utils/configUtils');
3+
const settingsCache = require('../../../../../core/shared/settings-cache');
34
const getConfigProperties = require('../../../../../core/server/services/public-config/config');
5+
const sinon = require('sinon');
46

57
// List of allowed keys to be returned by the public-config service
68
// This is kind of a duplicate of the keys in the config.js output serializer in the api-framework
@@ -27,8 +29,14 @@ const allowedKeys = [
2729

2830
describe('Public-config Service', function () {
2931
describe('Config Properties', function () {
32+
beforeEach(async function () {
33+
sinon.stub(settingsCache, 'get')
34+
.withArgs('site_uuid')
35+
.returns('931ade9e-a4f1-4217-8625-34bd34250c16');
36+
});
3037
afterEach(async function () {
3138
await configUtils.restore();
39+
sinon.restore();
3240
});
3341

3442
it('should return the correct default config properties', function () {
@@ -84,7 +92,19 @@ describe('Public-config Service', function () {
8492

8593
let configProperties = getConfigProperties();
8694

87-
assert.deepEqual(configProperties.stats, {endpoint: 'xxx'});
95+
assert.deepEqual(configProperties.stats, {endpoint: 'xxx', id: '931ade9e-a4f1-4217-8625-34bd34250c16'});
96+
});
97+
98+
it('should return stats id when tinybird config is set with the id key', function () {
99+
configUtils.set('tinybird', {
100+
stats: {
101+
id: '1234567890'
102+
}
103+
});
104+
105+
let configProperties = getConfigProperties();
106+
107+
assert.deepEqual(configProperties.stats.id, '1234567890');
88108
});
89109

90110
it('should NOT return stats when tinybird config is set without the stats key', function () {

ghost/core/test/unit/server/services/stats/utils/tinybird.test.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ describe('Tinybird Client', function () {
66
let tinybirdClient;
77
let mockConfig;
88
let mockRequest;
9+
let mockSettingsCache;
910

1011
beforeEach(function () {
1112
// Set up mocks
@@ -17,18 +18,23 @@ describe('Tinybird Client', function () {
1718
get: sinon.stub()
1819
};
1920

21+
mockSettingsCache = {
22+
get: sinon.stub()
23+
};
24+
2025
// Configure mocks
2126
mockConfig.get.withArgs('timezone').returns('UTC');
2227
mockConfig.get.withArgs('tinybird:stats').returns({
23-
id: 'site-id',
2428
endpoint: 'https://api.tinybird.co',
2529
token: 'tb-token'
2630
});
31+
mockSettingsCache.get.withArgs('site_uuid').returns('931ade9e-a4f1-4217-8625-34bd34250c16');
2732

2833
// Create tinybird client with mocked dependencies
2934
tinybirdClient = tinybird.create({
3035
config: mockConfig,
31-
request: mockRequest
36+
request: mockRequest,
37+
settingsCache: mockSettingsCache
3238
});
3339
});
3440

@@ -45,7 +51,7 @@ describe('Tinybird Client', function () {
4551

4652
should.exist(url);
4753
url.should.startWith('https://api.tinybird.co/v0/pipes/test_pipe.json?');
48-
url.should.containEql('site_uuid=site-id');
54+
url.should.containEql('site_uuid=931ade9e-a4f1-4217-8625-34bd34250c16');
4955
url.should.containEql('date_from=2023-01-01');
5056
url.should.containEql('date_to=2023-01-31');
5157
// url.should.containEql('timezone=UTC');
@@ -74,15 +80,14 @@ describe('Tinybird Client', function () {
7480
memberStatus: 'paid'
7581
});
7682

77-
url.should.containEql('site_uuid=site-id');
83+
url.should.containEql('site_uuid=931ade9e-a4f1-4217-8625-34bd34250c16');
7884
url.should.containEql('timezone=America%2FNew_York');
7985
url.should.containEql('member_status=paid');
8086
});
8187

8288
it('uses local endpoint and token when local is enabled', function () {
8389
// Update config mock to return local config
8490
mockConfig.get.withArgs('tinybird:stats').returns({
85-
id: 'site-id',
8691
endpoint: 'https://api.tinybird.co',
8792
token: 'tb-token',
8893
local: {
@@ -101,7 +106,6 @@ describe('Tinybird Client', function () {
101106
it('ignores tbVersion when local is enabled', function () {
102107
// Update config mock to return local config
103108
mockConfig.get.withArgs('tinybird:stats').returns({
104-
id: 'site-id',
105109
endpoint: 'https://api.tinybird.co',
106110
token: 'tb-token',
107111
local: {

0 commit comments

Comments
 (0)