کارنامهام فقط سایتهای روی ویترین نیست. بیشتر کارها روی محصول زنده بوده؛ فروشگاه، اپ، ابزار داخلی، گمرک، سرور و وردپرس. اینجا همان تجربهها را به زبان مسئله نوشتهام، نه لیست تکنولوژی.
01
فروشگاه و پرداخت
خیلی فروشگاهها ظاهر قشنگی دارند، ولی پرداخت که میرسد میشکنند. قسط جداست، درگاه جدا، سفارش جدا. من روی همین نقطه کار کردهام؛ جایی که اشتباه یعنی تماس پشتیبانی، نه باگ روی کاغذ.
WooCommerce
Installments
Crypto
پرداخت قسطی روی فروشگاه زنده
برای همهمشتری میخواست خرید قسطی باشد، بدون اینکه فروشگاه از ووکامرس جدا شود. قسط باید داخل همان سبد و سفارش دیده شود، نه یک فرم جدا که بعداً دستی چک شود.
برای متخصصپلاگین سفارشی اقساط روی WooCommerce، اتصال به order lifecycle و وضعیت سفارش، بهجای فرم ایزوله.
درگاه خارج از مسیر معمولی
برای همهبرای فروش با محدودیت درگاه ریالی، مسیر پرداخت کریپتو را کنار checkout ساختم تا سفارش همانجا ثبت شود، نه در اکسل بعد از فیش.
برای متخصصcrypto payment موازی با checkout، با ثبت سفارش و وضعیت پرداخت مشخص.
نمونه کد
php
add_action('woocommerce_checkout_order_processed', function ($order_id) {
$order = wc_get_order($order_id);
$plan = sanitize_text_field($_POST['installment_plan'] ?? '');
if (!$order || $plan === '') {
return;
}
$order->update_meta_data('_installment_plan', $plan);
$order->update_status('on-hold', 'Waiting for installment confirmation');
$order->save();
});
بعضی کارها روی دسکتاپ تمام میشوند. بعضیها باید در جیب باشند: فروشگاه، پورتال، یا محصولی که کاربر هر روز باز میکند. من هم اپ نیتیو ساختهام، هم وبویو کنترلشده، هم رابطی که روی موبایل مثل اپ حس شود.
React Native
WebView
PWA
اپ فروشگاه روی React Native
برای همهبرای فروشگاهی که مشتریاش بیشتر با موبایل میآمد، بهجای فقط نسخه واکنشگرا، رابط فروش را به اپ بردم تا سبد و محصول زیر انگشت باشد.
برای متخصصReact Native برای UI فروشگاه، اتصال به API موجود، بدون بازنویسی کل بکاند.
سایت داخل اپ، با مرز مشخص
برای همهبعضی محصولها باید همان سایت زنده را نشان بدهند، اما داخل اپ. وبویو را طوری بستم که کاربر از مسیر امن خارج نشود و حس اپ حفظ شود.
برای متخصصWebView با محدودیت URL، لودینگ مشخص، و بدون باز شدن پنجرهٔ خارج از کنترل.
نمونه کد
tsx
function ShopWebView({ uri }: { uri: string }) {
return (
<WebView
source={{ uri }}
startInLoadingState
setSupportMultipleWindows={false}
onShouldStartLoadWithRequest={(request) =>
request.url.startsWith("https://")
}
/>
);
}
سایت مشتری ویترین است. پشت آن ابزارهایی است که اگر خراب شوند، کل تیم میایستد: گزارش کار، دسترسی ریموت، داشبورد وضعیت. اینها معمولاً پرایوت میمانند، ولی بخش بزرگی از کار واقعی همینجاست.
Dashboard
RMM
Internal tools
گزارش روزانه بهجای پیام پراکنده
برای همهبهجای اینکه کار روز در چت گم شود، مسیر ثبت گزارش را طوری چیدم که انجامشده و مانعها در یک جا جمع شوند و بعداً قابل پیگیری باشند.
برای متخصصمدل داده مشخص برای report، API ثبت، و UI داخلی بدون وابستگی به پیامرسان.
داشبورد و ریموت برای تیم فنی
برای همهبرای کارهایی که باید از راه دور دیده و جمع شوند، داشبورد و ابزار ریموت ساختم تا وضعیت سیستمها در یک نگاه باشد، نه در ده تا ریموت جدا.
برای متخصصپنل داخلی، RMM و مانیتورینگ وضعیت؛ جدا از سایت عمومی مشتری.
نمونه کد
ts
type DailyReport = {
userId: string;
date: string;
done: string[];
blocked: string[];
};
export async function submitReport(report: DailyReport) {
const response = await fetch("/api/reports", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(report),
});
if (!response.ok) {
throw new Error("Report was not saved");
}
return response.json();
}
داده گمرک و تجارت خارجی اگر خام روی صفحه بیاید، کسی از آن استفاده نمیکند. کار این بوده که نقشه، شرکت خارجی، مشاوره و پورتال را به زبانی نشان بدهم که بازرگان بفهمد، نه فقط برنامهنویس.
React
Maps
ixport
نقشه گمرکهای ایران
برای همهبهجای جدول طولانی، گمرکها را روی نقشه گذاشتم تا موقعیت و اطلاعات در یک نگاه پیدا شود.
برای متخصصReact + نقشه، مارکر و پاپآپ روی دادهٔ مکانی گمرک.
پورتال صادرات برای کاربر واقعی
برای همهپورتال صادرات باید چندزبانه باشد و مسیر ثبت و پیگیری را برای کسی که برنامهنویس نیست روشن کند. همین را در ixport و نسخههای مرتبطش جلو بردم.
برای متخصصپورتال چندزبانه، تم child، و لایه داده برای شرکتها و مسیرهای صادرات.
دیپلوی یعنی سایت باز شود، ولی کار واقعی بعد از آن است: هدرهای امنیتی، کش استاتیک، کانفیگ nginx، و پنلی که وضعیت را نشان بدهد. این لایه را جدا از ظاهر سایت نگه میدارم.
Nginx
Linux
Security
کانفیگ سرور برای سایت زنده
برای همهبرای سایتی که باید سریع و پایدار بماند، مسیر استاتیک را کش کردم و هدرهایی گذاشتم که جلوی اشتباههای رایج مرورگر و iframe را بگیرد.
برای متخصصnginx با try_files، کش استاتیک، SSL/HTTP2 و هدرهای امنیتی.
لایه دیده شدن، نه فقط بالا بودن
برای همهبالا بودن سرور کافی نیست. داشبورد و پلتفرم امنیتی را طوری چیدم که وضعیت دیده شود، قبل از اینکه کاربر نهایی با خطا روبهرو شود.
برای متخصصپلتفرم مانیتورینگ/امنیت جدا از فرانت عمومی؛ لاگ و وضعیت در پنل داخلی.
بیشتر سایتهای زنده همینجا تمام میشوند: تم child روی وودمارت یا هلوی المنتور، پلاگین اقساط، استوری، اسلایدر، پیامک، سبد خرید. وردپرس برای من CMS آماده نیست؛ بستری است که باید مثل محصول رفتار کند.
WordPress
Plugin
Elementor
تم child بهجای دستکاری قالب اصلی
برای همهظاهر و رفتار سایت را در child theme نگه داشتم تا بهروزرسانی قالب والد، کار سفارشی را خراب نکند.
برای متخصصchild theme روی Woodmart / Hello / Elementor، override قالب و استایل بدون fork قالب والد.
پلاگین برای کاری که قالب نباید انجام دهد
برای همهاستوری، اسلایدر، ورود پیامکی و سبد سفارشی را به پلاگین بردم تا با عوض شدن ظاهر سایت، منطق از بین نرود.
برای متخصصcustom post type، shortcode، REST، و هوک وردپرس برای قابلیتهایی که باید مستقل از تم بمانند.