import { getApproximateQuotaBucket, type QuotaBucket } from "@nproxy/domain"; import type { PrismaClient, SubscriptionStatus } from "@prisma/client"; import { Prisma } from "@prisma/client"; import { prisma as defaultPrisma } from "./prisma-client.js"; export interface UserAccountOverview { user: { id: string; email: string; isAdmin: boolean; createdAt: Date; }; subscription: { id: string; status: SubscriptionStatus; renewsManually: boolean; activatedAt?: Date; currentPeriodStart?: Date; currentPeriodEnd?: Date; canceledAt?: Date; plan: { id: string; code: string; displayName: string; monthlyRequestLimit: number; monthlyPriceUsd: number; billingCurrency: string; isActive: boolean; }; } | null; quota: { approximateBucket: QuotaBucket; usedSuccessfulRequests: number; monthlyRequestLimit: number; } | null; } export function createPrismaAccountStore(database: PrismaClient = defaultPrisma) { return { async getUserAccountOverview(userId: string): Promise { const user = await database.user.findUnique({ where: { id: userId, }, }); if (!user) { return null; } const subscription = await database.subscription.findFirst({ where: { userId, }, include: { plan: true, }, orderBy: [ { currentPeriodEnd: "desc" }, { createdAt: "desc" }, ], }); const quota = subscription ? await buildQuotaSnapshot(database, userId, { monthlyRequestLimit: subscription.plan.monthlyRequestLimit, cycleStart: subscription.currentPeriodStart ?? subscription.activatedAt ?? subscription.createdAt, }) : null; return { user: { id: user.id, email: user.email, isAdmin: user.isAdmin, createdAt: user.createdAt, }, subscription: subscription ? { id: subscription.id, status: subscription.status, renewsManually: subscription.renewsManually, ...(subscription.activatedAt ? { activatedAt: subscription.activatedAt } : {}), ...(subscription.currentPeriodStart ? { currentPeriodStart: subscription.currentPeriodStart } : {}), ...(subscription.currentPeriodEnd ? { currentPeriodEnd: subscription.currentPeriodEnd } : {}), ...(subscription.canceledAt ? { canceledAt: subscription.canceledAt } : {}), plan: { id: subscription.plan.id, code: subscription.plan.code, displayName: subscription.plan.displayName, monthlyRequestLimit: subscription.plan.monthlyRequestLimit, monthlyPriceUsd: decimalToNumber(subscription.plan.monthlyPriceUsd), billingCurrency: subscription.plan.billingCurrency, isActive: subscription.plan.isActive, }, } : null, quota, }; }, }; } function decimalToNumber(value: Prisma.Decimal | { toNumber(): number }): number { return value.toNumber(); } async function buildQuotaSnapshot( database: PrismaClient, userId: string, input: { monthlyRequestLimit: number; cycleStart: Date; }, ): Promise { const usageAggregation = await database.usageLedgerEntry.aggregate({ where: { userId, entryType: "generation_success", createdAt: { gte: input.cycleStart, }, }, _sum: { deltaRequests: true, }, }); const usedSuccessfulRequests = usageAggregation._sum.deltaRequests ?? 0; return { approximateBucket: getApproximateQuotaBucket({ used: usedSuccessfulRequests, limit: input.monthlyRequestLimit, }), usedSuccessfulRequests, monthlyRequestLimit: input.monthlyRequestLimit, }; }