@@ -6,6 +6,53 @@ export async function getMetrics(
66 qx : QueryExecutor ,
77 segmentId ?: string ,
88) : Promise < IDashboardMetrics > {
9+ try {
10+ const [ snapshotData , projectsData ] = await Promise . all ( [
11+ getSnapshotMetrics ( qx , segmentId ) ,
12+ getProjectsCount ( qx , segmentId ) ,
13+ ] )
14+
15+ if ( ! snapshotData ) {
16+ // TODO: remove this mock once Tinybird sinks are available
17+ const mockMetrics = getMockMetrics ( )
18+ return {
19+ ...mockMetrics ,
20+ projectsTotal : projectsData . projectsTotal ,
21+ projectsLast30Days : projectsData . projectsLast30Days ,
22+ }
23+ }
24+
25+ return {
26+ ...snapshotData ,
27+ projectsTotal : projectsData . projectsTotal ,
28+ projectsLast30Days : projectsData . projectsLast30Days ,
29+ }
30+ } catch ( error : unknown ) {
31+ const msg = error instanceof Error ? error . message : ''
32+ const code = error && typeof error === 'object' && 'code' in error ? error . code : null
33+
34+ // Detect missing table
35+ const isMissingTable = code === '42P01' || / d o e s n o t e x i s t / i. test ( msg )
36+
37+ if ( isMissingTable ) {
38+ // TODO: remove this mock once Tinybird sinks are available
39+ const mockMetrics = getMockMetrics ( )
40+ const projectsData = await getProjectsCount ( qx , segmentId )
41+ return {
42+ ...mockMetrics ,
43+ projectsTotal : projectsData . projectsTotal ,
44+ projectsLast30Days : projectsData . projectsLast30Days ,
45+ }
46+ }
47+
48+ throw error
49+ }
50+ }
51+
52+ async function getSnapshotMetrics (
53+ qx : QueryExecutor ,
54+ segmentId ?: string ,
55+ ) : Promise < Omit < IDashboardMetrics , 'projectsTotal' | 'projectsLast30Days' > | null > {
956 const tableName = segmentId
1057 ? 'dashboardMetricsPerSegmentSnapshot'
1158 : 'dashboardMetricsTotalSnapshot'
@@ -31,29 +78,43 @@ export async function getMetrics(
3178 `
3279
3380 const params = segmentId ? { segmentId } : { }
81+ const [ row ] = await qx . select ( query , params )
3482
35- try {
36- const [ row ] = await qx . select ( query , params )
37-
38- if ( ! row ) {
39- // TODO: remove this mock once Tinybird sinks are available
40- return getMockMetrics ( )
41- }
42-
43- return row
44- } catch ( error : unknown ) {
45- const msg = error instanceof Error ? error . message : ''
46- const code = error && typeof error === 'object' && 'code' in error ? error . code : null
83+ return row || null
84+ }
4785
48- // Detect missing table
49- const isMissingTable = code === '42P01' || / d o e s n o t e x i s t / i. test ( msg )
86+ async function getProjectsCount (
87+ qx : QueryExecutor ,
88+ segmentId ?: string ,
89+ ) : Promise < { projectsTotal : number ; projectsLast30Days : number } > {
90+ let query : string
91+ let params : Record < string , any >
5092
51- if ( isMissingTable ) {
52- // TODO: remove this mock once Tinybird sinks are available
53- return getMockMetrics ( )
54- }
93+ if ( ! segmentId ) {
94+ // Count all segments
95+ query = `
96+ SELECT
97+ COUNT(*) as "projectsTotal",
98+ COUNT(CASE WHEN "createdAt" >= NOW() - INTERVAL '30 days' THEN 1 END) as "projectsLast30Days"
99+ FROM segments
100+ `
101+ params = { }
102+ } else {
103+ // Count segments where the provided segmentId is current, parent, or grandparent
104+ query = `
105+ SELECT
106+ COUNT(*) as "projectsTotal",
107+ COUNT(CASE WHEN s."createdAt" >= NOW() - INTERVAL '30 days' THEN 1 END) as "projectsLast30Days"
108+ FROM segments s
109+ WHERE (s.id = $(segmentId) OR s."parentId" = $(segmentId) OR s."grandparentId" = $(segmentId))
110+ `
111+ params = { segmentId }
112+ }
55113
56- throw error
114+ const [ result ] = await qx . select ( query , params )
115+ return {
116+ projectsTotal : parseInt ( result . projectsTotal ) || 0 ,
117+ projectsLast30Days : parseInt ( result . projectsLast30Days ) || 0 ,
57118 }
58119}
59120
0 commit comments