# چک‌لیست پذیرش صاحب محصول (User Acceptance Checklist)

این سند برای صاحب محصول/کارفرما نوشته شده، نه برای برنامه‌نویس —
هدف این است که بدون نیاز به خواندن کد، بتوانید هر بخش از ربات را
تست کنید و بفهمید «درست کار می‌کند» یا «مشکل دارد».

هر ردیف سه بخش دارد: **چه کاری انجام دهید**، **اگر درست بود چه
می‌بینید**، و **اگر خراب بود چه می‌بینید**.

## بخش ۱ — نصب

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۱.۱ | `install.php` را باز کنید | صفحه بررسی پیش‌نیازها با آیتم‌های سبز | صفحه سفید/خطای PHP، یا آیتم‌های قرمز |
| ۱.۲ | فرم‌های نصب را کامل و «شروع نصب» را بزنید | صفحه «نتیجه نصب» با پیام موفقیت و چک‌لیست بعد از نصب | پیام خطای قرمز که نصب متوقف شده |
| ۱.۳ | دوباره `install.php` را باز کنید | پیام «نصب قبلاً انجام شده است» | اجازه‌ی نصب دوباره (این یک مشکل امنیتی جدی است) |
| ۱.۴ | در `/start` تلگرام تست کنید | یک پیام پاسخ می‌آید | هیچ پاسخی نمی‌آید |

## بخش ۲ — ساخت یک آزمون کامل (از پنل ادمین)

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۲.۱ | با اکانت ادمین `/admin` بفرستید | منوی کامل پنل باز می‌شود | «دسترسی ندارید» یا بدون پاسخ |
| ۲.۲ | 🧪 آزمون‌ها → آزمون جدید → فقط عنوان بدهید | آزمون ساخته می‌شود، لینک اختصاصی نمایش داده می‌شود | خطا، یا از شما می‌خواهد اسلاگ/کد دستی وارد کنید (این نباید اتفاق بیفتد) |
| ۲.۳ | یک پروفایل با عنوان فارسی بسازید | پروفایل ساخته می‌شود، یک «نتیجه» خالی خودکار برایش ساخته می‌شود | از شما کد انگلیسی می‌خواهد (نباید) |
| ۲.۴ | یک سوال بسازید | فقط عنوان متنی از شما پرسیده می‌شود | از شما عکس/ویس سوال خواسته می‌شود (نباید) |
| ۲.۵ | برای سوال ۲ گزینه بسازید | هر دو گزینه ساخته می‌شوند | فقط ۱ گزینه قابل ساخت است، یا خطا |
| ۲.۶ | برای هر گزینه امتیازدهی کنید (➕/➖) و «✅ ثبت» بزنید | امتیازها ذخیره می‌شوند | امتیاز منفی قابل ثبت است (این یک باگ است) |
| ۲.۷ | بدون زدن «✅ ثبت»، «⬅️ بازگشت / انصراف» بزنید | هیچ امتیازی ذخیره نمی‌شود | امتیازهای نیمه‌کاره ذخیره شده باشند |
| ۲.۸ | برای یک نتیجه فقط متن تحلیل اضافه کنید (بدون ویس/فایل) | فقط همان متن بعداً برای دانش‌آموز ارسال می‌شود | جای خالی/برچسب «ویس: ...» خالی هم ارسال شود |
| ۲.۹ | برای یک نتیجه دکمه CTA (متن + لینک) اضافه کنید | فقط یک دکمه، بدون متن اضافه قبل از آن | متن اضافه قبل از دکمه، یا دکمه کار نکند |
| ۲.۱۰ | آزمون ناقص (بدون سوال) را فعال کنید | با پیام دقیق فارسی رد می‌شود («هیچ سوال فعالی...») | بدون پیام، یا اجازه فعال‌سازی آزمون خراب |
| ۲.۱۱ | آزمون کامل را فعال کنید | فعال می‌شود، لینک نمایش داده می‌شود | خطا |

## بخش ۳ — تجربه‌ی دانش‌آموز

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۳.۱ | با یک اکانت **غیر ادمین**، لینک آزمون را باز کنید | مستقیم سوال اول را می‌بینید (بدون هیچ متن معرفی/توضیح)، گزینه‌ها به‌صورت دکمه‌های متنی شماره‌دار («۱) ...») زیر کیبورد نمایش داده می‌شوند، همراه نوار پیشرفت («سوال ۱ از ...») | یک متن معرفی/توضیح قبل از سوال دیده شود، یا گزینه‌ها به‌صورت دکمه شیشه‌ای زیر پیام باشند |
| ۳.۲ | به همه سوالات پاسخ دهید | در پایان، نتیجه شخصی‌سازی‌شده (متن/ویس/فایل — هرکدام که تنظیم شده) دریافت می‌کنید | خطا، یا نتیجه‌ی اشتباه/عمومی |
| ۳.۳ | نتیجه‌ای که فقط CTA دارد و محتوای دیگری ندارد | فقط یک دکمه با عنوان نتیجه دیده می‌شود | پیام خالی یا برچسب بی‌معنی |
| ۳.۴ | روی یک دکمه گزینه قدیمی/غیرمرتبط (مثلاً پیام کپی‌شده از قبل، یا دکمه سوال قبلی) بزنید | ربات آن را نادیده می‌گیرد یا خطای «گزینه نامعتبر» می‌دهد، سشن خراب نمی‌شود | پاسخ اشتباه ثبت شود یا آزمون کرش کند |
| ۳.۵ | همان آزمون را دوباره از ابتدا شروع کنید (retake) | آزمون از نو اجرا می‌شود، اما شمارنده‌ی «شروع منحصربه‌فرد» آن آزمون در آمار ادمین دوباره زیاد نمی‌شود (فقط شمارنده‌ی «تعداد تلاش» بالا می‌رود) | آمار «شروع منحصربه‌فرد» با هر بار retake دوباره زیاد شود |
| ۳.۶ | بدون لینک اختصاصی فقط `/start` بفرستید | پیام پیش‌فرض «آزمون فعالی مشخص نشده» را می‌بینید (مگر این تنظیم را عمداً روشن کرده باشید) | مستقیم وارد یک آزمون تصادفی شوید |
| ۳.۷ | (اطلاعاتی، نه امنیتی) بعد از دیدن نتیجه، در کانال اصلی عضو شوید | هیچ پیام یا دکمه‌ای درباره‌ی عضویت نمی‌بینید — عضویت فقط در پس‌زمینه برای آمار ادمین ثبت می‌شود | ربات از شما بخواهد عضو شوید یا نتیجه را تا عضویت نگه دارد (این دیگر رفتار درست نیست و باید گزارش شود) |


## بخش ۴ — مدیریت کاربران، کمپین‌ها، آنالیتیکس

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۴.۱ | 👥 کاربران → جستجو با شناسه عددی یک کاربر | همان کاربر پیدا می‌شود | نتیجه اشتباه یا خطا |
| ۴.۲ | یک کاربر را بن کنید، سپس از همان اکانت به ربات پیام بدهید | ربات دیگر با آن کاربر تعامل نمی‌کند (طبق تنظیمات بن) | کاربر بن‌شده هنوز عادی کار می‌کند |
| ۴.۳ | 📣 کمپین‌ها → یک کمپین جدید بسازید | لینک کمپین (`c_...`) نمایش داده می‌شود | خطا |
| ۴.۴ | با لینک کمپین یک کاربر جدید وارد شود | در آمار آن کمپین یک «شروع» ثبت می‌شود | آمار صفر می‌ماند |
| ۴.۵ | 📈 آنالیتیکس → گزارش کلی | اعداد منطقی (کاربران/شروع/تکمیل) نمایش داده می‌شود | خطا یا اعداد بی‌معنی |

## بخش ۵ — بکاپ و بازیابی (⚠️ با احتیاط تست کنید)

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۵.۱ | 🗜 پشتیبان‌گیری → ساخت بکاپ جدید | فایل روی سرور ساخته می‌شود و (اگر حجم اجازه دهد) در همان چت ارسال می‌شود | خطا، یا فایل ساخته نشود |
| ۵.۲ | بازیابی از بکاپ را شروع کنید ولی عبارت تأیید را اشتباه بفرستید | هیچ داده‌ای تغییر نمی‌کند، دوباره از شما عبارت درست خواسته می‌شود | با عبارت اشتباه هم بازیابی انجام شود (این یک مشکل امنیتی جدی است) |
| ۵.۳ | با عبارت درست («تایید بازیابی») ادامه دهید | داده‌ها با محتوای بکاپ جایگزین می‌شوند و پیام موفقیت می‌بینید | خطا بدون توضیح |

⚠️ توصیه: مرحله ۵.۳ را فقط روی یک نسخه‌ی تستی/staging امتحان کنید،
نه مستقیم روی دیتابیس production، مگر مطمئن باشید بکاپ قبل از آن
دقیقاً همان چیزی است که می‌خواهید برگردانید.

## بخش ۶ — لاگ و عیب‌یابی

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۶.۱ | یک توکن ربات موقتاً اشتباه در `config/app.php` بگذارید (فقط در محیط تست/staging) و یک درخواست به ربات بفرستید | یک رکورد `[PROBLEM]` در `storage/logs/problems-امروز.log` ثبت می‌شود | هیچ ثبتی انجام نشود، یا ربات به‌کل کرش کند بدون هیچ اثری در لاگ |
| ۶.۲ | توکن را به مقدار درست برگردانید | ربات دوباره عادی کار می‌کند | — |
| ۶.۳ | از پنل ادمین → 📋 لاگ‌ها → «ارسال فایل مشکلات امروز» | فایل مستقیم در همان چت دریافت می‌شود | خطا یا فایل خالی با اینکه مشکلی رخ داده |
| ۶.۴ | فایل‌های لاگ را از داخل مرورگر مستقیم باز کنید (مثلاً `https://yoursite.com/storage/logs/app-....log`) | خطای «دسترسی غیرمجاز» / صفحه پیدا نشد | محتوای فایل لاگ نمایش داده شود (این یک نشتی امنیتی جدی است) |

## بخش ۷ — سلامت سیستم

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۷.۱ | 🩺 سلامت سیستم را باز کنید | چک‌لیست کامل (دیتابیس، توکن، وبهوک، کانال‌ها، فضای ذخیره، افشای نصب‌کننده) با ✅/⚠️/❌ | صفحه خطا یا اطلاعات ناقص |
| ۷.۲ | ربات را از ادمین کانال فایل‌ها موقتاً حذف کنید، سپس دوباره سلامت سیستم را چک کنید | هشدار «ربات باید ادمین کانال فایل‌ها باشد» دیده شود | بدون هشدار (یعنی این چک کار نمی‌کند) |
| ۷.۳ | پس از یک نصب موفق، آدرس `install.php` سایت را مستقیم در مرورگر باز کنید | خطای «دسترسی مجاز نیست»/۴۰۳، یا صفحه پیدا نشد (فایل اصلاً پاک شده) | فرم نصب دوباره باز شود (این یک مشکل امنیتی بسیار جدی است) |

## بخش ۸ — پیام همگانی (Broadcast)

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۸.۱ | 📨 پیام همگانی → مخاطب → متن پیام → (اختیاری) دکمه → پیش‌نمایش → تأیید و شروع | پیام «ارسال شروع شد» + یک پیام پیشرفت زنده (که با ادامه‌ی ارسال به‌روزرسانی می‌شود) دریافت می‌کنید | خطا، یا هیچ پیامی برای هیچ‌کس ارسال نشود |
| ۸.۲ | ارسال را وسط کار لغو کنید | ارسال باقی‌مانده متوقف می‌شود، وضعیت job به «لغوشده» تغییر می‌کند | ارسال با وجود لغو ادامه پیدا کند |
| ۸.۳ | یک کاربر که ربات را بلاک کرده در فهرست مخاطبان باشد | آن کاربر بدون خطا رد می‌شود و برای دفعات بعد هم دیگر هدف قرار نمی‌گیرد | ارسال به آن کاربر باعث توقف کل صف شود |

## بخش ۹ — لینک‌های کمپین قابل چرخش

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۹.۱ | برای یک کمپین یک لینک اختصاصی صادر کنید و آزمونی را به آن متصل کنید | یک لینک آماده (`k_...`) دریافت می‌کنید که مستقیم همان آزمون را باز می‌کند | خطا، یا لینک به آزمون اشتباه وصل شود |
| ۹.۲ | همان لینک را «چرخش» دهید (Rotate) | لینک قدیمی از کار می‌افتد (پیام «این لینک دیگر معتبر نیست» می‌دهد)، لینک جدید کار می‌کند، و آمار قبلی هر دو لینک زیر همان کمپین قابل مشاهده می‌ماند | لینک قدیمی هنوز کار کند، یا آمار قبلی از بین برود |

## بخش ۱۰ — گفت‌وگوی خصوصی (Relay)

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۱۰.۱ | از صفحه‌ی جزئیات یک کاربر، گفت‌وگوی خصوصی را شروع کنید و پیام بدهید | پیام مستقیم به همان کاربر ارسال می‌شود | پیام به کاربر اشتباه برود |
| ۱۰.۲ | همان کاربر (غیر ادمین) یک پیام معمولی به ربات بفرستد | پیام او مستقیم به چت ادمین فوروارد می‌شود (نه پاسخ عمومی ربات) | پیام او نادیده گرفته شود یا فقط پاسخ عمومی ببیند |
| ۱۰.۳ | با `/cancel` گفت‌وگو را از سمت ادمین ببندید | گفت‌وگو تمام می‌شود، پیام‌های بعدی آن کاربر دیگر فوروارد نمی‌شوند | گفت‌وگو باز بماند |

## بخش ۱۱ — به‌روزرسانی و کنسول امن (فقط مدیر ارشد)

| # | چه کار کنید | نتیجه درست | نتیجه خراب |
|---|---|---|---|
| ۱۱.۱ | 🔄 به‌روزرسانی → شروع به‌روزرسانی، سپس فایل ZIP بسازید | پیش از هر تغییری، یک بکاپ از کد و دیتابیس در کانال فایل‌ها ارسال می‌شود | تغییرات بدون بکاپ اعمال شوند |
| ۱۱.۲ | یک فایل ZIP دستکاری‌شده (شامل مسیر `../`) آپلود کنید | با خطای امنیتی رد می‌شود، هیچ فایلی جایگزین نمی‌شود | فایل مخرب پذیرفته شود |
| ۱۱.۳ | از 🔐 کنسول امن، لینک تغییر توکن/دیتابیس صادر کنید | یک لینک یک‌بارمصرف در چت خصوصی دریافت می‌کنید که با یک بار استفاده منقضی می‌شود | لینک بدون محدودیت قابل استفاده مجدد باشد |

## خلاصه‌ی نهایی پذیرش

قبل از اعلام «نسخه آماده است»، همه‌ی ردیف‌های بالا باید ✅ باشند. اگر
حتی یک مورد ❌ بود، آن را به تیم فنی گزارش دهید (همراه با فایل
`storage/logs/problems-امروز.log` اگر مرتبط با خطا بود).

