Files
clinicpro/.claude/guidelines.md
T

119 lines
13 KiB
Markdown

# راهنمای مشترک `prompt-writer` و `run-prompt`
این فایل مرجع کیفیت هر دو اسکیل است. هر دو اسکیل باید در ابتدای بدنهٔ خود این خط را داشته باشند:
> قبل از شروع، فایل `.claude/guidelines.md` را بخوان و همهٔ بخش‌های آن را اعمال کن.
قواعد stack و مسیر فایل‌ها در خود اسکیل‌ها می‌ماند؛ این فایل فقط **چگونه کار کردن** را تعیین می‌کند. اگر بین این فایل و متن پرامپت تناقضی بود، همین فایل برنده است — مگر اینکه کاربر صریحاً خلافش را بگوید.
---
## ۱. درک مسئله — قبل از هر خط کد
هیچ چیز گران‌تر از پیاده‌سازیِ درستِ مسئلهٔ اشتباه نیست. به همین دلیل:
- **پرامپت/درخواست را کامل بخوان**، بعد کد واقعیِ مرتبط را بخوان. هرگز از حافظه دربارهٔ کد پروژه فرض نکن — فایل را باز کن.
- مسئله را **با کلمات خودت بازگو کن**: «مشکل این است که X؛ رفتار درست Y است؛ محدودهٔ تغییر فایل‌های Z». اگر این سه جمله را نمی‌توانی بنویسی، هنوز مسئله را نفهمیده‌ای.
- برای هر قابلیت **معیار پذیرش (acceptance criteria)** تعریف کن: چه چیزی باید درست کار کند تا «تمام» حساب شود؟ شامل حالت موفق، حالت خطا، و حداقل یک حالت مرزی.
- **ابهام = توقف.** سوال را همان اول بپرس، نه وسط پیاده‌سازی. حدس زدن وسط کار یعنی دوباره‌کاری.
- در `prompt-writer`: قالب پرامپت باید بخش **«معیار پذیرش»** داشته باشد (بعد از «مشکل / هدف»). پرامپتی که معیار پذیرش ندارد ناقص است.
- در `run-prompt`: مرحلهٔ «تحلیل» با بازگویی مسئله و معیار پذیرش به کاربر تمام می‌شود، نه فقط با لیست قابلیت‌ها.
---
## ۲. Todo — ستون فقرات اجرا
Todo فقط نمایش پیشرفت نیست؛ قرارداد بین تو و کاربر است که هیچ مرحله‌ای بی‌صدا رد نشود.
- در ابتدای اجرا با `TodoWrite` لیست کامل بساز — **یک آیتم به ازای هر قابلیت**، همه `pending`.
- هر آیتم باید **قابل تست** باشد: خروجی مشخص داشته باشد («endpoint X با response Y کار می‌کند»)، نه فعل مبهم («بررسی سیستم نوبت»).
- در هر لحظه فقط **یک** آیتم `in_progress`.
- آیتم فقط وقتی `completed` می‌شود که **هر سهٔ** این‌ها انجام شده باشد: پیاده‌سازی + تست سبز + مستندات به‌روز. کد بدون تست یا بدون سند، «تمام» نیست.
- اگر وسط کار قابلیت جدیدی کشف شد (باگ جانبی، وابستگی پنهان)، به‌جای انجام بی‌صدا، آیتم جدید به todo اضافه کن و به کاربر بگو.
---
## ۳. تست — تعریف «تمام شد»
- **Definition of Done** برای هر قابلیت: syntax/lint/build سبز **و** پوشش سه سناریوی معیار پذیرش (موفق، خطا، مرزی). این همان قاعدهٔ پروژه است: هیچ تسکی بدون تست تمام نیست.
- خطا یعنی توقف کامل. هیچ قابلیتی روی خرابهٔ قابلیت قبلی ساخته نمی‌شود.
- دستورهای تست هر پروژه در خود اسکیل `run-prompt` آمده؛ آن‌ها حداقل‌اند نه سقف. اگر قابلیت منطق دارد (نه فقط UI)، تست واقعی همان منطق را اجرا کن — مثلاً صدا زدن endpoint با داده واقعی، نه فقط `php -l`.
- **تغییر cross-repo تست خودکار ندارد.** تغییر قرارداد API در build کلاینت‌ها خطا نمی‌دهد و در رانتایم می‌شکند؛ پس بعد از هر تغییر قرارداد، مصرف واقعی را در هر کلاینت متأثر دستی دنبال کن و نتیجه را گزارش بده.
- در `prompt-writer`: در بخش «وظایف» یا «نکات مهم» هر پرامپت بنویس این قابلیت **چطور تست می‌شود** — تا `run-prompt` مجبور نباشد خودش تست را اختراع کند.
---
## ۴. مستندسازی — بخشی از کار، نه بعد از کار
- سند در **همان جلسه‌ای** به‌روز می‌شود که کد تغییر کرده. «بعداً می‌نویسم» یعنی هرگز.
- مپینگ `src/*``docs/api/*.md` در اسکیل `run-prompt` است؛ الزام محتوایی: endpoint با method/path/permission، بدنهٔ request با نوع همهٔ فیلدها، response با **JSON واقعی** (خروجی اجرای واقعی، نه دست‌ساز)، همهٔ status/error codeها.
- سند باید با کد **هم‌خوان** باشد: اگر سند موجود با رفتار فعلی فرق دارد، اول سند را اصلاح کن، بعد قابلیت جدید را اضافه کن.
- خود فایل پرامپت هم سند است: در `prompt-writer` بخش «وضعیت فعلی» باید **کپی از کد واقعی** باشد؛ کد بازنویسی‌شده از حافظه ممنوع.
- کامنت بدیهی ننویس؛ مستندات کوتاه و دقیق فقط روی چیزهای عمومی (public API، قرارداد، تصمیم معماری).
---
## ۵. کدنویسی — SOLID و الگوها در بستر این پروژه
الگو ابزار حل مسئله است، نه مدال. اول مسئله، بعد الگو.
### SOLID — یعنی در این پروژه:
- **S (تک‌مسئولیتی):** Controller نازک — فقط دریافت request، صدا زدن Service، برگرداندن response با `$this->success()/paginated()/error()`. منطق دامنه در Service؛ کوئری در Repository. در فرانت: کامپوننتی که هم fetch می‌کند، هم state پیچیده دارد، هم render سنگین — بشکن.
- **O (باز/بسته):** رفتار جدید = کلاس/استراتژی جدید، نه `if/switch` جدید روی نوع. نمونه‌های واقعی این workspace: درگاه پرداخت، ارسال‌کنندهٔ SMS، نوع نوبت — برای این‌ها interface + پیاده‌سازی جدا، نه شاخه‌شاخه کردن یک Service.
- **L (جایگزینی):** پیاده‌سازی جدیدِ یک interface باید همان قرارداد را کامل رعایت کند — همان شکل response، همان exceptionها. کلاسی که «تقریباً» قرارداد را رعایت می‌کند، cross-repo bug تولید می‌کند.
- **I (تفکیک interface):** interfaceهای کوچک و متمرکز. اگر پیاده‌سازی‌ای مجبور است متدی را خالی بگذارد، interface بزرگ است.
- **D (وارونگی وابستگی):** Service به interface وابسته باشد، نه کلاس concrete؛ تزریق با DI خود Symfony (constructor injection + autowiring). `new` کردن سرویس داخل سرویس ممنوع.
### الگوهای پذیرفته‌شدهٔ این workspace:
| الگو | کجا | چرا |
|------|-----|-----|
| Repository | همهٔ دسترسی داده (Doctrine و لایهٔ repo در tauri) | جداسازی کوئری از منطق |
| Service Layer | منطق دامنه در `src/*/Service` | Controller نازک، منطق قابل تست |
| Strategy | پرداخت، SMS، هر جای «چند روش برای یک کار» | افزودن روش جدید بدون دست زدن به موجود |
| Factory | ساخت objectهای پیچیده/وابسته به نوع | تمرکز منطق ساخت |
| Event/Observer | Symfony EventDispatcher برای اثرات جانبی (نوتیف، لاگ) | جدا کردن اثر جانبی از جریان اصلی |
| Adapter | کلاینت‌های API (`api.ts`، `services/response.js`) | یک نقطهٔ تماس با backend |
### مرز over-engineering:
- الگو فقط وقتی که **الان** دو پیاده‌سازی یا یک نیاز مشخص برای تعویض وجود دارد. برای «شاید در آینده» abstraction نساز.
- error handling فقط در boundaryهای واقعی (Controller، فراخوانی API، I/O) — نه try/catch دفاعی دور هر متد.
- قبل از ساختن هر چیز جدید: اول بگرد (endpoint، کامپوننت، سرویس موجود)، بعد توسعه بده، در آخر بساز — و دلیلش را بنویس.
- در `prompt-writer`: اگر راه‌حل پیشنهادی الگویی را به کار می‌برد، در بخش «نکات مهم» نام الگو و **دلیل انتخابش** را بنویس تا `run-prompt` همان مسیر را برود.
---
## ۶. رفتار تحلیل‌گر — نقش agent در هر دو اسکیل
نقش agent یک تحلیل‌گر منطقی و منتقد است، نه دستیاری که هدفش راضی کردن کاربر باشد. هدف، پیدا کردن بهترین پاسخ است، نه موافقت.
- اگر تصمیم کاربر یا راه‌حل خواسته‌شده در پرامپت اشتباه، ناقص یا پرریسک است، **قبل از پیاده‌سازی** صریح و با دلیل بگو و منتظر تعیین تکلیف بمان. اجرای بی‌چون‌وچرای یک پرامپت غلط، خطای agent است نه کاربر.
- تأیید بدون تحلیل ممنوع — «ایدهٔ خوبی است» و «کاملاً درست است» بدون استدلال ننویس. هر نتیجه‌گیری بر پایهٔ منطق، شواهد، کد واقعی پروژه یا مستندات رسمی باشد.
- بین **واقعیت** (کد/سند موجود)، **فرضیه**، **نظر** و **حدس** تفاوت بگذار و در گزارش‌ها برچسبش را مشخص کن. اگر داده کافی نیست، همین را بگو؛ حدس را قطعی جا نزن.
- برای هر پیشنهاد طراحی: مزایا، معایب، ریسک‌ها و حداقل یک گزینهٔ جایگزین. اگر چند راه‌حل وجود دارد، مقایسه کن و دلیل انتخاب را بنویس. (جای طبیعی این کار مرحلهٔ «طراحی» در `run-prompt` و بخش «وظایف» در `prompt-writer` است.)
- در تصمیم‌های مهم و موضوعات پیچیده، اول قدم‌به‌قدم تحلیل کن و **ساختار/طرح پیشنهادی را قبل از خروجی نهایی ارائه بده و تأیید بگیر** — نه اینکه مستقیم سراغ کد یا متن نهایی بروی.
- مرجع ادعاهای فنی: مستندات رسمی فریم‌ورک‌ها و کد خود پروژه، نه حافظه.
و در تعامل:
- سبک کد جدید = سبک فایل‌های مشابه موجود در همان پروژه؛ کد واقعی پروژه، نمونهٔ سبک است.
- وقتی کاربر بازخورد می‌دهد، **همان خروجی موجود را اصلاح کن**؛ بازتولید از صفر فقط اگر خودش بخواهد.
---
## ۷. چک‌لیست پایان هر قابلیت (برای `run-prompt`)
قبل از `completed` کردن آیتم todo، همهٔ این‌ها باید تیک بخورد:
- [ ] مسئله و معیار پذیرش در ابتدای کار بازگو و تأیید شده بود
- [ ] اگر راه‌حل پرامپت ایراد یا ریسک داشت، قبل از اجرا اعلام و تعیین تکلیف شده بود
- [ ] Controller نازک است؛ منطق در Service/Repository است
- [ ] رفتار جدید با extension اضافه شده، نه با if روی نوع
- [ ] وابستگی‌ها تزریق شده‌اند، نه `new` شده
- [ ] تست‌ها سبزند: موفق + خطا + مرزی
- [ ] اگر قرارداد API تغییر کرده: کلاینت‌های متأثر دستی بررسی و گزارش شده‌اند
- [ ] `docs/api/` (یا سند مرتبط) در همین جلسه به‌روز شده و با رفتار واقعی هم‌خوان است
- [ ] هیچ کامنت بدیهی و هیچ abstraction بدون مصرف اضافه نشده