feat(patient): complete "اطلاعات پرونده" demographic form
Backend:
- Add profile columns field_of_study, province_id, city_id, postal_code,
referral_source (UserProfile + migration).
- Extend PATCH /api/v1/patient/{uuid} to persist all demographic fields
and return them in the patient profile payload.
- Support editable mobile (login identifier): validation, uniqueness,
User.setMobileNumber, new ERR_PROFILE_002.
- Update docs/api/patient.md.
Frontend:
- New reusable Input, Field, and PatientRecordInfoForm (RHF + Zod).
- usePatient/useUpdatePatient hooks and patientForm mapping helpers.
- Extend the existing "info" tab in MyPatientsPage to the full field set
via the shared form (province/city/insurance options, Jalali date).
Tests: Patient entity + PATCH integration (PHPUnit); form, hooks, and
mapping helpers (Vitest).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -55,12 +55,27 @@ class UserProfile
|
||||
#[ORM\Column(type: 'string', length: 100, nullable: true)]
|
||||
private ?string $education = null;
|
||||
|
||||
#[ORM\Column(name: 'field_of_study', type: 'string', length: 100, nullable: true)]
|
||||
private ?string $fieldOfStudy = null;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 100, nullable: true)]
|
||||
private ?string $job = null;
|
||||
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
private ?string $address = null;
|
||||
|
||||
#[ORM\Column(name: 'province_id', type: 'integer', nullable: true)]
|
||||
private ?int $provinceId = null;
|
||||
|
||||
#[ORM\Column(name: 'city_id', type: 'integer', nullable: true)]
|
||||
private ?int $cityId = null;
|
||||
|
||||
#[ORM\Column(name: 'postal_code', type: 'string', length: 20, nullable: true)]
|
||||
private ?string $postalCode = null;
|
||||
|
||||
#[ORM\Column(name: 'referral_source', type: 'string', length: 100, nullable: true)]
|
||||
private ?string $referralSource = null;
|
||||
|
||||
#[ORM\Column(name: 'home_phone', type: 'string', length: 30, nullable: true)]
|
||||
private ?string $homePhone = null;
|
||||
|
||||
@@ -116,8 +131,13 @@ class UserProfile
|
||||
public function getBloodType(): ?string { return $this->bloodType; }
|
||||
public function getMaritalStatus(): ?string { return $this->maritalStatus; }
|
||||
public function getEducation(): ?string { return $this->education; }
|
||||
public function getFieldOfStudy(): ?string { return $this->fieldOfStudy; }
|
||||
public function getJob(): ?string { return $this->job; }
|
||||
public function getAddress(): ?string { return $this->address; }
|
||||
public function getProvinceId(): ?int { return $this->provinceId; }
|
||||
public function getCityId(): ?int { return $this->cityId; }
|
||||
public function getPostalCode(): ?string { return $this->postalCode; }
|
||||
public function getReferralSource(): ?string { return $this->referralSource; }
|
||||
public function getHomePhone(): ?string { return $this->homePhone; }
|
||||
public function getWorkPhone(): ?string { return $this->workPhone; }
|
||||
public function getInsuranceId(): ?string { return $this->insuranceId; }
|
||||
@@ -140,8 +160,13 @@ class UserProfile
|
||||
public function setBloodType(?string $v): self { $this->bloodType = $v; $this->touch(); return $this; }
|
||||
public function setMaritalStatus(?string $v): self { $this->maritalStatus = $v; $this->touch(); return $this; }
|
||||
public function setEducation(?string $v): self { $this->education = $v; $this->touch(); return $this; }
|
||||
public function setFieldOfStudy(?string $v): self { $this->fieldOfStudy = $v; $this->touch(); return $this; }
|
||||
public function setJob(?string $v): self { $this->job = $v; $this->touch(); return $this; }
|
||||
public function setAddress(?string $v): self { $this->address = $v; $this->touch(); return $this; }
|
||||
public function setProvinceId(?int $v): self { $this->provinceId = $v; $this->touch(); return $this; }
|
||||
public function setCityId(?int $v): self { $this->cityId = $v; $this->touch(); return $this; }
|
||||
public function setPostalCode(?string $v): self { $this->postalCode = $v; $this->touch(); return $this; }
|
||||
public function setReferralSource(?string $v): self { $this->referralSource = $v; $this->touch(); return $this; }
|
||||
public function setHomePhone(?string $v): self { $this->homePhone = $v; $this->touch(); return $this; }
|
||||
public function setWorkPhone(?string $v): self { $this->workPhone = $v; $this->touch(); return $this; }
|
||||
public function setInsuranceId(?string $v): self { $this->insuranceId = $v; $this->touch(); return $this; }
|
||||
@@ -170,8 +195,13 @@ class UserProfile
|
||||
'blood_type' => $this->bloodType,
|
||||
'marital_status' => $this->maritalStatus,
|
||||
'education' => $this->education,
|
||||
'field_of_study' => $this->fieldOfStudy,
|
||||
'job' => $this->job,
|
||||
'address' => $this->address,
|
||||
'province_id' => $this->provinceId,
|
||||
'city_id' => $this->cityId,
|
||||
'postal_code' => $this->postalCode,
|
||||
'referral_source' => $this->referralSource,
|
||||
'home_phone' => $this->homePhone,
|
||||
'work_phone' => $this->workPhone,
|
||||
'insurance_id' => $this->insuranceId,
|
||||
|
||||
Reference in New Issue
Block a user