feat: implement realistic data seeding for doctors, clinics, and secretaries

- Added seed_realistic_data.php to clean existing data and populate the database with realistic entries for doctors, clinics, and secretaries.
- Created a structured approach to generate 100 doctors per city with diverse specialties and services.
- Implemented database cleanup routines to ensure a fresh start for data seeding.
- Enhanced the DoctorSecretaryRepository with improved comments for clarity.
This commit is contained in:
hamed
2026-06-15 14:18:25 +03:30
parent 68dfe613a2
commit df7a784701
15 changed files with 3024 additions and 1417 deletions
+27 -16
View File
@@ -14,30 +14,31 @@
قوانین:
| ایجادکننده | `owner_type` | `clinic_id` |
|-----------|-------------|-------------|
| خود دکتر | `'doctor'` | `null` |
| کلینیک | `'clinic'` | `<id کلینیک>` |
| ایجادکننده | `owner_type` | `clinic_id` |
| ---------- | ------------ | ------------- |
| خود دکتر | `'doctor'` | `null` |
| کلینیک | `'clinic'` | `<id کلینیک>` |
دسترسی‌ها، داشبورد، و فیلتر نوبت‌ها باید فقط در scope مربوطه اعمال شوند.
## فایل‌های مرتبط
| فایل | نقش |
|------|-----|
| `src/Secretary/Entity/DoctorSecretary.php` | entity اصلی — باید `owner_type` و `clinic_id` اضافه شود |
| `src/Secretary/Controller/SecretaryController.php` | ایجاد و لیست منشی — باید scope را تنظیم کند |
| `src/Secretary/Repository/DoctorSecretaryRepository.php` | query ها — باید scope-aware شوند |
| `src/Appointment/Controller/MyAppointmentsController.php` | فیلتر نوبت‌های منشی — باید scope-aware شود |
| `src/Dashboard/Controller/DashboardController.php` | داشبورد منشی — باید scope-aware شود |
| `src/Patient/Controller/PatientController.php` | دسترسی منشی به پرونده بیمار — باید scope-aware شود |
| `src/Auth/Controller/AuthController.php` | `/api/v1/me` context builder — باید scope را در context نشان دهد |
| `migrations/` | migration جدید برای `owner_type` + `clinic_id` |
| `docs/api/secretary.md` | مستندات API |
| فایل | نقش |
| --------------------------------------------------------- | ---------------------------------------------------------------- |
| `src/Secretary/Entity/DoctorSecretary.php` | entity اصلی — باید `owner_type` و `clinic_id` اضافه شود |
| `src/Secretary/Controller/SecretaryController.php` | ایجاد و لیست منشی — باید scope را تنظیم کند |
| `src/Secretary/Repository/DoctorSecretaryRepository.php` | query ها — باید scope-aware شوند |
| `src/Appointment/Controller/MyAppointmentsController.php` | فیلتر نوبت‌های منشی — باید scope-aware شود |
| `src/Dashboard/Controller/DashboardController.php` | داشبورد منشی — باید scope-aware شود |
| `src/Patient/Controller/PatientController.php` | دسترسی منشی به پرونده بیمار — باید scope-aware شود |
| `src/Auth/Controller/AuthController.php` | `/api/v1/me` context builder — باید scope را در context نشان دهد |
| `migrations/` | migration جدید برای `owner_type` + `clinic_id` |
| `docs/api/secretary.md` | مستندات API |
## وضعیت فعلی
### Entity (بدون scope)
```php
// src/Secretary/Entity/DoctorSecretary.php
// هیچ فیلد owner_type یا clinic_id وجود ندارد
@@ -54,6 +55,7 @@ class DoctorSecretary
```
### Repository — scope-blind
```php
public function findActiveBySecretary(User $user): ?DoctorSecretary
{
@@ -63,6 +65,7 @@ public function findActiveBySecretary(User $user): ?DoctorSecretary
```
### Controller — ایجاد بدون scope
```php
// create() در SecretaryController
// هیچ owner_type یا clinic_id ست نمی‌شود
@@ -70,6 +73,7 @@ $secretary = new DoctorSecretary($doctor, $secretaryUser);
```
### Auth context builder — scope-blind
```php
// AuthController::buildContexts()
foreach ($this->secretaryRepo->findAllActiveBySecretary($user) as $rel) {
@@ -86,6 +90,7 @@ foreach ($this->secretaryRepo->findAllActiveBySecretary($user) as $rel) {
```
### Appointment فیلتر — فقط یک رابطه
```php
// MyAppointmentsController — منشی فقط به نوبت‌های یک دکتر دسترسی دارد
} elseif (in_array('ROLE_SECRETARY', $roles, true)) {
@@ -128,6 +133,7 @@ public function getClinic(): ?Clinic { return $this->clinic; }
```
در `toArray()` هم اضافه شود:
```php
'owner_type' => $this->ownerType,
'clinic_uuid' => $this->clinic?->getUuid(),
@@ -136,6 +142,7 @@ public function getClinic(): ?Clinic { return $this->clinic; }
### ۲. Migration
بعد از تغییر Entity:
```bash
ddev exec php bin/console doctrine:migrations:diff --no-interaction
ddev exec php bin/console doctrine:migrations:migrate --no-interaction
@@ -206,7 +213,8 @@ public function findDoctorsBySecretaryInClinic(User $user, Clinic $clinic): arra
}
```
همچنین `findByClinic` باید فقط منشیان با `owner_type='clinic'` را برگرداند:
همچنین `findByClinic` باید فقط منشی ها با `owner_type='clinic'` را برگرداند:
```php
public function findByClinic(Clinic $clinic): array
{
@@ -225,6 +233,7 @@ public function findByClinic(Clinic $clinic): array
### ۴. SecretaryController: ایجاد با scope
در `create()`:
- اگر `currentUser` دارای `ROLE_CLINIC` بود → `ownerType = 'clinic'`، `clinic = clinicRepo->findByUser($currentUser)`
- اگر `ROLE_DOCTOR` بود → `ownerType = 'doctor'`، `clinic = null`
@@ -238,6 +247,7 @@ if ($currentUser->hasRole('ROLE_CLINIC')) {
```
همچنین `canManageDoctor()` باید scope را چک کند:
- `ROLE_DOCTOR` فقط می‌تواند روابط `owner_type='doctor'` را مدیریت کند
- `ROLE_CLINIC` فقط می‌تواند روابط `owner_type='clinic'` متعلق به کلینیک خودش را مدیریت کند
@@ -278,6 +288,7 @@ foreach ($this->secretaryRepo->findAllActiveBySecretary($user) as $rel) {
### ۶. Appointment و Dashboard: scope-aware
در `MyAppointmentsController` و `DashboardController` به جای `findActiveBySecretary`:
- اگر `db_uuid` در JWT به یک کلینیک اشاره دارد → همه دکترهای کلینیک که این منشی به آن‌ها متصل است
- اگر به یک دکتر اشاره دارد → فقط همان دکتر با `owner_type='doctor'`