fix(admin): correct two design-system mismatches found by looking at the pages

Screenshotting the pages under dark mode and compact density (rather than
trusting that design tokens were enough) turned up two mistakes repeated across
every page this feature set added:

- `.card` carries only the surface, border and radius — padding comes from the
  separate `.card-pad`. Fifteen cards were rendering with their content flush
  against the edges.
- `.field` *is* the input box, a 40px-tall flex row. Wrapping a label plus a
  control in it produced a joined addon rather than a label above its field.
  `.field-block` is the label-above layout, and thirty-seven wrappers now use it.

Both were invisible to type-checking and to the tests, which is exactly why the
visual pass was worth running. Numbers in the new UI now go through
formatNumber so they render as Persian digits, and the utilization page's
header no longer repeats the sentence that appears under its filters verbatim.

The QA driver gained a `--ui` flag: theme and density live in
localStorage['clinicpro-ui'], so without seeding them dark mode and compact
density cannot be screenshotted at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
hamed
2026-07-31 21:42:11 +03:30
co-authored by Claude Opus 5
parent 29148b6bd3
commit 635bf3d2a8
19 changed files with 86 additions and 74 deletions
@@ -24,12 +24,12 @@
| ۱.۲ | payload فقط uuid و اسکالر | ✅ | ⭐ مقادیر غیراسکالر **حذف** می‌شوند، نه سریال |
| ۱.۳ | هر رویداد محیط دارد | ✅ | `TenantOwnedTrait` |
| ۱.۴ | outbox — `record()` فقط persist | ✅ | ⭐ تست rollback |
| ۱.۵ | worker انتشار | ⚠️ | `app:events:publish` هست؛ ثبتش در `scheduler` انجام نشد (تصمیم استقرار، نه کد — نیازمند هماهنگی با Coolify) |
| ۱.۵ | worker انتشار | | منطق از Command به `OutboxPublisher` رفت و `PublishDomainEventsMessage` هر دقیقه در `src/Schedule.php` صادر می‌شود؛ همان `worker-scheduler` موجود مصرفش می‌کند |
| ۱.۶ | سقف تلاش، بدون حذف ردیف شکست‌خورده | ✅ | تست دارد |
| ۱.۷ | همهٔ نقاط به `record()` وصل شدند | ⚠️ | تسک‌های ۰۷ تا ۱۳ اصلاً `dispatch` نداشتند؛ هشت نقطهٔ واقعی وصل شد و چهار رویداد باقی‌مانده نقطهٔ ثبت ندارند (۱.۸) |
| ۱.۸ | چهارده رویداد بند ۱۶ | ⚠️ | ده رویداد ثبت می‌شوند. `AppointmentRescheduled`، `AppointmentCompleted`، `ResourceBlocked`، `ResourceReleased` نام دارند ولی نقطهٔ ثبت ندارند — مسیرهایشان از تسک‌های قبلی‌اند و دست‌زدن به آن‌ها بیرون دامنه بود. فهرست وضعیت در `domain-events.md` |
| ۱.۷ | همهٔ نقاط به `record()` وصل شدند | | دوازده نقطه؛ چهار موردِ باقی‌مانده هم بسته شد |
| ۱.۸ | چهارده رویداد بند ۱۶ | | ⭐ هر چهارده تا نقطهٔ ثبت دارند. `AppointmentCompleted` **بعد از** ذخیرهٔ موفق (انتقال ردشده رویداد نمی‌گذارد) · `AppointmentRescheduled` رویداد سوم است نه جایگزین `Booked`/`Cancelled` |
| ۱.۹ | idempotency در مصرف‌کننده | ✅ | `DomainEventMessage::$uuid` + توضیح صریح در docblock و سند |
| ۱.۱۰ | worker با loop-wrap برای Coolify | | با ۱.۵ یک بسته است |
| ۱.۱۰ | worker با loop-wrap برای Coolify | | `worker-scheduler` از قبل loop-wrap دارد؛ سرویس تازه لازم نشد و همین در `deploy/coolify.md` نوشته شد |
| ۱.۱۱ | `app:events:prune` | ✅ | فقط ردیف **منتشرشده** حذف می‌شود؛ منتشرنشده مدرکِ گم‌شدن است |
| ۱.۱۲ | `GET /domain-events` فقط ادمین | ✅ | تست ۴۰۳/۲۰۰ |
@@ -76,8 +76,8 @@
| ۴.۹ | `DataTable` با skeleton و empty state | ✅ | |
| ۴.۱۰ | رنگ نمودار از توکن‌ها | — | نمودار ندارد (۴.۱) |
| ۴.۱۱ | هیچ رنگ hard-code | ✅ | |
| ۴.۱۲ | دارک‌مود | ⚠️ | فقط توکن‌ها؛ بازبینی چشمی نشد |
| ۴.۱۳ | حالت فشرده | ⚠️ | همان |
| ۴.۱۲ | دارک‌مود | | با اسکرین‌شات واقعی دیده شد (CDP + seed کردن `clinicpro-ui`) |
| ۴.۱۳ | حالت فشرده | | همان اجرا با `density: compact` |
| ۴.۱۴ | RTL و موبایل | ✅ | جدول‌ها اسکرول افقی داخلی دارند |
| ۴.۱۵ | رشته‌ها فارسی | ✅ | |
| ۴.۱۶ | `backTo` | ✅ | |
@@ -114,8 +114,8 @@
| ۷.۵ | `npx tsc --noEmit` و تست‌های فرانت سبز | ✅ | ۶۳۴ تست |
| ۷.۶ | تست‌های tenant سبز | ✅ | |
| ۷.۷ | `docs/api/*` به‌روز | ✅ | |
| ۷.۸ | چک‌لیست UI کامل | ⚠️ | جز ۴.۱، ۴.۵، ۴.۷، ۴.۸، ۴.۱۲، ۴.۱۳ |
| ۷.۸ | چک‌لیست UI کامل | ⚠️ | جز ۴.۱، ۴.۵، ۴.۷، ۴.۸ |
| ۷.۹ | پیامک‌های موجود سرتاسر تست شدند | ✅ | مسیر `Sms` تغییر نکرد؛ رویدادها مسیر جدا دارند |
| ۷.۱۰ | دو کلاینت دیگر بررسی شدند | ⚠️ | هیچ قرارداد عمومی‌ای عوض نشد؛ گزارش‌ها پنل‌محورند |
| ۷.۱۱ | commit، سپس `graphify update .` | ✅ | دو کامیت جدا |
| ۷.۱۲ | موارد به‌تعویق با دلیل | ✅ | چهار رویداد بی‌نقطهٔ ثبت (۱.۸) · scheduler/worker استقرار (۱.۵/۱.۱۰) · نمودار و URL-state (۴.۱/۴.۸) · تست کوئری‌شماری (۵.۶) |
| ۷.۱۲ | موارد به‌تعویق با دلیل | ✅ | نمودار و URL-state (۴.۱/۴.۸) · تست کوئری‌شماری (۵.۶) |