# Pre-Registration Feature ## هدف پیاده‌سازی سیستم پیش ثبت‌نام برای دکتر و کلینیک: - روی صفحه اصلی (`/`) دو دکمه باشد: - **ورود به پنل** → `/admin` (برای کسانی که قبلاً ثبت‌نام شده‌اند) - **ثبت نام** → فرم پیش ثبت‌نام (فقط برای دکتر و کلینیک) - دکتر/کلینیک فرم را پر می‌کند - ادمین در پنل درخواست‌ها را می‌بیند و تأیید یا رد می‌کند - پس از تأیید: کاربر و entity مربوطه ساخته می‌شود و نام‌کاربری+پسورد از طریق SMS ارسال می‌شود --- ## قابلیت‌ها ### قابلیت ۱ — Entity و Migration: PreRegistration ایجاد Entity جدید `src/Auth/Entity/PreRegistration.php` با فیلدهای: - `id` (int, PK) - `uuid` (string, unique) - `type` (string: `independent_doctor` | `doctor_with_clinic` | `clinic_manager`) — نوع حساب (توضیح در پایین) - `name` (string, 255) — نام کامل - `mobile` (string, 20) — شماره موبایل - `info` (text, nullable) — توضیحات / اطلاعات اضافه (تخصص، سابقه، ...) - `status` (string: `pending` | `approved` | `rejected`) — default: `pending` - `adminNote` (text, nullable) — یادداشت ادمین هنگام رد کردن - `createdAt` (int) — Unix timestamp - `updatedAt` (int) — Unix timestamp بعد از ایجاد Entity: حتماً `doctrine:migrations:diff` و `doctrine:migrations:migrate` اجرا شود. --- ### قابلیت ۲ — Backend: Public Pre-Registration Endpoint **`POST /api/v1/pre-registration`** — endpoint عمومی (بدون auth) فایل: `src/Auth/Controller/PreRegistrationController.php` (class جدید، extends BaseController) Request body: ```json { "type": "independent_doctor", // independent_doctor | doctor_with_clinic | clinic_manager — الزامی "name": "دکتر احمدی", // الزامی "mobile": "09121234567", // الزامی "info": "متخصص داخلی، ۱۰ سال سابقه" // اختیاری } ``` مفهوم `type` و نقش‌های دریافتی پس از تأیید: | مقدار | متن نمایشی در فرم | نقش‌ها | entity ساخته می‌شود | |-------|-------------------|--------|---------------------| | `independent_doctor` | «دکتر هستم» | `ROLE_DOCTOR` | Doctor | | `doctor_with_clinic` | «دکتر هستم و کلینیک دارم و با چند دکتر همکاری می‌کنم» | `ROLE_DOCTOR` + `ROLE_CLINIC` | Doctor + Clinic | | `clinic_manager` | «تنها مدیر کلینیک هستم» | `ROLE_CLINIC` | Clinic | Validation: - `type` باید یکی از `independent_doctor`، `doctor_with_clinic`، یا `clinic_manager` باشد - `mobile` باید ۱۰ تا ۱۵ کاراکتر باشد - اگر همین موبایل با status=pending در جدول وجود داشت → خطا: `DUPLICATE_REQUEST` با پیام "درخواست ثبت‌نام شما در حال بررسی است" Response موفق: ```json { "success": true, "data": { "uuid": "...", "status": "pending" } } ``` امنیت: این endpoint باید در `security.yaml` به عنوان عمومی (public) تعریف شود. --- ### قابلیت ۳ — Backend: Admin Pre-Registration Management Endpoints در فایل `src/Auth/Controller/PreRegistrationController.php` متدهای زیر اضافه شوند: **`GET /api/v1/admin/pre-registrations`** — لیست درخواست‌ها - `#[IsGranted('ROLE_ADMIN')]` - Query params: `page`, `limit`, `status` (pending|approved|rejected|all — default: pending) - DQL array hydration، برگرداندن: uuid, type, name, mobile, info, status, admin_note, created_at - Return: `$this->paginated(...)` **`POST /api/v1/admin/pre-registrations/{uuid}/approve`** — تأیید درخواست - `#[IsGranted('ROLE_ADMIN')]` - اقدامات هنگام تأیید: 1. بررسی اینکه status=pending باشد (در غیر این صورت خطا: `ALREADY_PROCESSED`) 2. یک پسورد تصادفی ۸ کاراکتری بسازید (حروف+عدد) 3. اگر user با این mobile وجود ندارد → User جدید بسازید با این mobile و پسورد 4. اگر user وجود دارد → پسورد را reset کنید 5. بر اساس `type` entity و نقش‌ها را بساز: - `independent_doctor`: - Doctor entity بساز (firstName/lastName از split نام؛ اگر یک کلمه بود همه firstName) - به user بده: `ROLE_DOCTOR` - `doctor_with_clinic`: - Doctor entity بساز (مانند بالا) - Clinic entity بساز با `name`=نام درخواست - به user بده: `ROLE_DOCTOR` + `ROLE_CLINIC` - `clinic_manager`: - Clinic entity بساز با `name`=نام درخواست - به user بده: `ROLE_CLINIC` در همه حالت‌ها قبل از ساخت entity بررسی کن که قبلاً وجود نداشته باشد (جلوگیری از duplicate) 7. `status` را روی `approved` و `updatedAt` را update کنید 8. یک SMS بفرستید از طریق سرویس SMS موجود در پروژه (کلاس `App\Sms\`) با متن: "به کلینیک پرو خوش آمدید! شماره‌کاربری: {mobile} | رمز عبور: {password} | لینک ورود: https://clinic-pro.ddev.site/admin" - Response: `$this->success(['message' => 'تأیید شد و اطلاعات ورود ارسال گردید'])` **`POST /api/v1/admin/pre-registrations/{uuid}/reject`** — رد درخواست - `#[IsGranted('ROLE_ADMIN')]` - Request body: `{ "note": "توضیح دلیل رد" }` — اختیاری - `status` را `rejected` کن، `adminNote` را ذخیره کن - Response: `$this->success(['message' => 'درخواست رد شد'])` --- ### قابلیت ۴ — Frontend Homepage: دو دکمه در header و hero فایل: `templates/public/home.html.twig` **۴الف — جایگزینی کامل `