fix subscription page
Build & Deploy / Build & Push Docker Image (push) Successful in 7m57s
Test / Type Check (all packages) (push) Successful in 4m27s
Build & Deploy / Deploy to VPS (push) Successful in 7s
Test / API Unit Tests (push) Failing after 3m2s
Test / Homepage Unit Tests (push) Successful in 4m3s
Test / Storefront Unit Tests (push) Successful in 3m32s
Test / Admin Unit Tests (push) Successful in 3m27s
Test / Dashboard Unit Tests (push) Successful in 3m3s
Test / API Integration Tests (push) Failing after 3m53s
Build & Deploy / Build & Push Docker Image (push) Successful in 7m57s
Test / Type Check (all packages) (push) Successful in 4m27s
Build & Deploy / Deploy to VPS (push) Successful in 7s
Test / API Unit Tests (push) Failing after 3m2s
Test / Homepage Unit Tests (push) Successful in 4m3s
Test / Storefront Unit Tests (push) Successful in 3m32s
Test / Admin Unit Tests (push) Successful in 3m27s
Test / Dashboard Unit Tests (push) Successful in 3m3s
Test / API Integration Tests (push) Failing after 3m53s
This commit is contained in:
@@ -71,7 +71,7 @@
|
||||
{
|
||||
"number": "1",
|
||||
"title": "Create Account",
|
||||
"description": "Sign up for your company workspace and choose your pricing plan for the 90-day free trial."
|
||||
"description": "Sign up for your company workspace and choose your pricing plan for the 30-day free trial."
|
||||
},
|
||||
{
|
||||
"number": "2",
|
||||
@@ -89,7 +89,7 @@
|
||||
{
|
||||
"step": "1",
|
||||
"title": "Create your company workspace",
|
||||
"body": "Pick a plan, launch your 90-day trial, and verify the owner account."
|
||||
"body": "Pick a plan, launch your 30-day trial, and verify the owner account."
|
||||
},
|
||||
{
|
||||
"step": "2",
|
||||
@@ -180,7 +180,7 @@
|
||||
{
|
||||
"number": "1",
|
||||
"title": "Créer un compte",
|
||||
"description": "Inscrivez-vous à votre espace entreprise et choisissez votre forfait pour l'essai gratuit de 90 jours."
|
||||
"description": "Inscrivez-vous à votre espace entreprise et choisissez votre forfait pour l'essai gratuit de 30 jours."
|
||||
},
|
||||
{
|
||||
"number": "2",
|
||||
@@ -198,7 +198,7 @@
|
||||
{
|
||||
"step": "1",
|
||||
"title": "Créez votre espace entreprise",
|
||||
"body": "Choisissez un plan, lancez votre essai de 90 jours et vérifiez le compte propriétaire."
|
||||
"body": "Choisissez un plan, lancez votre essai de 30 jours et vérifiez le compte propriétaire."
|
||||
},
|
||||
{
|
||||
"step": "2",
|
||||
@@ -289,7 +289,7 @@
|
||||
{
|
||||
"number": "1",
|
||||
"title": "إنشاء حساب",
|
||||
"description": "قم بالتسجيل للحصول على مساحة عمل شركتك واختر خطتك للتجربة المجانية لمدة 90 يوماً."
|
||||
"description": "قم بالتسجيل للحصول على مساحة عمل شركتك واختر خطتك للتجربة المجانية لمدة 30 يوماً."
|
||||
},
|
||||
{
|
||||
"number": "2",
|
||||
|
||||
@@ -27,7 +27,7 @@ describe('requireSubscription middleware', () => {
|
||||
expect(next).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('blocks suspended companies with a billing URL', () => {
|
||||
it('blocks suspended companies with a subscription recovery URL', () => {
|
||||
const req = { company: { status: 'SUSPENDED' } } as Request
|
||||
const res = responseStub()
|
||||
const next = vi.fn() as NextFunction
|
||||
@@ -39,7 +39,7 @@ describe('requireSubscription middleware', () => {
|
||||
error: 'subscription_suspended',
|
||||
message: 'Your account has been suspended. Please contact support or renew your subscription.',
|
||||
statusCode: 402,
|
||||
billingUrl: 'https://dashboard.example.test/billing',
|
||||
billingUrl: 'https://dashboard.example.test/subscription',
|
||||
})
|
||||
expect(next).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
@@ -21,7 +21,7 @@ export function requireSubscription(req: Request, res: Response, next: NextFunct
|
||||
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}/billing` },
|
||||
{ billingUrl: `${process.env.NEXT_PUBLIC_DASHBOARD_URL}/subscription` },
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ export async function startAccount(body: AccountStartInput) {
|
||||
|
||||
const result = await prisma.$transaction(async (tx: any) => {
|
||||
const now = new Date()
|
||||
const trialEndAt = new Date(now.getTime() + 90 * 24 * 60 * 60 * 1000)
|
||||
const trialEndAt = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000)
|
||||
|
||||
const company = await tx.company.create({
|
||||
data: {
|
||||
|
||||
@@ -13,7 +13,7 @@ import { companySignupSchema } from './auth.company.schemas'
|
||||
import type { output } from 'zod'
|
||||
|
||||
type CompanySignupInput = output<typeof companySignupSchema>
|
||||
const TRIAL_PERIOD_DAYS = 90
|
||||
const TRIAL_PERIOD_DAYS = 30
|
||||
|
||||
function slugify(value: string) {
|
||||
return value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 50) || 'company'
|
||||
|
||||
@@ -2,7 +2,7 @@ export type AccessLevel = 'full' | 'limited' | 'read_only' | 'none'
|
||||
|
||||
export const SUBSCRIPTION_POLICY = {
|
||||
trial: {
|
||||
durationDays: 14,
|
||||
durationDays: 30,
|
||||
requiresPaymentMethod: false, // set true when payment capture is mandatory
|
||||
oneTrialPerCompany: true,
|
||||
},
|
||||
|
||||
@@ -70,18 +70,18 @@ describe('subscription.service operational edges', () => {
|
||||
|
||||
it('builds plans from pricing config rows when platform overrides exist', async () => {
|
||||
vi.mocked(prisma.pricingConfig.findMany).mockResolvedValue([
|
||||
{ plan: 'STARTER', billingPeriod: 'MONTHLY', amount: 9900 },
|
||||
{ plan: 'STARTER', billingPeriod: 'ANNUAL', amount: 99000 },
|
||||
{ plan: 'PRO', billingPeriod: 'MONTHLY', amount: 29900 },
|
||||
{ plan: 'STARTER', billingPeriod: 'MONTHLY', amount: 14900 },
|
||||
{ plan: 'STARTER', billingPeriod: 'ANNUAL', amount: 143040 },
|
||||
{ plan: 'PRO', billingPeriod: 'MONTHLY', amount: 39900 },
|
||||
] as never)
|
||||
|
||||
await expect(service.getPlans()).resolves.toEqual({
|
||||
STARTER: {
|
||||
MONTHLY: { MAD: 9900 },
|
||||
ANNUAL: { MAD: 99000 },
|
||||
MONTHLY: { MAD: 14900 },
|
||||
ANNUAL: { MAD: 143040 },
|
||||
},
|
||||
PRO: {
|
||||
MONTHLY: { MAD: 29900 },
|
||||
MONTHLY: { MAD: 39900 },
|
||||
},
|
||||
})
|
||||
})
|
||||
@@ -102,7 +102,7 @@ describe('subscription.service operational edges', () => {
|
||||
'PRO',
|
||||
'MONTHLY',
|
||||
'MAD',
|
||||
new Date('2026-06-15T00:00:00.000Z'),
|
||||
new Date('2026-07-01T00:00:00.000Z'),
|
||||
)
|
||||
expect(repo.createEvent).toHaveBeenCalledWith(expect.objectContaining({
|
||||
subscriptionId: 'sub_1',
|
||||
|
||||
@@ -94,7 +94,7 @@ describe('auth middleware API boundaries', () => {
|
||||
expect(res.status).toBe(402)
|
||||
expect(res.body).toEqual(expect.objectContaining({
|
||||
error: 'subscription_suspended',
|
||||
billingUrl: 'https://dashboard.example.test/billing',
|
||||
billingUrl: 'https://dashboard.example.test/subscription',
|
||||
}))
|
||||
expect(vehicleService.listVehicles).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ function uniqueEmail(prefix: string) {
|
||||
}
|
||||
|
||||
describe('Company signup API', () => {
|
||||
it('creates new accounts with a 90-day trial period', async () => {
|
||||
it('creates new accounts with a 30-day trial period', async () => {
|
||||
const startedAt = Date.now()
|
||||
|
||||
const res = await request(app)
|
||||
@@ -54,7 +54,7 @@ describe('Company signup API', () => {
|
||||
const trialEndsAt = new Date(res.body.data.trialEndsAt).getTime()
|
||||
const trialDurationDays = (trialEndsAt - startedAt) / (24 * 60 * 60 * 1000)
|
||||
|
||||
expect(trialDurationDays).toBeGreaterThan(89.9)
|
||||
expect(trialDurationDays).toBeLessThan(90.1)
|
||||
expect(trialDurationDays).toBeGreaterThan(29.9)
|
||||
expect(trialDurationDays).toBeLessThan(30.1)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user