import { Request, Response, NextFunction } from 'express' import { prisma } from '../lib/prisma' import { getAccessLevel, hasAnyAccess } from '../modules/subscriptions/subscription.policy' import { sendUnauthorized, sendPaymentRequired } from './authHelpers' const BLOCKED_STATUSES = ['SUSPENDED', 'PENDING'] /** * Blocks requests for companies with lapsed or unactivated subscriptions. * Must be applied after `requireTenant`. * * Guarantees on success: * req.company.status is not SUSPENDED or PENDING, and subscription access is not none */ export async function requireSubscription(req: Request, res: Response, next: NextFunction) { try { const company = req.company if (!company) return sendUnauthorized(res, 'unauthenticated', 'No company context') if (BLOCKED_STATUSES.includes(company.status)) { return sendPaymentRequired( res, `subscription_${company.status.toLowerCase()}`, company.status === 'SUSPENDED' ? 'Your account has been suspended. Please contact support or renew your subscription.' : 'Your account is pending activation. Please complete your subscription setup.', { billingUrl: `${process.env.NEXT_PUBLIC_DASHBOARD_URL}/subscription` }, ) } const subscription = await prisma.subscription.findUnique({ where: { companyId: company.id }, select: { status: true }, }) const subscriptionStatus = subscription?.status ?? 'EXPIRED' if (!hasAnyAccess(subscriptionStatus)) { return sendPaymentRequired( res, 'subscription_required', 'Your subscription has ended. Please reactivate to continue.', { billingUrl: `${process.env.NEXT_PUBLIC_DASHBOARD_URL}/subscription`, subscriptionStatus, accessLevel: getAccessLevel(subscriptionStatus), }, ) } next() } catch (error) { next(error) } }