Migrate donator requests to limit of 5

This commit is contained in:
Jorge Vargas 2025-05-10 00:02:16 -06:00
parent 1cd11fea2b
commit 042758d27c
5 changed files with 99 additions and 2 deletions

View file

@ -0,0 +1,36 @@
import { RequestState, type Prisma } from '@prisma/client'
import prismaClient from 'utils/prisma-client'
const LIMIT_PENDING = 5
export default async function MigrationFn(tx: Prisma.TransactionClient) {
const donatorRequests = await tx.requests.findMany({
where: { donator: true, state: RequestState.PENDING, userID: { not: null } }
})
const donatorMap = new Map<string, typeof donatorRequests>()
donatorRequests.forEach((request) => {
const userID = request.userID as string
donatorMap.set(userID, [...(donatorMap.get(userID) || []), request])
})
const holdRequests = new Set<number>()
for (const requests of donatorMap.values()) {
if (requests.length <= LIMIT_PENDING) continue
const end = requests.length - LIMIT_PENDING
const sortedRequests = requests.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime()).slice(0, end)
sortedRequests.forEach((r) => {
holdRequests.add(r.id)
})
}
await prismaClient.requests.updateMany({
where: { id: { in: Array.from(holdRequests) } },
data: { state: RequestState.HOLD }
})
console.log(`Updated ${holdRequests.size} requests to HOLD state`)
}

35
prisma/migrate.ts Normal file
View file

@ -0,0 +1,35 @@
import { Prisma } from '@prisma/client'
import fs from 'fs'
import path from 'path'
import { createRequire } from 'module'
import prismaClient from 'utils/prisma-client'
const require = createRequire(import.meta.url)
export type MigrationFn = (tx: Prisma.TransactionClient) => Promise<void>
interface Migration {
id: string
migrationFn: MigrationFn
}
const dataMigrationsPath = path.join(import.meta.dirname, 'data_migrations')
const migrationFiles = fs.readdirSync(dataMigrationsPath).filter((file) => file.endsWith('.ts'))
const migrations: Migration[] = migrationFiles
.sort()
.map((id) => ({ id, migrationFn: require(path.join(dataMigrationsPath, id)).default }))
.filter((migration) => migration.migrationFn !== undefined)
for (const { id, migrationFn } of migrations) {
const startDate = new Date()
const migration = await prismaClient.migration.findFirst({ where: { id } })
if (migration === null) {
console.log(`Migrating ${id}`)
await prismaClient.$transaction(async (tx) => {
await migrationFn(tx)
await tx.migration.create({ data: { id } })
})
const endDate = new Date()
console.log(`Migrated ${id} in ${(endDate.getTime() - startDate.getTime()) / 1000}s`)
}
}

View file

@ -0,0 +1,7 @@
-- CreateTable
CREATE TABLE `Migration` (
`id` VARCHAR(191) NOT NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

View file

@ -0,0 +1,8 @@
/*
Warnings:
- You are about to alter the column `state` on the `requests` table. The data in that column could be lost. The data in that column will be cast from `VarChar(255)` to `Enum(EnumId(1))`.
*/
-- AlterTable
ALTER TABLE `requests` MODIFY `state` ENUM('complete', 'hold', 'pending') NOT NULL;

View file

@ -334,13 +334,19 @@ model related_album {
@@id([albumId, relatedId]) @@id([albumId, relatedId])
} }
enum RequestState {
COMPLETE @map("complete")
HOLD @map("hold")
PENDING @map("pending")
}
model requests { model requests {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
title String? @db.VarChar(255) title String? @db.VarChar(255)
link String? @db.VarChar(255) link String? @db.VarChar(255)
user String? @db.VarChar(255) user String? @db.VarChar(255)
userID String? @db.VarChar(255) userID String? @db.VarChar(255)
state String @db.VarChar(255) state RequestState
donator Boolean donator Boolean
reason String? @db.VarChar(255) reason String? @db.VarChar(255)
comments String? @db.VarChar(255) comments String? @db.VarChar(255)
@ -402,7 +408,7 @@ model submissions {
model users { model users {
id String @id @db.VarChar(255) id String @id @db.VarChar(255)
name String @db.VarChar(20) name String @db.VarChar(20)
username String? @unique @db.VarChar(255) username String? @unique @db.VarChar(255)
displayUsername String @default("Default display name") displayUsername String @default("Default display name")
email String? @unique @db.VarChar(255) email String? @unique @db.VarChar(255)
emailVerified Boolean emailVerified Boolean
@ -461,3 +467,8 @@ model account {
user users @relation(fields: [userId], references: [id]) user users @relation(fields: [userId], references: [id])
} }
model Migration {
id String @id
createdAt DateTime @default(now())
}