diff --git a/.claude/prompt/pre-registration.md b/.claude/prompt/pre-registration.md new file mode 100644 index 00000000..66b79a96 --- /dev/null +++ b/.claude/prompt/pre-registration.md @@ -0,0 +1,212 @@ +# 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` + +**۴الف — جایگزینی کامل `