# 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` هم تبدیل کنم.