# Crop Simulation API Reference

این فایل توضیح کامل API های ماژول `crop_simulation` را پوشش می دهد:

- `POST /api/crop-simulation/current-farm-chart/`
- `POST /api/crop-simulation/growth/`
- `GET /api/crop-simulation/growth/{task_id}/status/`
- `POST /api/crop-simulation/harvest-prediction/`
- `GET /api/crop-simulation/yield-harvest-summary/`
- `POST /api/crop-simulation/yield-prediction/`

---

## الگوی کلی پاسخ ها

تقریبا همه endpoint ها از الگوی envelope زیر استفاده می کنند:

```json
{
  "code": 200,
  "msg": "success",
  "data": {}
}
```

### معنی فیلدهای envelope

| فیلد | نوع | توضیح |
|---|---|---|
| `code` | integer | کد منطقی پاسخ. معمولا با HTTP status همسو است. |
| `msg` | string | پیام کوتاه پاسخ. در موفقیت معمولا `success` و در خطا متن فارسی خطا است. |
| `data` | object / null | بدنه اصلی داده. در خطاهای validation معمولا شامل جزئیات خطا است. |

### خطاهای رایج

| HTTP Status | `code` | توضیح |
|---|---|---|
| `400` | `400` | ورودی نامعتبر است؛ مثل نبودن `farm_uuid` یا ناقص بودن payload |
| `500` | `500` | اجرای سرویس یا شبیه سازی داخلی با خطا مواجه شده است |
| `202` | `202` | تسک async با موفقیت در صف قرار گرفته است |

---

## 1) POST `/api/crop-simulation/current-farm-chart/`

### کاربرد

برای ساخت chart وضعیت فعلی مزرعه با استفاده از شبیه سازی رشد.  
این endpoint داده هایی مثل:

- روند روزانه رشد
- بیوماس
- وزن محصول
- شاخص سطح برگ
- رطوبت خاک

را برمی گرداند.

### درخواست

#### Body

```json
{
  "farm_uuid": "11111111-1111-1111-1111-111111111111",
  "plant_name": "گوجه‌فرنگی"
}
```

### فیلدهای ورودی

| فیلد | نوع | اجباری | توضیح |
|---|---|---:|---|
| `farm_uuid` | string (UUID) | بله | شناسه یکتای مزرعه |
| `plant_name` | string | خیر | نام گیاه. اگر ارسال نشود سیستم سعی می کند گیاه پیش فرض مزرعه را تشخیص دهد |

### پاسخ موفق

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "farm_uuid": "11111111-1111-1111-1111-111111111111",
    "plant_name": "گوجه‌فرنگی",
    "engine": "growth_projection",
    "model_name": "growth_projection_v1",
    "scenario_id": 12,
    "simulation_warning": null,
    "categories": ["2026-04-01", "2026-04-02"],
    "series": [
      {
        "name": "تعداد برگ تخمینی",
        "key": "leaf_count_estimate",
        "data": [120.0, 140.0]
      },
      {
        "name": "وزن بیوماس",
        "key": "biomass_weight",
        "data": [35.0, 45.0]
      }
    ],
    "summary": [
      {
        "title": "تعداد برگ تخمینی",
        "subtitle": "وضعیت فعلی",
        "amount": 140.0,
        "unit": "leaf",
        "avatarColor": "success",
        "avatarIcon": "tabler-leaf"
      }
    ],
    "current_state": {
      "date": "2026-04-02",
      "leaf_count_estimate": 140.0,
      "leaf_area_index": 0.0117,
      "biomass_weight": 45.0,
      "storage_organ_weight": 10.0,
      "soil_moisture_percent": 41.2,
      "development_stage": 0.35,
      "gdd": 9.0
    },
    "metrics": {
      "yield_estimate": 10.0
    },
    "daily_output": []
  }
}
```

### توضیح کامل فیلدهای پاسخ

| فیلد | نوع | توضیح |
|---|---|---|
| `farm_uuid` | string / null | شناسه مزرعه |
| `plant_name` | string | نام گیاهی که شبیه سازی برای آن انجام شده |
| `engine` | string / null | موتور شبیه سازی استفاده شده |
| `model_name` | string / null | نام مدل شبیه سازی |
| `scenario_id` | integer / null | شناسه سناریو اگر در سیستم ثبت شده باشد |
| `simulation_warning` | string / null | هشدار غیر بحرانی؛ مثلا وقتی fallback استفاده شده |
| `categories` | array[string] | محور زمانی نمودار؛ معمولا تاریخ های روزانه |
| `series` | array[object] | سری های نمودار برای رندر frontend |
| `summary` | array[object] | کارت های خلاصه برای نمایش سریع وضعیت فعلی |
| `current_state` | object | وضعیت آخرین روز شبیه سازی |
| `metrics` | object | شاخص های محاسبه شده نهایی |
| `daily_output` | array[object] | خروجی روزانه خام شبیه سازی |

### ساختار `series`

هر عضو `series` معمولا این ساختار را دارد:

| فیلد | نوع | توضیح |
|---|---|---|
| `name` | string | عنوان سری برای chart |
| `key` | string | کلید فنی سری |
| `data` | array[number] | داده های عددی سری به ترتیب `categories` |

نمونه key های مهم:

- `leaf_count_estimate`
- `biomass_weight`
- `storage_organ_weight`
- `lai`
- `soil_moisture_percent`

### ساختار `summary`

هر آیتم `summary` یک KPI card است:

| فیلد | نوع | توضیح |
|---|---|---|
| `title` | string | عنوان کارت |
| `subtitle` | string | زیرعنوان |
| `amount` | number | مقدار اصلی کارت |
| `unit` | string | واحد |
| `avatarColor` | string | رنگ پیشنهادی برای UI |
| `avatarIcon` | string | آیکن پیشنهادی برای UI |

### ساختار `current_state`

| فیلد | نوع | توضیح |
|---|---|---|
| `date` | string | تاریخ آخرین رکورد |
| `leaf_count_estimate` | number | تعداد برگ تخمینی |
| `leaf_area_index` | number | شاخص سطح برگ (LAI) |
| `biomass_weight` | number | وزن بیوماس |
| `storage_organ_weight` | number | وزن اندام ذخیره ای / محصول |
| `soil_moisture_percent` | number | رطوبت خاک به درصد |
| `development_stage` | number | مرحله رشد گیاه به صورت DVS |
| `gdd` | number | درجه روز رشد همان روز |

### ساختار `daily_output`

این بخش خروجی خام شبیه سازی است و معمولا شامل فیلدهایی مثل این هاست:

- `DAY`
- `DVS`
- `LAI`
- `TAGP`
- `TWSO`
- `SM`
- `GDD`
- `TMIN`
- `TMAX`
- `RAIN`
- `ET0`

### خطاها

#### 400

وقتی `farm_uuid` ارسال نشود:

```json
{
  "code": 400,
  "msg": "داده نامعتبر.",
  "data": {
    "farm_uuid": ["This field is required."]
  }
}
```

#### 500

وقتی شبیه ساز داخلی fail شود:

```json
{
  "code": 500,
  "msg": "خطا در اجرای chart شبیه سازی مزرعه: simulator offline",
  "data": null
}
```

---

## 2) POST `/api/crop-simulation/growth/`

### کاربرد

برای شروع شبیه سازی رشد گیاه به صورت async.  
این endpoint خود نتیجه نهایی را برنمی گرداند؛ فقط یک `task_id` می دهد تا بعدا از endpoint وضعیت استفاده شود.

### درخواست

#### نمونه با weather مستقیم

```json
{
  "plant_name": "گوجه‌فرنگی",
  "dynamic_parameters": ["DVS", "LAI", "TAGP", "TWSO", "SM"],
  "weather": [
    {
      "DAY": "2026-04-01",
      "LAT": 35.7,
      "LON": 51.4,
      "TMIN": 12,
      "TMAX": 24,
      "RAIN": 0.0,
      "ET0": 0.32
    }
  ],
  "soil_parameters": {
    "SMFCF": 0.34,
    "SMW": 0.14,
    "RDMSOL": 120.0
  },
  "site_parameters": {
    "WAV": 40.0
  },
  "page_size": 2
}
```

#### نمونه با farm

```json
{
  "plant_name": "گوجه‌فرنگی",
  "dynamic_parameters": ["DVS", "LAI", "TAGP"],
  "farm_uuid": "11111111-1111-1111-1111-111111111111"
}
```

### فیلدهای ورودی

| فیلد | نوع | اجباری | توضیح |
|---|---|---:|---|
| `plant_name` | string | بله | نام گیاه |
| `dynamic_parameters` | array[string] | بله | پارامترهای رشد که باید در خروجی stageها گزارش شوند |
| `farm_uuid` | string (UUID) | شرطی | اگر weather نفرستید لازم است |
| `weather` | array/object | شرطی | اگر `farm_uuid` نفرستید لازم است |
| `soil_parameters` | object | خیر | پارامترهای خاک |
| `site_parameters` | object | خیر | پارامترهای سایت / مزرعه |
| `crop_parameters` | object | خیر | پارامترهای مدل محصول |
| `agromanagement` | object / array | خیر | مدیریت زراعی |
| `page_size` | integer | خیر | اندازه صفحه stage ها، بین `1` تا `50` |

### نکته مهم validation

حداقل یکی از این دو باید وجود داشته باشد:

- `farm_uuid`
- `weather`

### پاسخ موفق

```json
{
  "code": 202,
  "msg": "تسک شبیه سازی رشد در صف قرار گرفت.",
  "data": {
    "task_id": "growth-task-1",
    "status_url": "/api/crop-simulation/growth/growth-task-1/status/",
    "plant_name": "گوجه‌فرنگی"
  }
}
```

### توضیح فیلدهای پاسخ

| فیلد | نوع | توضیح |
|---|---|---|
| `task_id` | string | شناسه تسک Celery |
| `status_url` | string | آدرس endpoint وضعیت برای پیگیری نتیجه |
| `plant_name` | string | نام گیاه مربوط به این شبیه سازی |

### خطاهای رایج

#### 400

اگر نه `farm_uuid` و نه `weather` ارسال نشده باشد:

```json
{
  "code": 400,
  "msg": "داده نامعتبر.",
  "data": {
    "non_field_errors": ["یکی از farm_uuid یا weather باید ارسال شود."]
  }
}
```

---

## 3) GET `/api/crop-simulation/growth/{task_id}/status/`

### کاربرد

برای گرفتن وضعیت تسک async شبیه سازی رشد.

### Query Parameters

| فیلد | نوع | اجباری | توضیح |
|---|---|---:|---|
| `page` | integer | خیر | شماره صفحه stage ها |
| `page_size` | integer | خیر | تعداد stage ها در هر صفحه، حداکثر `50` |

### حالت های پاسخ

این endpoint همیشه HTTP `200` می دهد، ولی فیلد `data.status` تعیین می کند تسک در چه وضعیتی است.

مقادیر مهم:

- `PENDING`
- `PROGRESS`
- `SUCCESS`
- `FAILURE`

---

### پاسخ در حالت `PENDING`

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "task_id": "growth-task-1",
    "status": "PENDING",
    "message": "تسک در صف یا یافت نشد."
  }
}
```

#### توضیح

| فیلد | توضیح |
|---|---|
| `task_id` | شناسه تسک |
| `status` | وضعیت فعلی |
| `message` | پیام کمکی برای کاربر |

---

### پاسخ در حالت `PROGRESS`

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "task_id": "growth-task-1",
    "status": "PROGRESS",
    "progress": {
      "current": 2,
      "total": 3,
      "message": "simulation finished"
    }
  }
}
```

#### توضیح

| فیلد | نوع | توضیح |
|---|---|---|
| `progress.current` | integer | مرحله فعلی پردازش |
| `progress.total` | integer | تعداد کل مراحل |
| `progress.message` | string | توضیح مرحله جاری |

---

### پاسخ در حالت `SUCCESS`

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "task_id": "growth-task-1",
    "status": "SUCCESS",
    "result": {
      "plant_name": "گوجه‌فرنگی",
      "dynamic_parameters": ["DVS"],
      "engine": "growth_projection",
      "model_name": "growth_projection_v1",
      "scenario_id": null,
      "simulation_warning": null,
      "summary_metrics": {},
      "stage_timeline": [
        {
          "order": 1,
          "stage_code": "establishment",
          "stage_name": "استقرار",
          "start_date": "2026-04-01",
          "end_date": "2026-04-02",
          "days_count": 2,
          "metrics": {
            "DVS": {
              "start": 0.1,
              "end": 0.2,
              "min": 0.1,
              "max": 0.2,
              "avg": 0.15
            }
          }
        }
      ],
      "stages_page": [
        {
          "order": 1,
          "stage_code": "establishment",
          "stage_name": "استقرار",
          "start_date": "2026-04-01",
          "end_date": "2026-04-02",
          "days_count": 2,
          "metrics": {
            "DVS": {
              "start": 0.1,
              "end": 0.2,
              "min": 0.1,
              "max": 0.2,
              "avg": 0.15
            }
          }
        }
      ],
      "pagination": {
        "page": 1,
        "page_size": 1,
        "total_items": 3,
        "total_pages": 3,
        "has_next": true,
        "has_previous": false
      },
      "daily_records_count": 7,
      "default_page_size": 1
    }
  }
}
```

### توضیح کامل `result`

| فیلد | نوع | توضیح |
|---|---|---|
| `plant_name` | string | نام گیاه |
| `dynamic_parameters` | array[string] | پارامترهایی که stage metrics برایشان تولید شده |
| `engine` | string / null | موتور شبیه سازی |
| `model_name` | string / null | نام مدل |
| `scenario_id` | integer / null | شناسه سناریو |
| `simulation_warning` | string / null | هشدار غیر بحرانی |
| `summary_metrics` | object | شاخص های خلاصه |
| `stage_timeline` | array[object] | کل timeline مراحل رشد |
| `stages_page` | array[object] | فقط صفحه فعلی timeline |
| `pagination` | object | اطلاعات صفحه بندی |
| `daily_records_count` | integer | تعداد رکوردهای روزانه شبیه سازی |
| `default_page_size` | integer | اندازه صفحه پیش فرض |

### ساختار هر stage

| فیلد | نوع | توضیح |
|---|---|---|
| `order` | integer | ترتیب مرحله در timeline |
| `stage_code` | string | کد فنی مرحله رشد |
| `stage_name` | string | نام قابل نمایش مرحله |
| `start_date` | string | تاریخ شروع مرحله |
| `end_date` | string | تاریخ پایان مرحله |
| `days_count` | integer | تعداد روزهای این مرحله |
| `metrics` | object | خلاصه آماری پارامترهای درخواستی |

### ساختار `metrics` در هر stage

برای هر پارامتر مثل `DVS` یا `LAI`:

| فیلد | توضیح |
|---|---|
| `start` | مقدار ابتدای مرحله |
| `end` | مقدار پایان مرحله |
| `min` | کمترین مقدار در مرحله |
| `max` | بیشترین مقدار در مرحله |
| `avg` | میانگین مقدار در مرحله |

### ساختار `pagination`

| فیلد | نوع | توضیح |
|---|---|---|
| `page` | integer | شماره صفحه فعلی |
| `page_size` | integer | اندازه صفحه فعلی |
| `total_items` | integer | تعداد کل stage ها |
| `total_pages` | integer | تعداد کل صفحه ها |
| `has_next` | boolean | آیا صفحه بعدی وجود دارد |
| `has_previous` | boolean | آیا صفحه قبلی وجود دارد |

---

### پاسخ در حالت `FAILURE`

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "task_id": "growth-task-1",
    "status": "FAILURE",
    "error": "task crashed"
  }
}
```

#### توضیح

| فیلد | توضیح |
|---|---|
| `error` | متن خطای نهایی تسک |

---

## 4) POST `/api/crop-simulation/harvest-prediction/`

### کاربرد

برای پیش بینی زمان تقریبی برداشت بر اساس خروجی شبیه سازی رشد و GDD.

### درخواست

```json
{
  "farm_uuid": "11111111-1111-1111-1111-111111111111",
  "plant_name": "گوجه‌فرنگی"
}
```

### فیلدهای ورودی

| فیلد | نوع | اجباری | توضیح |
|---|---|---:|---|
| `farm_uuid` | string (UUID) | بله | شناسه مزرعه |
| `plant_name` | string | خیر | نام گیاه |

### پاسخ موفق

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "date": "2026-05-14",
    "dateFormatted": "14 May 2026",
    "daysUntil": 43,
    "description": "شبيه ساز نشان مي دهد حدود 43 روز ديگر تا برداشت باقي مانده است.",
    "optimalWindowStart": "2026-05-11",
    "optimalWindowEnd": "2026-05-17",
    "gddDetails": {
      "current_cumulative_gdd": 50.0,
      "required_gdd_for_maturity": 1200.0,
      "remaining_gdd": 1150.0,
      "simulation_engine": "growth_projection"
    }
  }
}
```

### توضیح کامل فیلدهای پاسخ

| فیلد | نوع | توضیح |
|---|---|---|
| `date` | string | تاریخ تخمینی برداشت با فرمت ISO |
| `dateFormatted` | string | همان تاریخ به فرمت human-readable |
| `daysUntil` | integer | تعداد روز باقی مانده تا برداشت |
| `description` | string | توضیح متنی قابل نمایش برای کاربر |
| `optimalWindowStart` | string | شروع بازه مناسب برداشت |
| `optimalWindowEnd` | string | پایان بازه مناسب برداشت |
| `gddDetails` | object | جزئیات محاسبات GDD و داده های پشتیبان |

### ساختار `gddDetails`

معمولا شامل این فیلدهاست:

| فیلد | نوع | توضیح |
|---|---|---|
| `current_cumulative_gdd` | number | GDD تجمعی فعلی |
| `required_gdd_for_maturity` | number | GDD مورد نیاز برای رسیدن به بلوغ |
| `remaining_gdd` | number | میزان GDD باقی مانده |
| `estimated_days_to_harvest` | integer | روزهای برآوردی تا برداشت |
| `predicted_harvest_date` | string | تاریخ برآوردی برداشت |
| `predicted_harvest_window` | object | بازه شروع/پایان مناسب برداشت |
| `daily_gdd_forecast` | array[object] | پیش بینی روزانه GDD |
| `simulation_engine` | string | موتور شبیه سازی |
| `simulation_model_name` | string | نام مدل شبیه سازی |
| `simulation_warning` | string / null | هشدار داخلی شبیه سازی |
| `scenario_id` | integer / null | شناسه سناریو |

### ساختار `daily_gdd_forecast`

هر آیتم:

| فیلد | نوع | توضیح |
|---|---|---|
| `date` | string | تاریخ |
| `gdd` | number | GDD همان روز |
| `cumulative_gdd` | number | GDD تجمعی تا آن روز |
| `development_stage` | number | DVS آن روز |

### خطاها

#### 400

```json
{
  "code": 400,
  "msg": "داده نامعتبر.",
  "data": {
    "farm_uuid": ["This field is required."]
  }
}
```

#### 500

```json
{
  "code": 500,
  "msg": "خطا در پیش بینی زمان برداشت: harvest offline",
  "data": null
}
```

---

## 5) GET `/api/crop-simulation/yield-harvest-summary/`

### کاربرد

برای برگرداندن داشبورد کامل خلاصه عملکرد و برداشت.  
این endpoint ترکیبی از چند block مختلف است:

- season highlights
- yield prediction
- harvest prediction
- readiness zones
- quality bands
- harvest operations
- yield chart

این endpoint می تواند علاوه بر داده های deterministic، متن های narrative را هم اضافه کند.

### Query Parameters

| فیلد | نوع | اجباری | توضیح |
|---|---|---:|---|
| `farm_uuid` | string (UUID) | بله | شناسه یکتای مزرعه |
| `season_year` | integer | خیر | سال زراعی |
| `crop_name` | string | خیر | نام محصول |
| `include_narrative` | boolean | خیر | اگر `true` باشد متن های توضیحی RAG هم merge می شوند |

### نمونه درخواست

```http
GET /api/crop-simulation/yield-harvest-summary/?farm_uuid=11111111-1111-1111-1111-111111111111&season_year=1404&crop_name=wheat&include_narrative=true
```

### پاسخ موفق

نمونه واقعی پاسخ فعلی:

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "farm_uuid": "11111111-1111-1111-1111-111111111111",
    "season_highlights_card": {
      "farm_uuid": "11111111-1111-1111-1111-111111111111",
      "crop_name": "",
      "season_year": "",
      "title": "Season highlights",
      "subtitle": "Projected harvest in 152 days with minimal yield prediction issues due to simulation fallback.",
      "total_predicted_yield": 0.0,
      "yield_unit": "تن",
      "target_harvest_date": "28 September 2026",
      "days_until_harvest": 152,
      "average_readiness": null,
      "primary_quality_grade": "C",
      "estimated_revenue": null,
      "soil_type": "loam"
    },
    "yield_prediction": {
      "farm_uuid": "11111111-1111-1111-1111-111111111111",
      "crop_name": "خیار",
      "season_year": "",
      "predicted_yield_tons": 0.0,
      "predicted_yield_raw": 0.0,
      "unit": "تن",
      "source_unit": "kg/ha",
      "simulation_engine": "growth_projection",
      "simulation_model": "growth_projection_v1",
      "scenario_id": null,
      "simulation_warning": "Simulation engine failed, fallback projection used: Value for parameter CVL missing.",
      "secondary_kpis_estimated": true,
      "descriptionSource": "deterministic",
      "farm_context": {
        "soil_type": "loam",
        "soil_data_provider": "mock"
      },
      "supporting_metrics": {
        "yield_estimate": 0.0,
        "biomass": 232.9052,
        "max_lai": 0.1063
      },
      "explanation": "شبيه ساز با محدوديت داده مواجه شد؛ براورد فعلی بدون تضمین و با روش جایگزین انجام شده است."
    },
    "harvest_prediction_card": {
      "farm_uuid": "11111111-1111-1111-1111-111111111111",
      "crop_name": "",
      "season_year": "",
      "harvest_date": "2026-09-28",
      "harvest_date_formatted": "28 September 2026",
      "days_until": 152,
      "optimal_window_start": "2026-09-25",
      "optimal_window_end": "2026-10-01",
      "description": "شبيه ساز تا انتهاي forecast هنوز به رسيدگي کامل نرسيده، اما با ميانگين رشد فعلي براورد مي شود خیار حدود 152 روز ديگر به برداشت برسد.",
      "descriptionSource": "deterministic",
      "field_conditions": {
        "soil_moisture": 42.3,
        "soil_temperature": 21.4
      },
      "readiness_metrics": {
        "current_cumulative_gdd": 0.0,
        "required_gdd_for_maturity": 1200.0
      }
    },
    "harvest_readiness_zones": {
      "farm_uuid": "11111111-1111-1111-1111-111111111111",
      "observationDate": null,
      "vegetationHealthClass": "Unavailable",
      "meanNdvi": null,
      "ndviTrend": null,
      "averageReadiness": null,
      "zones": [],
      "source": "ndvi_health_service",
      "summary": "خیار هنوز در مراحل اولیه رشد است، 152 روز تا برداشته شدن باقی مانده است. میانگین آمادگی موجود نیست."
    },
    "yield_quality_bands": {
      "farm_uuid": "11111111-1111-1111-1111-111111111111",
      "crop_name": "",
      "season_year": "",
      "source": "deterministic_grading_rules",
      "is_estimated": true,
      "protein_content": {
        "value": 9.51,
        "unit": "%"
      },
      "moisture_percentage": {
        "value": 14.03,
        "unit": "%"
      },
      "grade_distribution": [
        {"grade": "A", "share_percent": 16},
        {"grade": "B", "share_percent": 41},
        {"grade": "C", "share_percent": 43}
      ],
      "primary_quality_grade": "C",
      "quality_score": 59,
      "summary": "Primary quality grade is C."
    },
    "harvest_operations_card": {
      "farm_uuid": "11111111-1111-1111-1111-111111111111",
      "crop_name": "خیار",
      "season_year": "",
      "stage_label": "early_pre_harvest",
      "phase_name": "vegetative",
      "days_until_harvest": 152,
      "current_dvs": 0.0394,
      "summary": "Operations are prioritized for خیار with 152 days remaining until the predicted harvest window.",
      "rules_source": "deterministic_dvs_rules",
      "field_context": {
        "soil_type": "loam",
        "soil_moisture": 42.3,
        "soil_temperature": 21.4
      },
      "steps": [
        {
          "key": "weekly_monitoring",
          "title": "Run weekly crop maturity checks",
          "status": "active",
          "is_completed": false,
          "estimated_days": 14,
          "note": "Check weekly crop status for any signs of maturity changes."
        }
      ]
    },
    "yield_prediction_chart": {
      "farm_uuid": "11111111-1111-1111-1111-111111111111",
      "crop_name": "خیار",
      "season_year": "",
      "series": [
        {
          "name": "Predicted Yield",
          "type": "line",
          "data": [[1777420800000, 0.0]]
        },
        {
          "name": "Biomass",
          "type": "area",
          "data": [[1777420800000, 89.392]]
        }
      ],
      "xAxis": {
        "type": "datetime"
      },
      "meta": {
        "unit": "kg/ha",
        "simulation_engine": "growth_projection",
        "simulation_model": "growth_projection_v1",
        "scenario_id": null,
        "simulation_warning": "Simulation engine failed, fallback projection used: Value for parameter CVL missing.",
        "field_context": {
          "soil_type": "loam",
          "center_coordinates": {
            "lat": 50.0,
            "lon": 50.0
          }
        }
      }
    }
  }
}
```

### توضیح top-level response

| فیلد | نوع | توضیح |
|---|---|---|
| `farm_uuid` | string | شناسه مزرعه |
| `season_highlights_card` | object | خلاصه مهم ترین KPI ها |
| `yield_prediction` | object | خروجی پیش بینی عملکرد |
| `harvest_prediction_card` | object | تاریخ و وضعیت برداشت |
| `harvest_readiness_zones` | object | وضعیت آمادگی برداشت در zoneها |
| `yield_quality_bands` | object | کیفیت برآوردی محصول |
| `harvest_operations_card` | object | عملیات پیشنهادی برداشت |
| `yield_prediction_chart` | object | داده نمودار عملکرد و بیوماس |

### توضیح `season_highlights_card`

| فیلد | نوع | توضیح |
|---|---|---|
| `title` | string | عنوان کارت |
| `subtitle` | string | متن توضیحی کوتاه؛ ممکن است از RAG بیاید |
| `total_predicted_yield` | number / null | عملکرد پیش بینی شده |
| `yield_unit` | string | واحد عملکرد |
| `target_harvest_date` | string / null | تاریخ هدف برداشت |
| `days_until_harvest` | integer / null | روز باقی مانده |
| `average_readiness` | number / null | میانگین آمادگی zoneها |
| `primary_quality_grade` | string / null | درجه کیفیت غالب |
| `estimated_revenue` | number / null | درآمد تخمینی اگر داده اقتصادی موجود باشد |
| `soil_type` | string / null | نوع خاک |

### توضیح `yield_prediction`

| فیلد | نوع | توضیح |
|---|---|---|
| `predicted_yield_tons` | number | عملکرد بر حسب تن |
| `predicted_yield_raw` | number | عملکرد خام معمولا بر حسب `kg/ha` |
| `unit` | string | واحد نمایشی |
| `source_unit` | string | واحد منبع |
| `simulation_engine` | string / null | موتور شبیه سازی |
| `simulation_model` | string / null | نام مدل |
| `scenario_id` | integer / null | شناسه سناریو |
| `simulation_warning` | string / null | هشدار شبیه سازی |
| `secondary_kpis_estimated` | boolean | آیا KPIهای ثانویه تخمینی هستند |
| `descriptionSource` | string | منبع توضیح؛ معمولا `deterministic` یا `rag` |
| `farm_context` | object | بخشی از context مزرعه |
| `supporting_metrics` | object | متریک های پشتیبان مثل `yield_estimate` و `biomass` |
| `explanation` | string | توضیح متنی برای کاربر |

### توضیح `harvest_prediction_card`

| فیلد | نوع | توضیح |
|---|---|---|
| `harvest_date` | string | تاریخ ISO برداشت |
| `harvest_date_formatted` | string | تاریخ قابل نمایش |
| `days_until` | integer | تعداد روز باقی مانده |
| `optimal_window_start` | string | شروع پنجره مناسب برداشت |
| `optimal_window_end` | string | پایان پنجره مناسب برداشت |
| `description` | string | توضیح متنی |
| `descriptionSource` | string | منبع متن |
| `field_conditions` | object | شرایط فعلی مزرعه مثل رطوبت و دما |
| `readiness_metrics` | object | جزئیات محاسبات readiness/GDD |

### توضیح `harvest_readiness_zones`

| فیلد | نوع | توضیح |
|---|---|---|
| `observationDate` | string / null | تاریخ مشاهده NDVI |
| `vegetationHealthClass` | string / null | کلاس سلامت پوشش گیاهی |
| `meanNdvi` | number / null | NDVI میانگین |
| `ndviTrend` | number / null | روند تغییر NDVI |
| `averageReadiness` | number / null | میانگین آمادگی zoneها |
| `zones` | array[object] | فهرست zoneها |
| `source` | string | منبع داده |
| `summary` | string | توضیح متنی خلاصه |

### ساختار هر zone

| فیلد | نوع | توضیح |
|---|---|---|
| `zoneId` | string | شناسه zone |
| `zoneLabel` | string | نام نمایشی zone |
| `gridPosition` | object / null | موقعیت zone در grid |
| `meanNdvi` | number | میانگین NDVI zone |
| `readiness` | integer | درصد آمادگی برداشت |
| `daysUntil` | integer | روزهای تخمینی تا آمادگی |
| `status` | string | وضعیت مثل `ready`, `approaching`, `monitoring`, `not_ready` |

### توضیح `yield_quality_bands`

| فیلد | نوع | توضیح |
|---|---|---|
| `source` | string | منبع محاسبه کیفیت |
| `is_estimated` | boolean | آیا مقادیر تخمینی هستند |
| `protein_content` | object | درصد پروتئین |
| `moisture_percentage` | object | درصد رطوبت |
| `grade_distribution` | array[object] | توزیع درصدی gradeها |
| `primary_quality_grade` | string | grade غالب |
| `quality_score` | number | امتیاز کیفیت |
| `summary` | string | خلاصه متنی کیفیت |

### ساختار `protein_content` و `moisture_percentage`

| فیلد | نوع | توضیح |
|---|---|---|
| `value` | number | مقدار |
| `unit` | string | واحد، معمولا `%` |

### ساختار `grade_distribution`

| فیلد | نوع | توضیح |
|---|---|---|
| `grade` | string | گرید کیفیت مثل `A`, `B`, `C` |
| `share_percent` | integer | سهم درصدی آن گرید |

### توضیح `harvest_operations_card`

| فیلد | نوع | توضیح |
|---|---|---|
| `stage_label` | string | برچسب مرحله عملیاتی |
| `phase_name` | string | نام فاز رشد |
| `days_until_harvest` | integer | روز باقی مانده تا برداشت |
| `current_dvs` | number | DVS فعلی |
| `summary` | string | خلاصه عملیاتی |
| `rules_source` | string | منبع قواعد تصمیم |
| `field_context` | object | context مزرعه |
| `steps` | array[object] | گام های عملیاتی |

### ساختار هر step

| فیلد | نوع | توضیح |
|---|---|---|
| `key` | string | کلید فنی step |
| `title` | string | عنوان عملیات |
| `status` | string | وضعیت مثل `active`, `upcoming`, `ready` |
| `is_completed` | boolean | آیا انجام شده |
| `estimated_days` | integer | روز برآوردی برای انجام / رسیدن |
| `note` | string | توضیح تکمیلی یا توصیه |

### توضیح `yield_prediction_chart`

| فیلد | نوع | توضیح |
|---|---|---|
| `series` | array[object] | سری های نمودار عملکرد و بیوماس |
| `xAxis` | object | تنظیم محور افقی |
| `meta` | object | متادیتای chart |

### ساختار `yield_prediction_chart.series`

| فیلد | نوع | توضیح |
|---|---|---|
| `name` | string | نام سری |
| `type` | string | نوع رسم مثل `line` یا `area` |
| `data` | array[[timestamp, value]] | داده های نمودار بر پایه timestamp یونیکس میلی ثانیه |

### توضیح `yield_prediction_chart.meta`

| فیلد | نوع | توضیح |
|---|---|---|
| `unit` | string | واحد داده chart |
| `simulation_engine` | string | موتور شبیه سازی |
| `simulation_model` | string | مدل |
| `scenario_id` | integer / null | شناسه سناریو |
| `simulation_warning` | string / null | هشدار شبیه سازی |
| `field_context` | object | context مزرعه مثل نوع خاک و مختصات |

### خطاها

#### 400

وقتی `farm_uuid` ارسال نشده باشد:

```json
{
  "code": 400,
  "msg": "داده نامعتبر.",
  "data": {
    "farm_uuid": ["This field is required."]
  }
}
```

---

## 6) POST `/api/crop-simulation/yield-prediction/`

### کاربرد

برای تبدیل خروجی شبیه سازی رشد به پیش بینی عملکرد مزرعه.

### درخواست

```json
{
  "farm_uuid": "11111111-1111-1111-1111-111111111111",
  "plant_name": "گوجه‌فرنگی"
}
```

### فیلدهای ورودی

| فیلد | نوع | اجباری | توضیح |
|---|---|---:|---|
| `farm_uuid` | string (UUID) | بله | شناسه مزرعه |
| `plant_name` | string | خیر | نام گیاه |

### پاسخ موفق

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "plant_name": "گوجه‌فرنگی",
    "predictedYieldTons": 5.4,
    "predictedYieldRaw": 5400.0,
    "unit": "تن",
    "sourceUnit": "kg/ha",
    "simulationEngine": "growth_projection",
    "simulationModel": "growth_projection_v1",
    "scenarioId": 12,
    "simulationWarning": null,
    "supportingMetrics": {
      "yield_estimate": 5400.0
    }
  }
}
```

### توضیح کامل فیلدهای پاسخ

| فیلد | نوع | توضیح |
|---|---|---|
| `farm_uuid` | string | شناسه مزرعه |
| `plant_name` | string / null | نام گیاه |
| `predictedYieldTons` | number | عملکرد پیش بینی شده بر حسب تن |
| `predictedYieldRaw` | number | مقدار خام عملکرد |
| `unit` | string | واحد نمایشی، معمولا `تن` |
| `sourceUnit` | string | واحد محاسباتی اصلی، معمولا `kg/ha` |
| `simulationEngine` | string / null | موتور شبیه سازی |
| `simulationModel` | string / null | مدل شبیه سازی |
| `scenarioId` | integer / null | شناسه سناریو |
| `simulationWarning` | string / null | هشدار شبیه سازی |
| `supportingMetrics` | object | متریک های پشتیبان مورد استفاده برای محاسبه عملکرد |

### خطاها

#### 400

```json
{
  "code": 400,
  "msg": "داده نامعتبر.",
  "data": {
    "farm_uuid": ["This field is required."]
  }
}
```

#### 500

```json
{
  "code": 500,
  "msg": "خطا در پیش بینی عملکرد: yield offline",
  "data": null
}
```

---

## جمع بندی تفاوت endpoint ها

| Endpoint | کاربرد اصلی | sync/async |
|---|---|---|
| `POST /current-farm-chart/` | ساخت نمودار وضعیت فعلی مزرعه | sync |
| `POST /growth/` | شروع شبیه سازی رشد | async |
| `GET /growth/{task_id}/status/` | بررسی وضعیت و نتیجه شبیه سازی رشد | async status |
| `POST /harvest-prediction/` | پیش بینی زمان برداشت | sync |
| `GET /yield-harvest-summary/` | داشبورد کامل عملکرد و برداشت | sync |
| `POST /yield-prediction/` | پیش بینی عملکرد نهایی | sync |

---

## نکات مهم برای frontend

- در endpoint `growth/status` همیشه به `data.status` نگاه کنید، نه فقط HTTP status.
- در پاسخ های chart و summary ممکن است `simulation_warning` مقدار داشته باشد، حتی اگر HTTP `200` باشد.
- در `yield-harvest-summary` بعضی فیلدها ممکن است `null` باشند، مخصوصا:
  - `estimated_revenue`
  - `average_readiness`
  - `scenario_id`
  - `simulation_warning`
- در `yield_prediction_chart.series[].data` timestamp ها بر حسب **milliseconds** هستند.
- در `yield-harvest-summary` اگر `include_narrative=true` باشد، بعضی متن ها ممکن است از RAG بیایند ولی اعداد deterministic باقی می مانند.

---

## مسیر فایل

این داکیومنت در مسیر زیر ذخیره شده است:

`docs/crop_simulation_api_reference.md`
