# ربات‌ساز میرزا احسان‌نت — نسخه جداسازی خودکار بدون ورودی اضافه

## نتیجه این نسخه

در Installer فقط اطلاعات ربات مادر و دیتابیس اصلی همان پروژه وارد می‌شود. برای ربات‌های فرزند هیچ‌کدام از موارد زیر گرفته یا استفاده نمی‌شود:

- دیتابیس جداگانه
- یوزر یا رمز دیتابیس فرزند
- cPanel یا DirectAdmin
- API Token کنترل‌پنل
- دسترسی `CREATE DATABASE`، `CREATE USER` یا `GRANT`

هر ربات فرزند به‌صورت خودکار یک فضای جدول اختصاصی و غیرقابل‌تداخل در دیتابیس مادر دریافت می‌کند. نمونه نام جدول‌ها:

```text
mb8d71c4c6192a11_user
mb8d71c4c6192a11_setting
mb8d71c4c6192a11_marzban_panel
```

پیشوند هر ربات از Secret تصادفی همان ربات ساخته می‌شود. تمام مسیرهای PDO و MySQLi قالب قبل از اجرا به جدول‌های همان ربات هدایت می‌شوند.

## محدوده جداسازی

این نسخه در هاست‌های معمولی که اجازه ساخت دیتابیس یا یوزر جدید ندارند، جداسازی منطقی کامل برنامه را فراهم می‌کند:

- پنل‌های فیلترشکن
- کاربران
- محصولات
- سفارش‌ها و فاکتورها
- تراکنش‌ها
- تنظیمات
- ادمین‌ها
- گزارش‌ها و جدول‌های کمکی

جدول‌های ربات مادر بدون پیشوند هستند و ربات‌های فرزند فقط از جدول‌های پیشونددار خود استفاده می‌کنند. ربات‌های فرزند نیز پیشوند متفاوت دارند.

> این روش «دیتابیس فیزیکی جدا با یوزر MySQL جدا» نیست؛ چون سرور مقصد چنین مجوز یا APIای در اختیار پروژه نمی‌گذارد. با این حال، فعالیت عادی کد هر ربات در فضای جدول اختصاصی خودش محدود شده و هیچ ورودی اضافه‌ای در Installer لازم نیست.

## پیش‌نیاز دیتابیس

یوزر دیتابیس مادر فقط باید روی همان دیتابیس اجازه‌های معمول زیر را داشته باشد:

- `SELECT`, `INSERT`, `UPDATE`, `DELETE`
- `CREATE`, `ALTER`, `DROP`, `INDEX`

گزینه `ALL PRIVILEGES` روی دیتابیس مادر معمولاً همین نیاز را پوشش می‌دهد. مجوز سطح سرور برای ساخت دیتابیس یا یوزر جدید لازم نیست.

## نصب تازه

1. فایل‌ها را روی هاست قرار دهید.
2. `public/install.php` را باز کنید.
3. اطلاعات ربات مادر و دیتابیس اصلی را وارد کنید.
4. نصب را اجرا کنید.
5. بعد از نصب، `public/install.php` را حذف یا مسدود کنید.

بخش ربات‌های فرزند هیچ فیلدی ندارد و ساخت فضای داده هنگام افزودن هر ربات خودکار انجام می‌شود.

## ارتقای نصب فعلی

ابتدا از فایل‌ها و دیتابیس مادر بکاپ بگیرید. فایل‌های نسخه جدید را جایگزین کنید، اما `app/config.php` فعلی را حذف نکنید. سپس اجرا کنید:

```bash
php tools/upgrade_zero_input.php
php tools/check_isolation.php
```

خروجی تست موفق با `OK:` شروع می‌شود.

برای سازگاری با دستور نسخه قبلی، این دستور نیز به همان ارتقای جدید هدایت می‌شود:

```bash
php tools/upgrade_cpanel_auto.php
```

هیچ cPanel یا API Token استفاده نمی‌شود.

## ربات‌های قدیمی و مشترک

داده‌های نسخه قدیمی داخل جدول‌های مشترک ذخیره شده‌اند و رکوردها شناسه قابل‌اعتماد ربات ندارند؛ بنابراین تفکیک دقیق اطلاعات مخلوط‌شده ممکن نیست.

برای بازسازی یک یا همه ربات‌های قدیمی با فضای خالی و کاملاً مستقل اجرا کنید:

```bash
php tools/isolate_existing_bots.php --yes
```

فقط یک ربات:

```bash
php tools/isolate_existing_bots.php --yes --bot-id=123
```

این ابزار قبل از جایگزینی سورس قدیمی بکاپ پوشه می‌گیرد و در صورت خطا Rollback می‌کند. اطلاعات مشترک تاریخی به فضای جدید کپی نمی‌شوند.

## پوشه خودکار هر ربات

برای هر ربات این مسیر خودکار ساخته می‌شود:

```text
storage/child_databases/<webhook-secret>/
├── manifest.json
└── backups/
```

`manifest.json` فقط اثر انگشت Secret، نام دیتابیس مادر، نوع جداسازی و پیشوند جدول را نگه می‌دارد. رمز دیتابیس داخل آن ذخیره نمی‌شود. مسیر با `.htaccess` و سطح دسترسی محدود محافظت شده است.

## رفتار حذف و Rollback

هنگام حذف ربات:

1. Webhook حذف می‌شود.
2. فقط جدول‌هایی که با پیشوند همان ربات شروع می‌شوند حذف می‌شوند.
3. پوشه اختصاصی همان ربات حذف می‌شود.
4. سورس Webhook همان ربات پاک می‌شود.
5. رکورد مدیریتی ربات حذف می‌شود.

اگر ساخت ربات در هر مرحله شکست بخورد، پوشه، جدول‌ها، Webhook و رکورد نیمه‌کاره پاک می‌شوند.

## محافظت‌های اضافه

- Installer اصلی قالب فرزند و `install.sh` داخل ربات‌های ساخته‌شده کپی نمی‌شوند.
- `config.php`، `table.php` و `tenant_db.php` از دسترسی مستقیم وب مسدود شده‌اند.
- بکاپ داخلی ربات دیگر `mysqldump` کل دیتابیس مادر را اجرا نمی‌کند؛ فقط جدول‌های همان ربات را خروجی می‌گیرد.
- `SHOW TABLES` فقط جدول‌های فضای همان ربات را نمایش می‌دهد.
- کوئری‌های procedural MySQLi قالب از Wrapper جداسازی عبور می‌کنند.
- نام جدول‌های پویا قبل از استفاده اعتبارسنجی و پیشوندگذاری می‌شوند.
- فایروال SQL دسترسی مستقیم به جدول‌های مادر، namespace ربات دیگر، دیتابیس دیگر و دستورهای مدیریتی خطرناک را متوقف می‌کند.
- حالت‌های JOIN قدیمی با چند جدول، Queryهای چنددستوری و کامنت‌های اجرایی MySQL نیز کنترل می‌شوند.
- بازنشانی داخلی ربات فقط جدول‌های همان ربات را حذف و فایل schema را به‌صورت محلی اجرا می‌کند؛ هیچ درخواست HTTP به Installer فرزند وجود ندارد.
- مسیرهای غیرعمومی `app`، `templates`، `storage`، `tools`، `sql` و `cron` در برابر دسترسی مستقیم وب محافظت شده‌اند.

## تست‌های بسته

تست بدون اتصال دیتابیس:

```bash
php tools/package_self_test.php
```

تست واقعی روی دیتابیس هاست:

```bash
php tools/check_isolation.php
```

تست دوم یک جدول موقت اختصاصی می‌سازد، نوشتن و خواندن را بررسی می‌کند و سپس آن را پاک می‌کند.

## نتیجه کنترل استاتیک این بسته

- بررسی نحوی ۱۲۱ فایل PHP
- بررسی نحوی JavaScript پنل
- بررسی ۱۴۷۹ رشته SQL قالب از مسیر بازنویسی و فایروال، بدون خطا
- تست تولید ۱۰۰۰ namespace یکتا
- بررسی نبود اتصال خام PDO/MySQLi در کد اجرایی ربات فرزند
- بررسی نبود Installer فرزند، `mysqldump` کل دیتابیس و وابستگی اجرایی cPanel

تست واقعی دسترسی MySQL فقط روی سرور مقصد قابل انجام است و با `php tools/check_isolation.php` انجام می‌شود.
