Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎖️ Badge Followups #836

Open
robin-macpherson opened this issue Mar 28, 2023 · 0 comments
Open

🎖️ Badge Followups #836

robin-macpherson opened this issue Mar 28, 2023 · 0 comments
Labels
backend Backend work! database design needs or would benefit from design input frontend Frontend work! improvement refactor

Comments

@robin-macpherson
Copy link
Contributor

Followups & Improvements

  • Create a badge earned notification with the badge icon
  • Add in a few extra badges for “thanks given” and those where there’s a large gap at the upper end
  • We can get some better DB parallelism here by doing the two badge assignments in parallel. I'd recommend factoring these out into functions, e.g. :
      const assignThanksCountBadges = async (userId: number, db: PrismaClient) => {
        const thanksCountQuery = Prisma.sql`
          SELECT COUNT(*) AS count
          FROM "CommentThanks" AS ct
          JOIN "Comment" AS c
            ON ct."commentId" = c.id
          WHERE c."authorId" = ${userId}
        `

        const newBadgeCount = await assignCountBadges(
          db,
          userId,
          thanksCountQuery,
          {
            10: BadgeType.TEN_THANKS,
            50: BadgeType.FIFTY_THANKS,
            100: BadgeType.ONEHUNDRED_THANKS,
            250: BadgeType.TWOHUNDREDFIFTY_THANKS,
            500: BadgeType.FIVEHUNDRED_THANKS,
            1000: BadgeType.ONETHOUSAND_THANKS,
            1250: BadgeType.ONETHOUSANDTWOHUNDREDFIFTY_THANKS,
            1500: BadgeType.ONETHOUSANDFIVEHUNDRED_THANKS,
            2250: BadgeType.TWOTHOUSANDTWOHUNDREDFIFTY_THANKS,
            2500: BadgeType.TWOTHOUSANDFIVEHUNDRED_THANKS,
            5000: BadgeType.FIVETHOUSAND_THANKS,
            10000: BadgeType.TENTHOUSAND_THANKS,
          }
        )

        if (newBadgeCount) {
          const newBadges = await db.userBadge.findMany({
            where: { user: { id: userId } },
            include: { user: true },
            orderBy: { createdAt: 'desc' },
            take: newBadgeCount,
          })

          await Promise.all(
            newBadges.map((badge) => {
              return sendNewBadgeEmail({
                badgeType: badge.type,
                user: badge.user,
              })
            }),
          )
      }
    }

    const assignThanksGivenCountBadges = async (userId: number) => {
      ....
    }

    ...inside resolver
    await Promise.all([
        assignThanksCountBadges(comment.author.id),
        assignThanksGivenCountBadges(userId),
    ])

Note that while both proposed functions here take in an arg they call userId it's important we call them with the appropriate user's ID (id of the comment author, not the requesting user, in the thanks received case).

I think pulling these out into functions will also make the code read a little cleaner and reduce the risk of transposing the user IDs like we've run into before

@robin-macpherson robin-macpherson added frontend Frontend work! backend Backend work! database refactor design needs or would benefit from design input improvement labels Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Backend work! database design needs or would benefit from design input frontend Frontend work! improvement refactor
Projects
None yet
Development

No branches or pull requests

1 participant