diff --git a/apps/web/lib/entitlements.ts b/apps/web/lib/entitlements.ts index 3d1c484..ab7e4db 100644 --- a/apps/web/lib/entitlements.ts +++ b/apps/web/lib/entitlements.ts @@ -2,6 +2,7 @@ import "server-only"; import { sqlClient } from "./db"; import { newId } from "@aiornot/db"; import { randomToken, hmac } from "./crypto"; +import { normalizePromoPercentOff } from "./promo-form"; const API_KEY_SALT = "aiornot-api-key"; @@ -129,7 +130,7 @@ export async function quotePromo( }); if (dup.rows[0]) return { ok: false, error: "You've already used this code." }; - const percentOff = Math.min(100, Math.max(1, Number(row.percent_off ?? 100))); + const percentOff = normalizePromoPercentOff(row.percent_off); const finalUsd = round2(baseUsd * (1 - percentOff / 100)); return { ok: true, code, percentOff, baseUsd, finalUsd, free: finalUsd <= 0 }; } @@ -167,7 +168,7 @@ export async function listPromoCodes(): Promise { ); return r.rows.map((x) => ({ code: x.code as string, - percentOff: Number(x.percent_off ?? 100), + percentOff: normalizePromoPercentOff(x.percent_off), appliesTo: (x.applies_to as string) || "any", active: Number(x.active) === 1, maxUses: x.max_uses == null ? null : Number(x.max_uses), diff --git a/apps/web/lib/promo-form.test.ts b/apps/web/lib/promo-form.test.ts index 6b2e0fe..8b175b3 100644 --- a/apps/web/lib/promo-form.test.ts +++ b/apps/web/lib/promo-form.test.ts @@ -4,12 +4,14 @@ import { normalizePromoMaxUses, normalizePromoPercentOff } from "./promo-form"; describe("promo form normalization", () => { it("clamps decimal percent discounts to the allowed range", () => { expect(normalizePromoPercentOff("25")).toBe(25); + expect(normalizePromoPercentOff(25)).toBe(25); expect(normalizePromoPercentOff("0")).toBe(1); expect(normalizePromoPercentOff("150")).toBe(100); }); it("falls back for invalid percent discounts", () => { expect(normalizePromoPercentOff("")).toBe(100); + expect(normalizePromoPercentOff("12.5")).toBe(100); expect(normalizePromoPercentOff("1e2")).toBe(100); expect(normalizePromoPercentOff("0x10")).toBe(100); expect(normalizePromoPercentOff("NaN")).toBe(100);