# ممیزی کشف باگ — تست رفتاری کل سیستم

## پروژه

`clinicpro` (Backend API + Admin SPA؛ منبع واحد داده/auth). جریان‌هایی که `nobat724_front` مصرف می‌کند هم از طریق همین APIها تست می‌شوند.

> این یک پرامپت **تست/ممیزی** است، نه پیاده‌سازی قابلیت. هدف: پیدا کردن باگ‌های واقعی با شواهد، نه تغییر کد. **هیچ فایل تولیدی را تغییر نده** مگر برای رفع باگ‌های قطعیِ کم‌ریسک (آن هم با تأیید جداگانه). خروجی اصلی = گزارش باگ.

## زمینه

سیستم suite تست خودکار ندارد (`tests/` فقط `bootstrap.php` دارد)، ولی مرجع کاملِ رفتار در `docs/api/*.md` و کاربرانِ تست در `TEST_USERS.md` موجود است. این ممیزی باید رفتار واقعیِ APIها را با قرارداد مستندشده مقایسه کند و انحراف‌ها/نشتی‌ها/خطاهای ۵۰۰ را پیدا کند.

## مشکل / هدف

کشف باگ در محورهای زیر و تولید یک **گزارش باگ اولویت‌بندی‌شده** (`docs/qa/bug-report-<date>.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 <mobile> --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/<path>" -H "Authorization: Bearer <token>"
```
بررسی DB برای تأیید اثر:
```bash
ddev exec bash -c "mysql -uroot -proot db -e \"<SQL>\""
```
سلامت 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-<YYYY-MM-DD>.md` بساز با جدول اولویت‌بندی‌شده:

```markdown
# گزارش باگ — <date>

## خلاصه
- تعداد کل: 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) را کامل کن، سپس بقیه.
