# Secretary API

> **Prefix:** `/api/v1/secretary`, `/api/v1/secretaries`

## مدل Scope

هر رابطه منشی-پزشک دارای یک **scope** است که از تداخل بین محیط‌های مختلف جلوگیری می‌کند:

| Scope    | `owner_type` | تعریف‌کننده | دسترسی                          |
| -------- | ------------ | ----------- | ------------------------------- |
| مطب شخصی | `doctor`     | خود پزشک    | فقط نوبت‌ها و داده‌های مطب شخصی |
| کلینیک   | `clinic`     | مدیر کلینیک | فقط نوبت‌ها و داده‌های کلینیک   |

- یک منشی می‌تواند هم در مطب شخصی یک دکتر و هم در کلینیک همان دکتر فعال باشد (دو ردیف مجزا)
- منشی کلینیک می‌تواند به چند دکتر در همان کلینیک متصل باشد
- scope فعال در runtime از جدول `user_active_context` (db_uuid) خوانده می‌شود

Secretaries are linked to a doctor and have granular permissions controlling what they can do on behalf of the doctor.

---

## POST `/api/v1/secretary`

Create a secretary for a doctor.

**Permission:** `ROLE_DOCTOR` (must own the doctor — creates `owner_type='doctor'`) | `ROLE_CLINIC` (must have the doctor in its clinic — creates `owner_type='clinic'`) | `ROLE_ADMIN`

### Request Body (`application/json`)

```json
{
    "doctor_uuid": "550e8400-...",
    "mobile_number": "09123456789",
    "password": "secretaryPass123",
    "permissions": {
        "version": 1,
        "resources": {
            "appointments": {
                "view": true,
                "create": true,
                "cancel": false,
                "update_status": true
            },
            "addresses": {
                "view": true,
                "create": false,
                "update": false,
                "delete": false
            },
            "clinic_info": { "view": true, "update": false },
            "insurances": {
                "view": true,
                "create": false,
                "update": false,
                "delete": false
            }
        }
    }
}
```

| Field           | Type          | Required | Description                                  |
| --------------- | ------------- | -------- | -------------------------------------------- |
| `doctor_uuid`   | string (UUID) | ✅       | Doctor to assign secretary to                |
| `mobile_number` | string        | ✅       | Secretary's login mobile                     |
| `password`      | string        | ❌       | Initial password (auto-generated if omitted) |
| `permissions`   | object        | ❌       | Permission set (see structure below)         |

**Permissions Structure:**

```json
{
    "version": 1,
    "resources": {
        "appointments": {
            "view": true, // Can view appointments list
            "create": true, // Can book appointments
            "cancel": false, // Can cancel appointments
            "update_status": true // Can mark as completed/no_show
        },
        "addresses": {
            "view": true,
            "create": false,
            "update": false,
            "delete": false
        },
        "clinic_info": {
            "view": true,
            "update": false
        },
        "insurances": {
            "view": true,
            "create": false,
            "update": false,
            "delete": false
        }
    }
}
```

### Response `201`

```json
{
  "success": true,
  "data": {
    "uuid": "sec-uuid-...",
    "user_name": "علی محمدی",
    "mobile_number": "09123456789",
    "doctor_name": "دکتر احمد رضایی",
    "doctor_uuid": "...",
    "owner_type": "doctor",
    "clinic_uuid": null,
    "is_active": true,
    "permissions": { ... },
    "created_at": 1717000000
  }
}
```

**مقادیر `owner_type`:**
| مقدار | معنی |
|-------|------|
| `doctor` | منشی توسط خود دکتر تعریف شده — فقط مطب شخصی |
| `clinic` | منشی توسط مدیر کلینیک تعریف شده — فقط کلینیک |

**پیامک خوش‌آمد:** پس از ساخت موفق منشی، یک پیامک به‌صورت async به `mobile_number` منشی ارسال می‌شود (تگ `secretary`). متن از قالب ویرایش‌پذیر DB می‌آید (fallback به پیش‌فرض) و placeholderهای `{owner}` (نام دکتر یا کلینیک بسته به `owner_type`)، `{username}` (موبایل منشی) و `{link}` (لینک ورود) را جایگزین می‌کند. ویرایش متن از `PATCH /api/v1/admin/sms/messages/secretary` — رجوع به [sms.md](sms.md).

### Errors

| Code                | HTTP | Description                                 |
| ------------------- | ---- | ------------------------------------------- |
| `ERR_AUTH_001`      | 401  | Missing token                               |
| `ERR_AUTH_006`      | 403  | Not the doctor owner / clinic owner / admin |
| `ERR_NOT_FOUND_001` | 404  | Doctor not found                            |
| `ERR_CONFLICT_001`  | 409  | Secretary already added for this doctor     |
| `ERR_SECRETARY_001` | 422  | Plan limit for secretaries reached          |

---

## GET `/api/v1/secretary/{uuid}`

Get secretary detail.

**Permission:** `AUTH` — must be the linked doctor or `ROLE_ADMIN`

### Path Parameters

| Param  | Type          | Description    |
| ------ | ------------- | -------------- |
| `uuid` | string (UUID) | Secretary UUID |

### Response `200`

```json
{
  "success": true,
  "data": {
    "uuid": "...",
    "mobile_number": "09123456789",
    "active": true,
    "permissions": { ... },
    "doctor": { "uuid": "...", "title": "دکتر علی احمدی" },
    "created_at": 1717000000
  }
}
```

### Errors

| Code                | HTTP | Description         |
| ------------------- | ---- | ------------------- |
| `ERR_AUTH_001`      | 401  | Missing token       |
| `ERR_FORBIDDEN_001` | 403  | Not authorized      |
| `ERR_NOT_FOUND_001` | 404  | Secretary not found |

---

## PATCH `/api/v1/secretary/{uuid}`

Update secretary active status or permissions.

**Permission:** `ROLE_DOCTOR` — must be the linked doctor

### Request Body (`application/json`)

```json
{
    "active": false,
    "permissions": {
        "version": 1,
        "resources": {
            "appointments": {
                "view": true,
                "create": false,
                "cancel": false,
                "update_status": false
            }
        }
    }
}
```

| Field         | Type    | Required | Description              |
| ------------- | ------- | -------- | ------------------------ |
| `active`      | boolean | ❌       | Enable/disable secretary |
| `permissions` | object  | ❌       | New permissions object   |

### Response `200`

Updated secretary object.

### Errors

| Code                | HTTP | Description           |
| ------------------- | ---- | --------------------- |
| `ERR_AUTH_001`      | 401  | Missing token         |
| `ERR_FORBIDDEN_001` | 403  | Not the linked doctor |
| `ERR_NOT_FOUND_001` | 404  | Secretary not found   |

---

## DELETE `/api/v1/secretary/{uuid}`

Delete a secretary.

**Permission:** `ROLE_DOCTOR` — must be the linked doctor

### Response `200`

```json
{ "success": true, "data": { "message": "منشی حذف شد" } }
```

### Errors

| Code                | HTTP | Description           |
| ------------------- | ---- | --------------------- |
| `ERR_AUTH_001`      | 401  | Missing token         |
| `ERR_FORBIDDEN_001` | 403  | Not the linked doctor |
| `ERR_NOT_FOUND_001` | 404  | Secretary not found   |

---

## GET `/api/v1/secretaries/{doctorUuid}`

Get all secretaries for a specific doctor.

**Permission:** `ROLE_DOCTOR` (must own doctor) | `ROLE_CLINIC` (must have doctor in clinic) | `ROLE_ADMIN`

### Path Parameters

| Param        | Type          | Description |
| ------------ | ------------- | ----------- |
| `doctorUuid` | string (UUID) | Doctor UUID |

### Response `200`

```json
{
  "success": true,
  "data": [
    {
      "uuid": "...",
      "user_name": "علی محمدی",
      "mobile_number": "09...",
      "doctor_name": "دکتر احمد رضایی",
      "doctor_uuid": "...",
      "is_active": true,
      "permissions": { ... },
      "created_at": 1717000000
    }
  ]
}
```

### Errors

| Code                | HTTP | Description      |
| ------------------- | ---- | ---------------- |
| `ERR_AUTH_001`      | 401  | Missing token    |
| `ERR_FORBIDDEN_001` | 403  | Not authorized   |
| `ERR_NOT_FOUND_001` | 404  | Doctor not found |

---

## GET `/api/v1/secretaries/clinic/{clinicUuid}`

Get all secretaries across **all doctors** of a clinic.

**Permission:** `ROLE_CLINIC` (must own clinic) | `ROLE_ADMIN`

### Path Parameters

| Param        | Type          | Description |
| ------------ | ------------- | ----------- |
| `clinicUuid` | string (UUID) | Clinic UUID |

### Response `200`

```json
{
  "success": true,
  "data": [
    {
      "uuid": "...",
      "user_name": "علی محمدی",
      "mobile_number": "09...",
      "doctor_name": "دکتر احمد رضایی",
      "doctor_uuid": "...",
      "is_active": true,
      "permissions": { ... },
      "created_at": 1717000000
    }
  ]
}
```

### Notes

- این endpoint فقط منشی های را برمی‌گرداند که با `owner_type='clinic'` تعریف شده‌اند
- منشی های که خود دکتر (با `owner_type='doctor'`) تعریف کرده از این لیست مخفی هستند
- یک منشی می‌تواند به چند دکتر در همان کلینیک متصل باشد — در لیست چندبار ظاهر می‌شود (یک ردیف به ازای هر دکتر)

### Errors

| Code                | HTTP | Description      |
| ------------------- | ---- | ---------------- |
| `ERR_AUTH_001`      | 401  | Missing token    |
| `ERR_FORBIDDEN_001` | 403  | Not clinic owner |
| `ERR_NOT_FOUND_001` | 404  | Clinic not found |

---

## محدودیت پنل اشتراکی

تعداد منشی‌های مجاز بر اساس پنل فعال doctor تعیین می‌شود:

| پنل                | حداکثر منشی |
| ------------------ | ----------- |
| Free (بدون اشتراک) | ۱           |
| Basic              | ۳           |
| Professional       | ۱۰          |

اگر تعداد منشی‌های فعال به حد مجاز رسیده باشد، ایجاد منشی جدید خطای زیر را برمی‌گرداند:

```json
{
    "success": false,
    "errors": [
        {
            "code": "ERR_SECRETARY_001",
            "message": "پلن فعلی اجازه منشی بیشتر را نمی‌دهد"
        }
    ]
}
```

برای افزایش محدودیت، باید پنل را از `POST /api/v1/subscription/trial` (تریال) یا `POST /api/v1/subscription-payment` (پرداخت) ارتقاء داد.
