Add shipping cost groups and reject spam contact-form SMS.

Wire cart/checkout shipping fees with category groups and static rates, reject gibberish contact submissions, and SMS only valid Iranian mobiles.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-10-02 21:52:41 +03:30
co-authored by Cursor
parent 1a49576752
commit 88ef4e82a1
19 changed files with 1501 additions and 25 deletions
@@ -119,6 +119,44 @@ function readBoolean(value: unknown, fallback: boolean) {
return typeof value === 'boolean' ? value : fallback;
}
function readNonNegativeNumber(value: unknown, fallback: number) {
if (typeof value === 'number' && Number.isFinite(value) && value >= 0) {
return value;
}
if (typeof value === 'string' && value.trim() !== '') {
const parsed = Number(value);
if (Number.isFinite(parsed) && parsed >= 0) return parsed;
}
return fallback;
}
function readStaticShippingProvinceExceptions(
value: unknown,
): BusinessSettings['store']['staticShippingProvinceExceptions'] {
if (!Array.isArray(value)) return [];
const seen = new Set<string>();
const items: BusinessSettings['store']['staticShippingProvinceExceptions'] =
[];
for (const entry of value) {
if (!isRecord(entry)) continue;
const provinceId =
typeof entry.provinceId === 'string'
? entry.provinceId.trim()
: typeof entry.provinceId === 'number'
? String(entry.provinceId)
: '';
if (!provinceId || seen.has(provinceId)) continue;
const amount = readNonNegativeNumber(entry.amount, Number.NaN);
if (!Number.isFinite(amount)) continue;
seen.add(provinceId);
items.push({ provinceId, amount });
}
return items;
}
function readString(value: unknown, fallback = '') {
return typeof value === 'string' ? value.trim() : fallback;
}
@@ -431,6 +469,17 @@ export function normalizeBusinessSettings(raw: unknown): BusinessSettings {
),
orderProcessSteps: readOrderProcessSteps(store.orderProcessSteps),
ePayment: normalizeEPaymentSettings(store.ePayment),
staticShippingEnabled: readBoolean(
store.staticShippingEnabled,
DEFAULT_BUSINESS_SETTINGS.store.staticShippingEnabled,
),
staticShippingAmount: readNonNegativeNumber(
store.staticShippingAmount,
DEFAULT_BUSINESS_SETTINGS.store.staticShippingAmount,
),
staticShippingProvinceExceptions: readStaticShippingProvinceExceptions(
store.staticShippingProvinceExceptions,
),
},
modules: {
// Missing `modules` → all enabled (legacy). Explicit `{ enabled: [] }` stays empty.
@@ -487,6 +536,14 @@ export function mergeBusinessSettings(
current.store.ePayment,
patch.store?.ePayment,
),
staticShippingEnabled:
patch.store?.staticShippingEnabled ??
current.store.staticShippingEnabled,
staticShippingAmount:
patch.store?.staticShippingAmount ?? current.store.staticShippingAmount,
staticShippingProvinceExceptions:
patch.store?.staticShippingProvinceExceptions ??
current.store.staticShippingProvinceExceptions,
},
modules: {
enabled: patch.modules?.enabled ?? current.modules.enabled,