Files
NianAIGC/app/api/admin/organizations/route.ts

90 lines
3.6 KiB
TypeScript

import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api";
import { requireAdminSession } from "@/lib/server/auth/current-user";
import {
AccountStoreError,
createPlatformOrganization,
deletePlatformOrganization,
listPlatformOrganizations,
updatePlatformOrganization
} from "@/lib/server/account-store";
import { hasSuperAdminAccess } from "@/lib/auth/permissions";
import type { AuthUser } from "@/lib/auth/session";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
export async function GET() {
try {
const session = await requireAdminSession();
const organizations = await listPlatformOrganizations({ includeDisabled: hasSuperAdminAccess(session.user) });
return jsonOk({ organizations: organizations
.filter((organization) => hasSuperAdminAccess(session.user) || organization.id === session.user.organizationId)
.map((organization) => ({ id: organization.id, name: organization.name, status: organization.status })) });
} catch (error) {
return jsonError(error, 500, { source: "api.admin.organizations" });
}
}
export async function POST(request: Request) {
try {
const session = await requireAdminSession();
requireSuperAdmin(session.user);
const body = await readJsonBody<Record<string, unknown>>(request);
const organization = await createPlatformOrganization(requiredString(body.name, "组织名称"));
return jsonOk({ ok: true, organization: publicOrganization(organization) }, { status: 201 });
} catch (error) {
return jsonError(error, 500, { request, source: "api.admin.organizations", logClientErrors: true });
}
}
export async function PATCH(request: Request) {
try {
const session = await requireAdminSession();
requireSuperAdmin(session.user);
const body = await readJsonBody<Record<string, unknown>>(request);
const organization = await updatePlatformOrganization(requiredString(body.organizationId, "组织 ID"), {
name: optionalString(body.name),
status: parseStatus(body.status)
});
return jsonOk({ ok: true, organization: publicOrganization(organization) });
} catch (error) {
return jsonError(error, 500, { request, source: "api.admin.organizations", logClientErrors: true });
}
}
export async function DELETE(request: Request) {
try {
const session = await requireAdminSession();
requireSuperAdmin(session.user);
const body = await readJsonBody<Record<string, unknown>>(request);
await deletePlatformOrganization(requiredString(body.organizationId, "组织 ID"));
return jsonOk({ ok: true });
} catch (error) {
return jsonError(error, 500, { request, source: "api.admin.organizations", logClientErrors: true });
}
}
function requireSuperAdmin(user: AuthUser) {
if (!hasSuperAdminAccess(user)) throw new AccountStoreError("需要超级管理员权限。", 403);
}
function publicOrganization(organization: { id: string; name: string; status: string }) {
return { id: organization.id, name: organization.name, status: organization.status };
}
function requiredString(value: unknown, label: string): string {
const normalized = optionalString(value);
if (!normalized) throw new AccountStoreError(`${label}不能为空。`, 400);
return normalized;
}
function optionalString(value: unknown): string | undefined {
return typeof value === "string" && value.trim() ? value.trim() : undefined;
}
function parseStatus(value: unknown): "active" | "disabled" | undefined {
if (value === undefined || value === null || value === "") return undefined;
if (value === "active" || value === "disabled") return value;
throw new AccountStoreError("组织状态不正确。", 400);
}