# ممیزی کشف باگ — تست رفتاری کل سیستم ## پروژه `clinicpro` (Backend API + Admin SPA؛ منبع واحد داده/auth). جریان‌هایی که `nobat724_front` مصرف می‌کند هم از طریق همین APIها تست می‌شوند. > این یک پرامپت **تست/ممیزی** است، نه پیاده‌سازی قابلیت. هدف: پیدا کردن باگ‌های واقعی با شواهد، نه تغییر کد. **هیچ فایل تولیدی را تغییر نده** مگر برای رفع باگ‌های قطعیِ کم‌ریسک (آن هم با تأیید جداگانه). خروجی اصلی = گزارش باگ. ## زمینه سیستم suite تست خودکار ندارد (`tests/` فقط `bootstrap.php` دارد)، ولی مرجع کاملِ رفتار در `docs/api/*.md` و کاربرانِ تست در `TEST_USERS.md` موجود است. این ممیزی باید رفتار واقعیِ APIها را با قرارداد مستندشده مقایسه کند و انحراف‌ها/نشتی‌ها/خطاهای ۵۰۰ را پیدا کند. ## مشکل / هدف کشف باگ در محورهای زیر و تولید یک **گزارش باگ اولویت‌بندی‌شده** (`docs/qa/bug-report-.md`): 1. **خطاهای ۵۰۰ / استثناهای کنترل‌نشده** در endpointها (به‌ویژه با ورودی‌های مرزی). 2. **نشتی دسترسی (authorization)** بین نقش‌ها: admin / clinic / doctor / secretary / representation / user. 3. **انحراف قرارداد API** از `docs/api/*` (شکل پاسخ، nestی، status code، فیلدهای گمشده). 4. **اعتبارسنجی ورودی** (موبایل، کد ملی، تاریخ، مقادیر منفی/خالی/طولانی، تزریق). 5. **سازگاری frontend↔backend**: جاهایی که SPA یا `nobat724_front` شکل پاسخ را اشتباه باز می‌کند (الگوی double-nested). ## فایل‌های مرتبط | فایل/مسیر | نقش | |------|-----| | `docs/api/*.md` | قرارداد مرجع — هر تست باید با این مقایسه شود | | `TEST_USERS.md` | کاربران هر نقش برای تولید توکن | | `src/*/Controller/*.php` | endpointها — سطح دسترسی `#[IsGranted]` و منطق | | `src/Shared/Controller/BaseController.php` | شکل `success`/`paginated`/`error` | | `config/packages/security.yaml` | firewall و access_control | | `assets/admin/lib/api.ts`, `services/response.js` (front عمومی) | مصرف پاسخ‌ها | ## ابزارها و روش تست (واقعی، داخل ddev) تولید توکن هر نقش: ```bash ddev exec bash -c 'php bin/console lexik:jwt:generate-token --user-class="App\\Auth\\Entity\\User"' ``` لیست همه‌ی routeها: ```bash ddev exec php bin/console debug:router | grep api/v1 ``` صدا زدن endpoint (prod host، مثل مصرف واقعی): ```bash curl -sk "https://clinic-pro.ddev.site/api/v1/" -H "Authorization: Bearer " ``` بررسی DB برای تأیید اثر: ```bash ddev exec bash -c "mysql -uroot -proot db -e \"\"" ``` سلامت TS/build فرانت: ```bash ddev exec npx tsc --noEmit --project tsconfig.json ddev exec yarn dev ``` ## وظایف ### ۱. نقشه‌برداری endpointها و دامنه‌ی تست - خروجی `debug:router | grep api/v1` را بگیر و لیست کامل endpointها را با method/path استخراج کن. - برای هر دامنه (`auth, doctor, clinic, appointment, payment, representation, secretary, sms, blog, rating, settlement, user-profile, ...`) فایل docs متناظر را بخوان و «قرارداد مورد انتظار» را یادداشت کن (status، شکل پاسخ، permission). ### ۲. تست خطاهای ۵۰۰ و ورودی مرزی برای endpointهای پرریسک (به‌خصوص آن‌هایی که از relation/Entity proxy می‌خوانند یا ورودی JSON می‌گیرند): - ورودی‌های مرزی بفرست: بدنه‌ی خالی `{}`، فیلد گمشده، نوع اشتباه (string به‌جای int)، عدد منفی، رشته‌ی خیلی بلند، uuid نامعتبر، تاریخ نامعتبر، صفحه/limit خیلی بزرگ. - هر پاسخی با `"code":"ERR_INTERNAL_001"` یا HTTP 500 = **باگ** (باید ۴xx ساختاریافته باشد). نمونه‌ی شناخته‌شده‌ی این کلاس باگ: دسترسی به getter روی proxyِ موجودیتِ حذف‌شده (مثل author در بلاگ) → `EntityNotFoundException` → 500. - لیست‌های paginated را با `page=99999` و `limit=0/-1/9999` بزن. ### ۳. ماتریس دسترسی نقش‌ها (مهم‌ترین بخش) برای هر نقش یک توکن بساز و **endpointهای خارج از حوزه‌اش** را صدا بزن؛ انتظار `403`: - `user` عادی → هر `/api/v1/admin/*` و `/api/v1/representation/*` و `/api/v1/sms/*` → باید 403. - `representation` → `/api/v1/admin/users`, `/admin/payments`, `/admin/settlements` → باید 403؛ ولی `/representation/me|doctors|clinics|appointments` → 200. - `doctor` (مهمان کلینیک، نه مالک) → endpointهای مدیریت کلینیک (staff/clinic-service برای کلینیکِ دیگران، ویرایش کلینیک) → باید 403 یا scopeِ شخصی؛ نباید روی کلینیک عمل کند. - `secretary` → فقط در محدوده‌ی scope مجازش؛ خارج از آن 403. - **IDOR**: با توکن نقش A، منبع متعلق به B را با uuid/id مستقیم بخوان/ویرایش کن (مثلاً `GET/PATCH /representation/{uuidِ نفر دیگر}`، نوبت/پروفایل کاربر دیگر). هر دسترسی موفق = باگ امنیتی. - هر endpointی که مالکیت را از **ورودی کلاینت** (uuid/id در query/path) تعیین می‌کند نه از `#[CurrentUser]` → مشکوک؛ تست و گزارش کن. ### ۴. انطباق قرارداد API برای نمونه‌ای از هر دامنه، پاسخ واقعی را با docs مقایسه کن: - شکل nestی درست است؟ (`paginated` → `data` تخت + `meta`؛ `success(['data'=>...])` → double-nested `data.data`). جاهایی که SPA/`nobat724_front` این nestی را اشتباه باز می‌کند را به‌عنوان باگ مصرف ثبت کن. - status codeها و فیلدهای الزامی مطابق docs هستند؟ فیلد گمشده/اضافه را گزارش کن. - تاریخ‌ها Unix timestamp صحیح‌اند (نه DateTime serialize‌شده‌ی خراب)؟ ### ۵. اعتبارسنجی ورودی - موبایل: ارقام فارسی/عربی، طول غلط، حروف → باید رد شود (۴۲۲)، نه ذخیره‌ی خراب. - کد ملی: الگوریتم رقم کنترلی (سمت سرور هم چک می‌شود یا فقط فرانت؟ اگر فقط فرانت = باگ). - مقادیر مالی/درصد کمیسیون/limit عکس گالری (سقف ۵) و امثال آن: مرزها را تست کن. ### ۶. سلامت build و سازگاری - `ddev exec npx tsc --noEmit` → هر خطای TS = باگ. - `ddev exec yarn dev` → هر خطای کامپایل = باگ. - (front عمومی) `cd nobat724_front && npm run build` → خطاهای صفحه/متادیتا. ### ۷. تولید گزارش باگ فایل `docs/qa/bug-report-.md` بساز با جدول اولویت‌بندی‌شده: ```markdown # گزارش باگ — ## خلاصه - تعداد کل: X | بحرانی: a | بالا: b | متوسط: c | پایین: d ## باگ‌ها ### [CRITICAL] <عنوان کوتاه> - **دامنه:** auth/clinic/... - **endpoint/صفحه:** `METHOD /api/v1/...` - **مراحل بازتولید:** دستور curl دقیق + توکن نقش - **انتظار:** (طبق docs) ... - **واقعیت:** (پاسخ واقعی + HTTP code) ... - **اثر:** (نشتی داده / 500 / خرابی UI / ...) - **فایل محتمل:** `src/...:line` - **رفع پیشنهادی:** یک جمله ``` اولویت‌بندی: نشتی دسترسی/IDOR = CRITICAL؛ 500 روی مسیر پرکاربرد = HIGH؛ انحراف قرارداد که UI را می‌شکند = HIGH/MEDIUM؛ اعتبارسنجی ناقص = MEDIUM؛ کاسمتیک = LOW. ## نکات مهم - **تخریب‌نکن:** برای تست‌های نوشتنی (POST/PATCH/DELETE) از داده‌ی تستیِ جداگانه استفاده کن و **در پایان پاک/بازگردانی کن**؛ روی داده‌ی واقعیِ کاربران اصلی عملیات مخرب نزن. - محیط: باگ‌های مخصوص prod ممکن است فقط روی `https://clinic-pro.ddev.site` (APP_ENV=prod) ظاهر شوند؛ بعد از تغییر config `cache:clear --env=prod`. dev هم خطای کامل‌تر می‌دهد (`var/log`), از آن برای تشخیص ریشه استفاده کن. - توکن: کد OTP در dev همیشه `12345`؛ یا مستقیم با `lexik:jwt:generate-token` توکن هر نقش را بساز. - هر یافته باید **بازتولیدپذیر** باشد (دستور دقیق + پاسخ واقعی)؛ حدس و گمان بدون شواهد در گزارش نیاید. - این پرامپت فقط **گزارش** تولید می‌کند؛ رفع باگ‌ها در پرامپت‌های جداگانه (بعد از تأیید اولویت‌ها) انجام شود — مگر باگِ تک‌خطیِ بدیهی و کم‌ریسک که می‌توان با ذکر در گزارش، هم‌زمان رفع کرد. - دامنه را کنترل کن: اگر تعداد endpointها زیاد است، اول دامنه‌های پرریسک (auth, representation, clinic, appointment, payment) را کامل کن، سپس بقیه.