209 lines
5.7 KiB
TypeScript
209 lines
5.7 KiB
TypeScript
import { alias, int, mysqlTable, text, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
|
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
|
import { and, eq, isNotNull } from 'drizzle-orm';
|
|
import { reportStatus } from './reportStatus.ts';
|
|
import { generateRandomString } from '@util/random.ts';
|
|
import { BASE_PATH } from 'astro:env/server';
|
|
import { strikeReason } from '@db/schema/strikeReason.ts';
|
|
import { strike } from '@db/schema/strike.ts';
|
|
import { user } from '@db/schema/user.ts';
|
|
|
|
type Database = MySql2Database<{ report: typeof report }>;
|
|
|
|
export const report = mysqlTable('report', {
|
|
id: int('id').primaryKey().autoincrement(),
|
|
reason: varchar('reason', { length: 255 }).notNull(),
|
|
body: text('body'),
|
|
urlHash: varchar('url_hash', { length: 255 }).notNull(),
|
|
createdAt: timestamp('created_at', { mode: 'date' }),
|
|
reporterId: int('reporter_id').references(() => user.id),
|
|
reportedId: int('reported_id').references(() => user.id)
|
|
});
|
|
|
|
export type AddReportReq = {
|
|
reason: string;
|
|
body: string | null;
|
|
createdAt?: Date | null;
|
|
reporterId?: number;
|
|
reportedId?: number | null;
|
|
};
|
|
|
|
export type EditReportReq = {
|
|
id: number;
|
|
reportedId: number | null;
|
|
};
|
|
|
|
export type SubmitReportReq = {
|
|
urlHash: string;
|
|
reportedId: number | null;
|
|
reason: string;
|
|
body: string;
|
|
};
|
|
|
|
export type GetReportsReq = {
|
|
reporter?: string | null;
|
|
reported?: string | null;
|
|
includeDrafts?: boolean | null;
|
|
};
|
|
|
|
export type GetReportById = {
|
|
id: number;
|
|
};
|
|
|
|
export type GetReportByUrlHash = {
|
|
urlHash: string;
|
|
};
|
|
|
|
export async function addReport(db: Database, values: AddReportReq) {
|
|
const urlHash = generateRandomString(16);
|
|
|
|
const r = await db
|
|
.insert(report)
|
|
.values({
|
|
reason: values.reason,
|
|
body: values.body,
|
|
urlHash: urlHash,
|
|
createdAt: values.createdAt,
|
|
reporterId: values.reporterId,
|
|
reportedId: values.reportedId
|
|
})
|
|
.$returningId();
|
|
|
|
return Object.assign(r[0], { url: `${BASE_PATH}/report/${urlHash}` });
|
|
}
|
|
|
|
export async function editReport(db: Database, values: EditReportReq) {
|
|
return db
|
|
.update(report)
|
|
.set({
|
|
reportedId: values.reportedId
|
|
})
|
|
.where(eq(report.id, values.id));
|
|
}
|
|
|
|
export async function submitReport(db: Database, values: SubmitReportReq) {
|
|
return db
|
|
.update(report)
|
|
.set({
|
|
reportedId: values.reportedId,
|
|
reason: values.reason,
|
|
body: values.body,
|
|
createdAt: new Date()
|
|
})
|
|
.where(eq(report.urlHash, values.urlHash));
|
|
}
|
|
|
|
export async function getReports(db: Database, values: GetReportsReq) {
|
|
const reporter = alias(user, 'reporter');
|
|
const reported = alias(user, 'reported');
|
|
|
|
return db
|
|
.select({
|
|
id: report.id,
|
|
reason: report.reason,
|
|
body: report.body,
|
|
urlHash: report.urlHash,
|
|
createdAt: report.createdAt,
|
|
reporter: {
|
|
id: reporter.id,
|
|
username: reporter.username,
|
|
uuid: reporter.uuid
|
|
},
|
|
reported: {
|
|
id: reported.id,
|
|
username: reported.username,
|
|
uuid: reported.uuid
|
|
},
|
|
status: {
|
|
status: reportStatus.status,
|
|
notice: reportStatus.notice,
|
|
statement: reportStatus.statement
|
|
},
|
|
strike: {
|
|
strikeReasonId: strikeReason.id
|
|
}
|
|
})
|
|
.from(report)
|
|
.innerJoin(reporter, eq(report.reporterId, reporter.id))
|
|
.leftJoin(reported, eq(report.reportedId, reported.id))
|
|
.leftJoin(reportStatus, eq(report.id, reportStatus.reportId))
|
|
.leftJoin(strike, eq(report.id, strike.reportId))
|
|
.leftJoin(strikeReason, eq(strike.strikeReasonId, strikeReason.id))
|
|
.where(
|
|
and(
|
|
values.reporter != null ? eq(reporter.username, values.reporter) : undefined,
|
|
values.reported != null ? eq(reported.username, values.reported) : undefined,
|
|
values.includeDrafts == false ? isNotNull(report.createdAt) : undefined
|
|
)
|
|
);
|
|
}
|
|
|
|
export async function getReportById(db: Database, values: GetReportById) {
|
|
const reporter = alias(user, 'reporter');
|
|
const reported = alias(user, 'reported');
|
|
|
|
const reports = await db
|
|
.select({
|
|
id: report.id,
|
|
reason: report.reason,
|
|
body: report.body,
|
|
createdAt: report.createdAt,
|
|
reporter: {
|
|
id: reporter.id,
|
|
username: reporter.username
|
|
},
|
|
reported: {
|
|
id: reported.id,
|
|
username: reported.username
|
|
},
|
|
status: {
|
|
status: reportStatus.status,
|
|
notice: reportStatus.notice,
|
|
statement: reportStatus.statement
|
|
}
|
|
})
|
|
.from(report)
|
|
.innerJoin(reporter, eq(report.reporterId, reporter.id))
|
|
.leftJoin(reported, eq(report.reportedId, reported.id))
|
|
.leftJoin(reportStatus, eq(report.id, reportStatus.reportId))
|
|
.where(eq(report.id, values.id));
|
|
|
|
return reports[0] ?? null;
|
|
}
|
|
|
|
export async function getReportByUrlHash(db: Database, values: GetReportByUrlHash) {
|
|
const reporter = alias(user, 'reporter');
|
|
const reported = alias(user, 'reported');
|
|
|
|
const reports = await db
|
|
.select({
|
|
id: report.id,
|
|
reason: report.reason,
|
|
body: report.body,
|
|
createdAt: report.createdAt,
|
|
urlHash: report.urlHash,
|
|
reporter: {
|
|
id: reporter.id,
|
|
username: reporter.username,
|
|
uuid: reporter.uuid
|
|
},
|
|
reported: {
|
|
id: reported.id,
|
|
username: reported.username,
|
|
uuid: reported.uuid
|
|
},
|
|
status: {
|
|
status: reportStatus.status,
|
|
notice: reportStatus.notice,
|
|
statement: reportStatus.statement
|
|
}
|
|
})
|
|
.from(report)
|
|
.innerJoin(reporter, eq(report.reporterId, reporter.id))
|
|
.leftJoin(reported, eq(report.reportedId, reported.id))
|
|
.leftJoin(reportStatus, eq(report.id, reportStatus.reportId))
|
|
.where(eq(report.urlHash, values.urlHash));
|
|
|
|
return reports[0] ?? null;
|
|
}
|