fix plan issues
Build & Push / Pipeline Tests (push) Successful in 2m1s
Test / Type Check (all packages) (push) Successful in 53s
Build & Push / Build & Push Docker Image (push) Successful in 5m29s
Test / API Unit Tests (push) Successful in 1m18s
Test / Homepage Unit Tests (push) Successful in 46s
Test / Carplace Unit Tests (push) Successful in 43s
Test / Admin Unit Tests (push) Successful in 40s
Test / Dashboard Unit Tests (push) Successful in 42s
Test / API Integration Tests (push) Successful in 1m9s

This commit is contained in:
root
2026-08-30 23:36:40 -04:00
parent 66877d66c2
commit c0eb1de7a7
16 changed files with 77 additions and 424 deletions
@@ -269,7 +269,8 @@ async function createRequiredCallTask(caseData: any) {
async function getRenewalPrice(plan: string, billingPeriod: string) {
const configured = await prisma.pricingConfig.findUnique({ where: { plan_billingPeriod: { plan, billingPeriod } } })
return configured?.amount ?? (PLAN_PRICES as any)[plan]?.[billingPeriod]?.MAD
const fallback = (PLAN_PRICES as any)[plan]?.[billingPeriod]?.MAD
return Number.isInteger(configured?.amount) && configured!.amount > 0 ? configured!.amount : fallback
}
export async function ensureRenewalCollectionsCases(now = new Date()) {
@@ -292,7 +292,7 @@ export async function ensurePrimaryBillingAccount(companyId: string, employeeId?
async function resolvePrice(plan: string, billingPeriod: string) {
const configured = await prisma.pricingConfig.findUnique({ where: { plan_billingPeriod: { plan, billingPeriod } } })
const fallback = (PLAN_PRICES as any)[plan]?.[billingPeriod]?.MAD
const amount = configured?.amount ?? fallback
const amount = Number.isInteger(configured?.amount) && configured!.amount > 0 ? configured!.amount : fallback
if (!Number.isInteger(amount) || amount <= 0) throw new ValidationError('Invalid plan or billing period')
return amount
}
@@ -78,6 +78,22 @@ describe('subscription.service operational edges', () => {
})
})
it('keeps catalog defaults when persisted pricing overrides are invalid', async () => {
vi.mocked(prisma.pricingConfig.findMany).mockResolvedValue([
{ plan: 'STARTER', billingPeriod: 'ANNUAL', amount: 0 },
{ plan: 'GROWTH', billingPeriod: 'ANNUAL', amount: null },
{ plan: 'PRO', billingPeriod: 'ANNUAL', amount: -1 },
{ plan: 'ENTERPRISE', billingPeriod: 'ANNUAL', amount: 575040 },
] as never)
await expect(service.getPlans()).resolves.toEqual(expect.objectContaining({
STARTER: expect.objectContaining({ ANNUAL: { MAD: 143040 } }),
GROWTH: expect.objectContaining({ ANNUAL: { MAD: 287040 } }),
PRO: expect.objectContaining({ ANNUAL: { MAD: 383040 } }),
ENTERPRISE: expect.objectContaining({ ANNUAL: { MAD: 575040 } }),
}))
})
it('starts trials only after enforcing one-trial-per-company policy', async () => {
vi.mocked(repo.findByCompany).mockResolvedValue({ id: 'sub_old', trialUsed: true } as never)
@@ -18,8 +18,9 @@ export async function getPlans() {
const configs = await prisma.pricingConfig.findMany()
const result: Record<string, Record<string, Record<string, number>>> = structuredClone(PLAN_PRICES)
for (const c of configs) {
if (!Number.isInteger(c.amount) || c.amount <= 0) continue
if (!result[c.plan]) result[c.plan] = {}
result[c.plan]![c.billingPeriod] = { MAD: c.amount }
result[c.plan]![c.billingPeriod] = { ...(result[c.plan]?.[c.billingPeriod] ?? {}), MAD: c.amount }
}
return result
}
@@ -61,7 +61,8 @@ async function getNextInvoiceSequence(tx: any) {
async function resolvePrice(plan: PlanCode, billingPeriod: BillingPeriodCode) {
const configured = await prisma.pricingConfig.findUnique({ where: { plan_billingPeriod: { plan, billingPeriod } } })
const amount = configured?.amount ?? (PLAN_PRICES as any)[plan]?.[billingPeriod]?.MAD
const fallback = (PLAN_PRICES as any)[plan]?.[billingPeriod]?.MAD
const amount = Number.isInteger(configured?.amount) && configured!.amount > 0 ? configured!.amount : fallback
if (!Number.isInteger(amount) || amount <= 0) throw new ValidationError('Invalid plan or billing period')
return amount
}