# WA Clone — نصب و آپدیت (Phase 9 · نسخه 1.03)

نسخهٔ کامل مسنجر واتساپی با Laravel 11، Blade/Alpine و Tailwind.
این بسته شامل کد برنامه، `vendor`، فایل‌های build‌شدهٔ Vite، مهاجرت‌ها، seeders و راهنماست.

- نسخه: **1.03 / Phase 9** (پیامک OTP و بازیابی رمز، درگاه‌های Twilio/WhatsApp/Kurdisoft، اعلان گروهی ادمین و Web Push، پنل کاربران ریسپانسیو، برندینگ کردی‌سافت، استیکر، واکنش، کاتالوگ، پیام ناپدیدشونده، پنل ادمین، چندزبانه، رمزنگاری سرتاسری، PWA، نسخه‌بندی)
- تاریخ بسته: 2026-11-02
- شاخهٔ Git متناظر: `feature/phase-9-advanced`

> از نسخهٔ 1.02 دو بستهٔ مستقل منتشر می‌شود: `wa-clone-1.03-install.zip` برای نصب تازه (شامل `vendor`) و
> `wa-clone-1.03-update.zip` برای آپدیت کامل (بدون `vendor`). برای ارتقا، راهنمای `UPDATE.md` را ببینید.

---

## ۱) پیش‌نیازها

| مورد | حداقل |
|---|---|
| PHP | 8.2 (ترجیحاً 8.3) |
| افزونه‌های PHP | `pdo_mysql`, `mbstring`, `openssl`, `fileinfo`, `gd` یا `imagick`, `zip`, `curl`, `bcmath` |
| MySQL / MariaDB | MySQL 5.7+ یا MariaDB 10.4+ (دیتابیس `wa_clone` با `utf8mb4`) |
| وب‌سرور | Apache (XAMPP) یا `php artisan serve` |
| مرورگر | Chrome/Edge/Firefox جدید (برای WebCrypto و WebRTC) |

Node.js فقط در صورت تغییر فایل‌های front-end لازم است؛ خروجی build در `public/build` موجود است.

---

## ۲) نصب تازه (Fresh install)

```bash
# 1. استخراج
#    مسیر پیشنهادی: C:\xampp\htdocs\mymessanger\wa-clone
#    نام پوشه را می‌توانید تغییر دهید؛ در این صورت APP_URL را هم عوض کنید.

cd C:\xampp\htdocs\mymessanger\wa-clone

# 2. فایل محیط
copy .env.example .env
php artisan key:generate

# 3. در .env این مقادیر را تنظیم کنید:
#    APP_URL=http://localhost:81/mymessanger/wa-clone/public
#    DB_DATABASE=wa_clone  DB_USERNAME=root  DB_PASSWORD=
#    REVERB_APP_ID / KEY / SECRET و پورت 8080

# 4. دیتابیس را در phpMyAdmin یا MySQL بسازید:
#    CREATE DATABASE wa_clone CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

# 5. جدول‌ها + دادهٔ نمونه
php artisan migrate --seed

# 6. لینک فایل‌ها (آواتار، کاور، استیکر، پیوست)
php artisan storage:link

# 7. ادمین پنل (اختیاری؛ بدون ADMIN_PASSWORD رمز تصادفی یک‌بار چاپ می‌شود)
php artisan db:seed --class=AdminUserSeeder

# 8. سرورها
php artisan reverb:start --port=8080      # WebSocket
php artisan queue:work                    # ارسال رویدادها و نوتیفیکیشن‌ها
```

سپس باز کنید: `http://localhost:81/mymessanger/wa-clone/public`

### حساب‌های نمونه (رمز همه: `password`)

`alice@waclone.test` · `bob@waclone.test` · `carol@waclone.test` · `dave@waclone.test` · `admin@waclone.test`

مسیر پنل ادمین از `ADMIN_PATH` در `.env` خوانده می‌شود (پیش‌فرض `admin-x7k2`).

### Apache روی پورت ۸۱ (XAMPP)

در `C:\xampp\apache\conf\extra\httpd-vhosts.conf` (یا `httpd.conf`):

```apache
Listen 81
<VirtualHost *:81>
    DocumentRoot "C:/xampp/htdocs"
    <Directory "C:/xampp/htdocs">
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
```

`mod_rewrite` باید فعال باشد و `.htaccess` موجود در `public/` اجازهٔ Override داشته باشد.
اگر مسیر یا پورت دیگری استفاده می‌کنید، `APP_URL` و متغیرهای `REVERB_*` را هم‌راستا کنید.

### سرویس‌های دائمی

- **Reverb** روی `8080` (جدا از Apache). بدون آن پیام‌ها فقط با رفرش دیده می‌شوند.
- **queue:work** برای پخش رویدادهای `ShouldBroadcast` و نوتیفیکیشن‌ها؛ بعد از هر تغییر کد eventها را restart کنید.
- زمان‌بند پیام‌های ناپدیدشونده در `routes/console.php` است؛ برای اجرا در ویندوز Task Scheduler:

```bat
schtasks /create /tn "wa-clone-schedule" /tr "C:\xampp\php\php.exe C:\xampp\htdocs\mymessanger\wa-clone\artisan schedule:run" /sc minute /mo 1
```

### مجوز پوشه‌ها (ویندوز معمولاً لازم نیست)

`storage/` و `bootstrap/cache/` باید قابل نوشتن باشند. در لینوکس:

```bash
chmod -R ug+rwx storage bootstrap/cache
```

---

## ۳) آپدیت از نسخهٔ قبلی

> قبل از هر چیز از دیتابیس (`wa_clone`) و پوشهٔ `storage/app/public` بکاپ بگیرید.

1. سرویس‌ها را متوقف کنید: `queue:work` و `reverb:start` (Ctrl+C).
2. فایل‌های بستهٔ جدید را روی پوشهٔ فعلی کپی کنید؛ **این‌ها را نگه دارید**:
   - `.env` (و تنظیمات محلی آن)
   - `storage/app/public` (آپلودهای کاربران) و `storage/logs`
   - در صورت وجود: `public/storage` (لینک)
3. اگر `vendor` را از بستهٔ جدید کپی کردید، نیازی به Composer نیست؛ در غیر این صورت:

```bash
composer install --no-dev --optimize-autoloader
npm ci && npm run build      # فقط اگر فایل‌های front-end را تغییر داده‌اید یا build را جایگزین نکرده‌اید
```

4. مهاجرت‌ها و کش:

```bash
php artisan migrate --force
php artisan optimize:clear
php artisan storage:link      # اگر لینک وجود ندارد
php artisan db:seed --class=PostUpdateSeeder   # در صورت وجود دادهٔ تکمیلی نسخه
```

5. سرویس‌ها را دوباره اجرا کنید:

```bash
php artisan reverb:start --port=8080
php artisan queue:work
```

6. در مرورگر یک‌بار `Ctrl+F5` بزنید تا JS/CSS جدید (`public/build`) بارگذاری شود.

### نکتهٔ مهم دربارهٔ رمزنگاری سرتاسری (Phase 9)

- مهاجرت `2026_11_03_000012_add_end_to_end_encryption` جدول‌های `user_keys` و `conversation_keys` و ستون‌های `messages.ciphertext/iv/is_encrypted` را می‌سازد.
- پیام‌های قدیمی روشن می‌مانند؛ فقط مکالمه‌هایی که رمزنگاری در آن‌ها روشن شود رمز می‌شوند.
- کلید خصوصی هر کاربر فقط در **IndexedDB همان مرورگر** است (`wa-e2e`). پاک‌کردن داده‌های مرورگر یا دستگاه جدید ⇒ پیام‌های رمز قبلی قابل خواندن نیستند (در حباب «key unavailable on this device» می‌بینید). بکاپ/انتقال کلید در این نسخه وجود ندارد.
- WebCrypto فقط در `https` یا `localhost` فعال است؛ روی IP/دومین بدون HTTPS ساخت کلید شکست می‌خورد.

---

## ۴) بازگشت به عقب (Rollback)

```bash
php artisan migrate:rollback --step=1     # حذف جدول‌های E2E و ستون‌ها
# سپس فایل‌های نسخهٔ قبلی را برگردانید و:
php artisan optimize:clear
```

هشدار: rollback مهاجرت E2E ستون‌های ciphertext را حذف می‌کند و پیام‌های رمز از دست می‌روند. ابتدا بکاپ دیتابیس بگیرید.

---

## ۵) عیب‌یابی سریع

| نشانه | علت/راه‌حل |
|---|---|
| صفحهٔ سفید یا خطای ۵۰۰ | `storage/logs/laravel.log`؛ معمولاً `APP_KEY` خالی یا مجوز `storage` |
| پیام‌ها بلادرنگ نمی‌رسند | Reverb روی `8080` بالا نیست، `queue:work` خاموش است، یا `VITE_REVERB_*` با `.env` هم‌خوان نیست (بعد از تغییر، build مجدد) |
| خطای WebSocket `ERR_CONNECTION_REFUSED` | `php artisan reverb:start --port=8080` را اجرا کنید |
| استیکر/آواتار ۴۰۴ | `php artisan storage:link` |
| «Waiting for encryption keys from…» | هر دو طرف باید صفحه را یک‌بار باز کنند تا کلید عمومی publish شود؛ سپس دوباره بفرستید |
| «key unavailable on this device» | کلید خصوصی در این مرورگر نیست (دستگاه/پروفایل دیگر یا داده پاک شده) |
| خطای ۴۲۲ در چت رمز | در مکالمهٔ رمزنگاری‌شده فقط متن مجاز است؛ استیکر/پیوست ارسال نکنید |
| زبان یا ترجمه اشتباه | `/admin` → Languages/Translations؛ زبان پیش‌فرض `en` و fallback انگلیسی است |
| خطای 405 در پایان نصب | اگر بستهٔ قدیمی را استفاده می‌کنید، فرم حذف به ریشهٔ برنامه POST می‌فرستد. بستهٔ جدید این POST را با ۳۰۳ به GET هدایت می‌کند؛ با این حال `public/install.php` را حذف کنید و آدرس برنامه را با GET باز کنید. |
| صفحهٔ پایان نصب، اما جداول ساخته نشده‌اند | ویزارد جدید در اولین خطا متوقف می‌شود و نشانگر نصب را ثبت نمی‌کند. لاگ مرحلهٔ ۴ را بخوانید؛ علت رایج، خطای `migrate` یا غیرفعال بودن `proc_open` است. پس از رفع خطا دوباره از مرحلهٔ ۴ تلاش کنید. |
| خطای 1045 Access denied در migrate | رمز/کاربر دیتابیس در `.env` با cPanel یکسان نیست یا کاربر به دیتابیس متصل نشده است. `php artisan config:clear` و سپس `migrate:status` را اجرا کنید؛ رمز را در `.env` داخل کوتیشن بگذارید. |

### نصب روی هاست اشتراکی Namecheap

- بهتر است Document Root دامنه/ساب‌دامین را مستقیماً روی پوشهٔ `public` تنظیم کنید. در این حالت آدرس نصب `https://example.com/install.php` است.
- اگر کل بسته را در `public_html` گذاشته‌اید، آدرس درست `https://example.com/public/install.php` است و آدرس برنامه هم باید `/public` داشته باشد.
- در پایان نصب، فایل `public/install.php` را از **File Manager → public** حذف کنید. اگر فرم حذف خودکار خطا داد، صفحه را با POST دوباره ارسال نکنید؛ فقط فایل را دستی حذف و سپس آدرس برنامه را باز کنید.
- دامنه را با HTTPS و بدون تکیه بر ریدایرکت HTTP→HTTPS باز کنید و `APP_URL` را در `.env` دقیقاً با همان مسیر (شامل `/public` در صورت وجود) تنظیم کنید.

---

## ۶) بررسی سلامت پس از نصب

```bash
php artisan about
php artisan migrate:status
php artisan test          # نیاز به محیط تست و دیتابیس جداگانه دارد
php artisan route:list --path=chat
```

- ورود با `alice@waclone.test` و ارسال پیام به `bob@waclone.test`.
- باز کردن `http://localhost:81/mymessanger/wa-clone/public/chat/1` در دو مرورگر و تست قفل رمزنگاری.

---

## ۷) محتوای بسته

- `app/`, `bootstrap/`, `config/`, `database/`, `lang/`, `public/`, `resources/`, `routes/`, `tests/`
- `vendor/` (وابستگی‌های Composer، آماده اجرا)
- `public/build/` (CSS/JS کامپایل‌شده)
- `composer.json`, `composer.lock`, `package.json`, `package-lock.json`
- `.env.example` (فایل `.env` واقعی داخل بسته نیست)
- `README.md`, `INSTALL.md`, `UPDATE.md`, مستندات فازها (`CHANGELOG_PHASE_*.md`)

حذف‌شده‌ها: `.git`, `node_modules`, `.env`, لاگ‌ها، کش‌های framework، بکاپ‌های `storage/app/releases` و فایل‌های موقت.
بستهٔ update علاوه بر این‌ها `vendor` و `public/install.php` را هم ندارد.
