# راهنمای جامع راه‌اندازی (نسخه ۲.۰)

این راهنما فرض می‌کنه یک سرور لینوکسی (Ubuntu 22.04+) با دسترسی root/sudo داری.
اگه از هاست اشتراکی استفاده می‌کنی، بخش «نصب پیش‌نیازها» رو رد کن و برو سراغ
«تنظیم دیتابیس» — هاستینگ‌های cPanel معمولاً PHP و MySQL آماده دارن.

## ۰. پیش‌نیازها

- PHP **۸.۱ یا بالاتر** با اکستنشن‌های: `pdo_mysql`, `curl`, `mbstring`, `json`
- MySQL **۸.۰+** یا MariaDB ۱۰.۶+
- یک دامنه یا ساب‌دامنه با گواهی SSL معتبر (Telegram **فقط HTTPS** رو برای webhook قبول می‌کنه، نه IP خام و نه HTTP)
- توکن ربات از [@BotFather](https://t.me/BotFather)

## ۱. نصب پیش‌نیازها روی سرور (Ubuntu)

```bash
sudo apt update
sudo apt install -y php8.2-fpm php8.2-cli php8.2-mysql php8.2-curl php8.2-mbstring \
    mysql-server nginx certbot python3-certbot-nginx unzip
```

## ۲. آپلود پروژه

فایل‌های این پکیج رو در مسیری مثل `/var/www/prediction-bot` قرار بده:

```bash
sudo mkdir -p /var/www/prediction-bot
cd /var/www/prediction-bot
unzip prediction-bot.zip -d .
# اگه zip یک پوشه prediction-bot داخلش داره:
mv prediction-bot/* .
```

## ۳. تنظیم دیتابیس

```bash
sudo mysql -u root -p
```
داخل MySQL:
```sql
CREATE DATABASE prediction_bot CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'pmbot'@'localhost' IDENTIFIED BY 'یک-پسورد-قوی-اینجا';
GRANT ALL PRIVILEGES ON prediction_bot.* TO 'pmbot'@'localhost';
FLUSH PRIVILEGES;
EXIT;
```
سپس ساختار جداول رو وارد کن:
```bash
mysql -u pmbot -p prediction_bot < sql/schema.sql
mysql -u pmbot -p prediction_bot < sql/migrations/002_v1.1_additions.sql
mysql -u pmbot -p prediction_bot < sql/migrations/003_v1.2_additions.sql
mysql -u pmbot -p prediction_bot < sql/migrations/004_fix_utf8mb4.sql
```
فایل ۰۰۴ برای مواردیه که دیتابیس یا جدول‌ها به هر دلیلی با charset غیر
از utf8mb4 ساخته شده باشن (که باعث می‌شه متن فارسی به‌شکل `؟؟؟` ذخیره
بشه) — اگه دستور بالا در بخش ۳ رو دقیق اجرا کرده باشی معمولاً لازم
نیست، ولی اجراش بی‌ضرره و برای اطمینان توصیه می‌شه.

## ۴. متغیرهای محیطی

از v1.2 به بعد ساده‌ترین راه (حتی روی VPS) کپی کردن `config/config.example.php`
به `config/config.local.php` و پر کردن مقادیر واقعی مستقیم توی همون فایله
— نیازی به تنظیم env var نداری. اگه ترجیح می‌دی همچنان از env var استفاده
کنی (مثلاً برای Docker)، کافیه `config.local.php` رو نسازی؛ در اون صورت
مقادیر زیر از env خونده می‌شن:

| متغیر | توضیح | مثال |
|---|---|---|
| `DB_HOST` | آدرس دیتابیس | `127.0.0.1` |
| `DB_NAME` | نام دیتابیس | `prediction_bot` |
| `DB_USER` | یوزر دیتابیس | `pmbot` |
| `DB_PASS` | پسورد دیتابیس | `...` |
| `TG_BOT_TOKEN` | توکن گرفته‌شده از BotFather | `123456:AA玩...` |
| `TG_BOT_USERNAME` | یوزرنیم ربات بدون @ (برای لینک دعوت) | `MyPredictionBot` |
| `TG_WEBHOOK_SECRET` | یک رشته تصادفی طولانی که خودت می‌سازی | `openssl rand -hex 32` |
| `TG_ADMIN_IDS` | آیدی عددی تلگرام ادمین‌ها، با کاما جدا | `111111,222222` |

تولید یک secret امن:
```bash
openssl rand -hex 32
```

## ۵. تنظیم Nginx (نمونه vhost)

چیدمان پروژه یکپارچه‌ست: `public/`, `admin/`, `src/`, `config/`, `sql/`,
`cron/` همه کنار هم زیر یک پوشه ریشه‌ان و با مسیر نسبی به هم وصلن (مثلاً
هم `public/webhook.php` هم `admin/index.php` دنبال `../src/Database.php`
می‌گردن). به همین خاطر `root` باید روی خودِ پوشه ریشه پروژه باشه، نه روی
`public/` — و آدرس‌ها یک تکه `/public/` یا `/admin/` اضافه دارن:

```nginx
server {
    listen 443 ssl http2;
    server_name bot.yourdomain.com;

    ssl_certificate     /etc/letsencrypt/live/bot.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/bot.yourdomain.com/privkey.pem;

    root /var/www/prediction-bot;
    index index.php;

    # پوشه‌های حساس هرگز نباید از وب قابل‌دسترس باشن (cron/ عمداً جا نیفتاده،
    # چون قراره با توکن از طریق URL هم قابل‌فراخوانی باشه)
    location ~ ^/(src|sql|config)/ {
        deny all;
        return 404;
    }

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param DB_HOST        "127.0.0.1";
        fastcgi_param DB_NAME        "prediction_bot";
        fastcgi_param DB_USER        "pmbot";
        fastcgi_param DB_PASS        "پسورد-دیتابیس";
        fastcgi_param TG_BOT_TOKEN   "توکن-ربات";
        fastcgi_param TG_BOT_USERNAME "MyPredictionBot";
        fastcgi_param TG_WEBHOOK_SECRET "secret-تولیدشده";
        fastcgi_param TG_ADMIN_IDS   "111111,222222";
    }
}

server {
    listen 80;
    server_name bot.yourdomain.com;
    return 301 https://$host$request_uri;
}
```

با این چیدمان آدرس‌ها این‌جوری می‌شن:
- Webhook: `https://bot.yourdomain.com/public/webhook.php`
- دیباگ: `https://bot.yourdomain.com/public/debug.php`
- پنل ادمین: `https://bot.yourdomain.com/admin/index.php`

(اگه ترجیح می‌دی webhook دقیقاً روی ریشه دامنه باشه بدون `/public/`، می‌تونی
`root` رو روی `public/` بذاری و به‌جاش یک `location /admin { alias
/var/www/prediction-bot/admin; }` جدا برای پنل ادمین در nginx تعریف کنی —
پیچیده‌تره ولی هردو راه کار می‌کنه؛ روش بالا برای اکثر کاربرها ساده‌تره.)

⚠️ نکته امنیتی: پنل ادمین رمز عبور و CSRF داره که برای شروع کافیه؛ برای
امنیت بیشتر می‌تونی یک IP allowlist یا Basic-Auth اضافه روی مسیر
`/admin/` هم در nginx بذاری.

گرفتن گواهی SSL رایگان:
```bash
sudo certbot --nginx -d bot.yourdomain.com
```

## ۶. ساخت اولین ادمین و seed اولیه

از v1.2 به بعد این کار از مرورگر انجام می‌شه (بدون نیاز به CLI)، هرچند
روی VPS هم می‌تونی از ترمینال به همون آدرس curl بزنی اگه خواستی. کافیه
برو به:

```
https://bot.yourdomain.com/admin/index.php
```
چون هنوز ادمینی نساختی، همین آدرس خودش فرم راه‌اندازی اولیه رو نشون
می‌ده. یک نام کاربری و رمز عبور قوی وارد کن. این فرم اولین ادمین (نقش
superadmin) رو می‌سازه و دسته‌بندی‌ها + چند Achievement نمونه رو هم اضافه
می‌کنه. بعد از اولین استفاده، همین آدرس خودش تبدیل به صفحه ورود می‌شه؛
برای ادمین‌های بعدی از داخل پنل (کاربران → افزودن ادمین) استفاده کن.

## ۷. ثبت Webhook در تلگرام

بهتره از پنل ادمین (`admin/index.php` -> Webhook) با یک کلیک ثبتش کنی —
آدرس درست رو خودش حدس می‌زنه. اگه ترجیح می‌دی دستی از ترمینال بزنی:

```bash
curl -F "url=https://bot.yourdomain.com/public/webhook.php" \
     -F "secret_token=همون-TG_WEBHOOK_SECRET" \
     https://api.telegram.org/bot<TOKEN>/setWebhook
```
بررسی وضعیت webhook:
```bash
curl https://api.telegram.org/bot<TOKEN>/getWebhookInfo
```
اگه `pending_update_count` بالا رفت یا `last_error_message` داشت، لاگ
php-fpm/nginx رو چک کن (`/var/log/nginx/error.log` و
`/var/log/php8.2-fpm.log`).

## ۸. کران‌جاب‌ها

```bash
crontab -e
```
این خط‌ها رو اضافه کن (تطبیق مسیر و مقادیر env با نصب خودت):
```
0 3 * * * DB_HOST=127.0.0.1 DB_NAME=prediction_bot DB_USER=pmbot DB_PASS=... php /var/www/prediction-bot/cron/reconcile.php >> /var/log/pm-reconcile.log 2>&1
*/10 * * * * DB_HOST=127.0.0.1 DB_NAME=prediction_bot DB_USER=pmbot DB_PASS=... TG_BOT_TOKEN=... php /var/www/prediction-bot/cron/notify.php >> /var/log/pm-notify.log 2>&1
```
`notify.php` هم بازارهای تموم‌شده رو می‌بنده و هم بازارهایی که زمان
شروعشون رسیده رو باز می‌کنه (حتی اگه هیچ ادمینی پنل رو باز نکنه)، علاوه
بر ارسال اعلان تسویه و یادآوری روزانه.

## ۹. تست نهایی

1. توی تلگرام دنبال ربات بگرد و `/start` بزن — باید پیام خوش‌آمد + موجودی اولیه بیاد.
2. یک بازار نمونه از `https://bot.yourdomain.com/admin/index.php?page=markets_create` بساز.
3. توی ربات از منو «بازارهای باز» رو بزن، بازار رو ببین، یک پیش‌بینی کوچیک ثبت کن.
4. از منو «پیش‌بینی‌های من» رو بزن و مطمئن شو پوزیشن نمایش داده می‌شه.
5. از پنل ادمین بازار رو (بعد از گذشت زمان بسته‌شدن) تسویه کن و ببین موجودی
   کاربر آپدیت شد.
6. `php cron/reconcile.php` رو دستی اجرا کن و مطمئن شو "reconciliation OK" چاپ می‌شه.

## چک‌لیست امنیتی قبل از رفتن به Production

- [ ] `TG_WEBHOOK_SECRET` یک رشته تصادفی واقعی هست، نه مقدار پیش‌فرض
- [ ] پسورد دیتابیس و پسورد ادمین قوی و یکتا هستن
- [ ] SSL معتبره و HTTP به HTTPS ریدایرکت می‌شه
- [ ] پوشه‌های `src/`, `sql/`, `config/` از وب قابل‌دسترس نیستن (بخش ۵ بالا، یا با `.htaccess` که در هر پوشه از قبل موجوده)
- [ ] بعد از ساخت اولین ادمین، `admin/index.php` دیگه فرم راه‌اندازی نشون نمی‌ده (بررسی کن)
- [ ] `debug_token` بعد از اطمینان از راه‌اندازی درست، از `config.local.php`/env پاک شده
- [ ] `display_errors` در PHP روی production خاموشه (`php.ini`: `display_errors = Off`)
- [ ] بک‌آپ روزانه از دیتابیس فعاله (حداقل `mysqldump` روزانه با نگهداری ۷-۳۰ روزه)
- [ ] کران reconcile هر شب اجرا و لاگش چک می‌شه
- [ ] متن فارسی آزمایشی درست ذخیره/نمایش می‌شه، نه به‌شکل `؟؟؟` (اگه بود، `sql/migrations/004_fix_utf8mb4.sql` رو اجرا کن)
