Files
nroxy/packages/db/src/bootstrap.ts

97 lines
2.3 KiB
TypeScript

import { Prisma, type PrismaClient } from "@prisma/client";
import { prisma as defaultPrisma } from "./prisma-client.js";
export interface SubscriptionPlanSeedInput {
code: string;
displayName: string;
monthlyRequestLimit: number;
monthlyPriceUsd: number;
billingCurrency: string;
}
export const defaultSubscriptionPlanSeed: SubscriptionPlanSeedInput = {
code: "monthly",
displayName: "Monthly",
monthlyRequestLimit: 100,
monthlyPriceUsd: 9.99,
billingCurrency: "USDT",
};
export async function ensureSubscriptionPlan(
input: SubscriptionPlanSeedInput,
database: PrismaClient = defaultPrisma,
): Promise<void> {
await reconcileDefaultSubscriptionPlan(input, database);
await database.subscriptionPlan.upsert({
where: {
code: input.code,
},
update: {
displayName: input.displayName,
monthlyRequestLimit: input.monthlyRequestLimit,
monthlyPriceUsd: new Prisma.Decimal(input.monthlyPriceUsd),
billingCurrency: input.billingCurrency,
isActive: true,
},
create: {
code: input.code,
displayName: input.displayName,
monthlyRequestLimit: input.monthlyRequestLimit,
monthlyPriceUsd: new Prisma.Decimal(input.monthlyPriceUsd),
billingCurrency: input.billingCurrency,
isActive: true,
},
});
}
export async function ensureDefaultSubscriptionPlan(
database: PrismaClient = defaultPrisma,
): Promise<void> {
await ensureSubscriptionPlan(defaultSubscriptionPlanSeed, database);
}
async function reconcileDefaultSubscriptionPlan(
input: SubscriptionPlanSeedInput,
database: PrismaClient,
): Promise<void> {
const existing = await database.subscriptionPlan.findUnique({
where: {
code: input.code,
},
select: {
id: true,
},
});
if (existing) {
return;
}
const candidate = await database.subscriptionPlan.findFirst({
where: {
monthlyRequestLimit: input.monthlyRequestLimit,
monthlyPriceUsd: new Prisma.Decimal(input.monthlyPriceUsd),
billingCurrency: input.billingCurrency,
},
orderBy: {
createdAt: "asc",
},
});
if (!candidate) {
return;
}
await database.subscriptionPlan.update({
where: {
id: candidate.id,
},
data: {
code: input.code,
displayName: input.displayName,
isActive: true,
},
});
}