feat: add local auth billing and usage management

This commit is contained in:
inman committed 2026-08-12 12:13:06 +08:00
1 parent f642b5e71f
commit 196fdde83f
119 files changed
+15695 -2650

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api";
import { requireAppSession } from "@/lib/server/auth/current-user";
import { requestOrigin } from "@/lib/server/runtime";
import { resolvePlatformUsageContext } from "@/lib/server/usage-context";
import { quoteImageGeneration, type SubmitImageJobInput } from "@/lib/server/generation-service";
import { quoteVideoGeneration, type SubmitVideoJobInput } from "@/lib/server/video-generation-service";
export const runtime = "nodejs";
export async function POST(request: Request) {
try {
const session = await requireAppSession();
const body = await readJsonBody<Record<string, unknown>>(request);
const usageContext = await resolvePlatformUsageContext(session);
const kind = body.kind === "video" || body.capability === "video.generate" ? "video" : "image";
const quote = kind === "video"
? await quoteVideoGeneration({ ...body, ownerId: session.user.id, usageContext } as SubmitVideoJobInput, requestOrigin(request))
: await quoteImageGeneration({ ...body, capability: "image.generate", ownerId: session.user.id, usageContext } as SubmitImageJobInput, requestOrigin(request));
return jsonOk({ quote });
} catch (error) {
return jsonError(error, 500, { request, source: "api.billing.quote" });
}
}
+24
View File
@@ -0,0 +1,24 @@
import { jsonError, jsonOk } from "@/lib/server/api";
import { requireAppSession } from "@/lib/server/auth/current-user";
import { getBillingOverview } from "@/lib/server/billing-service";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
export async function GET() {
try {
const session = await requireAppSession();
const organizationId = session.user.organizationId;
if (!organizationId) throw Object.assign(new Error("当前账号未绑定组织。"), { status: 422 });
const overview = await getBillingOverview({ organizationId, accountId: session.user.id });
return jsonOk({
organization: {
id: organizationId,
name: session.user.organizationName || organizationId
},
...overview
});
} catch (error) {
return jsonError(error, 500, { source: "api.billing" });
}
}