2024-03-20 00:37:31 +00:00
|
|
|
import { timeUnitForRange, whenRange } from '@/lib/time'
|
2023-11-09 00:15:36 +00:00
|
|
|
|
|
|
|
export function withClause (range) {
|
|
|
|
const unit = timeUnitForRange(range)
|
2022-12-01 21:31:04 +00:00
|
|
|
|
|
|
|
return `
|
|
|
|
WITH range_values AS (
|
2023-11-09 00:15:36 +00:00
|
|
|
SELECT date_trunc('${unit}', $1) as minval,
|
2023-11-13 23:15:43 +00:00
|
|
|
date_trunc('${unit}', $2) as maxval
|
|
|
|
),
|
2022-12-01 21:31:04 +00:00
|
|
|
times AS (
|
|
|
|
SELECT generate_series(minval, maxval, interval '1 ${unit}') as time
|
|
|
|
FROM range_values
|
|
|
|
)
|
|
|
|
`
|
|
|
|
}
|
|
|
|
|
2023-11-09 00:15:36 +00:00
|
|
|
export function intervalClause (range, table) {
|
|
|
|
const unit = timeUnitForRange(range)
|
2022-12-01 23:14:16 +00:00
|
|
|
|
2023-11-13 23:15:43 +00:00
|
|
|
return `date_trunc('${unit}', "${table}".created_at) >= date_trunc('${unit}', $1) AND date_trunc('${unit}', "${table}".created_at) <= date_trunc('${unit}', $2) `
|
2022-12-01 23:14:16 +00:00
|
|
|
}
|
|
|
|
|
2023-11-09 00:15:36 +00:00
|
|
|
export function viewIntervalClause (range, view) {
|
2024-01-19 21:19:26 +00:00
|
|
|
const unit = timeUnitForRange(range)
|
|
|
|
return `"${view}".t >= date_trunc('${unit}', timezone('America/Chicago', $1)) AND date_trunc('${unit}', "${view}".t) <= date_trunc('${unit}', timezone('America/Chicago', $2)) `
|
|
|
|
}
|
|
|
|
|
|
|
|
export function viewGroup (range, view) {
|
|
|
|
const unit = timeUnitForRange(range)
|
|
|
|
return `(
|
|
|
|
(SELECT *
|
|
|
|
FROM ${view}_days
|
|
|
|
WHERE ${viewIntervalClause(range, `${view}_days`)})
|
|
|
|
UNION ALL
|
|
|
|
(SELECT *
|
|
|
|
FROM ${view}_hours
|
|
|
|
WHERE ${viewIntervalClause(range, `${view}_hours`)}
|
|
|
|
${unit === 'hour' ? '' : `AND "${view}_hours".t >= date_trunc('day', timezone('America/Chicago', now()))`})
|
|
|
|
UNION ALL
|
|
|
|
(SELECT * FROM
|
|
|
|
${view}(
|
|
|
|
date_trunc('hour', timezone('America/Chicago', now())),
|
|
|
|
date_trunc('hour', timezone('America/Chicago', now())), '1 hour'::INTERVAL, 'hour')
|
2024-03-01 16:28:55 +00:00
|
|
|
WHERE "${view}".t >= date_trunc('${unit}', timezone('America/Chicago', $1))
|
|
|
|
AND "${view}".t <= date_trunc('${unit}', timezone('America/Chicago', $2)))
|
2024-01-19 21:19:26 +00:00
|
|
|
) u`
|
2023-05-18 23:41:56 +00:00
|
|
|
}
|
|
|
|
|
2024-02-14 20:27:00 +00:00
|
|
|
export function subViewGroup (range) {
|
|
|
|
const unit = timeUnitForRange(range)
|
|
|
|
return `(
|
|
|
|
(SELECT *
|
|
|
|
FROM sub_stats_days
|
|
|
|
WHERE ${viewIntervalClause(range, 'sub_stats_days')})
|
|
|
|
UNION ALL
|
|
|
|
(SELECT *
|
|
|
|
FROM sub_stats_hours
|
|
|
|
WHERE ${viewIntervalClause(range, 'sub_stats_hours')}
|
|
|
|
${unit === 'hour' ? '' : 'AND "sub_stats_hours".t >= date_trunc(\'day\', timezone(\'America/Chicago\', now()))'})
|
|
|
|
UNION ALL
|
|
|
|
(SELECT * FROM
|
|
|
|
sub_stats(
|
|
|
|
date_trunc('hour', timezone('America/Chicago', now())),
|
|
|
|
date_trunc('hour', timezone('America/Chicago', now())), '1 hour'::INTERVAL, 'hour')
|
|
|
|
WHERE "sub_stats".t >= date_trunc('${unit}', timezone('America/Chicago', $1)))
|
|
|
|
)`
|
|
|
|
}
|
|
|
|
|
2022-06-10 19:20:33 +00:00
|
|
|
export default {
|
|
|
|
Query: {
|
2023-11-09 00:15:36 +00:00
|
|
|
registrationGrowth: async (parent, { when, from, to }, { models }) => {
|
|
|
|
const range = whenRange(when, from, to)
|
|
|
|
|
2024-01-19 21:19:26 +00:00
|
|
|
return await models.$queryRawUnsafe(`
|
|
|
|
SELECT date_trunc('${timeUnitForRange(range)}', t) at time zone 'America/Chicago' as time, json_build_array(
|
|
|
|
json_build_object('name', 'referrals', 'value', sum(referrals)),
|
|
|
|
json_build_object('name', 'organic', 'value', sum(organic))
|
2022-12-01 21:31:04 +00:00
|
|
|
) AS data
|
2024-01-19 21:19:26 +00:00
|
|
|
FROM ${viewGroup(range, 'reg_growth')}
|
2022-06-10 19:20:33 +00:00
|
|
|
GROUP BY time
|
2023-11-09 00:15:36 +00:00
|
|
|
ORDER BY time ASC`, ...range)
|
2022-06-10 19:20:33 +00:00
|
|
|
},
|
2023-11-09 00:15:36 +00:00
|
|
|
spenderGrowth: async (parent, { when, to, from }, { models }) => {
|
|
|
|
const range = whenRange(when, from, to)
|
|
|
|
|
2024-01-19 21:19:26 +00:00
|
|
|
return await models.$queryRawUnsafe(`
|
|
|
|
SELECT date_trunc('${timeUnitForRange(range)}', t) at time zone 'America/Chicago' as time, json_build_array(
|
|
|
|
json_build_object('name', 'any', 'value', COUNT(DISTINCT "userId")),
|
|
|
|
json_build_object('name', 'jobs', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'STREAM')),
|
|
|
|
json_build_object('name', 'boost', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'BOOST')),
|
|
|
|
json_build_object('name', 'fees', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'FEE')),
|
|
|
|
json_build_object('name', 'poll', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'POLL')),
|
|
|
|
json_build_object('name', 'downzaps', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'DONT_LIKE_THIS')),
|
|
|
|
json_build_object('name', 'zaps', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'TIP')),
|
|
|
|
json_build_object('name', 'donation', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'DONATION')),
|
|
|
|
json_build_object('name', 'territories', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'TERRITORY'))
|
2022-12-01 21:31:04 +00:00
|
|
|
) AS data
|
2024-01-19 21:19:26 +00:00
|
|
|
FROM ${viewGroup(range, 'spender_growth')}
|
2022-06-10 19:20:33 +00:00
|
|
|
GROUP BY time
|
2023-11-09 00:15:36 +00:00
|
|
|
ORDER BY time ASC`, ...range)
|
2022-06-10 19:20:33 +00:00
|
|
|
},
|
2023-11-09 00:15:36 +00:00
|
|
|
itemGrowth: async (parent, { when, to, from }, { models }) => {
|
|
|
|
const range = whenRange(when, from, to)
|
|
|
|
|
2024-01-19 21:19:26 +00:00
|
|
|
return await models.$queryRawUnsafe(`
|
|
|
|
SELECT date_trunc('${timeUnitForRange(range)}', t) at time zone 'America/Chicago' as time, json_build_array(
|
|
|
|
json_build_object('name', 'posts', 'value', sum(posts)),
|
|
|
|
json_build_object('name', 'comments', 'value', sum(comments)),
|
|
|
|
json_build_object('name', 'jobs', 'value', sum(jobs)),
|
|
|
|
json_build_object('name', 'zaps', 'value', sum(zaps)),
|
|
|
|
json_build_object('name', 'territories', 'value', sum(territories)),
|
|
|
|
json_build_object('name', 'comments/posts', 'value', ROUND(sum(comments)/GREATEST(sum(posts), 1), 2))
|
2022-12-01 21:31:04 +00:00
|
|
|
) AS data
|
2024-01-19 21:19:26 +00:00
|
|
|
FROM ${viewGroup(range, 'item_growth')}
|
2022-06-10 19:20:33 +00:00
|
|
|
GROUP BY time
|
2023-11-09 00:15:36 +00:00
|
|
|
ORDER BY time ASC`, ...range)
|
2022-06-10 19:20:33 +00:00
|
|
|
},
|
2023-11-09 00:15:36 +00:00
|
|
|
spendingGrowth: async (parent, { when, to, from }, { models }) => {
|
|
|
|
const range = whenRange(when, from, to)
|
|
|
|
|
2024-01-19 21:19:26 +00:00
|
|
|
return await models.$queryRawUnsafe(`
|
|
|
|
SELECT date_trunc('${timeUnitForRange(range)}', t) at time zone 'America/Chicago' as time, json_build_array(
|
|
|
|
json_build_object('name', 'jobs', 'value', sum(jobs)),
|
|
|
|
json_build_object('name', 'boost', 'value', sum(boost)),
|
|
|
|
json_build_object('name', 'fees', 'value', sum(fees)),
|
|
|
|
json_build_object('name', 'zaps', 'value', sum(tips)),
|
|
|
|
json_build_object('name', 'donations', 'value', sum(donations)),
|
|
|
|
json_build_object('name', 'territories', 'value', sum(territories))
|
2022-12-01 21:31:04 +00:00
|
|
|
) AS data
|
2024-01-19 21:19:26 +00:00
|
|
|
FROM ${viewGroup(range, 'spending_growth')}
|
2022-06-10 19:20:33 +00:00
|
|
|
GROUP BY time
|
2023-11-09 00:15:36 +00:00
|
|
|
ORDER BY time ASC`, ...range)
|
2022-06-22 21:13:51 +00:00
|
|
|
},
|
2023-11-09 00:15:36 +00:00
|
|
|
stackerGrowth: async (parent, { when, to, from }, { models }) => {
|
|
|
|
const range = whenRange(when, from, to)
|
|
|
|
|
2024-01-19 21:19:26 +00:00
|
|
|
return await models.$queryRawUnsafe(`
|
|
|
|
SELECT date_trunc('${timeUnitForRange(range)}', t) at time zone 'America/Chicago' as time, json_build_array(
|
|
|
|
json_build_object('name', 'any', 'value', COUNT(DISTINCT "userId")),
|
|
|
|
json_build_object('name', 'posts', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'POST')),
|
|
|
|
json_build_object('name', 'comments', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'COMMENT')),
|
|
|
|
json_build_object('name', 'rewards', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'EARN')),
|
|
|
|
json_build_object('name', 'referrals', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'REFERRAL')),
|
|
|
|
json_build_object('name', 'territories', 'value', COUNT(DISTINCT "userId") FILTER (WHERE type = 'REVENUE'))
|
2022-12-01 21:31:04 +00:00
|
|
|
) AS data
|
2024-01-19 21:19:26 +00:00
|
|
|
FROM ${viewGroup(range, 'stackers_growth')}
|
2022-06-22 21:13:51 +00:00
|
|
|
GROUP BY time
|
2023-11-09 00:15:36 +00:00
|
|
|
ORDER BY time ASC`, ...range)
|
2022-06-24 15:38:00 +00:00
|
|
|
},
|
2023-11-09 00:15:36 +00:00
|
|
|
stackingGrowth: async (parent, { when, to, from }, { models }) => {
|
|
|
|
const range = whenRange(when, from, to)
|
|
|
|
|
2024-01-19 21:19:26 +00:00
|
|
|
return await models.$queryRawUnsafe(`
|
|
|
|
SELECT date_trunc('${timeUnitForRange(range)}', t) at time zone 'America/Chicago' as time, json_build_array(
|
|
|
|
json_build_object('name', 'rewards', 'value', sum(rewards)),
|
|
|
|
json_build_object('name', 'posts', 'value', sum(posts)),
|
|
|
|
json_build_object('name', 'comments', 'value', sum(comments)),
|
|
|
|
json_build_object('name', 'referrals', 'value', sum(referrals)),
|
|
|
|
json_build_object('name', 'territories', 'value', sum(territories))
|
2022-12-01 21:31:04 +00:00
|
|
|
) AS data
|
2024-01-19 21:19:26 +00:00
|
|
|
FROM ${viewGroup(range, 'stacking_growth')}
|
2022-06-24 15:38:00 +00:00
|
|
|
GROUP BY time
|
2023-11-09 00:15:36 +00:00
|
|
|
ORDER BY time ASC`, ...range)
|
2022-06-10 19:20:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|