fix(billing): build su VPS — ExtendedPrismaClient, apiVersion Stripe
Tre fix che emergono solo durante il build di produzione (typecheck stretto, niente tsx watch lazy):
- `packages/db` ora ri-esporta Subscription / BillingWebhookEvent / SubscriptionStatus / BillingInterval / Achievement, così non serve importare da `@prisma/client` direttamente da apps/api (che non ce l'ha tra le deps).
- `apps/api/src/modules/billing/{service,webhook.routes}.ts` usano ExtendedPrismaClient (il client post-`$extends` di prisma-field-encryption) invece di PrismaClient base. Il client esteso ha tipi diversi per via dell'estensione, e la tipizzazione stretta lo richiede.
- `apiVersion` di Stripe portata a `2026-04-22.dahlia` (la versione corrente in stripe@22.x). La precedente `2025-09-30.clover` era già obsoleta nei tipi.
Lint pulito, 99/99 test verdi, build api ok in locale.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
11d73eae69
commit
d98f95b7ca
4 files changed
+14
-9
No files matched your search
@@ -1,10 +1,10 @@
|
||||
import type { ExtendedPrismaClient, Subscription } from '@ketopath/db';
|
||||
import {
|
||||
computeTrialEndsAt,
|
||||
isProActive,
|
||||
type SubscriptionSnapshot,
|
||||
type SubscriptionStatus as SharedStatus,
|
||||
} from '@ketopath/shared';
|
||||
import type { PrismaClient, Subscription } from '@prisma/client';
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import type Stripe from 'stripe';
|
||||
|
||||
@@ -29,7 +29,7 @@ export function toSnapshot(sub: Subscription | null): SubscriptionSnapshot | nul
|
||||
* dalla data di registrazione. Idempotente: se esiste già, non tocca nulla.
|
||||
*/
|
||||
export async function ensureSubscription(
|
||||
prisma: PrismaClient,
|
||||
prisma: ExtendedPrismaClient,
|
||||
userId: string,
|
||||
signupAt: Date,
|
||||
): Promise<Subscription> {
|
||||
@@ -45,13 +45,13 @@ export async function ensureSubscription(
|
||||
}
|
||||
|
||||
export async function getSubscription(
|
||||
prisma: PrismaClient,
|
||||
prisma: ExtendedPrismaClient,
|
||||
userId: string,
|
||||
): Promise<Subscription | null> {
|
||||
return prisma.subscription.findUnique({ where: { userId } });
|
||||
}
|
||||
|
||||
export async function isUserPro(prisma: PrismaClient, userId: string): Promise<boolean> {
|
||||
export async function isUserPro(prisma: ExtendedPrismaClient, userId: string): Promise<boolean> {
|
||||
const sub = await getSubscription(prisma, userId);
|
||||
return isProActive(toSnapshot(sub));
|
||||
}
|
||||
@@ -100,7 +100,7 @@ function mapInterval(
|
||||
* payload N volte senza side effect.
|
||||
*/
|
||||
export async function applyStripeSubscription(
|
||||
prisma: PrismaClient,
|
||||
prisma: ExtendedPrismaClient,
|
||||
stripeSub: Stripe.Subscription,
|
||||
): Promise<void> {
|
||||
const userId = stripeSub.metadata?.userId;
|
||||
@@ -153,7 +153,7 @@ export async function applyStripeSubscription(
|
||||
* Invocata da uno scheduler giornaliero (vedi notifications/scheduler).
|
||||
* Restituisce il numero di record aggiornati.
|
||||
*/
|
||||
export async function expireFinishedTrials(prisma: PrismaClient, now: Date = new Date()) {
|
||||
export async function expireFinishedTrials(prisma: ExtendedPrismaClient, now: Date = new Date()) {
|
||||
const res = await prisma.subscription.updateMany({
|
||||
where: {
|
||||
status: 'TRIALING',
|
||||
|
||||
@@ -18,7 +18,7 @@ export function getStripe(): Stripe {
|
||||
_stripe = new Stripe(billingEnv.STRIPE_SECRET_KEY, {
|
||||
// Pin esplicito: niente sorprese quando Stripe rilascia una nuova
|
||||
// apiVersion. Aggiornare insieme allo `stripe` package.
|
||||
apiVersion: '2025-09-30.clover',
|
||||
apiVersion: '2026-04-22.dahlia',
|
||||
typescript: true,
|
||||
appInfo: { name: 'KetoPath', version: '0.0.0' },
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { PrismaClient } from '@prisma/client';
|
||||
import type { ExtendedPrismaClient } from '@ketopath/db';
|
||||
import type { FastifyPluginAsync } from 'fastify';
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import type Stripe from 'stripe';
|
||||
@@ -88,7 +88,7 @@ export const stripeWebhookRoutes: FastifyPluginAsync = async (parent) => {
|
||||
};
|
||||
|
||||
async function dispatchEvent(
|
||||
prisma: PrismaClient,
|
||||
prisma: ExtendedPrismaClient,
|
||||
stripe: Stripe,
|
||||
event: Stripe.Event,
|
||||
): Promise<void> {
|
||||
|
||||
@@ -2,6 +2,7 @@ export { prisma } from './client.js';
|
||||
export type { ExtendedPrismaClient } from './client.js';
|
||||
export {
|
||||
ActivityLevel,
|
||||
BillingInterval,
|
||||
CookingTime,
|
||||
Difficulty,
|
||||
FastStatus,
|
||||
@@ -12,9 +13,12 @@ export {
|
||||
Phase,
|
||||
Prisma,
|
||||
Role,
|
||||
SubscriptionStatus,
|
||||
} from '@prisma/client';
|
||||
export type {
|
||||
Account,
|
||||
Achievement,
|
||||
BillingWebhookEvent,
|
||||
DeviceToken,
|
||||
FastEvent,
|
||||
Ingredient,
|
||||
@@ -26,6 +30,7 @@ export type {
|
||||
Recipe,
|
||||
RecipeIngredient,
|
||||
Session,
|
||||
Subscription,
|
||||
User,
|
||||
Verification,
|
||||
WeightEntry,
|
||||
|
||||
Reference in new issue
Block a user