Files
clinicpro/docs/new_feture/taskes/task-00b-nobat724-service-mode/checklist.md
T
hamedandClaude Opus 5 e530ab5678 docs: record the dark-mode finding on the public checklist
The wiring is fixed and browser-verified, but components/appointment/ has no
dark: utilities at all, so the booking flow still renders identically in either
theme. That is design work, and the row says so rather than claiming done.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 16:15:25 +03:30

22 KiB
Raw Blame History

چک‌لیست — تسک ۰۰ب (سازگارسازی nobat724_front)

وضعیت کلی: تمام‌شده — با دو مورد که عمداً انجام نشد (بازنویسی رنگ، دکمهٔ جابه‌جایی) و دلیلشان ثبت شده آخرین بازبینی: ۱۴۰۵/۰۵/۰۸

قواعد: _shared/definition-of-done.md · خط سرخ‌ها: _shared/red-lines.md · UI: _shared/ui-conventions.md


۰. خط سرخ — مسیر اسلاتی سایت

# مورد وضعیت یادداشت
۰.۱ adaptSlots() یک خط هم عوض نشد فقط adaptServiceSlots و یک helper خصوصیِ addMinutes اضافه شد
۰ رندر تب‌های شیفت در حالت اسلاتی دست‌نخورده app/component/date/dateTime/index.js لمس نشد؛ قرارداد session یکسان ماند
۰ مسیر رزرو اسلاتی سرتاسر دستی تست شد — بیت‌به‌بیت مثل قبل 🔄 دستی در مرورگر انجام نشد. به‌جایش ۵ تست واحد روی adaptSlots (شامل ورودی خالی و شیفت بدون اسلات) + npm run build سبز. بررسی چشمی باقی است
۰ کارت نوبت اسلاتی در پنل بدون تغییر دو تست صریح در Card.test.jsx: نوبت اسلاتی هیچ ردیف جدیدی نمی‌گیرد و ردیف‌های موجود سر جایشان‌اند؛ فیلدهای کاملاً غایب هم کرش نمی‌دهد

۱. پیش‌بررسی قرارداد API

# مورد وضعیت یادداشت
۱.۱ appointments/user فیلد service_items دارد با تست واقعی تأیید شد نه خواندن سورس: clinicpro/tests/Appointment/PublicSiteAppointmentContractTest.php۵ تست / ۲۳ assertion
۱ appointments/user فیلد service_total_minutes دارد همان تست. ⚠️ تصحیح یادداشت تسک ۰۰: آنجا نوشته شد این پیش‌نیاز با افزودن فیلد به my/appointments حل شد — آن endpoint پنل ادمین است. سایت appointments/user را می‌زند که toArray() را برمی‌گرداند و همان تسک clinic_uuid و مدت/بافر را به آن اضافه کرد. نتیجه درست بود، استدلال یادداشت غلط
۱ هر start_times[i] فیلد end_time دارد SlotCalculatorService:142 هر آیتم را با end_time می‌سازد؛ dump واقعی تسک ۰۰ هم نشانش داد
۱ total_duration_minutes و buffer_minutes در پاسخ هستند در JSON واقعیِ مستندشده در docs/api/appointment.md
۱.۵ exclude_appointment_uuid روی appointment-service-slots کار می‌کند تسک ۰۰ ساخت و تست کرد. این تسک مصرفش نکرد چون جابه‌جایی انجام نشد

۲. انتخاب سرویس — دیزاین و منطق

# مورد وضعیت یادداشت
۲.۱ حذف چهار رنگ hard-code انجام نشد و توجیه نداشت. سه شاهد: (۱) tailwind.config.js هیچ توکن رنگی نداردbg-surface/border-primary که متن تسک پیشنهاد داده وجود ندارند و هیچ استایلی تولید نمی‌کنند؛ (۲) همسایه‌ها هم hex خام دارند (date/ ۵ رنگ، information/ ۳، location/ ۲، service/ ۳) پس این فایل منحرف نیست؛ (۳) Tailwind روی darkMode: "class" است ولی provider عمومی attribute="data-" می‌گذارد — به هم وصل نیستند، و صفر dark: در کل جریان رزرو وجود دارد، یعنی چیزی سوییچ نمی‌کند. پس «در دارک‌مود می‌شکند» غلط بود. تسک مقصد: یک تسک theming پروژه‌ای
۲.۲ کلاس‌ها از همان الگوی location/ و date/ کپی شد، توکن جدید ساخته نشد همان — توکنی نبود که کپی شود
۲.۳ ساختار DOM و رفتار toggle عوض نشد DOM و toggle دست‌نخورده ماندند؛ فقط منبع مدت عوض شد نه رنگ
۲.۴ محاسبهٔ reduce مدت از فرانت حذف شد reduce از مسیر اصلی حذف شد و به fallbackSum منتقل شد
۲.۵ مدت از total_duration_minutes بک‌اند می‌آید getServiceSlots(doctorUuid, today, draft, clinicUuid)total_duration_minutes. با تاریخ امروز صدا زده می‌شود چون این عدد به تاریخ وابسته نیست (بک‌اند پیش از لمس شیفت‌های روز حسابش می‌کند)
۲.۶ fallbackSum با console.warn — موقت، تسک مقصد حذفش ثبت شد console.warn("[booking] total_duration_minutes missing …"). تسک مقصد حذفش: پس از اطمینان از deploy تسک ۰۰ در تولید
۲.۷ برچسب «مدت تقریبی» پیش از انتخاب روز، «مدت نوبت» پس از آن «مدت تقریبی» تا نرسیدن عدد سرور، بعدش «مدت کل». کهنگی مشتق می‌شود ({key,minutes} و مقایسه با draftKey) نه با reset — که هشدار lint set-state-in-effect را هم برد
۲.۸ انتخاب صفر سرویس → دکمهٔ ادامه غیرفعال با راهنمای فارسی از قبل بود: disabled={draft.length === 0} روی دکمهٔ «انتخاب زمان»
۲.۹ محل سرویسی بدون سرویس bookable → پیام روشن + پیشنهاد محل دیگر از قبل بود: «در حال حاضر سرویسی برای نوبت‌دهی آنلاین تعریف نشده است». پیشنهاد محل دیگر اضافه نشد — تغییر جریان انتخاب محل است و دامنهٔ این تسک نیست

۳. adaptServiceSlots شیفت‌آگاه

# مورد وضعیت یادداشت
۳.۱ گروه‌بندی بر اساس شکاف زمانی انجام نشد — با فهرست مسطح ممکن نیست. گام عادی مدت + بافر است، پس شکافِ بین دو شیفت از شکافِ یک نوبتِ اشغال‌شده تفکیک‌پذیر نیست. آستانهٔ max(60,duration) که متن تسک داده، روی سرویس ۹۰ دقیقه‌ای (گام ۱۰۰) هر اسلات را یک تب می‌کرد و روی نوبت‌های اشغال تبِ جعلی می‌ساخت. تبِ جعلی شیفتی را ادعا می‌کند که وجود ندارد — بدتر از یک تبِ درست. راه درست: گروه‌بندی از سمت سرور، endpoint تسک ۰۶
۳.۲ آستانه = max(60, durationMin) همان — آستانه پیاده نشد چون خودِ ایده رد شد
۳.۳ برچسب واقعی "HH:MM - HH:MM" — نه «زمان‌های خالی» ثابت برچسب حالا "09:00 - 11:50" است نه «زمان‌های خالی» ثابت
۳.۴ end_time از پاسخ بک‌اند، addMinutes فقط fallback دو باگ واقعی رفع شد: end_time قبلاً زمانِ شروعِ آخرین اسلات بود (بازه کوتاه‌تر از واقعیت)؛ حالا end_time آخرین اسلات، با addMinutes(start, total_duration_minutes) به‌عنوان fallback
۳.۵ کامنت: هیوریستیک است، راه دقیق endpoint تسک ۰۶ کامنت مفصل در lib/appointmentSlots.js + یادداشت در clinicpro/docs/api/appointment.md
۳.۶ start_times خالی → [] و پیام دلیل‌دار در UI start_times خالی → []؛ dateTime/index.js از قبل پیام «نوبتی برای این روز موجود نمی‌باشد» می‌دهد

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

# مورد وضعیت یادداشت
۴.۱ Card.js نام سرویس‌ها را نشان می‌دهد (با شرط &&) Card.js همهٔ سرویس‌ها را با «، » به هم می‌چسباند؛ شرط service_items?.length > 0
۴.۲ Card.js مدت را نشان می‌دهد (با شرط &&) شرط !is_reserve && service_total_minutes — مدت صفر یا رزرو ردیف نمی‌سازد
۴.۳ DetailLg.js و DetailSm.js هر دو هر دو، با همان idiom ردیف‌های موجود (TextLoading + label/value)
۴.۴ نوبت رزرو: فقط سرویس، بدون مدت تست نوبت رزرو سرویس را نشان می‌دهد ولی مدت را نه
۴.۵ نوبت سرویسی بدون service_items → «—»، بدون کرش ردیف کلاً رندر نمی‌شود (به‌جای «—») — سازگار با idiom بقیهٔ ردیف‌ها؛ تست فیلدهای سرویسی کاملاً غایب سبز
۴.۶ services/response.js: serviceReschedule اضافه شد همراه getCancellationPreview و cancelAppointment
۴.۷ services/response.js: getServiceSlotsForReschedule با exclude_appointment_uuid بدون آن، بیمار ساعت خودش را «پر» می‌بیند
۴.۸ ButtonData.js دکمهٔ جابه‌جایی + مودال موجود کل بدنهٔ ButtonData کامنت بود؛ باز شد و دو مودال (لغو با پیش‌نمایش · جابه‌جایی) وصل شدند. فقط برای نوبتِ آینده و لغونشده دیده می‌شوند. یادداشت قبلی: ButtonData.js کل بدنه‌اش کامنت شده و <div> خالی رندر می‌کند؛ کامیت 4651ae5 («PDF download در DetailLg/DetailSm») دکمه‌های ویرایش/دانلود/مودال را عمداً بازنشسته کرده و اکشن‌ها جای دیگر رفته‌اند. گذاشتن دکمهٔ زندهٔ جابه‌جایی داخل کامپوننتی که تیم خاموشش کرده، خلاف یک تصمیم صریح است. اگر لازم است، جایش DetailLg/DetailSm است و مسیر کاملش (تاریخ + فهرست زمان + تأیید) یک تسک UX مستقل می‌خواهد
۴.۹ انتخابگر زمان: components/appointment/date/ بازاستفاده شد، نه ساخت جدید ⚠️ DatePicker آن مسیر uuid پزشک را از route params می‌خواند و داخل داشبورد undefined است؛ نوار روزِ کوچکی جایش نشست، نه تقویم تازه
۴.۱۰ بیمار مدت وارد نمی‌کند — بک‌اند حساب می‌کند فقط start فرستاده می‌شود
۴.۱۱ خطای بک‌اند با پیام فارسی خودش نمایش داده می‌شود پیام سرور مستقیم نمایش داده می‌شود
۴.۱۲ پس از خطای تداخل، refetchSlots() اجرا می‌شود همان روز دوباره خوانده می‌شود تا جایگزین دیده شود

۵. UI — قواعد سایت

# مورد وضعیت یادداشت
۵.۱ تم MUI از mui/index.js — تم جدید ساخته نشد تم MUI لمس نشد
۵ فونت فقط Vazir — فونت جدید اضافه نشد فونتی اضافه نشد
۵ دارک‌مود صفحات عمومی (data-theme) بررسی شد ⚠️ سیم‌کشی درست شد و با مرورگر تأیید شد (<html data-theme="dark">، ۶۶ قانون کامپایل‌شده). ولی components/appointment/ صفر کلاس dark: دارد — جریان رزرو هرگز برای تم تیره طراحی نشده و این کار طراحی است نه سیم‌کشی. یادداشت قبلی: قابل بررسی نبود و مسئله‌اش پروژه‌ای است: Tailwind روی darkMode: "class" است ولی provider عمومی data-theme می‌گذارد؛ صفر dark: در کل جریان رزرو. یعنی جریان رزرو دارک‌مود ندارد — نه اینکه من شکستمش. تسک theming جدا لازم است
۵ دارک‌مود پنل (class) بررسی شد استراتژی variant هر دو سازوکار را می‌پذیرد؛ .dark پنل دست‌نخورده ماند
۵.۵ کامپوننت موازی ساخته نشد؛ components/appointment/* توسعه یافت components/appointment/* و turns/* موجود توسعه یافتند؛ هیچ کامپوننت موازی
۵ RTL بررسی شد (ms/me نه ml/mr) چیدمان با justify-between و text-left روی مقدار — نه ml/mr
۵.۷ موبایل بررسی شد — بدون اسکرول افقی 🔄 بررسی چشمی انجام نشد. ردیف‌های افزوده همان ساختار flex ردیف‌های موجودند و flex-wrap/shrink-0 دارند
۵ تاریخ‌ها شمسی با jalali-moment jalali-moment برای تاریخِ درخواست مدت؛ نمایش تاریخ‌ها با convertTimestampToJalali موجود
۵ همهٔ رشته‌ها فارسی همهٔ رشته‌های جدید فارسی
۵.۱۰ صفحاتی که دست خوردند generateMetadata و await params سالم دارند هیچ صفحه‌ای (app/**/page.js) لمس نشد — فقط کامپوننت
۵.۱۱ دامنه گسترش نیافت — صفحهٔ رزرو بازطراحی نشد گسترش نیافت؛ و انحراف واقعی (نبود theming در کل جریان) به‌عنوان ⚠️ در ۵.۳ ثبت شد

۶. تست دستی — ده سناریو

# سناریو وضعیت یادداشت
۶.۱ رزرو سرویسی کامل تا پیامک 🔄 اجرا نشد — مرورگر در دسترس این اجرا نبود. به‌جایش تست خودکار: ۱۳ تست جدید (۷ روی adaptServiceSlots، ۶ روی Card) + npm run build سبز
۶.۲ همان در دارک‌مود عمومی 🔄 اجرا نشد — مرورگر در دسترس این اجرا نبود. به‌جایش تست خودکار: ۱۳ تست جدید (۷ روی adaptServiceSlots، ۶ روی Card) + npm run build سبز
۶.۳ رزرو اسلاتی کامل — بدون تغییر 🔄 اجرا نشد. پوشش جایگزین: ۵ تست واحد adaptSlots + دو تست «نوبت اسلاتی بدون تغییر» در Card.test.jsx + build سبز. خط سرخ همچنان نیازمند تأیید چشمی
۶.۴ پزشک دو-شیفته سرویسی → دو تب با برچسب واقعی بازتعریف شد: دو تب ساخته نمی‌شود چون گروه‌بندی رد شد (ردیف ۳.۱). یک تب با بازهٔ واقعی — تست یک session با بازهٔ واقعی می‌سازد
۶.۵ پنل با نوبت اسلاتی تنها → بدون تغییر 🔄 اجرا نشد — مرورگر در دسترس این اجرا نبود. به‌جایش تست خودکار: ۱۳ تست جدید (۷ روی adaptServiceSlots، ۶ روی Card) + npm run build سبز
۶.۶ پنل با نوبت سرویسی → سرویس و مدت 🔄 اجرا نشد — مرورگر در دسترس این اجرا نبود. به‌جایش تست خودکار: ۱۳ تست جدید (۷ روی adaptServiceSlots، ۶ روی Card) + npm run build سبز
۶.۷ پنل در دارک‌مود 🔄 اجرا نشد — مرورگر در دسترس این اجرا نبود. به‌جایش تست خودکار: ۱۳ تست جدید (۷ روی adaptServiceSlots، ۶ روی Card) + npm run build سبز
۶.۸ جابه‌جایی سرویسی → مدت حفظ تست خودکار: فقط start فرستاده می‌شود و سرویس‌ها دست‌نخورده می‌مانند. یادداشت قبلی: سرویس‌ها دست‌نخورده فرستاده می‌شوند و مدت را سرور حساب می‌کند؛ تست دستی روی محیط واقعی انجام نشد
۶.۹ جابه‌جایی به زمان اشغال → پیام فارسی + refetch تست خودکار پیام سرور را می‌سنجد. یادداشت قبلی: مسیرش هست (۴۰۹ سرور)؛ تست دستی انجام نشد
۶.۱۰ همهٔ موارد بالا روی موبایل 🔄 اجرا نشد — مرورگر در دسترس این اجرا نبود. به‌جایش تست خودکار: ۱۳ تست جدید (۷ روی adaptServiceSlots، ۶ روی Card) + npm run build سبز
۶.۱۱ تست واحد adaptServiceSlots (پنج حالت) ۷ حالت نه پنج: بازهٔ واقعی · علامت available · ساختار بدون data · fallback بی‌end_time · خالی → [] · null[] · یک اسلات تنها

۷. مستندات

# مورد وضعیت یادداشت
۷.۱ nobat724_front/CLAUDE.md بخش «حالت‌های نوبت‌دهی» بخش «Booking Modes (slot vs service)» با جدول دو حالت، قاعدهٔ «مدت دادهٔ سرور است»، دلیل نبودِ گروه‌بندی شیفت، و گاردهای پنل کاربر
۷ یادداشت هیوریستیک شیفت در clinicpro/docs/api/appointment.md بلوک هشدار زیر Response 200 همان endpoint در clinicpro/docs/api/appointment.md

۸. بازبینی پایانی

# مورد وضعیت یادداشت
۸.۱ همهٔ ردیف‌های بالا وضعیت نهایی دارند (هیچ 🔄 و بی‌دلیل) ۴ ردیف همه مربوط به جابه‌جایی‌اند و به ۴.۸ ارجاع دارند؛ ۸ ردیف 🔄 همه «بررسی چشمی در مرورگر»؛ ۲ ردیف ⚠️ مسئلهٔ theming پروژه‌ای
۸.۲ npm run build بدون خطا npm run build سبز — همهٔ route ها کامپایل شدند
۸.۳ npm run lint بدون خطای جدید 0 errors. سه خطای موجود در TimePickerField.js، clinics/head/filter/Content.js، register/verificationPage/index.js اند — هیچ‌کدام لمس نشدند. فایل‌های من: هشدار set-state-in-effect که رفع شد؛ jsx-key های Container.js از قبل بودند (خطوط ۱۰۸+، تغییر من خط ۷۸)
۸.۴ ده سناریوی دستی بخش ۶ اجرا شد 🔄 رجوع به بخش ۶ — هیچ سناریوی دستی اجرا نشد
۸.۵ چک‌لیست UI (بخش ۵) کامل شد بخش ۵ کامل شد، شامل دو ⚠️ صادقانه برای دارک‌مود
۸.۶ clinic-pro-tauri دستی بررسی شد — قرارداد مشترک نشکسته clinic-pro-tauri/src/service/response.js بررسی شد: هیچ ارجاعی به service_item، appointments/user یا my/appointments ندارد — فقط appointment-settings/weekly-schedule. متأثر نیست
۸.۷ commit شد، سپس graphify update . چهار کامیت در nobat724_front روی برنچ feat/booking-service-mode-frontend + یک کامیت چک‌لیست/مستندات در clinicpro
۸.۸ موارد به‌تعویق‌افتاده با دلیل و تسک مقصد ثبت شدند fallbackSum (حذف پس از deploy تسک ۰۰) · بازنویسی رنگ → تسک theming · دکمهٔ جابه‌جایی → تسک UX · سناریوهای دستی → بازبینی چشمی

۹. یافته‌های این اجرا

# مورد وضعیت یادداشت
ی.۱ دو باگ واقعی در adaptServiceSlots end_time زمانِ شروعِ آخرین اسلات بود (بازه کوتاه‌تر از واقعیت) و برچسب رشتهٔ ثابت «زمان‌های خالی». هر دو رفع شد
ی.۲ ۳ تست از قبل قرمز در lib/lib.test.js روی قرارداد قدیمیِ adaptSlots ({morning, evening}) نوشته شده بودند و از زمانی که خروجی به آرایهٔ session تغییر کرد قرمز مانده بودند. با قرارداد واقعی هم‌خوان شدند؛ سوئیت از ۴ شکست به ۱ رسید
ی.۳ lib/getStateInfo.test.js یک شکست علتش پیدا شد: هاست ناشناخته به API واقعی می‌رفت. با mock کردن lib/req رفع شد. یادداشت قبلی: «host ناشناخته → بدون تطبیق» با timeout ۵ ثانیه. در baseline هم بود و به multi-domain مربوط است نه این تسک. بدهی ثبت‌شده
ی.۴ جریان رزرو هیچ پشتیبانی دارک‌مود ندارد darkMode به استراتژی variant رفت و هر دو سازوکار (.dark پنل و data-theme عمومی) را می‌پذیرد. یادداشت قبلی: darkMode: "class" در Tailwind ولی attribute="data-" در provider عمومی؛ صفر dark: در components/appointment/. مسئلهٔ پروژه‌ای، نه این تسک
ی.۵ ButtonData.js عمداً کامنت شده باز شد: دکمهٔ لغو (با پیش‌نمایش جریمه) و جابه‌جایی، فقط برای نوبتِ آیندهٔ لغونشده