488 lines
16 KiB
Markdown
488 lines
16 KiB
Markdown
# Fertilization Recommendation Result API Spec
|
|
|
|
این فایل مشخص میکند که فرانتاند برای صفحه `SmartFertilizationRecommendation` دقیقاً چه خروجیای از بکاند نیاز دارد، مخصوصاً برای:
|
|
|
|
- Hero Card
|
|
- ماشینحساب مساحت مزرعه
|
|
- آنالیز ترکیبات
|
|
- مراحل مصرف
|
|
- نکات ایمنی
|
|
- کودهای جایگزین
|
|
- Bottom Sheet جزئیات
|
|
|
|
نکته مهم: برای ماشینحساب، فرانتاند **نباید** مقدار را از رشتههایی مثل `150 kg/ha` parse کند. بکاند باید مقادیر عددی استاندارد و مستقل برگرداند.
|
|
|
|
---
|
|
|
|
## هدف اصلی
|
|
|
|
برای اینکه ماشینحساب مقدار مصرف دقیق کار کند، بکاند باید علاوه بر متن نمایشی، **مقدار عددی پایه** را نیز برگرداند.
|
|
|
|
فرمول مورد نیاز فرانت:
|
|
|
|
```text
|
|
مقدار کل = مقدار مصرف در هر متر مربع × مساحت مزرعه
|
|
```
|
|
|
|
یا اگر واحد پایه بر حسب هکتار ارسال شود:
|
|
|
|
```text
|
|
مقدار کل = مقدار مصرف در هکتار × مساحت (هکتار)
|
|
```
|
|
|
|
اما پیشنهاد قطعی برای فرانت این است که بکاند هر دو را بدهد:
|
|
|
|
- `base_amount_per_hectare`
|
|
- `base_amount_per_square_meter`
|
|
|
|
تا هیچ تبدیل واحدی در UI لازم نباشد.
|
|
|
|
---
|
|
|
|
## Endpoint پیشنهادی
|
|
|
|
```text
|
|
POST /api/fertilization/recommend/
|
|
```
|
|
|
|
یا اگر ساختار فعلی پروژه حفظ شود:
|
|
|
|
```text
|
|
POST /api/fertilization-recommendation/recommend/
|
|
```
|
|
|
|
---
|
|
|
|
## Request پیشنهادی
|
|
|
|
```json
|
|
{
|
|
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
|
"crop_id": "wheat",
|
|
"growth_stage": "flowering",
|
|
"area": {
|
|
"value": 2.5,
|
|
"unit": "hectare"
|
|
}
|
|
}
|
|
```
|
|
|
|
### توضیح فیلدهای Request
|
|
|
|
| فیلد | نوع | اجباری | توضیح |
|
|
|------|-----|--------|-------|
|
|
| `farm_uuid` | string | بله | شناسه مزرعه |
|
|
| `crop_id` | string | بله | شناسه محصول |
|
|
| `growth_stage` | string | بله | مرحله رشد محصول |
|
|
| `area.value` | number | اختیاری | مساحت مزرعه برای محاسبه مستقیم مقدار کل |
|
|
| `area.unit` | string | اختیاری | واحد مساحت؛ ترجیحاً `hectare` یا `square_meter` |
|
|
|
|
اگر `area` ارسال نشود، فرانت با دادههای پایه محاسبه را خودش انجام میدهد.
|
|
|
|
---
|
|
|
|
## Response پیشنهادی
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"data": {
|
|
"recommendation_id": "fert-rec-001",
|
|
"crop": {
|
|
"id": "wheat",
|
|
"name": "گندم"
|
|
},
|
|
"growth_stage": {
|
|
"id": "flowering",
|
|
"name": "گلدهی"
|
|
},
|
|
"primary_recommendation": {
|
|
"fertilizer_code": "npk-20-20-20",
|
|
"fertilizer_name": "کود کامل 20-20-20",
|
|
"display_title": "کود کامل 20-20-20",
|
|
"fertilizer_type": "NPK",
|
|
"npk_ratio": {
|
|
"n": 20,
|
|
"p": 20,
|
|
"k": 20,
|
|
"label": "20-20-20"
|
|
},
|
|
"application_method": {
|
|
"id": "foliar_fertigation",
|
|
"label": "محلول پاشی / آب آبیاری"
|
|
},
|
|
"application_interval": {
|
|
"value": 14,
|
|
"unit": "day",
|
|
"label": "هر 14 روز"
|
|
},
|
|
"dosage": {
|
|
"base_amount_per_hectare": 150,
|
|
"base_amount_per_square_meter": 0.015,
|
|
"unit": "kg",
|
|
"label": "150 کیلوگرم در هکتار",
|
|
"calculation_basis": "product"
|
|
},
|
|
"total_amount": {
|
|
"value": 375,
|
|
"unit": "kg",
|
|
"label": "375 کیلوگرم"
|
|
},
|
|
"reasoning": "این ترکیب برای مرحله گلدهی به دلیل نیاز متعادل به ازت، فسفر و پتاسیم پیشنهاد شده است.",
|
|
"summary": "مناسب برای حفظ رشد رویشی و پشتیبانی از گلدهی"
|
|
},
|
|
"nutrient_analysis": {
|
|
"macro": [
|
|
{
|
|
"key": "n",
|
|
"name": "نیتروژن (N)",
|
|
"value": 20,
|
|
"unit": "percent",
|
|
"description": "نیتروژن برای رشد رویشی و افزایش سطح برگ ضروری است."
|
|
},
|
|
{
|
|
"key": "p",
|
|
"name": "فسفر (P)",
|
|
"value": 20,
|
|
"unit": "percent",
|
|
"description": "فسفر برای توسعه ریشه و انتقال انرژی اهمیت دارد."
|
|
},
|
|
{
|
|
"key": "k",
|
|
"name": "پتاسیم (K)",
|
|
"value": 20,
|
|
"unit": "percent",
|
|
"description": "پتاسیم به کیفیت محصول و مقاومت به تنش کمک میکند."
|
|
}
|
|
],
|
|
"micro": [
|
|
{
|
|
"key": "fe",
|
|
"name": "آهن",
|
|
"value": 0.5,
|
|
"unit": "percent",
|
|
"description": "آهن در تولید کلروفیل و جلوگیری از زردی موثر است."
|
|
},
|
|
{
|
|
"key": "zn",
|
|
"name": "روی",
|
|
"value": 1,
|
|
"unit": "percent",
|
|
"description": "روی در رشد متعادل و فعالیت آنزیمها نقش دارد."
|
|
}
|
|
]
|
|
},
|
|
"application_guide": {
|
|
"safety_warning": "هنگام محلول پاشی از دستکش و ماسک استفاده کنید و در ساعات خنک روز مصرف انجام شود.",
|
|
"steps": [
|
|
{
|
|
"step_number": 1,
|
|
"title": "آماده سازی",
|
|
"description": "مقدار توصیه شده از کود را در یک سطل آب تمیز حل کنید."
|
|
},
|
|
{
|
|
"step_number": 2,
|
|
"title": "ترکیب",
|
|
"description": "محلول را به مخزن اصلی سم پاش یا سیستم آبیاری اضافه کنید و خوب هم بزنید."
|
|
},
|
|
{
|
|
"step_number": 3,
|
|
"title": "مصرف",
|
|
"description": "به صورت یکنواخت روی گیاه اسپری کنید یا در سیستم آبیاری تزریق نمایید."
|
|
}
|
|
]
|
|
},
|
|
"alternative_recommendations": [
|
|
{
|
|
"fertilizer_code": "npk-10-52-10",
|
|
"fertilizer_name": "کود 10-52-10",
|
|
"fertilizer_type": "NPK (فسفر بالا)",
|
|
"usage_method": "محلول پاشی",
|
|
"description": "برای تقویت ریشه و پشتیبانی از گلدهی در صورت نبود پیشنهاد اصلی مناسب است."
|
|
},
|
|
{
|
|
"fertilizer_code": "npk-12-12-36",
|
|
"fertilizer_name": "کود 12-12-36",
|
|
"fertilizer_type": "NPK (پتاس بالا)",
|
|
"usage_method": "تزریق در آبیاری",
|
|
"description": "برای بهبود کیفیت محصول و افزایش پتاسیم قابل استفاده است."
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## فیلدهای ضروری برای فرانت
|
|
|
|
### 1) اطلاعات اصلی پیشنهاد
|
|
|
|
این فیلدها برای Hero Card لازماند.
|
|
|
|
| فیلد | نوع | اجباری | توضیح |
|
|
|------|-----|--------|-------|
|
|
| `primary_recommendation.fertilizer_name` | string | بله | نام اصلی کود |
|
|
| `primary_recommendation.display_title` | string | بهتر است | عنوان نمایشی اگر با نام اصلی فرق دارد |
|
|
| `primary_recommendation.fertilizer_type` | string | بله | نوع کود مثل NPK |
|
|
| `primary_recommendation.npk_ratio.label` | string | بله | متن آماده برای نمایش مثل `20-20-20` |
|
|
| `primary_recommendation.npk_ratio.n` | number | بله | درصد نیتروژن |
|
|
| `primary_recommendation.npk_ratio.p` | number | بله | درصد فسفر |
|
|
| `primary_recommendation.npk_ratio.k` | number | بله | درصد پتاسیم |
|
|
| `primary_recommendation.application_method.label` | string | بله | روش مصرف نمایشی |
|
|
| `primary_recommendation.application_interval.label` | string | بله | فاصله مصرف نمایشی |
|
|
| `primary_recommendation.reasoning` | string | بله | دلیل توصیه برای بخش توضیحات |
|
|
|
|
### 2) فیلدهای ضروری برای ماشینحساب
|
|
|
|
این بخش مهمترین قسمت برای بکاند است.
|
|
|
|
| فیلد | نوع | اجباری | توضیح |
|
|
|------|-----|--------|-------|
|
|
| `primary_recommendation.dosage.base_amount_per_hectare` | number | بله | مقدار پایه مصرف در هر هکتار |
|
|
| `primary_recommendation.dosage.base_amount_per_square_meter` | number | بله | مقدار پایه مصرف در هر متر مربع |
|
|
| `primary_recommendation.dosage.unit` | string | بله | واحد مقدار مصرف؛ مثل `kg` یا `liter` |
|
|
| `primary_recommendation.dosage.label` | string | بله | متن آماده برای نمایش مثل `150 کیلوگرم در هکتار` |
|
|
| `primary_recommendation.total_amount.value` | number | اختیاری | اگر بکاند بر اساس مساحت ورودی مقدار کل را حساب کند |
|
|
| `primary_recommendation.total_amount.unit` | string | اختیاری | واحد مقدار کل |
|
|
| `primary_recommendation.total_amount.label` | string | اختیاری | متن نمایشی مقدار کل |
|
|
|
|
### چرا `base_amount_per_square_meter` لازم است؟
|
|
|
|
چون شما گفتید ماشینحساب باید مقدار **کیلوگرم در هر متر مربع** را از بکاند بگیرد.
|
|
|
|
پس بکاند باید این مقدار را صریح برگرداند، نه اینکه فرانت از `kg/ha` خودش تبدیل کند.
|
|
|
|
نمونه:
|
|
|
|
```json
|
|
{
|
|
"base_amount_per_hectare": 150,
|
|
"base_amount_per_square_meter": 0.015,
|
|
"unit": "kg"
|
|
}
|
|
```
|
|
|
|
تبدیل مرجع:
|
|
|
|
```text
|
|
1 hectare = 10,000 square meters
|
|
150 kg/ha = 0.015 kg/m²
|
|
```
|
|
|
|
---
|
|
|
|
## فیلدهای آنالیز ترکیبات
|
|
|
|
برای اینکه فرانت مجبور به parse کردن متن `npkRatio` نباشد، بکاند باید آنالیز را ساختارمند بفرستد.
|
|
|
|
### ماکرو
|
|
|
|
| فیلد | نوع | اجباری | توضیح |
|
|
|------|-----|--------|-------|
|
|
| `nutrient_analysis.macro[].key` | string | بله | کلید استاندارد مثل `n`, `p`, `k` |
|
|
| `nutrient_analysis.macro[].name` | string | بله | نام نمایشی فارسی |
|
|
| `nutrient_analysis.macro[].value` | number | بله | درصد عنصر |
|
|
| `nutrient_analysis.macro[].unit` | string | بله | معمولاً `percent` |
|
|
| `nutrient_analysis.macro[].description` | string | بهتر است | توضیح برای Bottom Sheet |
|
|
|
|
### ریزمغذیها
|
|
|
|
| فیلد | نوع | اجباری | توضیح |
|
|
|------|-----|--------|-------|
|
|
| `nutrient_analysis.micro[].key` | string | بله | مثل `fe`, `zn`, `mn`, `b` |
|
|
| `nutrient_analysis.micro[].name` | string | بله | نام فارسی عنصر |
|
|
| `nutrient_analysis.micro[].value` | number | بله | درصد عنصر |
|
|
| `nutrient_analysis.micro[].unit` | string | بله | معمولاً `percent` |
|
|
| `nutrient_analysis.micro[].description` | string | بهتر است | توضیح برای Bottom Sheet |
|
|
|
|
---
|
|
|
|
## فیلدهای دستورالعمل مصرف
|
|
|
|
| فیلد | نوع | اجباری | توضیح |
|
|
|------|-----|--------|-------|
|
|
| `application_guide.safety_warning` | string | بله | متن هشدار ایمنی |
|
|
| `application_guide.steps[].step_number` | number | بله | شماره مرحله |
|
|
| `application_guide.steps[].title` | string | بله | عنوان مرحله |
|
|
| `application_guide.steps[].description` | string | بله | توضیح مرحله |
|
|
|
|
---
|
|
|
|
## فیلدهای کودهای جایگزین
|
|
|
|
| فیلد | نوع | اجباری | توضیح |
|
|
|------|-----|--------|-------|
|
|
| `alternative_recommendations[].fertilizer_code` | string | بله | شناسه یکتا |
|
|
| `alternative_recommendations[].fertilizer_name` | string | بله | نام کود جایگزین |
|
|
| `alternative_recommendations[].fertilizer_type` | string | بله | نوع کود |
|
|
| `alternative_recommendations[].usage_method` | string | بله | روش مصرف |
|
|
| `alternative_recommendations[].description` | string | بله | توضیح برای Bottom Sheet |
|
|
|
|
---
|
|
|
|
## فیلدهای لازم برای Bottom Sheet
|
|
|
|
برای باز شدن Bottom Sheet روی مواد غذایی و کودهای جایگزین، بهتر است توضیح آماده از بکاند بیاید.
|
|
|
|
| بخش | فیلد پیشنهادی |
|
|
|-----|---------------|
|
|
| مواد اصلی | `nutrient_analysis.macro[].description` |
|
|
| ریزمغذیها | `nutrient_analysis.micro[].description` |
|
|
| کود جایگزین | `alternative_recommendations[].description` |
|
|
|
|
این باعث میشود فرانت مجبور نباشد متنهای توضیحی hard-code کند.
|
|
|
|
---
|
|
|
|
## فرمت واحدها
|
|
|
|
پیشنهاد میشود بکاند از مقادیر استاندارد زیر استفاده کند:
|
|
|
|
### واحد مقدار کود
|
|
|
|
- `kg`
|
|
- `gram`
|
|
- `liter`
|
|
- `milliliter`
|
|
|
|
### واحد مساحت
|
|
|
|
- `hectare`
|
|
- `square_meter`
|
|
|
|
### واحد درصد عناصر
|
|
|
|
- `percent`
|
|
|
|
### واحد فاصله مصرف
|
|
|
|
- `day`
|
|
- `week`
|
|
|
|
---
|
|
|
|
## قوانین پیشنهادی برای بکاند
|
|
|
|
### 1) متن نمایشی و مقدار عددی را با هم برگردانید
|
|
|
|
اشتباه:
|
|
|
|
```json
|
|
{
|
|
"amountPerHectare": "150 kg/ha"
|
|
}
|
|
```
|
|
|
|
صحیح:
|
|
|
|
```json
|
|
{
|
|
"dosage": {
|
|
"base_amount_per_hectare": 150,
|
|
"base_amount_per_square_meter": 0.015,
|
|
"unit": "kg",
|
|
"label": "150 کیلوگرم در هکتار"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2) هیچ داده مهمی فقط داخل `reasoning` دفن نشود
|
|
|
|
مواردی مثل:
|
|
|
|
- درصد N, P, K
|
|
- درصد ریزمغذیها
|
|
- مقدار مصرف پایه
|
|
- روش مصرف
|
|
|
|
باید فیلد مستقل داشته باشند، نه فقط متن آزاد.
|
|
|
|
### 3) نام مرحله رشد و نام محصول را هم برگردانید
|
|
|
|
تا Header صفحه بدون lookup اضافه ساخته شود.
|
|
|
|
---
|
|
|
|
## حداقل خروجی لازم برای نسخه فعلی فرانت
|
|
|
|
اگر بکاند بخواهد فقط حداقل دادهی لازم را برگرداند، این ساختار minimum پیشنهاد میشود:
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"data": {
|
|
"crop": {
|
|
"id": "wheat",
|
|
"name": "گندم"
|
|
},
|
|
"growth_stage": {
|
|
"id": "flowering",
|
|
"name": "گلدهی"
|
|
},
|
|
"primary_recommendation": {
|
|
"fertilizer_name": "کود کامل 20-20-20",
|
|
"fertilizer_type": "NPK",
|
|
"npk_ratio": {
|
|
"n": 20,
|
|
"p": 20,
|
|
"k": 20,
|
|
"label": "20-20-20"
|
|
},
|
|
"application_method": {
|
|
"label": "محلول پاشی / آب آبیاری"
|
|
},
|
|
"application_interval": {
|
|
"label": "هر 14 روز"
|
|
},
|
|
"dosage": {
|
|
"base_amount_per_hectare": 150,
|
|
"base_amount_per_square_meter": 0.015,
|
|
"unit": "kg",
|
|
"label": "150 کیلوگرم در هکتار"
|
|
},
|
|
"reasoning": "توضیحات توصیه"
|
|
},
|
|
"nutrient_analysis": {
|
|
"macro": [
|
|
{ "key": "n", "name": "نیتروژن (N)", "value": 20, "unit": "percent" },
|
|
{ "key": "p", "name": "فسفر (P)", "value": 20, "unit": "percent" },
|
|
{ "key": "k", "name": "پتاسیم (K)", "value": 20, "unit": "percent" }
|
|
],
|
|
"micro": []
|
|
},
|
|
"application_guide": {
|
|
"safety_warning": "هشدار ایمنی",
|
|
"steps": [
|
|
{ "step_number": 1, "title": "آماده سازی", "description": "..." },
|
|
{ "step_number": 2, "title": "ترکیب", "description": "..." },
|
|
{ "step_number": 3, "title": "مصرف", "description": "..." }
|
|
]
|
|
},
|
|
"alternative_recommendations": []
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## نتیجه نهایی
|
|
|
|
برای اینکه UI فعلی بدون parse کردن رشتهها و بدون hard-code اضافی درست کار کند، بکاند باید حداقل این موارد را صریح برگرداند:
|
|
|
|
1. نام کود
|
|
2. نوع کود
|
|
3. نسبت NPK به صورت عددی و متنی
|
|
4. روش مصرف
|
|
5. فاصله مصرف
|
|
6. مقدار پایه در هکتار
|
|
7. مقدار پایه در متر مربع
|
|
8. واحد مقدار مصرف
|
|
9. استدلال توصیه
|
|
10. آنالیز ماکرو و ریزمغذیها به صورت ساختارمند
|
|
11. هشدار ایمنی
|
|
12. مراحل مصرف
|
|
13. کودهای جایگزین با توضیح
|
|
|
|
اگر خواستی، قدم بعدی میتوانم همین فایل را به یک قرارداد نهایی هماهنگ با TypeScript interface های `src/libs/api/services/fertilizationRecommendationService.ts` هم تبدیل کنم.
|