trigger streak when eligible

This commit is contained in:
keyan 2023-02-02 13:47:09 -06:00
parent d24b0727ea
commit b3f7f24cff
4 changed files with 67 additions and 7 deletions

View File

@ -2,17 +2,17 @@ import { Badge, OverlayTrigger, Tooltip } from 'react-bootstrap'
import CowboyHatIcon from '../svgs/cowboy.svg'
export default function CowboyHat ({ streak, badge, className = 'ml-1', height = 16, width = 16 }) {
if (!streak) {
if (streak === null) {
return null
}
return (
<HatTooltip overlayText={`${streak} days`}>
<HatTooltip overlayText={streak ? `${streak} days` : 'new'}>
{badge
? (
<Badge variant='grey-medium' className='ml-2 d-inline-flex align-items-center'>
<CowboyHatIcon className={className} height={height} width={width} />
<span className='ml-1'>{streak}</span>
<span className='ml-1'>{streak || 'new'}</span>
</Badge>)
: <CowboyHatIcon className={className} height={height} width={width} />}
</HatTooltip>
@ -25,7 +25,7 @@ function HatTooltip ({ children, overlayText, placement }) {
placement={placement || 'bottom'}
overlay={
<Tooltip>
{overlayText || '1 sat'}
{overlayText}
</Tooltip>
}
trigger={['hover', 'focus']}

View File

@ -0,0 +1,14 @@
CREATE OR REPLACE FUNCTION user_streak_check() RETURNS TRIGGER AS $$
DECLARE
BEGIN
INSERT INTO pgboss.job (name, data) VALUES ('checkStreak', jsonb_build_object('id', NEW.id));
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS user_streak ON users;
CREATE TRIGGER user_streak
AFTER UPDATE ON users
FOR EACH ROW
WHEN (NEW.msats < OLD.msats)
EXECUTE PROCEDURE user_streak_check();

View File

@ -10,7 +10,7 @@ const { earn } = require('./earn')
const { ApolloClient, HttpLink, InMemoryCache } = require('@apollo/client')
const { indexItem, indexAllItems } = require('./search')
const { timestampItem } = require('./ots')
const { computeStreaks } = require('./streak')
const { computeStreaks, checkStreak } = require('./streak')
const fetch = require('cross-fetch')
async function work () {
@ -49,6 +49,7 @@ async function work () {
await boss.work('auction', auction(args))
await boss.work('earn', earn(args))
await boss.work('streak', computeStreaks(args))
await boss.work('checkStreak', checkStreak(args))
console.log('working jobs')
}

View File

@ -1,3 +1,5 @@
const STREAK_THRESHOLD = 100
function computeStreaks ({ models }) {
return async function () {
console.log('computing streaks')
@ -19,7 +21,7 @@ function computeStreaks ({ models }) {
WHERE (created_at AT TIME ZONE 'UTC' AT TIME ZONE 'America/Chicago')::date = (now() AT TIME ZONE 'America/Chicago' - interval '1 day')::date
)) spending
GROUP BY "userId"
HAVING sum(sats_spent) >= 100
HAVING sum(sats_spent) >= ${STREAK_THRESHOLD}
), existing_streaks (id) AS (
SELECT "userId"
FROM "Streak"
@ -48,4 +50,47 @@ function computeStreaks ({ models }) {
}
}
module.exports = { computeStreaks }
function checkStreak ({ models }) {
return async function ({ data: { id } }) {
console.log('checking streak', id)
// if user is actively streaking skip
const streak = await models.streak.findFirst({
where: {
userId: Number(id),
endedAt: null
}
})
if (streak) {
console.log('done checking streak', id)
return
}
await models.$executeRaw`
WITH streak_started (id) AS (
SELECT "userId"
FROM
((SELECT "userId", floor(sum("ItemAct".msats)/1000) as sats_spent
FROM "ItemAct"
WHERE (created_at AT TIME ZONE 'UTC' AT TIME ZONE 'America/Chicago')::date = (now() AT TIME ZONE 'America/Chicago')::date
AND "userId" = ${Number(id)}
GROUP BY "userId")
UNION ALL
(SELECT "userId", sats as sats_spent
FROM "Donation"
WHERE (created_at AT TIME ZONE 'UTC' AT TIME ZONE 'America/Chicago')::date = (now() AT TIME ZONE 'America/Chicago')::date
AND "userId" = ${Number(id)}
)) spending
GROUP BY "userId"
HAVING sum(sats_spent) >= ${STREAK_THRESHOLD}
)
INSERT INTO "Streak" ("userId", "startedAt", created_at, updated_at)
SELECT id, (now() AT TIME ZONE 'America/Chicago')::date, now_utc(), now_utc()
FROM streak_started`
console.log('done checking streak', id)
}
}
module.exports = { checkStreak, computeStreaks }