Pro/business

This commit is contained in:
Timo Knuth
2026-07-06 00:18:06 +02:00
parent 0b9c8d2a8f
commit 91bd940edc
10 changed files with 384 additions and 40 deletions

View File

@@ -12,7 +12,12 @@ type ScoreReason =
| 'onboarding_update'
| 'qr_created'
| 'scan_recorded'
| 'subscription_changed';
| 'subscription_changed'
| 'subscription_created'
| 'subscription_updated'
| 'subscription_canceled_at_period_end'
| 'subscription_deleted'
| 'subscription_synced';
type UserForScoring = {
id: string;
@@ -159,7 +164,27 @@ export async function scoreUserLifecycle(userId: string, reason: ScoreReason) {
},
});
if (user.lifecycleStage !== nextStage) {
const isSubscriptionReason = reason.startsWith('subscription_');
const recentSubscriptionLog = isSubscriptionReason
? await db.userLifecycleLog.findFirst({
where: {
userId,
reason,
createdAt: {
gte: new Date(Date.now() - 10 * 60 * 1000),
},
},
select: {
id: true,
},
})
: null;
const shouldLogLifecycleEvent =
user.lifecycleStage !== nextStage ||
(isSubscriptionReason && !recentSubscriptionLog);
if (shouldLogLifecycleEvent) {
await db.userLifecycleLog.create({
data: {
userId,

View File

@@ -20,7 +20,7 @@ export function validateStripeKey() {
}
}
export const STRIPE_PLANS = {
export const STRIPE_PLANS = {
FREE: {
name: 'Free / Starter',
price: 0,
@@ -80,6 +80,28 @@ export const STRIPE_PLANS = {
priceId: process.env.STRIPE_PRICE_ID_BUSINESS_MONTHLY,
priceIdYearly: process.env.STRIPE_PRICE_ID_BUSINESS_YEARLY,
},
} as const;
export type PlanType = keyof typeof STRIPE_PLANS;
} as const;
export type PlanType = keyof typeof STRIPE_PLANS;
export function getPlanFromStripePriceId(priceId?: string | null): Exclude<PlanType, 'FREE'> | null {
if (!priceId) {
return null;
}
if (
priceId === process.env.STRIPE_PRICE_ID_BUSINESS_MONTHLY ||
priceId === process.env.STRIPE_PRICE_ID_BUSINESS_YEARLY
) {
return 'BUSINESS';
}
if (
priceId === process.env.STRIPE_PRICE_ID_PRO_MONTHLY ||
priceId === process.env.STRIPE_PRICE_ID_PRO_YEARLY
) {
return 'PRO';
}
return null;
}