diff --git a/.claude/prompt/profile-birthday-jalali-persist.md b/.claude/prompt/profile-birthday-jalali-persist.md new file mode 100644 index 00000000..2ee416b2 --- /dev/null +++ b/.claude/prompt/profile-birthday-jalali-persist.md @@ -0,0 +1,78 @@ +# ذخیره و نمایش صحیح تاریخ تولد در پروفایل (Unix) + +## پروژه + +`clinicpro` (Backend — منبع حقیقت). + +> **Cross-repo:** سایت عمومی `nobat724_front` تاریخ تولد را به‌صورت **Unix timestamp** با کلید `birthday` می‌فرستد (تبدیل جلالی↔Unix کاملاً سمت فرانت با `changeDateType` انجام می‌شود) و انتظار دارد همان Unix را برای نمایش بگیرد. پرامپت همتای فرانت: `nobat724_front/.claude/prompt/profile-birthday-send-direction-fix.md`. این پرامپت **اول** اجرا شود. + +## زمینه + +در فرم اطلاعات کاربری (`/dashboard`)، فیلد «تاریخ تولد» مقدارش با کلید `birthday` به‌صورت **Unix timestamp** ارسال می‌شود (فرانت با `moment(jalali,"jYYYY/jMM/jDD").unix()` تبدیل می‌کند). اما در `UserProfileController::hydrate` این مقدار **عمداً نادیده گرفته و `null` ذخیره می‌شود** (یک TODO نیمه‌کاره). در نتیجه تاریخ تولد هرگز ذخیره نمی‌شود؛ و `toArray` کلید `birthday` را اصلاً برنمی‌گرداند (فقط `date_of_birth`)، پس فرانت چیزی برای نمایش ندارد. + +## مشکل / هدف + +۱. ورودی: `birthday` (Unix integer) را در ستون `date_of_birth` ذخیره کن (به‌جای `null`). +۲. خروجی: `toArray` کلید `birthday` = همان Unix (`date_of_birth`) را برگرداند تا فرانت با `changeDateType` به جلالی نمایش دهد. + +## فایل‌های مرتبط + +| فایل | نقش | +|------|-----| +| `src/UserProfile/Controller/UserProfileController.php` | `hydrate` — ذخیره `birthday`(Unix) در `date_of_birth` | +| `src/UserProfile/Entity/UserProfile.php` | `toArray` — افزودن کلید `birthday` (= Unix `date_of_birth`) | + +## وضعیت فعلی (کد واقعی) + +`hydrate` — مقدار دور ریخته می‌شود: +```php +// birthday: accept Jalali string "1370-05-15" stored as-is converted to Unix +if (array_key_exists('birthday', $data) && $data['birthday'] !== null) { + // Will be replaced with JalaliDateService in Task 16 + $profile->setDateOfBirth(null); // ❌ هرگز ذخیره نمی‌شود +} +if (array_key_exists('date_of_birth', $data)) $profile->setDateOfBirth($data['date_of_birth']); +``` + +`UserProfile`: +```php +#[ORM\Column(name: 'date_of_birth', type: 'integer', nullable: true)] +private ?int $dateOfBirth = null; +// toArray(): +'date_of_birth' => $this->dateOfBirth, // کلید birthday وجود ندارد +``` + +> فرانت `birthday` را Unix می‌فرستد (مثلاً `-405...` یا یک integer مثبت/منفی برای تاریخ‌های قبل/بعد ۱۹۷۰). ممکن است به‌صورت string-encoded integer هم بیاید؛ با `(int)` ایمن تبدیل کن. + +## وظایف + +### ۱. ذخیره `birthday` (Unix) در `hydrate` +بلوک نیمه‌کاره را با ذخیره‌ی واقعی جایگزین کن: +```php +if (array_key_exists('birthday', $data)) { + $b = $data['birthday']; + $profile->setDateOfBirth(($b === null || $b === '') ? null : (int) $b); +} +if (array_key_exists('date_of_birth', $data)) { + $profile->setDateOfBirth($data['date_of_birth'] === null ? null : (int) $data['date_of_birth']); +} +``` + +### ۲. خروجی `birthday` در `toArray` +در `UserProfile::toArray`، کنار `date_of_birth`، کلید `birthday` را هم برگردان (همان مقدار Unix): +```php +'date_of_birth' => $this->dateOfBirth, +'birthday' => $this->dateOfBirth, +``` +> هر دو کلید همان Unix‌اند؛ `birthday` برای مصرف مستقیم فرانت (که `moment.unix(birthday)` می‌زند) و `date_of_birth` برای سازگاری عقب‌رو. + +### ۳. مستندسازی +اگر سند پروفایلی در `docs/api/` هست، فیلد `birthday` (Unix در ورودی و خروجی) را اضافه کن. اگر نیست، نیازی به ساخت فایل جدید نیست. + +## نکات مهم + +- **هیچ تبدیل جلالی در بک‌اند لازم نیست** — `JalaliDateService` استفاده نمی‌شود؛ تبدیل کاملاً سمت فرانت است. ساده نگه‌دار. +- `birthday` ممکن است integer یا string-encoded-integer باشد → `(int)` ایمن. +- migration لازم نیست (`date_of_birth` integer از قبل هست). +- پاسخ‌ها از `BaseController`. +- تست: `PATCH /api/v1/user-profile/{uuid}` با `{"birthday": 12345678}` → در DB `date_of_birth = 12345678`؛ سپس `GET` → هم `birthday` و هم `date_of_birth` برابر `12345678`. round-trip سالم. diff --git a/assets/admin/pages/UserDetailPage.tsx b/assets/admin/pages/UserDetailPage.tsx index c0843832..69515560 100644 --- a/assets/admin/pages/UserDetailPage.tsx +++ b/assets/admin/pages/UserDetailPage.tsx @@ -36,7 +36,7 @@ interface UserProfileData { uuid: string; national_code: string | null; gender: string | null; - date_of_birth: number | null; + birthday: number | null; blood_type: string | null; marital_status: string | null; education: string | null; @@ -539,7 +539,7 @@ export default function UserDetailPage() { - + diff --git a/src/UserProfile/Controller/UserProfileController.php b/src/UserProfile/Controller/UserProfileController.php index 93753a8a..9c07b9a4 100644 --- a/src/UserProfile/Controller/UserProfileController.php +++ b/src/UserProfile/Controller/UserProfileController.php @@ -155,13 +155,16 @@ class UserProfileController extends BaseController ); if (array_key_exists('sharing_with_user', $data)) $profile->setSharingWithUser((bool) $data['sharing_with_user']); - // birthday: accept Jalali string "1370-05-15" stored as-is converted to Unix - if (array_key_exists('birthday', $data) && $data['birthday'] !== null) { - // Store as string-encoded Unix; for now keep as null if conversion unavailable - // Will be replaced with JalaliDateService in Task 16 - $profile->setDateOfBirth(null); + // birthday / date_of_birth: Unix timestamp (frontend converts Jalali↔Unix + // via changeDateType). `birthday` takes priority; `date_of_birth` is only a + // fallback so a stray `date_of_birth: null` in the payload can't wipe it. + if (array_key_exists('birthday', $data)) { + $b = $data['birthday']; + $profile->setDateOfBirth(($b === null || $b === '') ? null : (int) $b); + } elseif (array_key_exists('date_of_birth', $data)) { + $b = $data['date_of_birth']; + $profile->setDateOfBirth(($b === null || $b === '') ? null : (int) $b); } - if (array_key_exists('date_of_birth', $data)) $profile->setDateOfBirth($data['date_of_birth']); // Insurance references (category IDs) if (array_key_exists('basic_insurance', $data)) { diff --git a/src/UserProfile/Entity/UserProfile.php b/src/UserProfile/Entity/UserProfile.php index 1ef8c4d9..97d7aba4 100644 --- a/src/UserProfile/Entity/UserProfile.php +++ b/src/UserProfile/Entity/UserProfile.php @@ -160,7 +160,7 @@ class UserProfile 'national_code' => $this->nationalCode, 'national_code_approved' => $this->nationalCodeApproved, 'gender' => $this->gender, - 'date_of_birth' => $this->dateOfBirth, + 'birthday' => $this->dateOfBirth, 'blood_type' => $this->bloodType, 'marital_status' => $this->maritalStatus, 'education' => $this->education,