docs/architecture/resource-first-model.md describes the shape: the three entities, why an option is a ServiceItem rather than a fourth table, the four-level resolution chain, the two conditions on the eligibility filter and what each of them prevented, and why containment is a graph beside the display tree rather than the tree itself. docs/api/resource.md gains both offering endpoints with the response captured from a real call, including a row where the price comes from the branch and one where it comes from the resource — the two cases the *_source fields exist for. docs/api/appointment.md documents resource_uuid, the doctor inference, and the nullable resource/service_option in the response. The checklists for tasks 9 to 14 keep their rows but open with a banner saying the task was removed, when, by whose decision, and which commit to revert. They are history now; deleting them would erase the record of work that shipped and was then withdrawn. Verified end to end: 1304 tests, slot-mode-frozen green, phpstan at 14, tsc clean, 648 panel tests, and app:seed-scenarios --reset builds all three environments. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9.5 KiB
9.5 KiB
چکلیست — تسک ۱۰ (فرم ساخت قانون و محیط آزمایش)
⛔ این تسک از محصول حذف شد
تصمیم مالک محصول، ۱۴۰۵/۰۵/۱۰: مدل نوبتدهی به منبع/سرویس/گزینه محدود شد و هر چیز خارج از آن حذف شد. کد، جدولها، endpointها، تستها و صفحات پنل این تسک در کامیت «Remove the policy, package, course, cancellation and event subsystems» برداشته شدند.
ریسکش پیش از اجرا دو بار مطرح و دو بار تأیید شد. ردیفهای زیر تاریخچهاند، نه کار جاری؛ برای برگرداندن به همان کامیت رجوع کنید.
مدل جایگزین:
docs/architecture/resource-first-model.mdو چکلیست تسک ۱۵.
وضعیت کلی: ✅ تمامشده با انحرافهای ثبتشده · آخرین بازبینی: ۱۴۰۵/۰۵/۰۹
قواعد: _shared/definition-of-done.md · red-lines.md · ui-conventions.md
۰. خط سرخ
| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۰.۱ | --group=slot-mode-frozen سبز |
✅ | |
| ۰.۲ | شبیهسازی هیچ ردیفی نمینویسد (جز policy_simulation_runs) |
✅ | ⭐⭐ testSimulationWritesNothingButItsOwnRun پنج جدول را قبل/بعد میشمارد |
| ۰.۳ | نوبتهای واقعی بیماران تغییر نکردند | ✅ | ارزیابی روی حقایق است، نه entity |
۱. بکاند — شبیهساز
| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۱.۱ | PolicySimulator · SimulationSampler · PolicySimulationRun |
✅ | بهعلاوهٔ SimulationFacts |
| ۱.۲ | سه لایهٔ تضمین | ✅ | ⭐ حقایق (نه entity) · تراکنش با rollback در finally · تست شمارش |
| ۱.۳ | $this->em->clear() بعد از rollback |
✅ | ⭐ قانون بعد از clear دوباره خوانده میشود |
| ۱.۴ | ثبت نتیجه بعد از rollback و در تراکنش جدا | ✅ | |
| ۱.۵ | ارزیابی جدا — فقط همان قانون | ✅ | evaluateIsolated() روی هر شش موتور. یادداشت قبلی: PolicyResolver::evaluateOne() بهجای evaluateIsolated() روی شش موتور؛ شش موتوری وجود ندارد که متد بگیرد (انحراف تسک ۰۹) |
| ۱.۶ | فیلتر شعبه/سرویس/دسته از دامنهٔ قانون | ✅ | تصمیم ثبتشده در deviations.md — از دامنهٔ قانون استخراج میشود، نه از داخل condition؛ شرطها فیلدِ id ندارند که به کوئری تبدیل شوند |
| ۱.۷ | سقف نمونه ۵۰؛ درخواست بیشتر → ۴۲۲ | ✅ | testSampleSizeAboveTheCapIsRejected |
| ۱.۸ | PolicyTemplateRegistry با پنج الگو |
✅ | شش الگو |
| ۱.۹ | activate شرط simulate همان نسخه |
✅ | ⭐ testSimulationOfTheOldVersionDoesNotUnlockTheNewOne |
| ۱.۱۰ | محیط بدون نوبت → آزمایش خالی موفق، فعالسازی مجاز | ✅ | ⭐ warning: دادهای برای آزمایش نیست |
| ۱.۱۱ | چهار سطح شدت با آستانههای مستند | ✅ | PolicySimulationRun::severityFor() — ۰٪ · ≤۲۰٪ · ≤۶۰٪ · >۶۰٪ |
| ۱.۱۲ | دو endpoint | ✅ | سه تا: policy-templates · simulate · simulations |
| ۱.۱۳ | app:policy:prune-simulations — آخرین اجرا per (قانون، نسخه) حذف نمیشود |
✅ | --days و --dry-run؛ SQL با MAX(id) GROUP BY policy_id, policy_version |
۲. دیتابیس
| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۲.۱ | policy_simulation_runs با جفت tenant |
✅ | Version20260731065427 + دو ایندکس |
| ۲.۲ | report سقف ۵۰ ردیف |
✅ | از سقف نمونه میآید: بیش از ۵۰ نوبت اصلاً خوانده نمیشود |
| ۲.۳ | TenantSchemaCoverageTest سبز |
✅ |
۳. UI
| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۳.۱ | PoliciesPage · PolicyFormPage · PolicySimulationPage |
✅ | + ورودی «قوانین» در منوی تنظیمات |
| ۳.۲ | PolicyConditionBuilder از GET /policy-schema |
✅ | ⭐ تست با فیلد ساختگی: بدون تغییر فرانت در UI ظاهر میشود |
| ۳.۳ | عملگرها per فیلد فیلتر میشوند | ✅ | ⭐ field_meta[].operators — تست جداگانه |
| ۳.۴ | نوع ورودی مقدار از schema | ✅ | int · enum · bool · list |
| ۳.۵ | همهٔ selectها SearchableSelect |
✅ | هیچ <select> بومی |
| ۳.۶ | انتخاب الگو → فرم کوتاه مقدارها | ✅ | حالت پیشفرض صفحه همین است |
| ۳.۷ | ستون «وضعیت فعلی ← با این قانون» | ✅ | ⭐ |
| ۳.۸ | درصد + شدت با رنگ توکنمحور | ✅ | کلاسهای badge green/amber/red موجود |
| ۳.۹ | شدت none هشدار میدهد |
✅ | «احتمالاً شرطش هرگز برقرار نمیشود» |
| ۳.۱۰ | شدت high → تأیید دوم |
✅ | |
| ۳.۱۱ | ConfirmDialog موجود |
✅ | نه window.confirm |
| ۳.۱۲ | DataTable + فیلتر دسته در URL |
✅ | useUrlState |
| ۳.۱۳ | backTo روی هر سه صفحه |
✅ | |
| ۳.۱۴ | هیچ رنگ/شعاع hard-code | ✅ | فقط var(--…) |
| ۳.۱۵ | دارکمود و حالت فشرده | ✅ | اسکرینشات واقعی در دارکمود و حالت فشرده؛ ایرادی نماند |
| ۳.۱۶ | RTL و موبایل — اسکرول افقی جدول | ✅ | overflow-x: auto دور جدول گزارش |
| ۳.۱۷ | تاریخها شمسی | ✅ | formatDate |
| ۳.۱۸ | همهٔ رشتهها فارسی | ✅ | |
| ۳.۱۹ | تاریخچهٔ نسخهها با diff | ✅ | PolicyVersionDiff — هر نسخه در برابر نسخهٔ پیش، فیلدبهفیلد؛ «بدون تغییرِ معنادار» هم صریح گفته میشود |
۴. تست
| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۴.۱ | شمارش ردیف قبل/بعد | ✅ | ⭐⭐ |
| ۴.۲ | استثنا → rollback + clear | ✅ | ⭐ خودِ خاصیت سنجیده میشود: entityِ در انتظار flush بعد از آزمایش ثبت نمیشود و تراکنش بسته است |
| ۴.۳ | نمونهگیری — فقط confirmed/completed، سقف | ✅ | سقف تست شد؛ فیلتر وضعیت غیرمستقیم (نوبتهای نمونه completed اند) |
| ۴.۴ | دروازهٔ فعالسازی | ✅ | ⭐ بدون آزمایش، نسخهٔ قدیمی، نسخهٔ درست، محیط خالی |
| ۴.۵ | هر الگو قانون معتبر میسازد | ✅ | هر شش الگو تا فعالسازی رفتند. یادداشت قبلی: dataProvider ششتایی نوشته نشد |
| ۴.۶ | چهار آستانهٔ شدت | ✅ | هر چهار آستانه روی مرزِ خودش، بهعلاوهٔ حالت کوتاهتر |
| ۴.۷ | فیلد ساختگی از mock schema در UI | ✅ | ⭐ PolicyFormPage.test.tsx |
| ۴.۸ | عملگر نامعتبر نمایش داده نمیشود | ✅ | |
| ۴.۹ | صفحهٔ آزمایش — قفل فعالسازی روی نسخهٔ قدیمی | ✅ | PolicySimulationPage.test.tsx |
اجرا: ddev exec php bin/phpunit tests/Policy → ۳۰ تست · npx vitest run → ۶۲۸ تست.
۵. مستندات
| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۵.۱ | docs/api/policy.md — simulate، policy-templates، شرط تازهٔ activate |
✅ | JSON واقعی |
| ۵.۲ | policy-engine.md بخش «چرا آزمایش اجباری است» |
✅ | + سه لایهٔ تضمین و دو حالت مرزی |
۶. بازبینی پایانی
| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۶.۱ | هیچ 🔄 و ⏳ بیدلیل نمانده | ✅ | ۷ مورد ⚠️ همه با دلیل |
| ۶.۲ | bin/phpunit کامل سبز |
✅ | ۱۲۵۰ تست |
| ۶.۳ | --group=slot-mode-frozen سبز |
✅ | |
| ۶.۴ | phpstan بدون خطای جدید |
✅ | ۱۴ = baseline |
| ۶.۵ | npx tsc --noEmit و تستهای فرانت سبز |
✅ | ۶۲۸ تست؛ yarn test داخل ddev اجرا نمیشود (باینری esbuild برای darwin نصب شده) — روی هاست اجرا شد |
| ۶.۶ | تستهای tenant سبز | ✅ | |
| ۶.۷ | docs/api/* بهروز |
✅ | |
| ۶.۸ | چکلیست UI کامل | ✅ | جز ۳.۱۵ و ۳.۱۹ |
| ۶.۹ | دو کلاینت دیگر بررسی شدند | ✅ | این تسک هیچ قرارداد عمومیای عوض نکرد؛ همهٔ اندپوینتها پنلمحورند |
| ۶.۱۰ | commit، سپس graphify update . |
✅ | دو کامیت جدا |
| ۶.۱۱ | موارد بهتعویق با دلیل | ✅ | ۳.۱۵ (بازبینی چشمی) · ۳.۱۹ (diff بصری) · ۴.۲/۴.۵/۴.۶ (پوشش تست) — همه در همین فایل ثبتاند |