mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-11 03:46:52 -05:00
User reports (#3232)
This commit is contained in:
77
app/features/user-report/UserReportRepository.server.ts
Normal file
77
app/features/user-report/UserReportRepository.server.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { subMonths, subYears } from "date-fns";
|
||||
import { db } from "~/db/sql";
|
||||
import type { TablesInsertable } from "~/db/tables";
|
||||
import { databaseTimestampNow, dateToDatabaseTimestamp } from "~/utils/dates";
|
||||
|
||||
/**
|
||||
* Inserts a report or, when the (reporter, reported) pair already has one, overwrites
|
||||
* its category and description bumping `createdAt`. Returns whether an existing report
|
||||
* was updated instead of a new one created.
|
||||
*/
|
||||
export function upsert(
|
||||
args: Omit<TablesInsertable["UserReport"], "createdAt">,
|
||||
) {
|
||||
return db.transaction().execute(async (trx) => {
|
||||
const existing = await trx
|
||||
.selectFrom("UserReport")
|
||||
.select("id")
|
||||
.where("reportedUserId", "=", args.reportedUserId)
|
||||
.where("reporterUserId", "=", args.reporterUserId)
|
||||
.executeTakeFirst();
|
||||
|
||||
await trx
|
||||
.insertInto("UserReport")
|
||||
.values(args)
|
||||
.onConflict((oc) =>
|
||||
oc.columns(["reportedUserId", "reporterUserId"]).doUpdateSet({
|
||||
category: args.category,
|
||||
description: args.description,
|
||||
createdAt: databaseTimestampNow(),
|
||||
}),
|
||||
)
|
||||
.execute();
|
||||
|
||||
return { isUpdate: Boolean(existing) };
|
||||
});
|
||||
}
|
||||
|
||||
/** Returns how many reports have been made against the given user in the last month and in the last year. */
|
||||
export async function countRecentByReportedUserId(reportedUserId: number) {
|
||||
const monthAgo = dateToDatabaseTimestamp(subMonths(new Date(), 1));
|
||||
const yearAgo = dateToDatabaseTimestamp(subYears(new Date(), 1));
|
||||
|
||||
const row = await db
|
||||
.selectFrom("UserReport")
|
||||
.select((eb) => [
|
||||
eb.fn
|
||||
.countAll<number>()
|
||||
.filterWhere("createdAt", ">=", monthAgo)
|
||||
.as("lastMonth"),
|
||||
eb.fn.countAll<number>().as("lastYear"),
|
||||
])
|
||||
.where("reportedUserId", "=", reportedUserId)
|
||||
.where("createdAt", ">=", yearAgo)
|
||||
.executeTakeFirstOrThrow();
|
||||
|
||||
return { lastMonth: row.lastMonth, lastYear: row.lastYear };
|
||||
}
|
||||
|
||||
/** Returns all reports made against the given user, newest first, with the reporter's identifying info. */
|
||||
export function findAllByReportedUserId(reportedUserId: number) {
|
||||
return db
|
||||
.selectFrom("UserReport")
|
||||
.innerJoin("User", "User.id", "UserReport.reporterUserId")
|
||||
.select([
|
||||
"UserReport.id",
|
||||
"UserReport.category",
|
||||
"UserReport.description",
|
||||
"UserReport.createdAt",
|
||||
"UserReport.reporterUserId",
|
||||
"User.username as reporterUsername",
|
||||
"User.discordId as reporterDiscordId",
|
||||
"User.customUrl as reporterCustomUrl",
|
||||
])
|
||||
.where("UserReport.reportedUserId", "=", reportedUserId)
|
||||
.orderBy("UserReport.createdAt", "desc")
|
||||
.execute();
|
||||
}
|
||||
Reference in New Issue
Block a user