173 lines
4.7 KiB
Markdown
173 lines
4.7 KiB
Markdown
# معماری — تسک ۱۰: مدیریت پرسنل (Staff)
|
|
|
|
## ساختار فایلها
|
|
|
|
```
|
|
src/Staff/
|
|
├── Controller/
|
|
│ └── StaffController.php
|
|
├── Entity/
|
|
│ └── ClinicStaff.php
|
|
├── Repository/
|
|
│ └── ClinicStaffRepository.php
|
|
└── Service/
|
|
└── StaffService.php
|
|
```
|
|
|
|
## Entity: ClinicStaff
|
|
|
|
```php
|
|
<?php
|
|
|
|
namespace App\Staff\Entity;
|
|
|
|
use Doctrine\ORM\Mapping as ORM;
|
|
use Symfony\Component\Uid\Uuid;
|
|
|
|
#[ORM\Entity(repositoryClass: \App\Staff\Repository\ClinicStaffRepository::class)]
|
|
#[ORM\Table(name: 'clinic_staff')]
|
|
#[ORM\Index(columns: ['entity_type', 'entity_id', 'active'], name: 'idx_clinic_staff_entity')]
|
|
class ClinicStaff
|
|
{
|
|
#[ORM\Id]
|
|
#[ORM\GeneratedValue]
|
|
#[ORM\Column(type: 'integer')]
|
|
private ?int $id = null;
|
|
|
|
#[ORM\Column(type: 'string', length: 36, unique: true)]
|
|
private string $uuid;
|
|
|
|
// polymorphic — 'doctor' یا 'clinic'
|
|
#[ORM\Column(type: 'string', length: 10)]
|
|
private string $entityType;
|
|
|
|
#[ORM\Column(type: 'integer')]
|
|
private int $entityId;
|
|
|
|
#[ORM\Column(type: 'string', length: 200)]
|
|
private string $fullName;
|
|
|
|
#[ORM\Column(type: 'string', length: 20, nullable: true)]
|
|
private ?string $phone = null;
|
|
|
|
#[ORM\Column(type: 'string', length: 100, nullable: true)]
|
|
private ?string $jobTitle = null;
|
|
|
|
#[ORM\Column(type: 'text', nullable: true)]
|
|
private ?string $address = null;
|
|
|
|
#[ORM\Column(type: 'string', length: 10, nullable: true)]
|
|
private ?string $nationalCode = null;
|
|
|
|
#[ORM\Column(type: 'boolean')]
|
|
private bool $active = true;
|
|
|
|
#[ORM\Column(type: 'integer')]
|
|
private int $createdAt;
|
|
|
|
#[ORM\Column(type: 'integer')]
|
|
private int $updatedAt;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->uuid = (string) Uuid::v4();
|
|
$this->createdAt = time();
|
|
$this->updatedAt = time();
|
|
}
|
|
|
|
// getters/setters ...
|
|
}
|
|
```
|
|
|
|
## Controller: StaffController
|
|
|
|
```php
|
|
<?php
|
|
|
|
namespace App\Staff\Controller;
|
|
|
|
use App\Shared\Controller\BaseController;
|
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\Routing\Attribute\Route;
|
|
|
|
#[Route('/api/v1')]
|
|
class StaffController extends BaseController
|
|
{
|
|
#[Route('/staff', methods: ['GET'])]
|
|
public function list(): JsonResponse
|
|
{
|
|
// 1. از JWT: entity_type و entity_id (db_key + db_uuid) را بگیر
|
|
// 2. StaffRepository::findByEntity($entityType, $entityId) صدا بزن
|
|
// 3. return $this->success($items);
|
|
}
|
|
|
|
#[Route('/staff', methods: ['POST'])]
|
|
public function create(Request $request): JsonResponse
|
|
{
|
|
// 1. validate: full_name اجباری
|
|
// 2. ClinicStaff جدید با entityType/entityId از JWT بساز
|
|
// 3. persist و flush
|
|
// 4. return $this->success($staff->toArray());
|
|
}
|
|
|
|
#[Route('/staff/{uuid}', methods: ['PATCH'])]
|
|
public function update(string $uuid, Request $request): JsonResponse
|
|
{
|
|
// 1. find by uuid → 404 اگر نبود
|
|
// 2. بررسی مالکیت: staff->entityType/entityId == JWT claim → 403 اگر نبود
|
|
// 3. ویرایش فیلدهای موجود در body
|
|
// 4. return $this->success($staff->toArray());
|
|
}
|
|
|
|
#[Route('/staff/{uuid}/toggle', methods: ['PATCH'])]
|
|
public function toggle(string $uuid): JsonResponse
|
|
{
|
|
// 1. find → ownership check
|
|
// 2. active = !active
|
|
// 3. return $this->success(['active' => $staff->isActive()]);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Service: StaffService
|
|
|
|
```php
|
|
<?php
|
|
|
|
namespace App\Staff\Service;
|
|
|
|
class StaffService
|
|
{
|
|
public function toArray(ClinicStaff $staff): array
|
|
{
|
|
return [
|
|
'uuid' => $staff->getUuid(),
|
|
'full_name' => $staff->getFullName(),
|
|
'phone' => $staff->getPhone(),
|
|
'job_title' => $staff->getJobTitle(),
|
|
'address' => $staff->getAddress(),
|
|
'national_code' => $staff->getNationalCode(),
|
|
'active' => $staff->isActive(),
|
|
'created_at' => $staff->getCreatedAt(),
|
|
];
|
|
}
|
|
}
|
|
```
|
|
|
|
## نحوه خواندن entity_type / entity_id از JWT
|
|
|
|
```php
|
|
// در BaseController یا trait:
|
|
// JWT payload شامل: db_key ('doctor'/'clinic') و db_uuid (uuid entity)
|
|
// باید uuid را به id تبدیل کنیم:
|
|
$entityType = $this->getUser()->getDbKey(); // 'doctor' یا 'clinic'
|
|
$entityUuid = $this->getUser()->getDbUuid();
|
|
// سپس از Repository مربوطه id واقعی را بگیریم
|
|
```
|
|
|
|
## وابستگیهای آینده
|
|
|
|
- `src/ClinicService/Entity/ServiceItem.php` → `staff_id FK → clinic_staff.id`
|
|
- `src/Patient/Entity/SessionService.php` → `staff_id FK → clinic_staff.id`
|