# مرحله ۸ — Notification Center، حالت خالی، حالت خطا: خلاصه

## ۱. مرکز اعلان‌ها (کاملاً جدید)
جدول `notifications` + کلاس `Notify` (`log()` برای ثبت، `recent()` برای گرفتن جدیدترین‌ها اول). به هر ۴ رویداد وصل شد:
- 📡 سیگنال جدید
- 🎯 برخورد به تارگت (هر ۳ حالت: T1، T2، تارگت نهایی)
- ⏰ نزدیک‌شدن انقضای اشتراک — **این تابع اصلاً وجود نداشت**؛ قبلاً فقط انقضای *گذشته* چک می‌شد (`checkPlanExpirations`)، نه هشدار *قبل از* انقضا. تابع کاملاً جدید `checkPlanExpiringSoon()` نوشتم: هر پلن فعال که کمتر از ۳ روز مونده، فقط یک‌بار (با ستون `expiry_reminder_sent`) به کاربر یادآوری می‌کنه.
- 🤖 فعال‌شدن ربات (هم ربات‌های ثابت، هم شخصی)

صفحه‌ی «🔔 اعلان‌ها» به زیرمنوی «امکانات بیشتر» اضافه شد؛ جدیدترین بالا.

## ۲. حالت خالی طراحی‌شده
- **My Bots بدون ربات فعال**: از قبل یه پیام داشت، حالا یه دکمه‌ی مستقیم «📡 سیگنال» هم بهش اضافه شد (به‌جای فقط راهنمایی متنی).
- **ریفرال بدون دعوت‌شده**: یه خط تشویقی جدید («هنوز کسی رو دعوت نکردی...») وقتی مجموع زیرمجموعه صفره اضافه شد.
- **مرکز اعلان‌ها بدون هیچ اعلانی**: پیام طراحی‌شده‌ی مخصوص («هنوز اعلانی نداری، به‌محض این‌که...»).
- **پروفایل بدون اشتراک/ربات**: از قبل خط جداگانه داشت (نه خطا، نه خالی بی‌توضیح)؛ فقط بررسی شد، تغییری نداد چون کافی بود.

## ۳. حالت خطای اتصال + دکمه‌ی تلاش مجدد واقعی (مهم‌ترین بخش این مرحله)
اینجا یه باگ واقعی پیدا شد: وقتی کاربر سیگنال درخواست می‌کرد (`درخواست سیگنال جدید`)، درخواست فقط یه پرچم داخلی می‌ذاشت و اسکنر پس‌زمینه بعداً باید قیمت رو می‌گرفت. اگه API قیمت (Twelve Data/Binance) قطع می‌شد، اسکنر پس‌زمینه فقط `continue` می‌زد — **کاربر تا ابد فقط «در حال جستجو...» می‌دید، بدون هیچ خطا یا پیام دیگه.**

اصلاح شد با ردیابی سلامت منبع داده:
- `markFeedResult()`/`feedDownSeconds()`: زمان شروع قطعی رو ثبت می‌کنن.
- اگه قطعی بیش از ۳ دقیقه طول بکشه، **فقط یک‌بار** (نه هر ۲۰ ثانیه، با ستون جدید `data_error_notified_at`) پیام خطای طراحی‌شده با دکمه‌ی «تلاش مجدد» ارسال می‌شه.
- دکمه‌ی تلاش مجدد از همون کیبورد `reqsig_` استفاده می‌کنه که واقعاً درخواست رو دوباره صف می‌کنه — تزئینی نیست.
- وقتی داده برگرده، پرچم پاک می‌شه تا اگه دوباره قطع شد، بشه یه‌بار دیگه هم خبر داد.
- این دقیقاً همون سناریوییه که «معیار پایان مرحله» ازش امتحان می‌خواد.

## ۴. یکدست‌سازی پیام‌های جستجو/بارگذاری
دو تا ایموجی جستجوی متفاوت (🔍 و 🔎) برای همون مفهوم «در حال جستجو/تحلیل» استفاده می‌شدن. یکدست شدن روی 🔎 (که در اکثریت پیام‌های مشابه از قبل استفاده می‌شد). دکمه‌های واقعی جستجو (مثل «جستجوی کاربر» در پنل ادمین یا دکمه‌ی «سرچ جدید») دست نخوردن چون اون‌ها اکشن هستن، نه حالت انتظار.

## وضعیت چک‌لیست
- [x] نقاط بی‌صدا بررسی شدن — مهم‌ترینش (سکوت ابدی موقع قطعی API) پیدا و اصلاح شد.
- [x] حالت خالی همه‌ی صفحات اصلی چک شد.
- [x] دکمه‌ی «تلاش مجدد» واقعاً همون درخواست رو دوباره می‌فرسته.
- [x] اعلان‌ها جدیدترین بالا نمایش داده می‌شن (`ORDER BY id DESC`).

## معیار پایان مرحله — نیاز به تست شماست
«با قطع عمدی منبع داده، کاربر پیام خطای طراحی‌شده ببینه، نه سکوت» — منطقش پیاده شد، ولی تست واقعیش (مثلاً بستن موقت دسترسی به Twelve Data و صبر کردن +۳ دقیقه) رو فقط خودتون رو سرور واقعی می‌تونید انجام بدید.

## فایل تحویلی
- `traderpro.php` — به‌روزرسانی‌شده.
