diff --git a/src/app/admin/logs/page.tsx b/src/app/admin/logs/page.tsx
new file mode 100644
index 0000000..5b274bd
--- /dev/null
+++ b/src/app/admin/logs/page.tsx
@@ -0,0 +1,47 @@
+"use client";
+import useSWR from "swr";
+
+const fetcher = (url: string) => fetch(url).then((r) => r.json());
+
+export default function AdminLogsPage() {
+ const { data: audits } = useSWR<{ logs: any[] }>("/api/admin/audit-logs?limit=100", fetcher);
+ const { data: reports } = useSWR<{ reports: any[] }>("/api/admin/reports", fetcher);
+ const { data: views } = useSWR<{ views: any[] }>("/api/admin/views", fetcher);
+ return (
+
+
감사/신고/열람 로그
+
감사 로그
+
({ a: x.createdAt, b: x.action, c: x.targetType, d: x.targetId }))} headers={["시각", "행위", "대상", "ID"]} />
+ 신고
+ ({ a: x.createdAt, b: x.targetType, c: x.reason, d: x.status }))} headers={["시각", "대상", "사유", "상태"]} />
+ 열람 로그
+ ({ a: x.createdAt, b: x.postId, c: x.userId, d: x.ip }))} headers={["시각", "postId", "userId", "ip"]} />
+
+ );
+}
+
+function Table({ headers, rows }: { headers: string[]; rows: { a: any; b: any; c: any; d: any }[] }) {
+ return (
+
+
+
+ {headers.map((h) => (
+ | {h} |
+ ))}
+
+
+
+ {rows.map((r, i) => (
+
+ | {String(r.a)} |
+ {String(r.b)} |
+ {String(r.c)} |
+ {String(r.d)} |
+
+ ))}
+
+
+ );
+}
+
+
diff --git a/src/app/api/admin/audit-logs/route.ts b/src/app/api/admin/audit-logs/route.ts
new file mode 100644
index 0000000..446a049
--- /dev/null
+++ b/src/app/api/admin/audit-logs/route.ts
@@ -0,0 +1,14 @@
+import { NextResponse } from "next/server";
+import prisma from "@/lib/prisma";
+
+export async function GET(req: Request) {
+ const { searchParams } = new URL(req.url);
+ const limit = Number(searchParams.get("limit") || 100);
+ const logs = await prisma.auditLog.findMany({
+ orderBy: { createdAt: "desc" },
+ take: Math.min(limit, 200),
+ });
+ return NextResponse.json({ logs });
+}
+
+
diff --git a/src/app/api/admin/reports/route.ts b/src/app/api/admin/reports/route.ts
new file mode 100644
index 0000000..08a23e2
--- /dev/null
+++ b/src/app/api/admin/reports/route.ts
@@ -0,0 +1,9 @@
+import { NextResponse } from "next/server";
+import prisma from "@/lib/prisma";
+
+export async function GET() {
+ const items = await prisma.report.findMany({ orderBy: { createdAt: "desc" }, take: 200 });
+ return NextResponse.json({ reports: items });
+}
+
+
diff --git a/src/app/api/admin/views/route.ts b/src/app/api/admin/views/route.ts
new file mode 100644
index 0000000..0eb3dcc
--- /dev/null
+++ b/src/app/api/admin/views/route.ts
@@ -0,0 +1,9 @@
+import { NextResponse } from "next/server";
+import prisma from "@/lib/prisma";
+
+export async function GET() {
+ const items = await prisma.postViewLog.findMany({ orderBy: { createdAt: "desc" }, take: 200 });
+ return NextResponse.json({ views: items });
+}
+
+
diff --git a/todolist.txt b/todolist.txt
index bf79cb3..3dc3fd2 100644
--- a/todolist.txt
+++ b/todolist.txt
@@ -73,7 +73,7 @@
10.2 게시판 스키마/설정 관리 UI o
10.3 사용자 검색/정지/권한 변경 o
10.4 공지/배너 등록 및 노출 설정 o
-10.5 감사 이력/신고 내역/열람 로그
+10.5 감사 이력/신고 내역/열람 로그 o
10.6 카테고리 유형/설정 관리(일반/특수/승인/레벨/익명/태그)
[테스트/품질]