stacker.news/api/resolvers/growth.js

168 lines
7.8 KiB
JavaScript
Raw Normal View History

import { timeUnitForRange, whenRange } from '@/lib/time'
export function withClause (range) {
const unit = timeUnitForRange(range)
2022-12-01 21:31:04 +00:00
return `
WITH range_values AS (
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
)
`
}
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
}
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')
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
}
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: {
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
ORDER BY time ASC`, ...range)
2022-06-10 19:20:33 +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
ORDER BY time ASC`, ...range)
2022-06-10 19:20:33 +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
ORDER BY time ASC`, ...range)
2022-06-10 19:20:33 +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
ORDER BY time ASC`, ...range)
2022-06-22 21:13:51 +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
ORDER BY time ASC`, ...range)
2022-06-24 15:38:00 +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
ORDER BY time ASC`, ...range)
2022-06-10 19:20:33 +00:00
}
}
}