update reports
This commit is contained in:
69
README.md
69
README.md
@ -41,6 +41,75 @@
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><code>POST</code> <code>/api/report</code> (Erstellt einen Report)</summary>
|
||||||
|
|
||||||
|
##### Request Body
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
// UUID des Report Erstellers
|
||||||
|
"reporter": string,
|
||||||
|
// UUID des Reporteten Spielers
|
||||||
|
"reported": string | null,
|
||||||
|
// Report Grund
|
||||||
|
"reason": string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Response Codes
|
||||||
|
|
||||||
|
| http code | beschreibung |
|
||||||
|
| --------- | ----------------------------------------------------------------- |
|
||||||
|
| 200 | / |
|
||||||
|
| 400 | Der Request Body ist falsch |
|
||||||
|
| 401 | Es wurde ein falsches API Secret angegeben |
|
||||||
|
| 404 | Der Report Ersteller, oder der reportete Spieler, existiert nicht |
|
||||||
|
|
||||||
|
##### Response Body
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
// URL, wo der Ersteller den Report abschicken kann
|
||||||
|
"url": string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><code>PUT</code> <code>/api/report</code> (Erstellt einen Abgeschlossenen Report)</summary>
|
||||||
|
|
||||||
|
##### Request Body
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
// UUID des Reporters. Wenn `null`, wird der Reporter als System interpretiert
|
||||||
|
"reporter": string | null,
|
||||||
|
// UUID des Reporteten Spielers
|
||||||
|
"reported": string,
|
||||||
|
// Report Grund
|
||||||
|
"reason": string,
|
||||||
|
// Inhalt des Reports
|
||||||
|
"body": string | null,
|
||||||
|
// Interne Notiz
|
||||||
|
"notice": string | null,
|
||||||
|
// Öffentliches Statement
|
||||||
|
"statement": string | null,
|
||||||
|
// ID des Strikegrundes
|
||||||
|
"strike_reason_id": number
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| http code | beschreibung |
|
||||||
|
| --------- | ----------------------------------------------------------------- |
|
||||||
|
| 200 | / |
|
||||||
|
| 400 | Der Request Body ist falsch |
|
||||||
|
| 401 | Es wurde ein falsches API Secret angegeben |
|
||||||
|
| 404 | Der Report Ersteller, oder der reportete Spieler, existiert nicht |
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><code>POST</code> <code>/api/player/death</code> (Registriert einen Spielertod)</summary>
|
<summary><code>POST</code> <code>/api/player/death</code> (Registriert einen Spielertod)</summary>
|
||||||
|
|
||||||
|
@ -47,12 +47,21 @@ export const report = {
|
|||||||
status: z.enum(['open', 'closed']).nullable(),
|
status: z.enum(['open', 'closed']).nullable(),
|
||||||
notice: z.string().nullable(),
|
notice: z.string().nullable(),
|
||||||
statement: z.string().nullable(),
|
statement: z.string().nullable(),
|
||||||
strikeId: z.number().nullable()
|
strikeReasonId: z.number().nullable()
|
||||||
}),
|
}),
|
||||||
handler: async (input, context) => {
|
handler: async (input, context) => {
|
||||||
Session.actionSessionFromCookies(context.cookies, Permissions.Reports);
|
Session.actionSessionFromCookies(context.cookies, Permissions.Reports);
|
||||||
|
|
||||||
await db.editReportStatus(input);
|
await db.transaction(async (tx) => {
|
||||||
|
await tx.editReportStatus(input);
|
||||||
|
|
||||||
|
if (input.strikeReasonId) {
|
||||||
|
await db.editStrike({
|
||||||
|
reportId: input.reportId,
|
||||||
|
strikeReasonId: input.strikeReasonId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
reports: defineAction({
|
reports: defineAction({
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
let status = $state<'open' | 'closed' | null>(null);
|
let status = $state<'open' | 'closed' | null>(null);
|
||||||
let notice = $state<string | null>(null);
|
let notice = $state<string | null>(null);
|
||||||
let statement = $state<string | null>(null);
|
let statement = $state<string | null>(null);
|
||||||
|
let strikeReason = $state<string | null>(null);
|
||||||
|
|
||||||
// consts
|
// consts
|
||||||
const strikeReasonValues = strikeReasons.reduce(
|
const strikeReasonValues = strikeReasons.reduce(
|
||||||
@ -50,7 +51,7 @@
|
|||||||
status: status,
|
status: status,
|
||||||
notice: notice,
|
notice: notice,
|
||||||
statement: statement,
|
statement: statement,
|
||||||
strikeId: null
|
strikeReasonId: Number(strikeReason)
|
||||||
} as ReportStatus)
|
} as ReportStatus)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -75,12 +76,14 @@
|
|||||||
<div class="flex flex-col w-[42rem]">
|
<div class="flex flex-col w-[42rem]">
|
||||||
<Textarea bind:value={statement} label="Öffentliche Report Antwort" dynamicWidth rows={5} />
|
<Textarea bind:value={statement} label="Öffentliche Report Antwort" dynamicWidth rows={5} />
|
||||||
<Select
|
<Select
|
||||||
|
bind:value={status}
|
||||||
values={{ open: 'In Bearbeitung', closed: 'Bearbeitet' }}
|
values={{ open: 'In Bearbeitung', closed: 'Bearbeitet' }}
|
||||||
defaultValue="Unbearbeitet"
|
defaultValue="Unbearbeitet"
|
||||||
label="Bearbeitungsstatus"
|
label="Bearbeitungsstatus"
|
||||||
dynamicWidth
|
dynamicWidth
|
||||||
/>
|
/>
|
||||||
<Select bind:value={status} values={strikeReasonValues} defaultValue="" label="Vergehen" dynamicWidth></Select>
|
<Select bind:value={strikeReason} values={strikeReasonValues} defaultValue="" label="Vergehen" dynamicWidth
|
||||||
|
></Select>
|
||||||
<div class="divider mt-0 mb-2"></div>
|
<div class="divider mt-0 mb-2"></div>
|
||||||
<button class="btn mt-auto" onclick={onSaveButtonClick}>Speichern</button>
|
<button class="btn mt-auto" onclick={onSaveButtonClick}>Speichern</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,7 +9,7 @@ export type Report = Reports[0];
|
|||||||
export type ReportStatus = Exclude<
|
export type ReportStatus = Exclude<
|
||||||
Exclude<ActionReturnType<typeof actions.report.reportStatus>['data'], undefined>['reportStatus'],
|
Exclude<ActionReturnType<typeof actions.report.reportStatus>['data'], undefined>['reportStatus'],
|
||||||
null
|
null
|
||||||
>;
|
> & { strikeReasonId: number | null };
|
||||||
|
|
||||||
export type StrikeReasons = Exclude<
|
export type StrikeReasons = Exclude<
|
||||||
ActionReturnType<typeof actions.report.strikeReasons>['data'],
|
ActionReturnType<typeof actions.report.strikeReasons>['data'],
|
||||||
@ -65,7 +65,7 @@ export async function editReportStatus(report: Report, reportStatus: ReportStatu
|
|||||||
status: reportStatus.status,
|
status: reportStatus.status,
|
||||||
notice: reportStatus.notice,
|
notice: reportStatus.notice,
|
||||||
statement: reportStatus.statement,
|
statement: reportStatus.statement,
|
||||||
strikeId: reportStatus.strikeId
|
strikeReasonId: reportStatus.strikeReasonId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -68,29 +68,14 @@ CREATE TABLE IF NOT EXISTS death (
|
|||||||
FOREIGN KEY (killer_user_id) REFERENCES user(id) ON DELETE CASCADE
|
FOREIGN KEY (killer_user_id) REFERENCES user(id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
-- strike reason
|
s-- report
|
||||||
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 (
|
CREATE TABLE IF NOT EXISTS report (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
reason VARCHAR(255) NOT NULL,
|
reason VARCHAR(255) NOT NULL,
|
||||||
body TEXT,
|
body TEXT,
|
||||||
url_hash VARCHAR(255) NOT NULL UNIQUE,
|
url_hash VARCHAR(255) NOT NULL UNIQUE,
|
||||||
created_at TIMESTAMP,
|
created_at TIMESTAMP,
|
||||||
reporter_team_id INT NOT NULL,
|
reporter_team_id INT,
|
||||||
reported_team_id INT,
|
reported_team_id INT,
|
||||||
FOREIGN KEY (reporter_team_id) REFERENCES team(id) ON DELETE CASCADE,
|
FOREIGN KEY (reporter_team_id) REFERENCES team(id) ON DELETE CASCADE,
|
||||||
FOREIGN KEY (reported_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,
|
statement TEXT,
|
||||||
report_id INT NOT NULL UNIQUE,
|
report_id INT NOT NULL UNIQUE,
|
||||||
reviewer_id INT,
|
reviewer_id INT,
|
||||||
strike_id INT,
|
|
||||||
FOREIGN KEY (report_id) REFERENCES report(id) ON DELETE CASCADE,
|
FOREIGN KEY (report_id) REFERENCES report(id) ON DELETE CASCADE,
|
||||||
FOREIGN KEY (reviewer_id) REFERENCES admin(id) ON DELETE CASCADE,
|
FOREIGN KEY (reviewer_id) REFERENCES admin(id) ON DELETE CASCADE
|
||||||
FOREIGN KEY (strike_id) REFERENCES strike(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
|
-- feedback
|
||||||
|
@ -109,7 +109,13 @@ import {
|
|||||||
type DeleteStrikeReasonReq,
|
type DeleteStrikeReasonReq,
|
||||||
deleteStrikeReason
|
deleteStrikeReason
|
||||||
} from '@db/schema/strikeReason.ts';
|
} 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 {
|
import {
|
||||||
editReportStatus,
|
editReportStatus,
|
||||||
type EditReportStatusReq,
|
type EditReportStatusReq,
|
||||||
@ -248,7 +254,8 @@ export class Database {
|
|||||||
getStrikeReasons = (values: GetStrikeReasonsReq) => getStrikeReasons(this.db, values);
|
getStrikeReasons = (values: GetStrikeReasonsReq) => getStrikeReasons(this.db, values);
|
||||||
|
|
||||||
/* strikes */
|
/* strikes */
|
||||||
getStrikesByTeamId = (values: GetStrikesByTeamId) => getStrikesByTeamId(this.db, values);
|
editStrike = (values: EditStrikeReq) => editStrike(this.db, values);
|
||||||
|
getStrikesByTeamId = (values: GetStrikesByTeamIdReq) => getStrikesByTeamId(this.db, values);
|
||||||
|
|
||||||
/* feedback */
|
/* feedback */
|
||||||
addFeedback = (values: AddFeedbackReq) => addFeedback(this.db, values);
|
addFeedback = (values: AddFeedbackReq) => addFeedback(this.db, values);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { alias, int, mysqlTable, text, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
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 type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||||
import { and, eq } from 'drizzle-orm';
|
import { and, eq } from 'drizzle-orm';
|
||||||
import { reportStatus } from './reportStatus.ts';
|
import { reportStatus } from './reportStatus.ts';
|
||||||
import { generateRandomString } from '@util/random.ts';
|
import { generateRandomString } from '@util/random.ts';
|
||||||
import { team } from '@db/schema/team.ts';
|
import { team } from '@db/schema/team.ts';
|
||||||
|
import { BASE_PATH } from 'astro:env/server';
|
||||||
|
|
||||||
type Database = MySql2Database<{ report: typeof report }>;
|
type Database = MySql2Database<{ report: typeof report }>;
|
||||||
|
|
||||||
@ -14,9 +14,7 @@ export const report = mysqlTable('report', {
|
|||||||
body: text('body'),
|
body: text('body'),
|
||||||
urlHash: varchar('url_hash', { length: 255 }).notNull(),
|
urlHash: varchar('url_hash', { length: 255 }).notNull(),
|
||||||
createdAt: timestamp('created_at', { mode: 'string' }),
|
createdAt: timestamp('created_at', { mode: 'string' }),
|
||||||
reporterTeamId: int('reporter_team_id')
|
reporterTeamId: int('reporter_team_id').references(() => team.id),
|
||||||
.notNull()
|
|
||||||
.references(() => team.id),
|
|
||||||
reportedTeamId: int('reported_team_id').references(() => team.id)
|
reportedTeamId: int('reported_team_id').references(() => team.id)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -24,7 +22,7 @@ export type AddReportReq = {
|
|||||||
reason: string;
|
reason: string;
|
||||||
body: string | null;
|
body: string | null;
|
||||||
createdAt?: string | null;
|
createdAt?: string | null;
|
||||||
reporterTeamId: number;
|
reporterTeamId?: number;
|
||||||
reportedTeamId?: number | null;
|
reportedTeamId?: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -34,19 +32,21 @@ export type GetReportsReq = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export async function addReport(db: Database, values: AddReportReq) {
|
export async function addReport(db: Database, values: AddReportReq) {
|
||||||
|
const urlHash = generateRandomString(16);
|
||||||
|
|
||||||
const r = await db
|
const r = await db
|
||||||
.insert(report)
|
.insert(report)
|
||||||
.values({
|
.values({
|
||||||
reason: values.reason,
|
reason: values.reason,
|
||||||
body: values.body,
|
body: values.body,
|
||||||
urlHash: generateRandomString(16),
|
urlHash: urlHash,
|
||||||
createdAt: values.createdAt,
|
createdAt: values.createdAt,
|
||||||
reporterTeamId: values.reporterTeamId,
|
reporterTeamId: values.reporterTeamId,
|
||||||
reportedTeamId: values.reportedTeamId
|
reportedTeamId: values.reportedTeamId
|
||||||
})
|
})
|
||||||
.$returningId();
|
.$returningId();
|
||||||
|
|
||||||
return r[0];
|
return Object.assign(r[0], { url: `${BASE_PATH}/report/${urlHash}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getReports(db: Database, values: GetReportsReq) {
|
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))
|
.innerJoin(reporterTeam, eq(report.reporterTeamId, reporterTeam.id))
|
||||||
.leftJoin(reportedTeam, eq(report.reportedTeamId, reportedTeam.id))
|
.leftJoin(reportedTeam, eq(report.reportedTeamId, reportedTeam.id))
|
||||||
.leftJoin(reportStatus, eq(report.id, reportStatus.reportId))
|
.leftJoin(reportStatus, eq(report.id, reportStatus.reportId))
|
||||||
.leftJoin(strike, eq(reportStatus.strikeId, strike.id))
|
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
values.reporter != null ? eq(report.reporterTeamId, reporterIdSubquery!.id) : undefined,
|
values.reporter != null ? eq(report.reporterTeamId, reporterIdSubquery!.id) : undefined,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { int, mysqlEnum, mysqlTable, text } from 'drizzle-orm/mysql-core';
|
import { int, mysqlEnum, mysqlTable, text } from 'drizzle-orm/mysql-core';
|
||||||
import { strike } from './strike.ts';
|
|
||||||
import { admin } from './admin.ts';
|
import { admin } from './admin.ts';
|
||||||
import { report } from './report.ts';
|
import { report } from './report.ts';
|
||||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||||
@ -15,8 +14,7 @@ export const reportStatus = mysqlTable('report_status', {
|
|||||||
.notNull()
|
.notNull()
|
||||||
.unique()
|
.unique()
|
||||||
.references(() => report.id),
|
.references(() => report.id),
|
||||||
reviewerId: int('reviewer_id').references(() => admin.id),
|
reviewerId: int('reviewer_id').references(() => admin.id)
|
||||||
strikeId: int('strike_id').references(() => strike.id)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type GetReportStatusReq = {
|
export type GetReportStatusReq = {
|
||||||
@ -28,7 +26,6 @@ export type EditReportStatusReq = {
|
|||||||
status: 'open' | 'closed' | null;
|
status: 'open' | 'closed' | null;
|
||||||
notice: string | null;
|
notice: string | null;
|
||||||
statement: string | null;
|
statement: string | null;
|
||||||
strikeId: number | null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function getReportStatus(db: Database, values: GetReportStatusReq) {
|
export async function getReportStatus(db: Database, values: GetReportStatusReq) {
|
||||||
@ -47,8 +44,7 @@ export async function editReportStatus(db: Database, values: EditReportStatusReq
|
|||||||
set: {
|
set: {
|
||||||
status: values.status,
|
status: values.status,
|
||||||
notice: values.notice,
|
notice: values.notice,
|
||||||
statement: values.statement,
|
statement: values.statement
|
||||||
strikeId: values.strikeId
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -8,27 +8,50 @@ import { reportStatus } from '@db/schema/reportStatus.ts';
|
|||||||
type Database = MySql2Database<{ strike: typeof strike }>;
|
type Database = MySql2Database<{ strike: typeof strike }>;
|
||||||
|
|
||||||
export const strike = mysqlTable('strike', {
|
export const strike = mysqlTable('strike', {
|
||||||
id: int('id').primaryKey().autoincrement(),
|
at: timestamp('at', { mode: 'date' }).notNull(),
|
||||||
at: timestamp('at', { mode: 'string' }).notNull(),
|
reportId: int('report_id')
|
||||||
|
.notNull()
|
||||||
|
.references(() => report.id),
|
||||||
strikeReasonId: int('strike_reason_id')
|
strikeReasonId: int('strike_reason_id')
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => strikeReason.id)
|
.references(() => strikeReason.id)
|
||||||
});
|
});
|
||||||
|
|
||||||
export type GetStrikesByTeamId = {
|
export type EditStrikeReq = {
|
||||||
|
reportId: number;
|
||||||
|
at?: Date;
|
||||||
|
strikeReasonId: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetStrikesByTeamIdReq = {
|
||||||
teamId: number;
|
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
|
return db
|
||||||
.select({
|
.select({
|
||||||
id: strike.id,
|
|
||||||
at: strike.at,
|
at: strike.at,
|
||||||
|
report: report,
|
||||||
reason: strikeReason
|
reason: strikeReason
|
||||||
})
|
})
|
||||||
.from(strike)
|
.from(strike)
|
||||||
.innerJoin(strikeReason, eq(strike.strikeReasonId, strikeReason.id))
|
.innerJoin(strikeReason, eq(strike.strikeReasonId, strikeReason.id))
|
||||||
.innerJoin(reportStatus, eq(strike.id, reportStatus.strikeId))
|
|
||||||
.innerJoin(report, eq(reportStatus.reportId, report.id))
|
.innerJoin(report, eq(reportStatus.reportId, report.id))
|
||||||
.where(eq(report.reportedTeamId, values.teamId));
|
.where(eq(report.reportedTeamId, values.teamId));
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import { user } from './user.ts';
|
|||||||
import { teamDraft } from './teamDraft.ts';
|
import { teamDraft } from './teamDraft.ts';
|
||||||
import { death } from '@db/schema/death.ts';
|
import { death } from '@db/schema/death.ts';
|
||||||
import { report } from '@db/schema/report.ts';
|
import { report } from '@db/schema/report.ts';
|
||||||
import { reportStatus } from '@db/schema/reportStatus.ts';
|
|
||||||
import { strikeReason } from '@db/schema/strikeReason.ts';
|
import { strikeReason } from '@db/schema/strikeReason.ts';
|
||||||
import { strike } from '@db/schema/strike.ts';
|
import { strike } from '@db/schema/strike.ts';
|
||||||
|
|
||||||
@ -142,8 +141,7 @@ export async function getTeamsFull(db: Database, _values: GetTeamsFullReq) {
|
|||||||
})
|
})
|
||||||
.from(strike)
|
.from(strike)
|
||||||
.innerJoin(strikeReason, eq(strike.strikeReasonId, strikeReason.id))
|
.innerJoin(strikeReason, eq(strike.strikeReasonId, strikeReason.id))
|
||||||
.innerJoin(reportStatus, eq(strike.id, reportStatus.strikeId))
|
.innerJoin(report, eq(strike.reportId, report.id))
|
||||||
.innerJoin(report, eq(reportStatus.reportId, report.id))
|
|
||||||
.innerJoin(team, eq(report.reportedTeamId, team.id))
|
.innerJoin(team, eq(report.reportedTeamId, team.id))
|
||||||
.as('strike_weight_subquery');
|
.as('strike_weight_subquery');
|
||||||
|
|
||||||
|
96
src/pages/api/report/index.ts
Normal file
96
src/pages/api/report/index.ts
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import type { APIRoute } from 'astro';
|
||||||
|
import { z } from 'astro:schema';
|
||||||
|
import { API_SECRET } from 'astro:env/server';
|
||||||
|
import { db } from '@db/database.ts';
|
||||||
|
|
||||||
|
const postSchema = z.object({
|
||||||
|
reporter: z.string(),
|
||||||
|
reported: z.string().nullable(),
|
||||||
|
reason: z.string()
|
||||||
|
});
|
||||||
|
|
||||||
|
export const POST: APIRoute = async ({ request }) => {
|
||||||
|
if (API_SECRET && request.headers.get('authorization') !== `Basic ${API_SECRET}`) {
|
||||||
|
return new Response(null, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsed;
|
||||||
|
try {
|
||||||
|
parsed = await postSchema.parseAsync(await request.json());
|
||||||
|
} catch (_) {
|
||||||
|
return new Response(null, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const reporterTeam = await db.getTeamByUserUuid({ uuid: parsed.reporter });
|
||||||
|
if (!reporterTeam) return new Response(null, { status: 404 });
|
||||||
|
|
||||||
|
let reportedTeam = null;
|
||||||
|
if (parsed.reported) {
|
||||||
|
reportedTeam = await db.getTeamByUserUuid({ uuid: parsed.reported });
|
||||||
|
if (!reportedTeam) return new Response(null, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const report = await db.addReport({
|
||||||
|
reporterTeamId: reporterTeam.team.id,
|
||||||
|
reportedTeamId: reportedTeam?.team.id,
|
||||||
|
reason: parsed.reason,
|
||||||
|
body: null
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Response(JSON.stringify({ url: report.url }), { status: 200 });
|
||||||
|
};
|
||||||
|
|
||||||
|
const putSchema = z.object({
|
||||||
|
reporter: z.string().nullable(),
|
||||||
|
reported: z.string(),
|
||||||
|
reason: z.string(),
|
||||||
|
body: z.string().nullable(),
|
||||||
|
notice: z.string().nullable(),
|
||||||
|
statement: z.string().nullable(),
|
||||||
|
strike_reason_id: z.number()
|
||||||
|
});
|
||||||
|
|
||||||
|
export const PUT: APIRoute = async ({ request }) => {
|
||||||
|
if (API_SECRET && request.headers.get('authorization') !== `Basic ${API_SECRET}`) {
|
||||||
|
return new Response(null, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsed;
|
||||||
|
try {
|
||||||
|
parsed = await putSchema.parseAsync(await request.json());
|
||||||
|
} catch (_) {
|
||||||
|
return new Response(null, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
let reporterTeam = null;
|
||||||
|
if (parsed.reported) {
|
||||||
|
reporterTeam = await db.getTeamByUserUuid({ uuid: parsed.reported });
|
||||||
|
if (!reporterTeam) return new Response(null, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const reportedTeam = await db.getTeamByUserUuid({ uuid: parsed.reported });
|
||||||
|
if (!reportedTeam) return new Response(null, { status: 404 });
|
||||||
|
|
||||||
|
await db.transaction(async (tx) => {
|
||||||
|
const report = await tx.addReport({
|
||||||
|
reporterTeamId: reporterTeam?.team.id,
|
||||||
|
reportedTeamId: reportedTeam.team.id,
|
||||||
|
reason: parsed.reason,
|
||||||
|
body: parsed.body
|
||||||
|
});
|
||||||
|
|
||||||
|
await tx.editReportStatus({
|
||||||
|
reportId: report.id,
|
||||||
|
notice: parsed.notice,
|
||||||
|
statement: parsed.statement,
|
||||||
|
status: 'closed'
|
||||||
|
});
|
||||||
|
|
||||||
|
await tx.editStrike({
|
||||||
|
reportId: report.id,
|
||||||
|
strikeReasonId: parsed.strike_reason_id
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Response(null, { status: 200 });
|
||||||
|
};
|
Reference in New Issue
Block a user