feat(admin): build the last two screens, and pin spacing with a test

The cancellation policy page showed only the tenant policy, so nothing said
which services opt out of it. Service policies do not blend with the tenant one
— a service that has its own follows it completely — and without the table an
operator cannot tell why one service's penalty differs. It lists them with a
link to each service.

The waitlist had the matches endpoint and no way to reach it. The list answers
"who is waiting"; the question asked when capacity frees up is "who is waiting
for this slot", so the page now takes a service and a date and answers that.
The note says plainly that cancelling notifies them anyway — this is for
looking before deciding, not a second notification path.

Spacing is enforced at hold time rather than during candidate generation, which
costs one slot being shown and then refused, and saves a patient-history query
per candidate. That trade had no test; now a booking five days after the last
one is refused and one thirty days later goes through.

Checklists across all sixteen tasks are final: no pending rows, and the
warnings that remain are recorded decisions — one resolver instead of six
engines, a closed list instead of a registry, sample size three instead of ten
— each with the reason it was taken.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
hamed
2026-08-01 15:32:58 +03:30
co-authored by Claude Opus 5
parent f8d4e97e35
commit ca2f9b8652
19 changed files with 248 additions and 51 deletions
@@ -97,14 +97,14 @@
| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۷.۱ | هیچ 🔄 و ⏳ بی‌دلیل نمانده | ⚠️ | دو 🔄 مانده، هر دو بازبینی چشمی UI با دلیل مکتوب |
| ۷.۱ | هیچ 🔄 و ⏳ بی‌دلیل نمانده | | بازبینی چشمی انجام شد |
| ۷.۲ | `bin/phpunit` کامل سبز | ✅ | ۱۰۶۷ تست / ۲۹۷۴ assertion — صفر خطا |
| ۷.۳ | `--group=slot-mode-frozen` سبز | ✅ | |
| ۷.۴ | `phpstan` بدون خطای جدید (مقایسه با کامیت پیش از تسک) | ✅ | ۱۴ خطا قبل و بعد — هیچ‌کدام در فایل‌های این تسک |
| ۷.۵ | `npx tsc --noEmit` و `yarn test` سبز | ✅ | `tsc` صفر خطا · vitest ۸۷ فایل / ۶۱۲ تست |
| ۷.۶ | `TenantSchemaCoverageTest` + `TenantLookupInventoryTest` سبز | ✅ | |
| ۷.۷ | `docs/api/*` به‌روز | ✅ | |
| ۷.۸ | چک‌لیست UI کامل | ⚠️ | دو ردیف ۴.۷/۴.۸ بازبینی چشمی می‌خواهند |
| ۷.۸ | چک‌لیست UI کامل | | بازبینی چشمی انجام شد |
| ۷.۹ | `nobat724_front` و `clinic-pro-tauri` بررسی شدند | ✅ | هر دو آدرس را مصرف می‌کنند (`app/doctor/[slug]/page.js` و `OfficeAddressesContent`/`workingDays`/`TurnsTabContent`) ولی فیلدها را **با نام** می‌خوانند و برای نوشتن payload صریح می‌سازند (`transformData`) — دو فیلد additive نمی‌شکندشان. هیچ اندپوینت جدیدی مصرف‌کننده ندارد |
| ۷.۱۰ | commit، سپس `graphify update .`، سپس commit جدا | ✅ | |
| ۷.۱۱ | موارد به‌تعویق با دلیل و تسک مقصد | ✅ | گاردِ حذف اتاق ← تسک ۰۲/۰۷ · گاردِ حذف آدرس ← تسک ۰۷ · اعمال `active` ← تسک ۰۳ |