Skip to content

Commit 80eb089

Browse files
Merge pull request #40 from Eshvar-Thevar/Reports
Reports table issue finished
2 parents a5bb0a6 + 257faac commit 80eb089

File tree

4 files changed

+91
-14
lines changed

4 files changed

+91
-14
lines changed

.env.example

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/app/api/reports/route.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// This file defines the API route for POST /api/reports
2+
// It lets logged-in users submit a report for a specific file.
3+
4+
import { NextResponse } from "next/server"; // Used to send HTTP responses (JSON, status codes)
5+
import { z } from "zod"; // Zod validates and parses input data
6+
7+
// Import database connection and the "report" table schema
8+
import { db } from "@src/server/db";
9+
import { report } from "@src/server/db/schema/reports";
10+
11+
// Import session helper to check if a user is logged in
12+
import { getServerAuthSession } from "@src/server/auth";
13+
14+
// This ensures the API only accepts the correct fields
15+
const CreateReportSchema = z.object({
16+
fileId: z.string().min(1),
17+
category: z
18+
.enum(["inappropriate", "copyright", "spam", "other"])
19+
.default("other"),
20+
details: z.string().min(1),
21+
});
22+
23+
// This function runs when someone sends a POST request to /api/reports
24+
export async function POST(req: Request) {
25+
const session = await getServerAuthSession();
26+
27+
// If there’s no session or no user ID, reject the request
28+
if (!session?.user?.id) {
29+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
30+
}
31+
32+
// Try to parse and validate the incoming request body
33+
let body: z.infer<typeof CreateReportSchema>;
34+
try {
35+
body = CreateReportSchema.parse(await req.json());
36+
} catch (e) {
37+
return NextResponse.json(
38+
{ error: "Invalid body", details: (e as Error).message },
39+
{ status: 400 }
40+
);
41+
}
42+
43+
// Insert the validated report into the database
44+
const [created] = await db
45+
.insert(report)
46+
.values({
47+
userId: session.user.id,
48+
fileId: body.fileId,
49+
category: body.category,
50+
details: body.details,
51+
})
52+
.returning(); // return the newly created record
53+
54+
// Send the inserted report back as JSON
55+
return NextResponse.json(created, { status: 201 });
56+
}

src/server/db/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import { env } from '@src/env.mjs';
44
import * as user from './schema/user';
55
import * as file from './schema/file';
66
import * as section from './schema/section';
7+
import * as report from "./schema/reports";
78
const schema = {
89
...file,
910
...section,
1011
...user,
12+
...report
1113
};
1214

1315
export const db = drizzle(env.DATABASE_URL, {

src/server/db/schema/reports.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Minimal table so API can insert a report.
2+
3+
import { sql } from "drizzle-orm";
4+
import { pgTable, text, varchar, timestamp } from "drizzle-orm/pg-core";
5+
import { user } from "./user";
6+
import { file } from "./file";
7+
8+
export const report = pgTable("report", {
9+
id: text("id")
10+
.default(sql`nanoid(20)`)
11+
.primaryKey(),
12+
13+
userId: text("user_id")
14+
.notNull()
15+
.references(() => user.id),
16+
17+
fileId: text("file_id")
18+
.notNull()
19+
.references(() => file.id),
20+
21+
// Short category (e.g., "inappropriate", "copyright", "spam", "other")
22+
category: varchar("category", { length: 32 })
23+
.notNull()
24+
.default("other"),
25+
26+
// Free-text explanation
27+
details: text("details").notNull(),
28+
29+
// Created timestamp
30+
createdAt: timestamp("created_at", { mode: "date" })
31+
.notNull()
32+
.default(sql`now()`),
33+
});

0 commit comments

Comments
 (0)