gitdataai/admin/src/app/api/permissions/route.ts
ZhenYi 3773fdc780 feat(admin): add structured error logger for all API routes
Replace bare console.error() calls with logError() utility across all
47 API route handlers. logError() prints timestamp + context + message
+ stack trace + extra request data to stderr, and redacts sensitive
fields (password, token, secret, key, etc.) from logged objects.
2026-04-23 09:55:35 +08:00

133 lines
4.0 KiB
TypeScript

import { logError } from "@/lib/logger";
import { NextRequest, NextResponse } from "next/server";
import {
listPermissions,
createPermission,
updatePermission,
deletePermission,
} from "@/lib/rbac";
import { createAuditLog } from "@/lib/log";
function getAuthInfo(req: NextRequest) {
return {
userId: parseInt(req.headers.get("x-admin-user-id") || "0", 10),
username: req.headers.get("x-admin-username") || "unknown",
};
}
export async function GET() {
try {
const permissions = await listPermissions();
return NextResponse.json({ permissions });
} catch (e) {
logError("List permissions error:", e);
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
}
}
export async function POST(req: NextRequest) {
try {
const body = await req.json() as {
name?: string;
code?: string;
description?: string;
};
const { name = "", code = "", description = "" } = body;
if (!name || !code) {
return NextResponse.json({ error: "名称和代码不能为空" }, { status: 400 });
}
if (!/^[a-z0-9_:]+$/.test(code)) {
return NextResponse.json(
{ error: "代码只能包含小写字母、数字、冒号和下划线" },
{ status: 400 }
);
}
const permission = await createPermission(name, code, description);
const { userId, username } = getAuthInfo(req);
await createAuditLog({
userId,
username,
action: "create",
resource: "admin_permission",
resourceId: String(permission.id),
requestParams: { name, code, description },
ipAddress: req.headers.get("x-forwarded-for") || undefined,
userAgent: req.headers.get("user-agent") || undefined,
});
return NextResponse.json(permission, { status: 201 });
} catch (e: unknown) {
if ((e as { code?: string }).code === "23505") {
return NextResponse.json({ error: "权限代码已存在" }, { status: 409 });
}
logError("Create permission error:", e);
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
}
}
export async function PUT(req: NextRequest) {
try {
const body = await req.json() as {
id?: number;
name?: string;
code?: string;
description?: string;
};
const { id, name = "", code = "", description = "" } = body;
if (!id) return NextResponse.json({ error: "ID 不能为空" }, { status: 400 });
const permission = await updatePermission(id, name, code, description);
if (!permission) return NextResponse.json({ error: "权限不存在" }, { status: 404 });
const { userId, username } = getAuthInfo(req);
await createAuditLog({
userId,
username,
action: "update",
resource: "admin_permission",
resourceId: String(id),
requestParams: { name, code, description },
ipAddress: req.headers.get("x-forwarded-for") || undefined,
userAgent: req.headers.get("user-agent") || undefined,
});
return NextResponse.json(permission);
} catch (e) {
logError("Update permission error:", e);
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
}
}
export async function DELETE(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const id = parseInt(searchParams.get("id") || "0", 10);
if (!id) return NextResponse.json({ error: "ID 不能为空" }, { status: 400 });
const ok = await deletePermission(id);
if (!ok) return NextResponse.json({ error: "权限不存在" }, { status: 404 });
const { userId, username } = getAuthInfo(req);
await createAuditLog({
userId,
username,
action: "delete",
resource: "admin_permission",
resourceId: String(id),
ipAddress: req.headers.get("x-forwarded-for") || undefined,
userAgent: req.headers.get("user-agent") || undefined,
});
return NextResponse.json({ success: true });
} catch (e) {
logError("Delete permission error:", e);
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
}
}