61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
import { prisma } from "@/lib/prisma";
|
|
|
|
// НЕ "clean-pdf": так CopyButton логирует копирования — они не должны тратить лимит
|
|
export const PDF_TOOL_ID = "clean-pdf-generate";
|
|
export const BURST_LIMIT = 5; // успешных генераций в минуту
|
|
const BURST_WINDOW_MS = 60_000;
|
|
|
|
export function decidePaidAccess(input: {
|
|
role: string;
|
|
banned: boolean;
|
|
enrollments: { courseSlug: string; expiresAt: Date | null }[];
|
|
freeSlug: string;
|
|
now?: Date;
|
|
}): boolean {
|
|
const now = input.now ?? new Date();
|
|
if (input.banned) return false;
|
|
if (input.role === "admin" || input.role === "curator") return true;
|
|
return input.enrollments.some(
|
|
(e) => e.courseSlug !== input.freeSlug && (e.expiresAt === null || e.expiresAt > now),
|
|
);
|
|
}
|
|
|
|
export async function hasPaidAccess(userId: string): Promise<boolean> {
|
|
const user = await prisma.user.findUnique({
|
|
where: { id: userId },
|
|
select: {
|
|
role: true,
|
|
banned: true,
|
|
enrollments: { select: { expiresAt: true, course: { select: { slug: true } } } },
|
|
},
|
|
});
|
|
if (!user) return false;
|
|
return decidePaidAccess({
|
|
role: user.role,
|
|
banned: user.banned ?? false,
|
|
freeSlug: process.env.FREE_COURSE_SLUG ?? "obsidian-start",
|
|
enrollments: user.enrollments.map((e) => ({ courseSlug: e.course.slug, expiresAt: e.expiresAt })),
|
|
});
|
|
}
|
|
|
|
export function monthStartUtc(now: Date): Date {
|
|
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1));
|
|
}
|
|
|
|
export function getMonthlyLimit(): number {
|
|
const n = Number(process.env.PDF_MONTHLY_LIMIT);
|
|
return Number.isFinite(n) && n > 0 ? n : 100;
|
|
}
|
|
|
|
export async function getMonthlyUsage(userId: string): Promise<number> {
|
|
return prisma.toolUsage.count({
|
|
where: { userId, tool: PDF_TOOL_ID, createdAt: { gte: monthStartUtc(new Date()) } },
|
|
});
|
|
}
|
|
|
|
export async function getBurstUsage(userId: string): Promise<number> {
|
|
return prisma.toolUsage.count({
|
|
where: { userId, tool: PDF_TOOL_ID, createdAt: { gte: new Date(Date.now() - BURST_WINDOW_MS) } },
|
|
});
|
|
}
|