The account tab read basic_insurance.id (object) but the profile returns basic_insurance_id (number), yielding [NaN], and never loaded the medical history (other). Map basic_insurance_id/supplementary_insurance_id and merge profile.other on load, and keep the profile uuid even for an empty profile so PATCH saves work. Verified round-trip (name→label, insurance, other) against the live API. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
10 KiB
اتصال دقیق همهی تبهای داشبورد کاربر به دادهی واقعی backend
پروژه
nobat724_front — سایت عمومی. frontend-only؛ همهی endpointهای لازم در backend موجودند (پروفایل، نوبتهای کاربر، پرداختها). تبهایی که backend ندارند (نظرات/پیامها) باید empty-state درست نشان دهند، نه دادهی جعلی.
زمینه
/dashboard شش تب دارد (components/dashboard/userAccount/index.js):
۱. حساب کاربری (DetailUser → اطلاعات عمومی + سوابق پزشکی: بیماریها/آلرژی/داروها/جراحی/سابقهخانوادگی/بستگان)
۲. نوبتهای من (Turns)
۳. تراکنشهای من (Transactions)
۴. نظرات من (Comments)
۵. پیامها (Messages)
۶. خروج
وضعیت فعلی بعد از رفعهای اخیر:
- نوبتها →
GET /api/v1/appointments/user(وصل شده) - تراکنشها →
GET /api/v1/my/payments(وصل شده) - حساب کاربری →
getUserProfile(userUuid)لود میشود ولی مپینگ فیلدها چند ایراد دارد (بیمه، سوابق پزشکی) و کامل round-trip نمیشود. - نظرات/پیامها → از
user.comments/user.messagesکهbuildPatientUserهمیشه[]میگذارد؛ هیچ endpoint کاربری برای این دو در backend نیست (تأییدشده: فقط/comments/{doctorUuid}و admin؛ messages اصلاً نیست).
مشکل / هدف
۱. تب حساب کاربری را درست لود و ذخیره کن: مپینگ صحیح بیمه و سوابق پزشکی (other)، استفاده از uuid پروفایل برای PATCH.
۲. تبهای نوبتها/تراکنشها را تأیید کن (شکل پاسخ، empty-state، تاریخ شمسی، مبلغ).
۳. تبهای نظرات/پیامها: چون backend ندارند، empty-state تمیز نشان بده (نه crash، نه دادهی ساختگی). در گزارش ذکر کن که نیاز به endpoint backend دارند (cross-repo آینده).
فایلهای مرتبط
| فایل | نقش |
|---|---|
components/dashboard/userAccount/detailUser/information/index.js |
لود پروفایل برای فرم اطلاعات + سوابق |
components/dashboard/userAccount/detailUser/index.js |
PATCH ذخیره (patchUserProfile(usedKeys, information?.uuid)) |
components/dashboard/userAccount/detailUser/function.js |
setNewData (تغییر سوابق پزشکی) |
helper/index.js |
removeAdditionalKeysDashboard, changeDateType |
components/dashboard/userAccount/sidebars/turns/index.js |
نوبتها (وصلشده — تأیید) |
components/dashboard/userAccount/sidebars/transactions/index.js |
تراکنشها (وصلشده — تأیید) |
components/dashboard/userAccount/sidebars/comments/index.js |
user.comments |
components/dashboard/userAccount/sidebars/messages/index.js |
user.messages |
lib/representationAdapters.js |
buildPatientUser |
clinicpro/docs/api/user-profile.md |
قرارداد پروفایل + فیلد other |
وضعیت فعلی (کد واقعی)
مپینگ غلط بیمه در information/index.js
const profile = res?.data?.data;
// ...
let changedData = { ...profile };
changedData.basic_insurance = [Number(profile?.basic_insurance?.id)]; // ❌ backend فیلد basic_insurance_id (عدد) میدهد، نه object با .id → [NaN]
changedData.prev_data = true;
changedData = changeDateType(changedData, false);
setInformation(changedData);
پاسخ پروفایل backend (از
toArray):basic_insurance_id,supplementary_insurance_id(اعداد یا null)، نهbasic_insurance.id. همچنین سوابق پزشکی درotherاست ({ disease, allergies, medications, surgeries, family_history, relatives }).
قرارداد backend (از user-profile.md و entity toArray)
{
"uuid": "...", "user_uuid": "...",
"label": "...", "family": "...", "national_code": "...", "gender": "male",
"date_of_birth": null, "fathers_name": null, "blood_type": null,
"marital_status": null, "education": null, "job": null, "address": null,
"home_phone": null, "work_phone": null,
"insurance_id": null, "basic_insurance_id": 1, "supplementary_insurance_id": null,
"other": { "disease": [...], "allergies": [...], "medications": [...], "surgeries": [...], "family_history": [...], "relatives": [...] },
"description": null, "sharing_with_user": false
}
پاسخ دوبار تودرتو است →
res.data.data.
ذخیره در detailUser/index.js
const updateData = () => {
const usedKays = removeAdditionalKeysDashboard(information);
request.patchUserProfile(usedKays, information?.uuid, Cookies.get("access_token")) // arg سوم نادیده گرفته میشود
.then(...).catch(...);
};
وظایف
۱. مپینگ درست پروفایل هنگام لود (information/index.js)
- بیمه را از فیلد درست بخوان (نه
.id):
let changedData = { ...profile };
changedData.basic_insurance = profile?.basic_insurance_id ? [profile.basic_insurance_id] : [];
changedData.supplementary_insurance = profile?.supplementary_insurance_id ? [profile.supplementary_insurance_id] : [];
changedData.other = profile?.other ?? { disease, allergies: [], medications: [], surgeries: [], family_history: [], relatives: [] };
changedData.prev_data = true;
changedData = changeDateType(changedData, false);
setInformation(changedData);
- اطمینان حاصل کن
changedData.uuid = profile.uuid(uuid پروفایل) حفظ میشود تاpatchUserProfile(..., information.uuid)درست کار کند. hasProfileDataفعلی (label || family || national_code) قابلقبول است؛ ولی چون backend حالا پروفایل خالی lazy-create میکند، پروفایل همیشهuuidدارد — برای تشخیص «پر بودن» همان منطق فیلد محتوا را نگهدار، ولیuuidرا حتی در حالت خالی هم درinformationبگذار تا PATCH کار کند:
} else {
setInformation({
uuid: profile?.uuid, // ✅ تا ذخیره ممکن باشد
prev_data: false,
other: { disease, allergies: [], medications: [], surgeries: [], family_history: [], relatives: [] },
});
}
۲. تأیید ذخیره (سوابق پزشکی → other)
removeAdditionalKeysDashboard(information)باید payloadی بسازد که شاملother(سوابق) و فیلدهای پروفایل باشد و کلیدهای اضافی frontend (مثلprev_data) را حذف کند. بررسی کن خروجی با آنچه backendhydrateمیپذیرد همخوان است (name/label,family,national_code,gender,basic_insurance,supplementary_insurance,other, ...).- بعد از PATCH موفق،
information.uuidرا از پاسخ بهروز نگهدار (اگر backend پروفایل جدید برگرداند). - arg سوم
patchUserProfile(access_token) زائد است (interceptor خودش توکن میزند) — حذفش کن یا بگذار (بیاثر). ترجیحاً امضای تابع را تمیز نگهدار.
۳. تأیید تبهای نوبتها و تراکنشها
- نوبتها (
turns/index.js): پاسخappointments/userدوبار تودرتو است →res.data.data(آرایه). تأیید کن کارتها (turns/Card.js,List.js) فیلدهای واقعی نوبت (slot_start,status,doctor,patient_name) را میخوانند؛ تاریخ شمسی باmoment-jalaali، وضعیتها به فارسی map شوند. اگر کارت فیلدهای mock قدیمی میخواند، با شکل واقعیAppointment.toArray()همخوان کن. - تراکنشها (
transactions/index.js): پاسخmy/paymentspaginated است →res.dataآرایه،res.meta.totalPages. تأیید کنCard.js/List.jsفیلدهای واقعی پرداخت (amount_rials,status,gateway,type,created_at) را میخوانند؛ مبلغ ریال→تومان با جداکنندهی فارسی، وضعیتها فارسی. - empty-state: اگر آرایه خالی بود، پیام «موردی یافت نشد» (نه crash، نه اسپینر بیپایان).
۴. تبهای نظرات و پیامها (بدون backend)
- چون endpoint کاربری وجود ندارد،
Comments/Messagesازuser.comments/user.messages(همیشه[]) میخوانند → empty-state تمیز نشان بده: «نظری ثبت نکردهاید» / «پیامی ندارید». مطمئن شو روی آرایهی خالی crash نمیکنند (user.comments?.map، گارد طول). - دادهی جعلی نساز. در گزارش پایانی ذکر کن که این دو تب برای دادهی واقعی نیاز به endpoint backend دارند (پرامپت cross-repo جداگانه در آینده).
نکات مهم
- هیچ تغییر backend در این پرامپت نیست. پروفایل/نوبت/پرداخت همه آمادهاند؛ نظرات/پیامها عمداً empty میمانند.
- double-nesting:
user-profileوappointments/user→res.data.data؛my/payments→ paginated (res.data+res.meta). هرکدام را درست مصرف کن (با pitfallهای قبلی یکدست). - uuid پروفایل برای PATCH:
information.uuidباید uuid پروفایل باشد (ازres.data.data.uuid)، نه user-uuid. - سوابق پزشکی =
other: همهی sub-tabها (allergies/medications/...) داخلinformation.otherکار میکنند و با PATCHotherذخیره میشوند. - Jalali/RTL/مبلغ: تاریخها شمسی، مبالغ ریال→تومان با جداکنندهی فارسی، timestampها یونیکس.
- تست:
npm run build؛ سپس دستی با کاربر09210651788(پروفایل خالی + ۱ نوبت): تب حساب کاربری فرم خالی قابلویرایش و ذخیره؛ تب نوبتها ۱ نوبت با تاریخ/وضعیت درست؛ تب تراکنشها empty-state؛ نظرات/پیامها empty-state بدون crash. سپس commit per-tab.