اول مشخص کنید چه کسی، چه آگهیای و برای چه کسی ثبت میکند
برای ساخت سایت آگهی، اولین تصمیم دستهبندی بازار است. فروش وسایل دستدوم در یک شهر، اجاره ملک و معرفی خدمات محلی، فرم ثبت و قواعد بررسی یکسانی ندارند. یک پلتفرم عمومی از روز اول به دستههای بیشتر، پشتیبانی گستردهتر و تصمیمهای پیچیدهتری درباره اعتماد نیاز دارد.
اگر هدف شما محصولی شبیه دیوار یا شیپور است، یک مسیر کامل را برای نسخه اول انتخاب کنید: فروشنده ثبتنام کند، آگهی بسازد، تصاویرش را بفرستد، تأیید بگیرد و از خریدار پیام یا تماس دریافت کند. هر قابلیت باید بخشی از همین مسیر را بهتر کند. انتشار آگهی بدون راه رسیدگی به تخلف، یک نسخه آماده بهرهبرداری نیست.
این راهنمای ۱۴۰۵ درباره تصمیمهای ساخت چنین محصولی است. معماری زیر پیشنهاد نکسکد برای یک پروژه تازه است؛ انتخاب نهایی به تیم، بودجه، زیرساخت در دسترس و رفتار واقعی کاربران بستگی دارد.
نسخه اول سایت آگهی چه امکاناتی لازم دارد؟
| بخش | خروجی قابل بررسی | تصمیمی که باید روشن شود |
|---|---|---|
| حساب کاربری | ورود، خروج، بازیابی و مدیریت آگهیهای خود | ورود با ایمیل یا شماره؛ هزینه و محدودیت ارائهدهنده |
| ثبت آگهی | پیشنویس، دسته، شهر، مشخصات و عکس | اطلاعات اجباری هر دسته و تعداد/حجم عکسها |
| کشف آگهی | فهرست، جستوجو، فیلتر و مرتبسازی | محدوده جغرافیایی و معنای قیمت توافقی |
| صفحه آگهی | نشانی مستقل، مشخصات، وضعیت و راه تماس | نمایش شماره یا گفتوگو؛ سیاست حریم خصوصی |
| پنل بررسی | تأیید، رد با دلیل، تعلیق و رسیدگی به گزارش | اختیارات نقشها و سابقه تصمیمها |
| عملیات | گزارش خطا، پشتیبان و راه پیگیری | مسئول پشتیبانی و معیار بازگردانی سرویس |
چت بلادرنگ، کیف پول، پرداخت امانی، پیشنهاد هوشمند و اپلیکیشنهای چندسکویی را جدا برآورد کنید. برای مثال، چت فقط یک کادر پیام نیست: وضعیت دریافت، گزارش مزاحمت، مسدودکردن کاربر، نگهداری پیام و اعلان هم میخواهد. اگر تماس تلفنی مسیر اصلی معامله است، شاید نسخه اول به چت نیاز نداشته باشد.
چرخه آگهی را قبل از طراحی فرم تعریف کنید
سرور باید تعیین کند چه کسی اجازه تغییر هر وضعیت را دارد. صاحب آگهی میتواند پیشنویس خودش را اصلاح کند؛ اجازه انتشار یا تعلیق ممکن است متعلق به ناظر باشد. پنهانکردن یک دکمه در رابط کاربری، کنترل دسترسی محسوب نمیشود.
برای ویرایش آگهی منتشرشده تصمیم مشخص بگیرید. میتوانید نسخه تأییدشده را تا بررسی تغییرات نگه دارید، یا آگهی را موقتاً از انتشار خارج کنید. در هر دو حالت، قیمت و عکسهای صفحه عمومی باید با همان نسخه سازگار باشند. ثبتکننده هم باید وضعیت و دلیل رد را به زبان روشن ببیند.
- تاریخ انقضا، تمدید و معنای فروختهشدن را در مدل داده ثبت کنید.
- دستهبندی را از مشخصات دسته جدا نگه دارید؛ متراژ ملک با حافظه تلفن همراه یکی نیست.
- حذف نرم و نگهداری سوابق را با سیاست حریم خصوصی و مدت نگهداری هماهنگ کنید.
- ارسال دوباره فرم روی اینترنت ضعیف نباید دو آگهی یا دو پرداخت بسازد؛ عملیات حساس به شناسه تکرارناپذیر نیاز دارند.
وبسایت، PWA یا اپلیکیشن React Native؟
برای شروعی که جستوجوی گوگل و اشتراک لینک آگهی مهم است، وب واکنشگرا انتخاب قابل بررسیای است. صفحه آگهی باید بدون ورود قابل خواندن باشد، روی نمایشگر کوچک خوب کار کند و از نشانی مستقلی باز شود. این تصمیم مانع ساخت اپلیکیشن بعدی نمیشود.
| گزینه | زمانی که ارزش بررسی دارد | کاری که همچنان باقی میماند |
|---|---|---|
| وب واکنشگرا | اشتراک لینک، جذب از جستوجو و شروع با یک رابط | بهینهسازی موبایل، آپلود قابل اعتماد و دسترسپذیری |
| PWA | تجربه نصبپذیر و بخشی از رفتار آفلاین روی وب | آزمون قابلیتها و نصب در مرورگرها و سیستمعاملهای هدف |
| React Native | تعامل پرتکرار، نیازهای بومی و برنامه مشخص انتشار موبایل | توزیع نسخه، مجوزهای دستگاه، آزمون و نگهداری Android/iOS |
PWA با manifest و رفتارهای مناسب وب قابل طراحی است؛ قابلیت نصب و دسترسیهای دستگاه بین مرورگرها فرق دارند. یک service worker میتواند بخشی از رابط یا پیشنویس را آفلاین کند، اما بدون ارتباط سرور نمیتوان قطعیبودن انتشار آگهی را تأیید کرد. وضعیت «ذخیره روی دستگاه» باید از «دریافت سرور» جدا باشد.
راهنمای رسمی React Native برای شروع، استفاده از framework را پیشنهاد میکند. برای یک تیم، Expo میتواند مسیر قابل بررسیای باشد؛ نیازهای بومی، شیوه ساخت و دسترسی به سرویسهای لازم را پیش از انتخاب آزمایش کنید. React مشترک به معنای اشتراک خودکار همه اجزای HTML و رابط موبایل نیست.
Headless یعنی قواعد آگهی به یک صفحه وابسته نباشند
اعتبار قیمت، اجازه ویرایش، انقضا و بررسی آگهی باید پشت یک قرارداد مشخص قرار بگیرند. وبسایت، اپ موبایل و پنل مدیریت از همان قواعد استفاده میکنند؛ هرکدام میتوانند فرم و چیدمان متفاوتی داشته باشند. اعتبارسنجی سمت کاربر برای راهنمایی سریع است و سرور دوباره همان ورودی را با قواعد معتبر بررسی میکند.
API را بر اساس کار محصول طراحی کنید: ساخت پیشنویس، اتصال تصویر تأییدشده، ارسال برای بررسی، جستوجو و گزارش تخلف. پاسخ خطا باید قابل فهم و قابل پردازش باشد. تغییر قرارداد هم نباید نسخه قدیمی اپ موبایل را ناگهان از کار بیندازد؛ نسخههای نصبشده همزمان بهروزرسانی نمیشوند.
برای تیم کوچک، این مرزبندی میتواند داخل یک برنامه ماژولار باشد. جداکردن منطق از UI به معنای اجبار به چند سرویس شبکهای نیست. API مستقل زمانی ارزش هزینه استقرار و نگهداری دارد که مصرفکنندهها، تیمها یا نیاز اجرایی واقعاً به آن نیاز داشته باشند.
یک monorepo پیشنهادی برای وب و موبایل
| بخش | مسئولیت | چه چیزی نباید به آن نشت کند؟ |
|---|---|---|
| apps/web | Next.js برای صفحات عمومی و پنل وب | توکن سرویسها در بسته مرورگر |
| apps/mobile | رابط React Native در صورت نیاز محصول | وابستگی اجباری به DOM وب |
| apps/api | ورودیهای سرور و اجرای عملیات مجاز | اعتماد به نقش یا قیمت ارسالی کلاینت |
| packages/domain | قواعد آگهی، مجوزها و انتقال وضعیت | کامپوننت React یا جزئیات HTTP |
| packages/contracts | ساختار درخواست/پاسخ و اعتبارسنجی مشترک | مدل خام جدولها و اطلاعات محرمانه |
| packages/ui | توکنهای طراحی و اجزای قابل اشتراک | فرض اینکه تمام UI وب و موبایل یکسان است |
اگر فقط وب دارید، apps/api میتواند بعداً از لایه سرور وب جدا شود. از ابتدا مرز ماژول را روشن نگه دارید و برای پوشهای که مصرفکننده ندارد سرویس نسازید. در packages/ui نیز میتوان توکن رنگ و فاصله را مشترک کرد و اجزای بومی هر پلتفرم را جدا نگه داشت.
نسخه دسکتاپ را فقط برای نیاز مشخص اضافه کنید؛ مثلاً ابزار اپراتوری با قابلیت ضروری سیستمعامل. بستهبندی یک وبسایت داخل wrapper بهتنهایی ارزش تازهای برای کاربر نمیسازد و مسئولیت بهروزرسانی و امنیت توزیع را اضافه میکند.

داده اصلی در PostgreSQL؛ جستوجو با نیاز واقعی رشد میکند
در معماری پیشنهادی، PostgreSQL مرجع وضعیت آگهی، مالکیت، بررسی و پرداخت است. کاربران، دستهها، موقعیت، آگهیها، تصاویر، گزارشها و سابقه تصمیم ناظر، موجودیتهای جدا دارند. قیود پایگاه داده باید روابط ضروری را حفظ کنند؛ ORM جای کلید خارجی، تراکنش و طراحی درست را نمیگیرد.
برای شروع، جستوجوی داخل PostgreSQL را با داده مشابه محصول آزمایش کنید. متن کامل با tsvector و ایندکس GIN و امکانات شباهت pg_trgm، ابزارهای قابل بررسیاند. وجود این ابزارها تضمین کیفیت جستوجوی فارسی نیست: یکسانسازی ی/ک، اعداد، فاصله و نیمفاصله، غلط تایپی، نام محله و تفاوت اصطلاحات دستهها باید با مجموعه پرسوجوی واقعی ارزیابی شود.
یک فهرست آزمون بسازید: «آیفون کارکرده»، یک املای ناقص، نام دو محله مشابه و جستوجویی که واقعاً نتیجه ندارد. ترتیب نتایج، زمان پاسخ و رفتار فیلترها را بررسی کنید. برای فهرستهای بزرگ، صفحهبندی مبتنی بر cursor و مرتبسازی پایدار را در برابر حرکت دادهها آزمایش کنید.
اگر رتبهبندی، تحمل غلط یا ترکیب فیلترها به موتور مستقل نیاز پیدا کرد، search index را یک نمای قابل بازسازی از داده اصلی نگه دارید. پس از تغییر وضعیت، بهروزرسانی آن ممکن است با تأخیر انجام شود؛ صفحه جزئیات باید وضعیت معتبر را دوباره کنترل کند. روش بازسازی ایندکس و جبران رویداد ازدسترفته، بخشی از طراحی است.
تصویر آگهی را مثل ورودی غیرقابل اعتماد مدیریت کنید
برای محصول آگهی، تصاویر را در object storage نگه دارید و مشخصات، مالکیت و وضعیت پردازش را در پایگاه داده ثبت کنید. وب و موبایل باید از قرارداد مشترک آپلود استفاده کنند؛ پیشرفت ارسال، حذف از پیشنویس و تلاش مجدد در اینترنت ضعیف، رفتارهای مستقل از ظاهر فرماند.
- پیش از آپلود، مجوز کوتاهعمر مخصوص همان کاربر، فایل و عملیات صادر کنید؛ کلید دسترسی storage به مرورگر نمیرود.
- اندازه، نوع واقعی و ابعاد فایل را در سرور/مرحله پردازش کنترل کنید؛ نام فایل و Content-Type ارسالی کاربر کافی نیست.
- فایل تازه ابتدا در فضای خصوصی یا قرنطینه قرار بگیرد. پس از بررسی و تولید نسخه مناسب، اجازه انتشار بگیرد.
- داده موقعیت داخل تصاویر و EXIF را مطابق سیاست حریم خصوصی پاک کنید؛ نسخههای کوچک برای کارت و نسخه بزرگتر برای جزئیات بسازید.
- فایلهای رهاشده، پیشنویس منقضی و تصاویر حذفشده به سیاست پاکسازی نیاز دارند؛ رکورد و فایل یتیم نباید بیحساب جمع شوند.
برای نمونه، R2 از URL امضاشده PUT برای ارسال مستقیم فایل پشتیبانی میکند. این URL مثل یک مجوز قابل انتقال است و ممکن است تا انقضا دوباره استفاده شود؛ عمر کوتاه و کلید شیء محدود لازم است. امضا بهتنهایی محتوا را تأیید یا یکبارمصرفبودن را تضمین نمیکند. انتخاب storage و CDN باید با مسیر شبکه کاربران و امکانات میزبانی سنجیده شود.
کش سریع است، اگر آگهی حذفشده را زنده نگه ندارد
صفحات دستهبندی و فایلهای تصویری عمومی، نامزدهای کش هستند. پیامهای خصوصی، اطلاعات تماس محدودشده و پاسخهای وابسته به حساب را نباید بیدقت در کش مشترک گذاشت. کلید کش فهرست نیز باید شهر، دسته، مرتبسازی و فیلترهای مؤثر را منعکس کند.
برای هر تغییر، مقصدهای باطلسازی را مشخص کنید: ویرایش قیمت روی صفحه آگهی و فهرستها اثر دارد؛ تعلیق روی جستوجو، CDN و هر مسیر تماس اثر میگذارد. برای محتوای حساس به حذف، صرفاً منتظر پایان TTL نمانید. کنترل وضعیت/دسترسی در مسیر معتبر سرور لازم است و زمان باقیماندن نسخه عمومی باید تعریف و آزموده شود.
در Next.js، سازوکار کش را برای نسخه و روش استقرار انتخابشده بخوانید. مستندات فعلی بین revalidateTag با الگوی stale-while-revalidate و updateTag برای مشاهده تغییر خود کاربر در Server Action تفاوت میگذارند. باطلسازی کش Next.js، کش موتور جستوجو یا CDN دیگری را خودکار مدیریت نمیکند؛ آنها قراردادهای جدا دارند.
اعتماد، ورود و رسیدگی به تخلف بخشی از محصولاند
ورود با کد یکبارمصرف به محدودیت درخواست، مهلت انقضا و سقف تلاش ناموفق نیاز دارد. هزینه پیامک و امکان سوءاستفاده را در بودجه بیاورید. تأیید شماره، مدرک معتبر بودن محتوای آگهی یا سالم بودن معامله نیست.
گزارش تخلف باید به پرونده قابل پیگیری تبدیل شود: نوع گزارش، آگهی مربوط، اولویت، تصمیم ناظر و امکان بازبینی. دسترسی ادمین را محدود و تصمیمهای مهم را ثبت کنید. داده شخصی و توکنها نباید برای راحتی دیباگ وارد log عمومی شوند.
برای شروع، ترکیبی از قواعد ساده و بررسی انسانی معمولاً قابل فهمتر است. ابزار خودکار میتواند مورد مشکوک را علامت بزند؛ معیار خطای مثبت، اعتراض کاربر و مسئول تصمیم نهایی باید معلوم باشد. استفاده از AI بهتنهایی تضمین تشخیص کلاهبرداری نیست.
صف، مشاهدهپذیری و پشتیبان قبل از رشد جدی
تغییر اندازه تصویر، اعلان و همگامسازی جستوجو میتوانند در صف اجرا شوند. برای ارتباط تغییر پایگاه داده با صف، الگوی outbox قابل بررسی است: رویداد همراه تغییر اصلی ثبت میشود و پردازشگر آن را منتشر میکند. این پیشنهاد طراحی است، نه تضمین آماده هر سرویس میزبانی.
پردازشگر باید دریافت تکراری را تحمل کند. تلاش مجدد با فاصله، سقف تلاش و محل نگهداری خطاهای تکرارشونده تعریف کنید. اگر سرویس پیامک قطع شد، ثبت آگهی نباید بدون دلیل از بین برود؛ وضعیت اعلان جدا ثبت شود تا قابل پیگیری باشد.
- زمان پاسخ و خطاهای مسیر ثبت، جستوجو و ارسال تصویر را جدا اندازه بگیرید.
- طول صف، سن قدیمیترین کار و عقبماندگی ایندکس را پایش کنید.
- هزینه storage، تبدیل تصویر، پیامک، خروجی شبکه و رسیدگی انسانی را کنار هزینه سرور ببینید.
- برای پایگاه داده و فایلها پشتیبان و روش بازگردانی داشته باشید؛ بکاپی که بازگردانی نشده، هنوز قابلیت اتکای اثباتشده ندارد.
- مدت قابل تحمل ازدسترفتن داده و زمان قابل قبول بازیابی را با صاحب محصول مشخص کنید؛ این دو عدد روی هزینه اثر دارند.
چه زمانی معماری را بزرگتر کنیم؟
تعداد کاربر ثبتنامشده، معیار کافی برای ظرفیت نیست. نرخ جستوجوی همزمان، حجم تصاویر، پیچیدگی فیلتر و تعداد عملیات نوشتن را اندازه بگیرید. یک query بدون ایندکس یا تصویر بسیار بزرگ میتواند پیش از نیاز به چند سرویس، تجربه را خراب کند.
| نشانه | بررسی اول | تغییر قابل بررسی |
|---|---|---|
| جستوجوی کند | طرح اجرای query، ایندکس و الگوی فیلتر | اصلاح query؛ سپس موتور جستوجوی مستقل در صورت نیاز |
| دریافت عکس کند | ابعاد، فرمت، کش و مسیر CDN | نسخههای مناسب دستگاه و بهبود مسیر تحویل |
| انتشار با تأخیر | ظرفیت ناظر و عقبماندگی صف | ابزار بهتر بررسی یا پردازشگر بیشتر |
| نوشتن تحت فشار | تراکنشها، قفلها و اتصالهای DB | کوتاهکردن تراکنش، مدیریت اتصال و طرح ظرفیت |
| اختلال انتشار تیمها | مرز مالکیت و وابستگی انتشار | جداسازی سرویس فقط در مرز دارای دلیل اجرایی |
تقسیم زودهنگام به microservice، تراکنش بین سرویسها، انتشار و عیبیابی را سختتر میکند. برای یک تیم کوچک، برنامه ماژولار با مرز روشن میتواند نقطه شروع معقولی باشد. تضمین «پاسخگویی به میلیونها کاربر» بدون سناریوی بار، داده و آزمون، مبنای خرید یا قرارداد خوبی نیست.
آگهیباز؛ تجربه گذشته را از پیشنهاد امروز جدا میکنیم
بر اساس سابقه پروژه اعلامشده از سوی نکسکد، آگهیباز در سال ۱۴۰۴ ساخته شده است. در اطلاعات فنی بازیابیشده از مخزن قدیمی، استفاده از Next.js، React، TypeScript، Drizzle و PostgreSQL قابل تأیید است. این سابقه با تاریخ انتشار این مقاله، ۱۴۰۵، تفاوت دارد.
از این شواهد نمیتوان نتیجه گرفت که نسخه تاریخی، اپ React Native، monorepo، معماری صف و کش همین مقاله یا ترافیک مشخصی داشته است. پیشنهادهای معماری این راهنما برای ارزیابی پروژه تازهاند. تصاویر مفهومی مقاله نیز جای اسکرینشات واقعی محصول یا مستندات اجرایی آن را نمیگیرند.
ارزش بررسی نمونهکار وقتی بیشتر میشود که مسئله، محدوده تحویل و بخش قابل مشاهده معلوم باشند. برای برآورد محصول شما هم همین رویکرد را داریم: اول مسیر ثبت و پیدا کردن آگهی، بعد تصمیم درباره وب، موبایل و زیرساخت.
هزینه و زمان را از محدوده و معیار پذیرش دربیاورید
برای «سایت شبیه دیوار» یک قیمت ثابت بدون شرح محدوده نمیتوان داد. دستهها و فرمهای تخصصی، کیفیت جستوجو، چت، پرداخت، اپ موبایل، مهاجرت داده و سطح بررسی محتوا روی برآورد اثر دارند. هزینه جاری هم شامل پشتیبانی، پیامک، ذخیره فایل، پردازش تصویر و نگهداری است.
- فروشنده روی گوشی و اتصال ضعیف، آگهی بسازد؛ قطع آپلود باعث انتشار ناقص نشود.
- کاربر نتواند آگهی یا تصویر متعلق به دیگری را تغییر دهد.
- آگهی ردشده، منقضی یا تعلیقشده طبق سیاست محصول از مسیرهای عمومی خارج شود.
- فیلتر شهر، دسته و قیمت همزمان نتیجه درست بدهند؛ پیوند جستوجو قابل بازکردن باشد.
- بازکردن لینک آگهی در وب و اپ به همان آگهی برسد و وضعیت ناموجود را روشن نشان دهد.
- رویداد تکراری یا retry پرداخت، نتیجه مالی/آگهی تکراری نسازد.
- بازگردانی پایگاه داده و نمونه فایلها در محیط جدا تمرین و زمان آن ثبت شود.
برای گفتوگوی اول، بازار هدف، شهرها، دستهها، راه تماس خریدار و فروشنده و کانال انتشار را بنویسید. اگر نمونهای دارید، مشخص کنید کدام رفتار آن را میخواهید. سپس میتوان نسخه اول و مراحل بعدی را جدا قیمتگذاری و تحویل داد.
