Files
clinicpro/.claude/prompt/profile-birthday-jalali-persist.md
T
hamedandClaude Opus 4.8 b60dbdadba fix(profile): persist & expose birthday as a single Unix field
Birthday was never saved (hydrate forced null) and not returned in a form the
clients use. Now:
- hydrate stores the incoming `birthday` (Unix) into date_of_birth; `birthday`
  takes priority over a stray `date_of_birth: null` in the same payload so it
  can't be wiped.
- toArray exposes a single `birthday` (Unix) key — drop the duplicate
  `date_of_birth` output to avoid overlap.
- admin UserDetailPage reads profile.birthday (formatDate renders Jalali).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:42:31 +03:30

79 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ذخیره و نمایش صحیح تاریخ تولد در پروفایل (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 سالم.