Skip to content

Commit bf0d860

Browse files
authored
Fix/reset grinder roles (#45)
* feat: `is_break` column on CheckinStreak * refactor: column naming into `streak_broken_at` * fix: do not include whole `db` folder for it is detect our OS * fix: repeated reset grinder roles
1 parent 7f2ffa9 commit bf0d860

6 files changed

Lines changed: 39 additions & 14 deletions

File tree

db/migrations/20250810031908_init/migration.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ CREATE TABLE "public"."CheckinStreak" (
1313
"first_date" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
1414
"last_date" TIMESTAMP(3),
1515
"streak" INTEGER NOT NULL DEFAULT 0,
16+
"streak_broken_at" TIMESTAMP(3) DEFAULT NULL,
1617
"updated_at" TIMESTAMP(3),
1718

1819
CONSTRAINT "CheckinStreak_pkey" PRIMARY KEY ("id")

db/schema.prisma

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ model CheckinStreak {
2323
first_date DateTime @default(now())
2424
last_date DateTime?
2525
streak Int @default(0)
26+
streak_broken_at DateTime?
2627
updated_at DateTime?
2728
2829
user User @relation(fields: [user_id], references: [id])

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ services:
1414
condition: service_healthy
1515
volumes:
1616
- ./src:/usr/src/app/src
17-
- ./db:/usr/src/app/db
17+
- ./db/schema.prisma:/usr/src/app/db/schema.prisma
1818
- ./prisma.config.ts:/usr/src/app/prisma.config.ts
1919
- ./package.json:/usr/src/app/package.json
2020
- ./tsconfig.json:/usr/src/app/tsconfig.json

src/bot/events/client-ready/jobs/handlers/reset-grinder-roles.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ export default {
2727
const guild = await client.guilds.fetch(process.env.GUILD_ID!)
2828
const channel = await getChannel(guild, GRIND_ASHES_CHANNEL)
2929
ResetGrinderRoles.assertChannel(channel)
30-
const users = await ResetGrinderRoles.getUsersWithLatestCheckin(client.prisma)
30+
const users = await ResetGrinderRoles.getUsersWithLatestStreak(client.prisma)
3131

32-
await ResetGrinderRoles.validateUsers(guild, channel, users)
32+
await ResetGrinderRoles.validateUsers(client.prisma, guild, channel, users)
3333

3434
log.success(ResetGrinderRoles.MSG.JobSuccess)
3535
})

src/bot/events/client-ready/jobs/validators/reset-grinder-roles.ts

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
import type { PrismaClient } from '@generatedDB/client'
2+
import type { CheckinStreak } from '@type/checkin-streak'
3+
import type { User } from '@type/user'
24
import type { Guild, GuildMember, TextChannel } from 'discord.js'
35
import { getGrindRoles, GRINDER_ROLE } from '@config/discord'
46
import { isDateToday, isDateYesterday } from '@utils/date'
57
import { sendAsBot } from '@utils/discord'
68
import { log } from '@utils/logger'
79
import { ResetGrinderRolesMessage } from '../messages/reset-grinder-roles'
810

9-
interface UserWithLatestCheckin {
10-
discord_id: string
11-
checkins: {
12-
status: string
13-
created_at: Date
14-
}[]
15-
}
16-
1711
export class ResetGrinderRoles extends ResetGrinderRolesMessage {
1812
static hasValidCheckin(checkin?: { created_at: Date, status: string }): boolean {
1913
if (!checkin)
@@ -39,14 +33,19 @@ export class ResetGrinderRoles extends ResetGrinderRolesMessage {
3933
}
4034
}
4135

42-
static async validateUsers(guild: Guild, channel: TextChannel, users: UserWithLatestCheckin[]) {
36+
static async validateUsers(prisma: PrismaClient, guild: Guild, channel: TextChannel, users: User[]) {
4337
for (const user of users) {
4438
const lastCheckin = user.checkins?.[0]
4539
if (this.hasValidCheckin(lastCheckin))
4640
continue
4741

42+
const checkinStreak = user.checkin_streaks?.[0]
43+
if (!checkinStreak)
44+
continue
45+
4846
const member = await guild.members.fetch(user.discord_id)
4947
await this.removeGrinderRoles(member)
48+
await this.breakCheckinStreakAt(prisma, checkinStreak)
5049

5150
await sendAsBot(
5251
null,
@@ -58,7 +57,7 @@ export class ResetGrinderRoles extends ResetGrinderRolesMessage {
5857
}
5958
}
6059

61-
static async getUsersWithLatestCheckin(prisma: PrismaClient): Promise<UserWithLatestCheckin[]> {
60+
static async getUsersWithLatestStreak(prisma: PrismaClient): Promise<User[]> {
6261
const users = await prisma.user.findMany({
6362
select: {
6463
discord_id: true,
@@ -70,9 +69,32 @@ export class ResetGrinderRoles extends ResetGrinderRolesMessage {
7069
orderBy: { created_at: 'desc' },
7170
take: 1,
7271
},
72+
checkin_streaks: {
73+
orderBy: { first_date: 'desc' },
74+
take: 1,
75+
where: {
76+
streak_broken_at: null,
77+
},
78+
include: {
79+
checkins: {
80+
orderBy: { created_at: 'desc' },
81+
take: 1,
82+
},
83+
},
84+
},
7385
},
74-
}) as UserWithLatestCheckin[]
86+
}) as User[]
7587

7688
return users
7789
}
90+
91+
static async breakCheckinStreakAt(prisma: PrismaClient, checkinStreak: CheckinStreak) {
92+
await prisma.checkinStreak.update({
93+
where: { id: checkinStreak.id },
94+
data: {
95+
streak_broken_at: new Date(),
96+
updated_at: new Date(),
97+
},
98+
})
99+
}
78100
}

src/types/checkin-streak.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface CheckinStreak {
77
first_date: Date
88
last_date?: Date | null
99
streak: number
10+
streak_broken_at?: Date | null
1011
updated_at?: Date | null
1112

1213
user?: User

0 commit comments

Comments
 (0)