Files
clinicpro/.claude/prompt/booking-engine-task-runner.md
hamedandClaude Opus 5 c37c0cee39 test(booking): freeze slot-mode contract before service-mode work
Adds SlotModeFrozenTest (#[Group('slot-mode-frozen')]) locking three things
against the multi-resource booking phase:
  - GET /api/v1/appointment-slots response shape
  - GET /api/v1/appointment-settings/month-availability/{uuid} response shape
  - public method signatures of SlotCalculatorService

Fixtures are structural, not raw snapshots: a fixed past date is rejected by
isWithinBookingWindow so an empty snapshot would prove nothing. Instead a
deterministic schedule on a computed near-future date, with epoch/uuid values
normalized to placeholders. What stays locked is the contract itself: keys,
ordering, types and local times.

No production code touched.

Task: docs/new_feture/taskes/task-00-service-mode-completion/
Slot-mode contract: unchanged (--group=slot-mode-frozen green, 3 tests)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 12:31:57 +03:30

31 KiB
Raw Permalink Blame History

راهبر اجرای تسک‌های موتور نوبت‌دهی — یک تسک در هر اجرا

پروژه

clinicpro (بک‌اند + پنل ادمین)

پرامپت همتا برای سایت عمومی: nobat724_front/.claude/prompt/booking-engine-task-00b-service-mode.md (همین راهبر وقتی به تسک ۰۰ب برسد، تحویلش می‌دهد و می‌ایستد.)


زمینه

docs/new_feture/taskes/ شانزده تسک برای پیاده‌سازی مستند موتور نوبت‌دهی دارد. هر تسک یک پوشه با شش فایل است و خودش یک پرامپت کامل است: task.md (دامنه و معیار پذیرش)، architecture.md (فایل‌ها و سرویس‌ها)، database.md (جداول و migration)، implementation_notes.md (نکات و edge case و تست)، checklist.md (وضعیت)، و برای تسک‌های پیچیده user_flow.md.

جمع زمان تخمینی ۲۱۴ تا ۲۵۶ ساعت است. هیچ اجرایی نمی‌تواند همه را در یک نشست تمام کند.

پس این پرامپت خودش قابلیت نیست — راهبر است. هر اجرا:

وضعیت را از checklist.md ها بخوان
  → تسک بعدی واجد شرایط را انتخاب کن
    → همان یک تسک را کامل انجام بده (پیاده‌سازی + تست + مستند + چک‌لیست)
      → commit + graphify update
        → بایست و بگو تسک بعدی چیست

همین پرامپت را دوباره اجرا کن تا تسک بعدی برود. تا وقتی همهٔ چک‌لیست‌ها نشده‌اند، کار تمام نیست.


مشکل / هدف

هدف: یک مسیر اجرای تکرارشونده و ایمن که شانزده تسک را به ترتیب وابستگی، یکی‌یکی و بدون از دست دادن وضعیت پیش ببرد — طوری که هر اجرا مستقل باشد و قطع شدن وسط کار، کار انجام‌شده را از بین نبرد.

چرا این شکل و نه یک پرامپت غول: وضعیت در checklist.md روی دیسک زندگی می‌کند، نه در context. اجرای بعدی همان فایل را می‌خواند و می‌فهمد کجا مانده. هزینهٔ این طراحی یک مرحلهٔ «خواندن وضعیت» در ابتدای هر اجراست؛ سودش این است که هیچ اجرایی به context اجرای قبلی وابسته نیست.


معیار پذیرش

معیار پذیرش این راهبر، رفتار خودِ راهبر است. معیار پذیرش هر تسک در task.md همان تسک است و اینجا تکرار نمی‌شود.

  • موفق: اجرا با شناسایی وضعیت شروع می‌شود (جدول ۱۶ تسک با /🔄/)، دقیقاً یک تسک انتخاب می‌شود، همهٔ ردیف‌های checklist.md آن تسک به می‌رسند، bin/phpunit و --group=slot-mode-frozen سبزند، docs/api/* به‌روز است، یک commit زده می‌شود، graphify update . اجرا می‌شود، و اجرا با اعلام تسک بعدی تمام می‌شود.
  • موفق (ازسرگیری): اجرای دوم روی همان مخزن، تسک تمام‌شده را دوباره انجام نمی‌دهد و مستقیم سراغ تسک بعدی می‌رود.
  • موفق (نیمه‌کاره): اگر چک‌لیستی ردیف 🔄 دارد، همان تسک ادامه داده می‌شود، نه تسک بعدی.
  • خطا: اگر تسکی وابستگی‌اش نیست → اجرا شروع نمی‌شود؛ پیام روشن با نام تسک پیش‌نیاز و توقف.
  • خطا: اگر --group=slot-mode-frozen قرمز شد → توقف کامل، rollback تغییرات آن مرحله، گزارش دقیق کدام fixture شکست. fixture هرگز به‌روز نمی‌شود.
  • خطا: اگر تستی سبز نشد → تسک completed نمی‌شود؛ ردیف چک‌لیست 🔄 می‌ماند و اجرا با گزارش خطا تمام می‌شود. تسک بعدی شروع نمی‌شود.
  • ⚠️ مرزی: همهٔ ۱۶ چک‌لیست → پیام «همهٔ تسک‌ها تمام شده‌اند» و توقف بدون تغییر.
  • ⚠️ مرزی: تسک انتخاب‌شده ۰۰ب است (پروژهٔ دیگر) → اجرا کد نمی‌زند؛ دستور اجرای پرامپت nobat724_front را می‌دهد و می‌ایستد.
  • ⚠️ مرزی: کاربر شمارهٔ تسک را صریح داد (/run-prompt … --task=05) → همان تسک، ولی وابستگی‌ها همچنان بررسی می‌شوند و اگر ناقص بودند توقف.
  • ⚠️ مرزی: ردیفی از چک‌لیست به دلیل موجه قابل انجام نیست → می‌ماند با دلیل مکتوب و تسک مقصد در ستون یادداشت. بی‌دلیل = تسک تمام نشده.

فایل‌های مرتبط

فایل نقش
docs/new_feture/taskes/README.md فهرست ۱۶ تسک، وابستگی‌ها، ترتیب اجرا
docs/new_feture/taskes/00-current-state-report.md تحلیل شکاف وضعیت فعلی در برابر مستند
docs/new_feture/taskes/_shared/red-lines.md قواعد قفل‌شده — منطق اسلاتی دست‌کاری نمی‌شود
docs/new_feture/taskes/_shared/ui-conventions.md 🎨 توکن‌ها و کامپوننت‌های اجباری
docs/new_feture/taskes/_shared/definition-of-done.md ☑️ نمادها و بازبینی پایانی
docs/new_feture/taskes/task-XX-*/task.md دامنه و معیار پذیرش هر تسک
docs/new_feture/taskes/task-XX-*/architecture.md فایل‌ها، سرویس‌ها، قواعد UI
docs/new_feture/taskes/task-XX-*/database.md جداول، ایندکس، migration، backfill
docs/new_feture/taskes/task-XX-*/implementation_notes.md edge case و فهرست تست
docs/new_feture/taskes/task-XX-*/checklist.md وضعیت پایدار — منبع حقیقت پیشرفت
docs/new_feture/taskes/task-XX-*/user_flow.md جریان کاربری (۰۰، ۰۰ب، ۰۵، ۰۶، ۰۷، ۱۲)
CLAUDE.md · docs/architecture/tenancy.md قواعد ثابت پروژه

وضعیت فعلی

هر شانزده checklist.md ساخته شده و همهٔ ردیف‌هایشان است. هیچ تسکی شروع نشده.

ساختار ثابت هر چک‌لیست:

# چک‌لیست — تسک XX (عنوان)

**وضعیت کلی:** ⏳ شروع نشده · **آخرین بازبینی:**## ۰. خط سرخ
| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۰.۱ | `--group=slot-mode-frozen` سبز | ⏳ | |
...

## ۱. بک‌اند
## ۲. دیتابیس
## ۳. UI
## ۴. تست
## ۵. مستندات
## ۶. بازبینی پایانی

نمادها (از _shared/definition-of-done.md):

نماد معنی اجازهٔ باقی‌ماندن در پایان تسک
انجام‌شده و تأییدشده بله
🔄 در حال انجام نه
انجام‌نشده نه — مگر با دلیل مکتوب و تسک مقصد
⚠️ نیازمند بررسی یا تست نه — باید تعیین تکلیف شود

ترتیب و وابستگی (از README.md):

۰۰ ── ۰۰ب
  │
  ├─ ۰۱ ─┬─ ۰۲ ── ۰۳ ─┐
  │      └─ ۰۴ ── ۰۵ ─┴─ ۰۶ ── ۰۷ ─┬─ ۰۸ ─┬─ ۰۹ ── ۱۰
  │                                │      └─ ۱۱ ── ۱۲
  │                                ├─ ۱۳
  │                                └─ ۱۴
تسک پروژه وابستگی
۰۰ تکمیل نوبت‌دهی سرویسی clinicpro
۰۰ب سازگارسازی سایت nobat724_front ۰۰
۰۱ شعبه و اتاق clinicpro ۰۰
۰۲ منبع، مهارت، استخر clinicpro ۰۱
۰۳ تقویم منبع clinicpro ۰۱، ۰۲
۰۴ کاتالوگ خدمات v2 clinicpro ۰۱
۰۵ بخش‌های نوبت clinicpro ۰۲، ۰۴
۰۶ جستجوی وقت چندمنبعی clinicpro ۰۳، ۰۵
۰۷ رزرو موقت و ثبت clinicpro ۰۶
۰۸ قیمت و snapshot clinicpro ۰۴، ۰۷
۰۹ موتور قوانین clinicpro ۰۵، ۰۶، ۰۸
۱۰ فرم و sandbox قانون clinicpro ۰۹
۱۱ پکیج و دفتر اعتبار clinicpro ۰۸
۱۲ دوره درمان clinicpro ۰۷، ۱۱
۱۳ لغو، عدم حضور، انتظار clinicpro ۰۷
۱۴ رویدادها و بهره‌وری clinicpro ۰۷

وظایف

⚠️ این هفت وظیفه مراحل یک اجرای راهبرند، نه هفت قابلیت مستقل. todo را از روی ردیف‌های checklist.md تسکِ انتخاب‌شده بساز، نه از روی این هفت مرحله.

۱. خواندن قواعد حاکم — پیش از هر چیز

سه سند را کامل بخوان و در همین اجرا اعمال کن:

docs/new_feture/taskes/_shared/red-lines.md
docs/new_feture/taskes/_shared/ui-conventions.md
docs/new_feture/taskes/_shared/definition-of-done.md

در تناقض با متن هر تسک، این سه برنده‌اند.

مهم‌ترین بندشان:

  • منطق اسلاتی (booking_mode = 'slot') در هیچ تسکی دست‌کاری نمی‌شود. فهرست فایل‌ها و متدهای قفل‌شده در red-lines.md است.
  • 🎨 هر صفحه یا کامپوننت جدید عیناً با دیزاین‌سیستم موجود — توکن‌های assets/admin/styles.css، کامپوننت‌های assets/admin/components/ui/، پنج قاعدهٔ غیرقابل‌مذاکره.
  • ☑️ هیچ تسکی بدون تکمیل چک‌لیستش تمام نیست.

نحوه تست: بعد از خواندن، در گزارش شروع بنویس کدام سه سند خوانده شد و مهم‌ترین قید مربوط به تسک انتخاب‌شده چیست (یک جمله).


۲. شناسایی وضعیت و انتخاب تسک

همهٔ چک‌لیست‌ها را بخوان و وضعیت هر تسک را از ردیف‌هایش استنتاج کن، نه از خط «وضعیت کلی» (که ممکن است به‌روز نشده باشد):

# فهرست چک‌لیست‌ها به ترتیب
ls -1 docs/new_feture/taskes/*/checklist.md | sort

# شمارش نمادها per تسک — دیدِ سریع وضعیت
for f in docs/new_feture/taskes/*/checklist.md; do
  echo "$(dirname "$f" | xargs basename): ✅=$(grep -c '| ✅ |' "$f") 🔄=$(grep -c '| 🔄 |' "$f") ⏳=$(grep -c '| ⏳ |' "$f") ⚠️=$(grep -c '| ⚠️ |' "$f")"
done

قاعدهٔ استنتاج:

تمام‌شده   = هیچ ردیف 🔄 · هیچ ردیف ⚠️ · هیچ ردیف ⏳ بدون یادداشتِ دلیل
در جریان   = حداقل یک ردیف 🔄 یا ⚠️
شروع نشده  = همهٔ ردیف‌ها ⏳ و هیچ یادداشتی

قاعدهٔ انتخاب، به همین ترتیب:

  1. اگر تسکی در جریان است → همان. (تسک نیمه‌کاره رها نمی‌شود.)
  2. وگرنه اولین تسکِ شروع نشده که همهٔ وابستگی‌هایش تمام‌شده اند.
  3. اگر کاربر --task=XX داد → همان، ولی وابستگی‌ها همچنان بررسی می‌شوند.
  4. اگر همه تمام‌شده‌اند → پیام و توقف.
  5. اگر تسک انتخاب‌شده وابستگی ناقص دارد → توقف با نام تسک پیش‌نیاز.

جدول وضعیت را به کاربر نشان بده و تسک انتخاب‌شده را اعلام کن:

📊 وضعیت تسک‌ها
  ۰۰  تکمیل سرویسی        ✅ تمام‌شده
  ۰۰ب سازگارسازی سایت      ✅ تمام‌شده
  ۰۱  شعبه و اتاق          🔄 در جریان (۱۲/۳۸)
  ۰۲  منبع و مهارت         ⏳ شروع نشده
  …
🎯 تسک انتخاب‌شده: ۰۱ — شعبه و اتاق  (ادامهٔ کار نیمه‌کاره)

نحوه تست: دستور شمارش بالا را اجرا کن و خروجی واقعی‌اش را در گزارش بگذار. جدول نمایش‌داده‌شده باید با آن خروجی بخواند.


۳. تحویل به پرامپت همتا اگر تسک ۰۰ب انتخاب شد

تسک ۰۰ب روی nobat724_front است و در این پروژه هیچ کدی ندارد.

اگر انتخاب ۰۰ب شد، هیچ فایلی را تغییر نده و این را چاپ کن و بایست:

🔀 تسک ۰۰ب روی پروژهٔ nobat724_front است.
   اجرا کن:  /run-prompt nobat724_front/.claude/prompt/booking-engine-task-00b-service-mode.md
   بعد از تمام شدنش، همین راهبر را دوباره اجرا کن تا تسک ۰۱ برود.

نحوه تست: موقتاً همهٔ ردیف‌های task-00-service-mode-completion/checklist.md را کن، راهبر را اجرا کن، و ببین همین پیام چاپ می‌شود و هیچ فایلی در src/ عوض نمی‌شود. بعد تغییر موقت را برگردان.


۴. اجرای تسک انتخاب‌شده — یکی، کامل

چهار (یا پنج) فایل تسک را کامل بخوان:

task-XX-*/task.md                 ← دامنه، endpoint ها، معیار پذیرش
task-XX-*/architecture.md         ← فایل‌ها، سرویس‌ها، الگوها، قواعد UI
task-XX-*/database.md             ← جداول، ایندکس، migration، backfill
task-XX-*/implementation_notes.md ← edge case ها، فهرست تست، تله‌های مشخص
task-XX-*/user_flow.md            ← اگر وجود دارد

بعد کد واقعی مرتبط را بخوان — هیچ فرضی از حافظه (guidelines §۱).

سپس todo بساز: یک آیتم به ازای هر ردیفِ غیر- چک‌لیست، مرتب بر اساس بخش (۰ خط سرخ → ۱ بک‌اند → ۲ دیتابیس → ۳ UI → ۴ تست → ۵ مستندات → ۶ بازبینی پایانی).

اجرای هر ردیف با همان هفت‌مرحلهٔ run-prompt:

① تحلیل  ② طراحی  ③ پیاده‌سازی  ④ تست  ⑤ رفع خطا  ⑥ مستندسازی  ⑦ چک‌لیست + گزارش

قواعدی که در این مرحله شکستنی نیستند:

  • بخش ۰ چک‌لیست اول از همه. خط سرخ‌ها پیش از هر کد بررسی می‌شوند. در تسک ۰۰ این یعنی ساختن SlotModeFrozenTest و سه fixture قبل از هر تغییر — وگرنه snapshot وضعیت تغییریافته گرفته می‌شود و چیزی را تضمین نمی‌کند.
  • یک ردیف در هر لحظه in_progress.
  • ردیف فقط با هر سه می‌شود: پیاده‌سازی + تست سبز + مستند به‌روز.
  • خطا = توقف کامل. هیچ ردیفی روی خرابهٔ ردیف قبلی ساخته نمی‌شود.
  • کشف کار جدید (باگ جانبی، وابستگی پنهان) → ردیف جدید به همان checklist.md اضافه کن و به کاربر بگو. انجام بی‌صدا ممنوع.

نحوه تست: دستورهای هر پروژه بعد از هر ردیفِ منطق‌دار:

ddev exec php bin/console cache:clear
ddev exec php bin/console doctrine:migrations:diff --no-interaction   # اگر entity عوض شد
ddev exec php bin/console doctrine:migrations:migrate --no-interaction
ddev exec php bin/phpunit tests/<Domain>                              # تست همان تسک
ddev exec php bin/phpunit --group=slot-mode-frozen                    # ⛔ بعد از هر ردیف
ddev exec php vendor/bin/phpstan analyse src/<Domain>
npx tsc --noEmit --project tsconfig.json                              # اگر tsx عوض شد
yarn dev                                                              # بررسی خطای build
yarn test

برای هر endpoint، تست واقعی با داده واقعی — نه فقط php -l. کاربر تست: 09390039833 / 09390039833 (اگر کار نکرد، اعتبارهای per-نقش با QaTest@1234).


۵. به‌روزرسانی زندهٔ checklist.md

چک‌لیست حافظهٔ بین‌اجرایی است. اگر به‌روز نشود، اجرای بعدی کار انجام‌شده را دوباره انجام می‌دهد.

قواعد نوشتن:

  • ردیف را همان لحظه که شروع می‌کنی ⏳ → 🔄 کن، نه در پایان تسک
  • تمام شد → 🔄 → ✅ با یادداشت کوتاه اگر چیزی برای گفتن هست (مسیر فایل، عدد اندازه‌گیری‌شده)
  • شکست خورد یا بلاک شد → ⚠️ با دلیل در ستون یادداشت
  • به تعویق افتاد → با دلیل + تسک مقصد در یادداشت. بی‌دلیل = تسک تمام نشده.
  • خط سربرگ را هم به‌روز کن:
**وضعیت کلی:** 🔄 در حال انجام · **آخرین بازبینی:** ۱۴۰۵/۰۵/۰۳

پیش از رفتن به وظیفهٔ ۶، بخش ۶ (یا ۷/۸ بسته به تسک) بازبینی پایانی را ردیف‌به‌ردیف اجرا کن. ردیف‌های مشترک همهٔ تسک‌ها:

همهٔ ردیف‌های بالا وضعیت نهایی دارند (هیچ 🔄 و ⏳ بی‌دلیل)
ddev exec php bin/phpunit                       کامل سبز
ddev exec php bin/phpunit --group=slot-mode-frozen   سبز
ddev exec php vendor/bin/phpstan analyse         بدون خطای جدید
npx tsc --noEmit                                 بدون خطا
yarn test                                        سبز
TenantSchemaCoverageTest + TenantLookupInventoryTest  سبز
docs/api/* به‌روز شد
چک‌لیست UI کامل شد (اگر تسک صفحه دارد)
nobat724_front و clinic-pro-tauri دستی بررسی شدند
commit شد، سپس graphify update .
موارد به‌تعویق‌افتاده با دلیل و تسک مقصد ثبت شدند

ردیف «دو کلاینت دیگر» در build هیچ‌کدام خطا نمی‌دهد — بررسی فقط دستی ممکن است (guidelines §۳). نتیجه را با ذکر فایل‌های بررسی‌شده گزارش بده، نه با «بررسی شد».

نحوه تست: بعد از به‌روزرسانی، دستور شمارش وظیفهٔ ۲ را دوباره اجرا کن. تسک باید ✅=<همه> 🔄=0 ⏳=0 ⚠️=0 بدهد.


۶. Commit و به‌روزرسانی گراف

ترتیب مهم است: اول commit، بعد graphify update — وگرنه گراف وضعیت کامیت‌نشده را ایندکس می‌کند.

git add -A
git commit -m "$(cat <<'EOF'
feat(booking): <عنوان انگلیسی تسک>

<دو-سه خط: چه چیزی اضافه شد، چه چیزی عمداً دست‌نخورده ماند>

Task: docs/new_feture/taskes/task-XX-<name>/
Slot-mode contract: unchanged (--group=slot-mode-frozen green)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
EOF
)"

graphify update .

پیام کامیت انگلیسی (قاعدهٔ پروژه). خط Slot-mode contract اجباری است — رد مکتوبِ اینکه خط سرخ رعایت شده.

اگر روی برنچ main هستی، اول برنچ بساز:

git checkout -b feat/booking-engine-task-XX

نحوه تست: git log --oneline -1 و git status را در گزارش بگذار.


۷. گزارش پایانی و اعلام تسک بعدی

اجرا با این قالب تمام می‌شود و تسک بعدی شروع نمی‌شود:

✅ تسک XX — <عنوان> تمام شد

پیاده‌سازی
  • <سه تا پنج خط: چه ساخته شد، با مسیر فایل>

تست
  • bin/phpunit                     : <N> تست، سبز
  • --group=slot-mode-frozen        : سبز
  • phpstan / tsc / yarn test       : سبز
  • تست‌های جدید این تسک            : <فهرست کوتاه>

مستندات
  • <فایل‌های docs/api/* و docs/architecture/* که عوض شدند>

خط سرخ
  • منطق اسلاتی دست‌نخورده — <یک جمله شاهد، مثلاً: هیچ متد SlotCalculatorService عوض نشد>

کلاینت‌های دیگر
  • nobat724_front  : <چه بررسی شد و نتیجه>
  • clinic-pro-tauri: <همان>

به تعویق افتاد (اگر هست)
  • <ردیف> — دلیل: <…> — تسک مقصد: <XX>

commit: <hash کوتاه>  ·  graphify: به‌روز شد

────────────────────────────────
🎯 تسک بعدی: XX — <عنوان>   (وابستگی‌ها: ✅)
   اجرا کن:  /run-prompt clinicpro/.claude/prompt/booking-engine-task-runner.md

اگر تسک ناتمام ماند، به‌جای بنویس:

⛔ تسک XX ناتمام ماند

بلاک‌کننده: <چه چیزی و کجا>
ردیف‌های باقی: <فهرست با وضعیت>
چک‌لیست به‌روز شد؛ اجرای بعدی از همین‌جا ادامه می‌دهد.

نحوه تست: گزارش باید با خروجی واقعی دستورها بخواند. عدد تست ساختگی ننویس.


نکات مهم

خط سرخ — تنها چیزی که هیچ تسکی نمی‌تواند نقض کند

booking_mode = 'slot' منطق تولیدیِ زنده است. _shared/red-lines.md فهرست دقیق دارد؛ خلاصه‌اش:

قفل یعنی
هفت متد عمومی SlotCalculatorService امضا و رفتار عوض نمی‌شود
GET /api/v1/appointment-slots قرارداد request/response
GET /api/v1/appointment-settings/month-availability/{doctorUuid} قرارداد
Appointment::active_slot_key و refreshActiveSlotKey() مکانیزم یکتایی موجود
AppointmentRepository::isSlotTaken امضا و معنا
WeeklySchedule::DEFAULT_META['booking_mode'] مقدار slot می‌ماند

مجاز: افزودن متد جدید · کلاس موازی · ستون تهی‌پذیر · کلید جدید در meta با حفظ پیش‌فرض ممنوع: تغییر امضای متد موجود · refactor «یکدست‌سازی» · اعمال قوانین جدید روی حالت slot

fixture های tests/Appointment/fixtures/slot-mode-contract.json و month-availability-contract.json و slot-calculator-signatures.php read-only اند. اگر تست قرمز شد، کد برمی‌گردد، نه fixture. تسک ۰۰ آن‌ها را می‌سازد؛ هیچ تسک دیگری اجازهٔ به‌روزرسانی‌شان را ندارد.

فاز ۰ اختیاری نیست

تسک ۰۰ و ۰۰ب پیش‌نیاز واقعی‌اند، نه توصیه. حالت service امروز پنج شکاف در چرخهٔ عمر نوبت دارد (ویرایش، جابه‌جایی، رزرو، پنل بیمار، دیزاین‌سیستم سایت — جزئیات در 00-current-state-report.md بخش ۲-۵ب). اگر حالت resource (تسک ۰۶) روی این پایه ساخته شود، هر باگ موجود به موتور جدید ارث می‌رسد و تشخیص منبعش غیرممکن می‌شود.

دیزاین‌سیستم — هر صفحهٔ جدید

_shared/ui-conventions.md کامل است. پنج قاعده‌ای که رعایت نکردنشان یعنی رد شدن ردیف:

  1. SearchableSelect، هرگز <select> بومی
  2. زیرصفحه‌ها backTo یا <BackButton fallback="…" /> — دکمهٔ دست‌ساز نه
  3. وضعیت لیست (جستجو/فیلتر/صفحه) در URL با hooks/useUrlState.ts، نه useState
  4. داده فقط TanStack Query از lib/api.ts؛ استخراج: paginated → data?.data + data?.meta?.totalRecords · single → data?.data · Category → data?.data?.data ?? []
  5. فرم با React Hook Form + Zod

و: هیچ رنگ/شعاع/سایهٔ hard-code — همه از توکن‌های :root در assets/admin/styles.css. دارک‌مود ([data-theme="dark"]) و حالت فشرده ([data-density="compact"]) بررسی شوند. مقدار hex در دارک‌مود می‌شکند.

پیش از ساختن هر کامپوننت، assets/admin/components/ui/ را بگرد. ساختن نسخهٔ موازیِ DataTable/Modal/ConfirmDialog/PageHeader/StatCard/StatusBadge/Pagination/ PersianDatePicker/PriceInput رد می‌شود.

قواعد ثابت پروژه در هر تسک

از CLAUDE.md و docs/architecture/tenancy.md:

  • entity جدید یا TenantOwnedTrait می‌گیرد یا با دلیل در App\Shared\Tenant\GlobalTables ثبت می‌شود؛ TenantSchemaCoverageTest هر دو حالت را اجبار می‌کند
  • entity_type, entity_id ستون‌های اول هر ایندکس ترکیبیِ لیست — وگرنه MariaDB برای شرط TenantFilter از ایندکس استفاده نمی‌کند
  • هر uuid که از request می‌آید با App\Shared\Tenant\TenantOwnershipChecker سنجیده می‌شود؛ TenantLookupInventoryTest شمارنده per-file دارد و findByUuid تازه تست را قرمز می‌کند
  • timestamp ها int یونیکس، نه DateTime؛ نمایش شمسی فقط در UI با formatDate
  • کنترلر نازک · extends BaseController · $this->success()/paginated()/error()
  • خطا با throw new AppException(ErrorCodes::ERR_XXX, null, $status)؛ کد و پیام فارسی در src/Shared/Constant/ErrorCodes.php
  • لیست‌های ادمین با ->getArrayResult()
  • API جدید فقط وقتی هیچ endpoint موجودی — حتی با توسعه — کافی نباشد؛ دلیلش نوشته شود
  • هر endpoint جدید یا تغییریافته → docs/api/*.md در همان نشست

الگوهای معماری که تسک‌ها تصریح کرده‌اند

الگو تسک دلیل انتخاب (در همان تسک مکتوب است)
Strategy + tagged_iterator ۰۶ ResourcePickerInterface افزودن استراتژی پنجم نباید کلاس موجود را عوض کند (OCP)
Repository + سرویس واحدِ نویسنده ۰۷ OccupancyWriter تنها نقطهٔ نوشتن در resource_occupancy
Registry بسته ۰۹ FieldRegistry/OperatorRegistry/EffectRegistry مستند بند ۸: کد دلخواه در قانون ممنوع، وگرنه جستجوی وقت کند می‌شود
Outbox ۱۴ DomainEventPublisher commit اتمی رویداد با کار؛ نه «پیامک رفته و نوبت نیست»
Ledger (دفتر) نه شمارنده ۱۱ SessionCreditLedger مستند بند ۱۲: با شمارنده، اولین اشتباه غیرقابل‌ردیابی است
کلید یکتای سطل زمانی ۰۷ resource_occupancy_slot MariaDB EXCLUDE ندارد؛ تضمین از دیتابیس نه از کد

این‌ها تصمیم گرفته‌شده‌اند، نه پیشنهاد. اگر در اجرا به مشکل خوردی، قبل از تغییر الگو دلیل را به کاربر بگو و تعیین تکلیف بخواه (guidelines §۶).

تسک‌های پرخطر — جای کندی و دقت

تسک ریسک کاری که باید بکنی
۰۰ fixture بعد از تغییرات ساخته شود fixture اول، بعد کد
۰۶ I/O داخل حلقه → جستجو کند AvailabilityPerformanceTest تعداد کوئری را قفل می‌کند: ≤۵
۰۷ تست همزمانی با mock بی‌ارزش است دو اتصال DBAL واقعی، assertSame(1, ok1+ok2)
۰۹ spacing per-slot حلقه بزند forbiddenRanges() کوئری‌محور؛ AvailabilityPerformanceTest باید با قوانین فعال هم سبز بماند
۱۰ شبیه‌سازی داده واقعی بنویسد rollback در finally + em->clear() + تست شمارش ردیف
۱۱ quote اعتبار مصرف کند مصرف فقط در confirm؛ تست: ده quote → مانده بی‌تغییر
۱۲ book-all نیمه‌کاره همه یا هیچ در یک تراکنش

cross-repo — بررسی دستی اجباری

nobat724_front/services/response.js و clinic-pro-tauri/src/service/response.js هر دو مصرف‌کنندهٔ همان /api/v1/... اند. تغییر قرارداد در build هیچ‌کدام خطا نمی‌دهد و در runtime می‌شکند (guidelines §۳).

تسک‌هایی که قرارداد را واقعاً عوض می‌کنند و بررسی دستی‌شان بحرانی است:

  • ۰۰service_item تکی باید با service_items هم‌گام بماند (چهار مصرف‌کننده رویش خوانده‌اند)
  • ۰۴ — مدت نوبت‌های چندسرویسی عوض می‌شود (فرمول «زمان تنها/زمان اضافه»)
  • ۰۶ — پس از ارتقای یک کلینیک به resource، کلاینت باید مسیر جدید صدا بزند
  • ۰۸ — مبلغ نمایشی رزرو ممکن است عوض شود
  • ۱۳ — سایت باید cancellation-preview را نشان دهد

در گزارش هر تسک، فایل‌های بررسی‌شده را نام ببر؛ «بررسی شد» بی‌ارزش است.

وقتی متن تسک با کد واقعی نمی‌خواند

تسک‌ها از خواندن کد در تاریخ نوشتنشان ساخته شده‌اند. اگر جایی متن با کد امروز نخواند:

  1. کد واقعی مرجع است، نه متن تسک
  2. اختلاف را به کاربر بگو
  3. متن تسک را اصلاح کن (فایل تسک هم سند است — guidelines §۴)
  4. بعد پیاده‌سازی کن

موارد شناخته‌شده‌ای که تسک‌ها خودشان علامت زده‌اند و باید پیش از کدنویسی تأیید شوند:

  • تسک ۱۴ ردیف ۲.۹ — وجود patient_sessions.started_at/ended_at؛ اگر نبود، گزارش plan-accuracy به تسک جدا موکول می‌شود، نه ساخته شدن با داده حدسی
  • تسک ۰۰ب بخش ۱ — وجود service_items و service_total_minutes در پاسخ GET /api/v1/appointments/user؛ اگر نبود، به تسک ۰۰ برمی‌گردد
  • تسک ۰۷ database.md — وابستگی معکوس: جدول resource_occupancy در تسک ۰۶ migrate می‌شود، تعریفش در ۰۷ است