diff --git a/components/cowboy-hat.js b/components/cowboy-hat.js index d5ee37a1..3dd841db 100644 --- a/components/cowboy-hat.js +++ b/components/cowboy-hat.js @@ -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 ( - + {badge ? ( - {streak} + {streak || 'new'} ) : } @@ -25,7 +25,7 @@ function HatTooltip ({ children, overlayText, placement }) { placement={placement || 'bottom'} overlay={ - {overlayText || '1 sat'} + {overlayText} } trigger={['hover', 'focus']} diff --git a/prisma/migrations/20230202164411_streak_trigger/migration.sql b/prisma/migrations/20230202164411_streak_trigger/migration.sql new file mode 100644 index 00000000..6fec04de --- /dev/null +++ b/prisma/migrations/20230202164411_streak_trigger/migration.sql @@ -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(); \ No newline at end of file diff --git a/worker/index.js b/worker/index.js index 73322379..b0932ddf 100644 --- a/worker/index.js +++ b/worker/index.js @@ -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') } diff --git a/worker/streak.js b/worker/streak.js index 9c4aebf4..5352ed17 100644 --- a/worker/streak.js +++ b/worker/streak.js @@ -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 }