update reports
All checks were successful
deploy / build-and-deploy (/testvaro, /opt/website-test, website-test) (push) Successful in 21s
deploy / build-and-deploy (/varo, /opt/website, website) (push) Successful in 13s

This commit is contained in:
2025-06-10 00:03:38 +02:00
parent 8262fd90aa
commit 5c41857530
11 changed files with 253 additions and 50 deletions

View File

@@ -68,21 +68,6 @@ CREATE TABLE IF NOT EXISTS death (
FOREIGN KEY (killer_user_id) REFERENCES user(id) ON DELETE CASCADE
);
-- strike reason
CREATE TABLE IF NOT EXISTS strike_reason (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
weight TINYINT NOT NULL
);
-- strike
CREATE TABLE IF NOT EXISTS strike (
id INT AUTO_INCREMENT PRIMARY KEY,
at TIMESTAMP NOT NULL,
strike_reason_id INT NOT NULL,
FOREIGN KEY (strike_reason_id) REFERENCES strike_reason(id) ON DELETE CASCADE
);
-- report
CREATE TABLE IF NOT EXISTS report (
id INT AUTO_INCREMENT PRIMARY KEY,
@@ -90,7 +75,7 @@ CREATE TABLE IF NOT EXISTS report (
body TEXT,
url_hash VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP,
reporter_team_id INT NOT NULL,
reporter_team_id INT,
reported_team_id INT,
FOREIGN KEY (reporter_team_id) REFERENCES team(id) ON DELETE CASCADE,
FOREIGN KEY (reported_team_id) REFERENCES team(id) ON DELETE CASCADE
@@ -103,10 +88,24 @@ CREATE TABLE IF NOT EXISTS report_status (
statement TEXT,
report_id INT NOT NULL UNIQUE,
reviewer_id INT,
strike_id INT,
FOREIGN KEY (report_id) REFERENCES report(id) ON DELETE CASCADE,
FOREIGN KEY (reviewer_id) REFERENCES admin(id) ON DELETE CASCADE,
FOREIGN KEY (strike_id) REFERENCES strike(id) ON DELETE CASCADE
FOREIGN KEY (reviewer_id) REFERENCES admin(id) ON DELETE CASCADE
);
-- strike reason
CREATE TABLE IF NOT EXISTS strike_reason (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
weight TINYINT NOT NULL
);
-- strike
CREATE TABLE IF NOT EXISTS strike (
at TIMESTAMP NOT NULL,
report_id INT NOT NULL UNIQUE,
strike_reason_id INT NOT NULL,
FOREIGN KEY (report_id) REFERENCES report(id) ON DELETE CASCADE,
FOREIGN KEY (strike_reason_id) REFERENCES strike_reason(id) ON DELETE CASCADE
);
-- feedback

View File

@@ -109,7 +109,13 @@ import {
type DeleteStrikeReasonReq,
deleteStrikeReason
} from '@db/schema/strikeReason.ts';
import { getStrikesByTeamId, type GetStrikesByTeamId, strike } from '@db/schema/strike.ts';
import {
editStrike,
type EditStrikeReq,
getStrikesByTeamId,
type GetStrikesByTeamIdReq,
strike
} from '@db/schema/strike.ts';
import {
editReportStatus,
type EditReportStatusReq,
@@ -248,7 +254,8 @@ export class Database {
getStrikeReasons = (values: GetStrikeReasonsReq) => getStrikeReasons(this.db, values);
/* strikes */
getStrikesByTeamId = (values: GetStrikesByTeamId) => getStrikesByTeamId(this.db, values);
editStrike = (values: EditStrikeReq) => editStrike(this.db, values);
getStrikesByTeamId = (values: GetStrikesByTeamIdReq) => getStrikesByTeamId(this.db, values);
/* feedback */
addFeedback = (values: AddFeedbackReq) => addFeedback(this.db, values);

View File

@@ -1,10 +1,10 @@
import { alias, int, mysqlTable, text, timestamp, varchar } from 'drizzle-orm/mysql-core';
import { strike } from './strike.ts';
import type { MySql2Database } from 'drizzle-orm/mysql2';
import { and, eq } from 'drizzle-orm';
import { reportStatus } from './reportStatus.ts';
import { generateRandomString } from '@util/random.ts';
import { team } from '@db/schema/team.ts';
import { BASE_PATH } from 'astro:env/server';
type Database = MySql2Database<{ report: typeof report }>;
@@ -14,9 +14,7 @@ export const report = mysqlTable('report', {
body: text('body'),
urlHash: varchar('url_hash', { length: 255 }).notNull(),
createdAt: timestamp('created_at', { mode: 'string' }),
reporterTeamId: int('reporter_team_id')
.notNull()
.references(() => team.id),
reporterTeamId: int('reporter_team_id').references(() => team.id),
reportedTeamId: int('reported_team_id').references(() => team.id)
});
@@ -24,7 +22,7 @@ export type AddReportReq = {
reason: string;
body: string | null;
createdAt?: string | null;
reporterTeamId: number;
reporterTeamId?: number;
reportedTeamId?: number | null;
};
@@ -34,19 +32,21 @@ export type GetReportsReq = {
};
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: generateRandomString(16),
urlHash: urlHash,
createdAt: values.createdAt,
reporterTeamId: values.reporterTeamId,
reportedTeamId: values.reportedTeamId
})
.$returningId();
return r[0];
return Object.assign(r[0], { url: `${BASE_PATH}/report/${urlHash}` });
}
export async function getReports(db: Database, values: GetReportsReq) {
@@ -94,7 +94,6 @@ export async function getReports(db: Database, values: GetReportsReq) {
.innerJoin(reporterTeam, eq(report.reporterTeamId, reporterTeam.id))
.leftJoin(reportedTeam, eq(report.reportedTeamId, reportedTeam.id))
.leftJoin(reportStatus, eq(report.id, reportStatus.reportId))
.leftJoin(strike, eq(reportStatus.strikeId, strike.id))
.where(
and(
values.reporter != null ? eq(report.reporterTeamId, reporterIdSubquery!.id) : undefined,

View File

@@ -1,5 +1,4 @@
import { int, mysqlEnum, mysqlTable, text } from 'drizzle-orm/mysql-core';
import { strike } from './strike.ts';
import { admin } from './admin.ts';
import { report } from './report.ts';
import type { MySql2Database } from 'drizzle-orm/mysql2';
@@ -15,8 +14,7 @@ export const reportStatus = mysqlTable('report_status', {
.notNull()
.unique()
.references(() => report.id),
reviewerId: int('reviewer_id').references(() => admin.id),
strikeId: int('strike_id').references(() => strike.id)
reviewerId: int('reviewer_id').references(() => admin.id)
});
export type GetReportStatusReq = {
@@ -28,7 +26,6 @@ export type EditReportStatusReq = {
status: 'open' | 'closed' | null;
notice: string | null;
statement: string | null;
strikeId: number | null;
};
export async function getReportStatus(db: Database, values: GetReportStatusReq) {
@@ -47,8 +44,7 @@ export async function editReportStatus(db: Database, values: EditReportStatusReq
set: {
status: values.status,
notice: values.notice,
statement: values.statement,
strikeId: values.strikeId
statement: values.statement
}
});
}

View File

@@ -8,27 +8,50 @@ import { reportStatus } from '@db/schema/reportStatus.ts';
type Database = MySql2Database<{ strike: typeof strike }>;
export const strike = mysqlTable('strike', {
id: int('id').primaryKey().autoincrement(),
at: timestamp('at', { mode: 'string' }).notNull(),
at: timestamp('at', { mode: 'date' }).notNull(),
reportId: int('report_id')
.notNull()
.references(() => report.id),
strikeReasonId: int('strike_reason_id')
.notNull()
.references(() => strikeReason.id)
});
export type GetStrikesByTeamId = {
export type EditStrikeReq = {
reportId: number;
at?: Date;
strikeReasonId: number;
};
export type GetStrikesByTeamIdReq = {
teamId: number;
};
export async function getStrikesByTeamId(db: Database, values: GetStrikesByTeamId) {
export async function editStrike(db: Database, values: EditStrikeReq) {
return db
.insert(strike)
.values({
at: values.at ?? new Date(),
reportId: values.reportId,
strikeReasonId: values.strikeReasonId
})
.onDuplicateKeyUpdate({
set: {
at: values.at ?? new Date(),
strikeReasonId: values.strikeReasonId
}
});
}
export async function getStrikesByTeamId(db: Database, values: GetStrikesByTeamIdReq) {
return db
.select({
id: strike.id,
at: strike.at,
report: report,
reason: strikeReason
})
.from(strike)
.innerJoin(strikeReason, eq(strike.strikeReasonId, strikeReason.id))
.innerJoin(reportStatus, eq(strike.id, reportStatus.strikeId))
.innerJoin(report, eq(reportStatus.reportId, report.id))
.where(eq(report.reportedTeamId, values.teamId));
}

View File

@@ -6,7 +6,6 @@ import { user } from './user.ts';
import { teamDraft } from './teamDraft.ts';
import { death } from '@db/schema/death.ts';
import { report } from '@db/schema/report.ts';
import { reportStatus } from '@db/schema/reportStatus.ts';
import { strikeReason } from '@db/schema/strikeReason.ts';
import { strike } from '@db/schema/strike.ts';
@@ -142,8 +141,7 @@ export async function getTeamsFull(db: Database, _values: GetTeamsFullReq) {
})
.from(strike)
.innerJoin(strikeReason, eq(strike.strikeReasonId, strikeReason.id))
.innerJoin(reportStatus, eq(strike.id, reportStatus.strikeId))
.innerJoin(report, eq(reportStatus.reportId, report.id))
.innerJoin(report, eq(strike.reportId, report.id))
.innerJoin(team, eq(report.reportedTeamId, team.id))
.as('strike_weight_subquery');