# باشگاه مشتریان سایت ساز زرین

سامانه فارسی مدیریت منتورینگ سایت، اطلاعات مشتری، تیکت، سفارش، پیامک و امتیاز باشگاه.

**نسخه تحویل: 0.9.0، آماده نصب و ارزیابی پذیرش.** این بسته سورس واقعی Laravel است. آزمون‌های خودکار گردش‌های حساس همراه پروژه قرار دارند. تأیید بهره‌برداری نهایی به آزمون روی میزبانی مقصد، ارسال واقعی IPPanel، تراکنش واقعی زیبال و بازبینی مرورگر نیاز دارد. گزارش دقیق در `docs/verification.fa.md` است.

## فناوری و محتویات

- PHP 8.3 یا جدیدتر، Laravel 13، Livewire 4 و Filament 5؛ نسخه‌های دقیق در `composer.lock` قفل شده‌اند.
- MySQL با InnoDB و utf8mb4 برای محیط عملیاتی؛ SQLite برای آزمون توسعه.
- فارسی و RTL، فایل محلی فونت وزیرمتن، رنگ‌های سرمه‌ای و طلایی، چیدمان واکنش‌گرا.
- تقویم و نمایش تاریخ شمسی با منطقه زمانی تهران؛ ذخیره زمان در UTC.
- فایل‌های رابط و وابستگی‌های PHP داخل بسته کامل نصب قرار دارند؛ در هاست نیازی به Node.js یا اجرای Composer نیست.

## نصب آسان با مرورگر

۱. یک زیر‌دامنه با HTTPS مانند `club.example.com` و یک پایگاه داده **خالی** بسازید. نسخه PHP وب و خط فرمان باید حداقل 8.3 باشد.

۲. بسته را از حالت فشرده خارج کنید. ریشه وب زیر‌دامنه را دقیقاً روی پوشه `zarrin-club/public` تنظیم کنید. فایل‌های `app`، `vendor`، `storage` و `.env` باید بیرون ریشه عمومی وب بمانند. کل پوشه برنامه را به‌عنوان ریشه عمومی منتشر نکنید.

۳. به کاربر اجرای PHP اجازه نوشتن در `storage`، `bootstrap/cache` و در زمان نصب، پوشه اصلی برنامه بدهید. روی سرور لینوکسی معمولاً مالکیت درست و مجوز پوشه 750 و فایل 640 کافی است؛ از مجوز عمومی 777 استفاده نکنید.

۴. یکی از دو روش زیر را برای فعال‌کردن نصب انتخاب کنید:

- با SSH یا Terminal کنترل‌پنل، در پوشه برنامه اجرا کنید: `php install.php --web`. کد نمایش‌داده‌شده را نزد خود نگه دارید.
- بدون SSH، فایل `installer/prepare.html` داخل بسته را روی رایانه خود باز کنید. «ساخت کد نصب» را بزنید، فایل `install.token` را دانلود و با File Manager در پوشه `storage` قرار دهید. کد نصب همان صفحه را کپی کنید. این ابزار محلی است و اطلاعاتی ارسال نمی‌کند.

۵. صفحه `https://club.example.com/install.php` را باز کنید. کد نصب، آدرس دامنه، مشخصات پایگاه داده و اطلاعات اولین مدیر را وارد کنید. پس از موفقیت، نصب قفل می‌شود و کد موقت حذف می‌شود. حساب یا رمز عمومی پیش‌فرض وجود ندارد.

۶. وارد حساب مدیر شوید. در «مرکز عملیات» بخش‌ها، کارکنان، مشتریان و پلن‌ها را تنظیم کنید. پلن‌های نمونه عمداً قیمت صفر و وضعیت غیرفعال دارند؛ تعرفه واقعی کسب‌وکار باید توسط مدیر تعیین و فعال شود.

۷. پیامک و پرداخت را طبق بخش بعد فعال کنید و اجرای خودکار را برقرار کنید.

اگر نصب نیمه‌کاره ماند، علت را در گزارش سرور بررسی کنید. نصب‌گر پایگاه داده غیرخالی را پاک یا بازنویسی نمی‌کند. برای ادامه نصب نیمه‌کاره توسط مسئول فنی: `php artisan migrate --force` و `php artisan db:seed --force`، سپس `php artisan club:bootstrap-admin` را اجرا کنید. این دستور فقط وقتی هنوز هیچ مدیری وجود ندارد اجازه ایجاد اولین مدیر را می‌دهد. بعد از موفقیت قفل نصب را ایجاد می‌کند.

## نصب از خط فرمان

در پوشه برنامه `php install.php` را اجرا و به پرسش‌ها پاسخ دهید. رمزهای مدیر و پایگاه داده در ترمینال سازگار نمایش داده نمی‌شوند. همه پیش‌نیازها در شروع بررسی می‌شوند.

اگر فقط سورس بدون پوشه vendor دریافت کرده‌اید، ابتدا روی محیط ساخت `composer install --no-dev --prefer-dist --optimize-autoloader` را اجرا کنید. بسته کامل این مرحله را از قبل دارد.

## تنظیم IPPanel و زیبال

در «مرکز عملیات ← تنظیمات اتصال و یادآوری» کلید IPPanel، خط فرستنده و مرچنت زیبال را وارد کنید. کلیدها رمزگذاری و در فرم تنظیمات دوباره نمایش داده نمی‌شوند؛ خالی‌گذاشتن فیلد رمز، مقدار قبلی را حفظ می‌کند.

در «قالب‌های پیامک» برای هر رویداد، شناسه پترن تأییدشده حساب خود را وارد کنید. نگاشت متغیر به شکل `نام_متغیر_در_IPPanel=نام_متغیر_باشگاه`، هر مورد در یک سطر است. متن داخل باشگاه پیش‌نمایش و مرجع نگاشت است؛ تغییر آن به‌تنهایی پترن تأییدشده ارائه‌دهنده را تغییر نمی‌دهد. ارسال آزمایشی هر قالب فقط به شماره مدیر واردشده انجام می‌شود. OTP مستقیم ارسال می‌شود؛ سایر پیام‌ها از صف می‌روند.

زیبال مبلغ را به **ریال صحیح** دریافت می‌کند؛ قیمت پلن در پنل مدیر و نمایش رسید **تومان** است و تبدیل ×۱۰ در سرور انجام می‌شود. بازگشت مرورگر سند پرداخت نیست؛ خدمت فقط پس از تأیید سمت سرور، تطبیق مبلغ و سفارش اعمال می‌شود. پاسخ «قبلاً تأیید شده» با استعلام مستقل بازیابی می‌شود. کلید آزمایشی، حساب واقعی یا تراکنش واقعی در بسته وجود ندارد.

سفارش نامشخص در پنل سفارش‌ها قابل بررسی مجدد است. درخواست نامشخص بدون شناسه پیگیری نیازمند بررسی مدیر در زیبال است. سفارش پرداخت‌شده با پروژه متوقف یا مسئول غیرفعال به «نیازمند رسیدگی» می‌رود؛ پس از رفع مشکل، مدیر می‌تواند خدمت پرداخت‌شده را بازیابی کند. ثبت استرداد در پنل صرفاً ثبت مستندِ بازپرداخت انجام‌شده در خارج سامانه است و انتقال وجه بانکی انجام نمی‌دهد.

## اجرای خودکار ضروری

روی هاست یا سرور، Cron زیر را **هر دقیقه** اجرا کنید؛ مسیر PHP و پروژه را با مسیر واقعی میزبان جایگزین کنید:

```cron
* * * * * cd /home/ACCOUNT/zarrin-club && /usr/bin/php artisan schedule:run >> /dev/null 2>&1
```

برای صف، روش ترجیحی اجرای دائم زیر با Supervisor است:

```sh
php artisan queue:work --queue=sms,default --sleep=2 --tries=1 --timeout=30 --max-time=3600
```

نمونه Supervisor و Nginx در پوشه `deploy` قرار دارد. اگر هاست اجرای worker دائم ندارد، Cron جداگانه هر دقیقه اجرا شود:

```cron
* * * * * cd /home/ACCOUNT/zarrin-club && /usr/bin/php artisan queue:work --queue=sms,default --stop-when-empty --max-time=50 --tries=1 --timeout=30 >> /dev/null 2>&1
```

بهتر است کنترل‌پنل از هم‌پوشانی Cron صف جلوگیری کند. صف و قفل‌های پایگاه داده مانع مصرف هم‌زمان یک job می‌شوند، اما افزایش worker بدون ظرفیت سرور سودی ندارد. پس از نصب، «سلامت یادآوری‌ها» و «گزارش ارسال پیامک» را بررسی کنید. بدون Cron و worker، یادآوری‌ها و پیامک‌های صف‌شده ارسال نمی‌شوند.

## کار با سامانه

- مشتری با موبایل تأییدشده و رمز ثابت یا کد وارد می‌شود؛ عضو کارمند تا تأیید مدیر هیچ دسترسی کاری ندارد.
- مشتری می‌تواند درخواست پروژه ثبت کند؛ مدیر آن را با پلن، منتور، بخش و تاریخ شمسی فعال می‌کند یا خودش پروژه می‌سازد.
- تاریخ پایان انتخابی شامل کل همان روز تهران است. در پایگاه داده، مرز پایان به‌صورت ابتدای روز بعد ذخیره می‌شود.
- ذخیره پیش‌نویس و خطای فرم ویرایش مصرف نمی‌کند. ارسال اولیه رایگان و پس از آن دو ارسال اصلاحیه آزاد مجاز است. تکمیل نقص فقط در فیلدهای مشخص‌شده سهمیه را مصرف نمی‌کند.
- قبل از ارسال نهایی، تیکت راهنمای فرم در دسترس است. تیکت آزاد منتورینگ پس از ارسال نهایی و در دوره فعال باز می‌شود. تحویل زودهنگام، زمان باقی‌مانده خدمت را از بین نمی‌برد.
- تمدید زودهنگام از پایان اعتبار جاری و تمدید پس از انقضا از زمان تأیید پرداخت محاسبه می‌شود. ظرفیت جدید از شروع دوره جدید فعال می‌شود. فرم تکمیلی هر دوره با فرم اصلی و سهمیه دو ویرایش آن مستقل است.
- سفارش لوگوی پرداخت‌شده پس از پایان منتورینگ هم فایل و پشتیبانی خود را حفظ می‌کند.
- تیکت داخلی برای مشتری نمایش داده نمی‌شود. پیوست‌های تیکت مشترک‌اند؛ اطلاعات داخلی محرمانه را به‌عنوان پیوست مشترک نفرستید.
- نظر منفی یا نظر بدون رضایت انتشار هم می‌تواند امتیاز بگیرد. نظرها پس از بررسی مدیر امتیاز می‌گیرند و ارتقای متن به ویدئو فقط اختلاف امتیاز را ثبت می‌کند.
- ویرایش راهنما در مدیریت فقط روی پروژه‌های جدید اثر می‌گذارد؛ فرم پروژه موجود نسخه مستقل دارد.

## نگهداری و ظرفیت

پس از نصب و تغییر تنظیمات استقرار:

```sh
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan queue:restart
```

کلید `APP_KEY` را همراه نسخه پشتیبان امن نگه دارید. تعویض یا ازدست‌دادن آن، دسترسی به رمزهای سایت، کلیدهای سرویس و برخی داده‌های رمزگذاری‌شده را از بین می‌برد. نسخه پشتیبان باید پایگاه داده، `storage/app/private` و تنظیمات محرمانه را شامل شود و بازیابی آن روی محیط جداگانه تمرین شود. هیچ داده مشتری در بسته نمونه نیست.

برای ترافیک زیاد از PHP-FPM و OPcache، MySQL روی دیسک سریع، صف مستقل، پایش زمان پاسخ و نسخه پشتیبان استفاده کنید. Redis در تنظیمات آماده است و با افزونه PHP Redis می‌تواند cache، صف و session مشترک چند سرور را فراهم کند. فایل خصوصی در استقرار چند سروری باید volume مشترک یا ذخیره‌ساز مشترک مورد تأیید شما داشته باشد. حد کاربران هم‌زمان تضمین نشده؛ اندازه سرور و آزمون بار مقصد تعیین‌کننده است.

`upload_max_filesize=200M`، `post_max_size=220M` و محدودیت بدنه Nginx مناسب فایل ویدئو تنظیم شود. از بارگذاری SVG، HTML، PHP و فایل اجرایی جلوگیری شده است. فایل خصوصی لینک عمومی ندارد و هر بار مجوز آن بررسی می‌شود. حذف خودکار اطلاعات مشتری فعال نشده است؛ سیاست نگهداری و حذف نهایی باید برای مجموعه تعریف شود.

## توسعه و آزمون

```sh
composer install
php vendor/bin/phpunit
```

آزمون‌ها پایگاه داده SQLite در حافظه و پاسخ شبیه‌سازی‌شده سرویس‌ها دارند. `tests/Feature/ClubTest.php` شامل سناریوهای دسترسی، OTP، فرم، سهمیه، پرداخت، تمدید، نظر، فایل و پیامک است. اجرای آزمون هیچ پیامک یا پرداخت واقعی ایجاد نمی‌کند.

## مراجع اتصال‌ها

- [مستندات Laravel](https://laravel.com/docs/13.x)
- [پترن IPPanel Edge](https://ippanelcom.github.io/Edge-Document/fa/docs/send/pattern/)
- [API درگاه زیبال](https://help.zibal.ir/ipg/)

منابع اتصال برای قرارداد API استفاده شده‌اند؛ صحت نهایی پترن و مرچنت باید با حساب خود مجموعه تأیید شود.
