# معماری — تسک ۱۲: تکمیل منشی

## فایل‌های موجود که تغییر می‌کنند

```
src/Secretary/Controller/SecretaryController.php   ← inject SubscriptionService + limit check
src/Shared/Constant/ErrorCodes.php                ← ثابت جدید ERR_SECRETARY_LIMIT_REACHED
assets/admin/pages/SecretariesPage.tsx             ← Modal permissions checkbox matrix
```

## تغییرات Backend

### SecretaryController — constructor injection
```php
public function __construct(
    private readonly EntityManagerInterface      $em,
    private readonly DoctorSecretaryRepository  $secretaryRepo,
    private readonly DoctorRepository           $doctorRepo,
    private readonly SubscriptionService        $subscriptionService,  // ← جدید
) {}
```

### SecretaryRepository — متد جدید countActive
```php
// src/Secretary/Repository/DoctorSecretaryRepository.php
public function countActive(int $doctorId): int
{
    return (int) $this->createQueryBuilder('s')
        ->select('COUNT(s.id)')
        ->where('s.doctor = :doctor')
        ->andWhere('s.active = true')
        ->setParameter('doctor', $doctorId)
        ->getQuery()
        ->getSingleScalarResult();
}
```

## تغییرات Frontend

### SecretariesPage.tsx — ساختار Modal permissions

```tsx
// types جدید
interface PermissionsMatrix {
  version: number;
  resources: {
    appointments?: { view: boolean; create: boolean; cancel: boolean; update_status: boolean };
    addresses?:    { view: boolean; create: boolean; update: boolean; delete: boolean };
    clinic_info?:  { view: boolean; update: boolean };
    insurances?:   { view: boolean; create: boolean; update: boolean; delete: boolean };
  };
}

// component
function PermissionsEditor({ value, onChange }: {
  value: PermissionsMatrix;
  onChange: (v: PermissionsMatrix) => void;
}) {
  // رندر جدول checkbox
  // هر ردیف: نام بخش + چک‌باکس‌های action
  // onChange ساختار را update می‌کند
}
```

### نکته: مدیریت خطای 403 در فرم ایجاد منشی

```tsx
// وقتی POST /api/v1/secretary با 403 برمی‌گردد:
// نمایش toast: "سقف منشی پنل رسیده است. برای افزایش به صفحه اشتراک بروید"
// دکمه "ارتقاء پنل" → navigate('/admin/subscription')
```
