Skip to content

Commit 8176752

Browse files
committed
feat: add tinybird pipes for organization page
Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
1 parent 600ee6f commit 8176752

10 files changed

Lines changed: 534 additions & 0 deletions
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
DESCRIPTION >
2+
Precomputed organization-level KPIs for the org page. Rebuilt nightly by org_page_kpis_copy_pipe.
3+
One row per organizationId. Used by org_page_kpis.pipe for cheap request-time lookups.
4+
5+
SCHEMA >
6+
`organizationId` String,
7+
`activeContributors` UInt32,
8+
`activeContributorsPrevious` UInt32,
9+
`maintainerRoles` UInt32,
10+
`criticalProjects` UInt32,
11+
`computedAt` DateTime
12+
13+
ENGINE ReplacingMergeTree
14+
ENGINE_SORTING_KEY organizationId
15+
ENGINE_VER computedAt
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
DESCRIPTION >
2+
Precomputed per-org per-project metrics for the org page. Rebuilt nightly by org_page_projects_copy_pipe.
3+
One row per (organizationId, segmentId). Used by org_page_projects.pipe.
4+
5+
SCHEMA >
6+
`organizationId` String,
7+
`segmentId` String,
8+
`projectSlug` String,
9+
`projectName` String,
10+
`projectLogo` String,
11+
`activityCount` UInt64,
12+
`contributorCount` UInt32,
13+
`computedAt` DateTime
14+
15+
ENGINE ReplacingMergeTree
16+
ENGINE_SORTING_KEY organizationId, segmentId
17+
ENGINE_VER computedAt
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
DESCRIPTION >
2+
Activity timeseries for a given organization, bucketed by granularity.
3+
Filters to activities where the member belongs to the given org.
4+
5+
TAGS "Organization page"
6+
7+
NODE org_page_activities_bounds
8+
SQL >
9+
%
10+
SELECT min(timestamp) AS actual_start_date, max(timestamp) AS actual_end_date
11+
FROM activityRelations_deduplicated_cleaned_bucket_union
12+
WHERE
13+
organizationId = {{ String(orgId, '', description="Organization ID", required=True) }}
14+
{% if defined(startDate) %}
15+
AND timestamp >= {{ DateTime(startDate, description="Filter activity timestamp after") }}
16+
{% end %}
17+
{% if defined(endDate) %}
18+
AND timestamp < {{ DateTime(endDate, description="Filter activity timestamp before") }}
19+
{% end %}
20+
21+
NODE org_page_activities_timeseries_data
22+
SQL >
23+
%
24+
SELECT
25+
CASE
26+
WHEN {{ String(granularity, 'monthly') }} = 'daily'
27+
THEN toDate(addDays(bounds.actual_start_date, numbers.number))
28+
WHEN {{ String(granularity, 'monthly') }} = 'weekly'
29+
THEN toStartOfWeek(addDays(bounds.actual_start_date, numbers.number * 7))
30+
WHEN {{ String(granularity, 'monthly') }} = 'monthly'
31+
THEN toStartOfMonth(addMonths(bounds.actual_start_date, numbers.number))
32+
WHEN {{ String(granularity, 'monthly') }} = 'quarterly'
33+
THEN toStartOfQuarter(addMonths(bounds.actual_start_date, numbers.number * 3))
34+
WHEN {{ String(granularity, 'monthly') }} = 'yearly'
35+
THEN toStartOfYear(addYears(bounds.actual_start_date, numbers.number))
36+
END AS startDate,
37+
CASE
38+
WHEN {{ String(granularity, 'monthly') }} = 'daily'
39+
THEN toDate(addDays(bounds.actual_start_date, numbers.number))
40+
WHEN {{ String(granularity, 'monthly') }} = 'weekly'
41+
THEN
42+
toDate(
43+
toStartOfWeek(addDays(bounds.actual_start_date, numbers.number * 7))
44+
+ INTERVAL 6 DAY
45+
)
46+
WHEN {{ String(granularity, 'monthly') }} = 'monthly'
47+
THEN
48+
toDate(
49+
toStartOfMonth(addMonths(bounds.actual_start_date, numbers.number))
50+
+ INTERVAL 1 MONTH
51+
- INTERVAL 1 DAY
52+
)
53+
WHEN {{ String(granularity, 'monthly') }} = 'quarterly'
54+
THEN
55+
toDate(
56+
toStartOfQuarter(addMonths(bounds.actual_start_date, numbers.number * 3))
57+
+ INTERVAL 3 MONTH
58+
- INTERVAL 1 DAY
59+
)
60+
WHEN {{ String(granularity, 'monthly') }} = 'yearly'
61+
THEN
62+
toDate(
63+
toStartOfYear(addYears(bounds.actual_start_date, numbers.number))
64+
+ INTERVAL 1 YEAR
65+
- INTERVAL 1 DAY
66+
)
67+
END AS endDate,
68+
count() AS activityCount
69+
FROM numbers(1000) numbers
70+
CROSS JOIN
71+
(
72+
SELECT
73+
CASE
74+
WHEN {{ String(granularity, 'monthly') }} = 'weekly'
75+
THEN toStartOfWeek(actual_start_date)
76+
WHEN {{ String(granularity, 'monthly') }} = 'monthly'
77+
THEN toStartOfMonth(actual_start_date)
78+
WHEN {{ String(granularity, 'monthly') }} = 'quarterly'
79+
THEN toStartOfQuarter(actual_start_date)
80+
WHEN {{ String(granularity, 'monthly') }} = 'yearly'
81+
THEN toStartOfYear(actual_start_date)
82+
ELSE actual_start_date
83+
END AS actual_start_date,
84+
actual_end_date
85+
FROM org_page_activities_bounds
86+
) bounds
87+
LEFT JOIN
88+
activityRelations_deduplicated_cleaned_bucket_union af
89+
ON organizationId = {{ String(orgId, '') }}
90+
AND CASE
91+
WHEN {{ String(granularity, 'monthly') }} = 'daily'
92+
THEN toDate(af.timestamp)
93+
WHEN {{ String(granularity, 'monthly') }} = 'weekly'
94+
THEN toStartOfWeek(af.timestamp)
95+
WHEN {{ String(granularity, 'monthly') }} = 'monthly'
96+
THEN toStartOfMonth(af.timestamp)
97+
WHEN {{ String(granularity, 'monthly') }} = 'quarterly'
98+
THEN toStartOfQuarter(af.timestamp)
99+
WHEN {{ String(granularity, 'monthly') }} = 'yearly'
100+
THEN toStartOfYear(af.timestamp)
101+
END = CASE
102+
WHEN {{ String(granularity, 'monthly') }} = 'daily'
103+
THEN toDate(addDays(bounds.actual_start_date, numbers.number))
104+
WHEN {{ String(granularity, 'monthly') }} = 'weekly'
105+
THEN toStartOfWeek(addDays(bounds.actual_start_date, numbers.number * 7))
106+
WHEN {{ String(granularity, 'monthly') }} = 'monthly'
107+
THEN toStartOfMonth(addMonths(bounds.actual_start_date, numbers.number))
108+
WHEN {{ String(granularity, 'monthly') }} = 'quarterly'
109+
THEN toStartOfQuarter(addMonths(bounds.actual_start_date, numbers.number * 3))
110+
WHEN {{ String(granularity, 'monthly') }} = 'yearly'
111+
THEN toStartOfYear(addYears(bounds.actual_start_date, numbers.number))
112+
END
113+
WHERE startDate >= bounds.actual_start_date AND startDate < bounds.actual_end_date
114+
GROUP BY startDate, endDate
115+
ORDER BY startDate
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
DESCRIPTION >
2+
Top contributors for a given organization leaderboard.
3+
Returns members sorted by contribution count within the specified date range.
4+
5+
TAGS "Organization page"
6+
7+
NODE org_page_contributors_activity_aggregates
8+
SQL >
9+
%
10+
{% if Boolean(count, false) %}
11+
SELECT count(distinct memberId)
12+
FROM activityRelations_deduplicated_cleaned_bucket_union
13+
WHERE
14+
organizationId = {{ String(orgId, '', description="Organization ID", required=True) }}
15+
{% if defined(startDate) %}
16+
AND timestamp
17+
>= {{ DateTime(startDate, description="Filter activity timestamp after") }}
18+
{% end %}
19+
{% if defined(endDate) %}
20+
AND timestamp < {{ DateTime(endDate, description="Filter activity timestamp before") }}
21+
{% end %}
22+
{% else %}
23+
SELECT
24+
memberId,
25+
count() as "contributionCount",
26+
ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2) as "contributionPercentage"
27+
FROM activityRelations_deduplicated_cleaned_bucket_union
28+
WHERE
29+
organizationId = {{ String(orgId, '', description="Organization ID", required=True) }}
30+
{% if defined(startDate) %}
31+
AND timestamp
32+
>= {{ DateTime(startDate, description="Filter activity timestamp after") }}
33+
{% end %}
34+
{% if defined(endDate) %}
35+
AND timestamp < {{ DateTime(endDate, description="Filter activity timestamp before") }}
36+
{% end %}
37+
GROUP BY memberId
38+
ORDER BY contributionCount DESC, memberId DESC
39+
LIMIT {{ Int32(limit, 10) }}
40+
OFFSET {{ Int32(offset, 0) }}
41+
{% end %}
42+
43+
NODE org_page_contributors_leaderboard
44+
SQL >
45+
%
46+
{% if Boolean(count, false) %}
47+
SELECT count(distinct memberId) as count
48+
FROM activityRelations_deduplicated_cleaned_bucket_union
49+
WHERE
50+
organizationId = {{ String(orgId, '') }}
51+
{% if defined(startDate) %} AND timestamp >= {{ DateTime(startDate) }} {% end %}
52+
{% if defined(endDate) %} AND timestamp < {{ DateTime(endDate) }} {% end %}
53+
{% else %}
54+
SELECT
55+
m.id,
56+
m.avatar,
57+
m.displayName,
58+
m.githubHandleArray,
59+
agg.contributionCount,
60+
agg.contributionPercentage,
61+
mr.roles
62+
FROM members_sorted AS m ANY
63+
INNER JOIN org_page_contributors_activity_aggregates agg ON agg.memberId = m.id
64+
LEFT JOIN member_roles mr ON mr.memberId = m.id
65+
WHERE m.id IN (SELECT memberId FROM org_page_contributors_activity_aggregates)
66+
ORDER BY agg.contributionCount DESC
67+
{% end %}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
DESCRIPTION >
2+
Contributor count timeseries for a given organization, bucketed by granularity.
3+
Filters to activities where the member belongs to the given org.
4+
5+
TAGS "Organization page"
6+
7+
NODE org_page_contributors_bounds
8+
SQL >
9+
%
10+
SELECT min(timestamp) AS actual_start_date, max(timestamp) AS actual_end_date
11+
FROM activityRelations_deduplicated_cleaned_bucket_union
12+
WHERE
13+
organizationId = {{ String(orgId, '', description="Organization ID", required=True) }}
14+
{% if defined(startDate) %}
15+
AND timestamp >= {{ DateTime(startDate, description="Filter activity timestamp after") }}
16+
{% end %}
17+
{% if defined(endDate) %}
18+
AND timestamp < {{ DateTime(endDate, description="Filter activity timestamp before") }}
19+
{% end %}
20+
21+
NODE org_page_contributors_timeseries_data
22+
SQL >
23+
%
24+
SELECT
25+
CASE
26+
WHEN {{ String(granularity, 'monthly') }} = 'daily'
27+
THEN toDate(addDays(bounds.actual_start_date, numbers.number))
28+
WHEN {{ String(granularity, 'monthly') }} = 'weekly'
29+
THEN toStartOfWeek(addDays(bounds.actual_start_date, numbers.number * 7))
30+
WHEN {{ String(granularity, 'monthly') }} = 'monthly'
31+
THEN toStartOfMonth(addMonths(bounds.actual_start_date, numbers.number))
32+
WHEN {{ String(granularity, 'monthly') }} = 'quarterly'
33+
THEN toStartOfQuarter(addMonths(bounds.actual_start_date, numbers.number * 3))
34+
WHEN {{ String(granularity, 'monthly') }} = 'yearly'
35+
THEN toStartOfYear(addYears(bounds.actual_start_date, numbers.number))
36+
END AS startDate,
37+
CASE
38+
WHEN {{ String(granularity, 'monthly') }} = 'daily'
39+
THEN toDate(addDays(bounds.actual_start_date, numbers.number))
40+
WHEN {{ String(granularity, 'monthly') }} = 'weekly'
41+
THEN
42+
toDate(
43+
toStartOfWeek(addDays(bounds.actual_start_date, numbers.number * 7))
44+
+ INTERVAL 6 DAY
45+
)
46+
WHEN {{ String(granularity, 'monthly') }} = 'monthly'
47+
THEN
48+
toDate(
49+
toStartOfMonth(addMonths(bounds.actual_start_date, numbers.number))
50+
+ INTERVAL 1 MONTH
51+
- INTERVAL 1 DAY
52+
)
53+
WHEN {{ String(granularity, 'monthly') }} = 'quarterly'
54+
THEN
55+
toDate(
56+
toStartOfQuarter(addMonths(bounds.actual_start_date, numbers.number * 3))
57+
+ INTERVAL 3 MONTH
58+
- INTERVAL 1 DAY
59+
)
60+
WHEN {{ String(granularity, 'monthly') }} = 'yearly'
61+
THEN
62+
toDate(
63+
toStartOfYear(addYears(bounds.actual_start_date, numbers.number))
64+
+ INTERVAL 1 YEAR
65+
- INTERVAL 1 DAY
66+
)
67+
END AS endDate,
68+
uniqExact(af.memberId) AS contributorCount
69+
FROM numbers(1000) numbers
70+
CROSS JOIN
71+
(
72+
SELECT
73+
CASE
74+
WHEN {{ String(granularity, 'monthly') }} = 'weekly'
75+
THEN toStartOfWeek(actual_start_date)
76+
WHEN {{ String(granularity, 'monthly') }} = 'monthly'
77+
THEN toStartOfMonth(actual_start_date)
78+
WHEN {{ String(granularity, 'monthly') }} = 'quarterly'
79+
THEN toStartOfQuarter(actual_start_date)
80+
WHEN {{ String(granularity, 'monthly') }} = 'yearly'
81+
THEN toStartOfYear(actual_start_date)
82+
ELSE actual_start_date
83+
END AS actual_start_date,
84+
actual_end_date
85+
FROM org_page_contributors_bounds
86+
) bounds
87+
LEFT JOIN
88+
activityRelations_deduplicated_cleaned_bucket_union af
89+
ON organizationId = {{ String(orgId, '') }}
90+
AND CASE
91+
WHEN {{ String(granularity, 'monthly') }} = 'daily'
92+
THEN toDate(af.timestamp)
93+
WHEN {{ String(granularity, 'monthly') }} = 'weekly'
94+
THEN toStartOfWeek(af.timestamp)
95+
WHEN {{ String(granularity, 'monthly') }} = 'monthly'
96+
THEN toStartOfMonth(af.timestamp)
97+
WHEN {{ String(granularity, 'monthly') }} = 'quarterly'
98+
THEN toStartOfQuarter(af.timestamp)
99+
WHEN {{ String(granularity, 'monthly') }} = 'yearly'
100+
THEN toStartOfYear(af.timestamp)
101+
END = CASE
102+
WHEN {{ String(granularity, 'monthly') }} = 'daily'
103+
THEN toDate(addDays(bounds.actual_start_date, numbers.number))
104+
WHEN {{ String(granularity, 'monthly') }} = 'weekly'
105+
THEN toStartOfWeek(addDays(bounds.actual_start_date, numbers.number * 7))
106+
WHEN {{ String(granularity, 'monthly') }} = 'monthly'
107+
THEN toStartOfMonth(addMonths(bounds.actual_start_date, numbers.number))
108+
WHEN {{ String(granularity, 'monthly') }} = 'quarterly'
109+
THEN toStartOfQuarter(addMonths(bounds.actual_start_date, numbers.number * 3))
110+
WHEN {{ String(granularity, 'monthly') }} = 'yearly'
111+
THEN toStartOfYear(addYears(bounds.actual_start_date, numbers.number))
112+
END
113+
WHERE startDate >= bounds.actual_start_date AND startDate < bounds.actual_end_date
114+
GROUP BY startDate, endDate
115+
ORDER BY startDate
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
DESCRIPTION >
2+
Returns KPIs for a given organization from the precomputed org_page_kpis_copy_ds.
3+
Includes trend calculations comparing current to previous 365-day period.
4+
5+
TAGS "Organization page"
6+
7+
NODE org_page_kpis_main
8+
SQL >
9+
SELECT
10+
activeContributors,
11+
if(
12+
activeContributorsPrevious = 0, 0,
13+
round(
14+
(toInt64(activeContributors) - toInt64(activeContributorsPrevious))
15+
/ activeContributorsPrevious * 100,
16+
1
17+
)
18+
) AS activeContributorsTrend,
19+
toInt64(activeContributors) - toInt64(activeContributorsPrevious) AS activeContributorsTrendAbsolute,
20+
activeContributorsPrevious AS activeContributorsTrendPrevious,
21+
maintainerRoles,
22+
criticalProjects
23+
FROM org_page_kpis_copy_ds FINAL
24+
WHERE organizationId = {{ String(orgId, '', description="Organization ID", required=True) }}

0 commit comments

Comments
 (0)