Files
Logic/Modules/Ai/docs/irrigation_fertilization_plan_parser_apis.md
T
2026-05-11 03:27:21 +03:30

18 KiB

Free-Text Plan Parser APIs

این فایل برای تیم فرانت‌اند آماده شده و دو API جدید زیر را توضیح می‌دهد:

  • POST /api/irrigation/plan-from-text/
  • POST /api/fertilization/plan-from-text/

هدف هر دو API:

  • کاربر یک متن آزاد می‌نویسد
  • بک‌اند تلاش می‌کند برنامه آبیاری یا کودهی را به JSON ساختاریافته تبدیل کند
  • اگر اطلاعات کامل باشد، JSON نهایی برمی‌گردد
  • اگر اطلاعات ناقص باشد، API سوال‌های تکمیلی برمی‌گرداند
  • فرانت‌اند سوال‌ها را از کاربر می‌پرسد و پاسخ‌ها را دوباره برای API می‌فرستد

رفتار کلی هر دو API

هر دو endpoint یک flow یکسان دارند:

  1. کاربر متن آزاد اولیه را می‌فرستد
  2. اگر متن کامل باشد:
    • status = "completed"
    • final_plan برمی‌گردد
  3. اگر متن ناقص باشد:
    • status = "needs_clarification"
    • missing_fields برمی‌گردد
    • questions برمی‌گردد
  4. فرانت‌اند پاسخ کاربر به سوال‌ها را جمع می‌کند
  5. دوباره همان endpoint را با answers و partial_plan صدا می‌زند
  6. این روند تا ساخته شدن final_plan ادامه پیدا می‌کند

الگوی کلی response

هر دو API از envelope استاندارد استفاده می‌کنند:

{
  "code": 200,
  "msg": "موفق",
  "data": {}
}

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

فیلد نوع توضیح
code number کد منطقی پاسخ
msg string پیام کوتاه پاسخ
data object داده اصلی API

1) API استخراج برنامه آبیاری

Endpoint

POST /api/irrigation/plan-from-text/

کاربرد

این API متن آزاد کاربر درباره برنامه آبیاری را به JSON ساختاریافته تبدیل می‌کند.

Request Body

هر سه فیلد زیر اختیاری هستند، اما حداقل یکی از این‌ها باید ارسال شود:

  • message
  • answers
  • partial_plan

ساختار request

{
  "message": "برای گوجه فرنگی با آبیاری قطره ای هر سه روز یک بار صبح زود 25 دقیقه آبیاری می کنم و حدود 18 لیتر برای هر بوته می دهم.",
  "answers": {
    "growth_stage": "گلدهی"
  },
  "partial_plan": {
    "crop_name": "گوجه فرنگی",
    "irrigation_method": "قطره ای"
  },
  "farm_uuid": "11111111-1111-1111-1111-111111111111"
}

فیلدهای request

فیلد نوع اجباری توضیح
message string خیر متن آزاد کاربر
answers object خیر پاسخ‌های تکمیلی کاربر به سوال‌هایی که قبلا API داده
partial_plan object خیر خروجی مرحله قبل برای ادامه تکمیل
farm_uuid string خیر برای غنی‌سازی context مزرعه در RAG

قانون validation

اگر هیچ‌کدام از message، answers یا partial_plan ارسال نشوند:

{
  "code": 400,
  "msg": "داده نامعتبر.",
  "data": {
    "non_field_errors": [
      "حداقل یکی از message، answers یا partial_plan باید ارسال شود."
    ]
  }
}

پاسخ موفق - حالت تکمیل شده

وقتی همه اطلاعات لازم موجود باشد:

{
  "code": 200,
  "msg": "موفق",
  "data": {
    "status": "completed",
    "status_fa": "تکمیل شد",
    "summary": "برنامه آبیاری برای گوجه‌فرنگی به روش قطره‌ای هر سه روز یک‌بار صبح زود به مدت 25 دقیقه اجرا می‌شود.",
    "missing_fields": [],
    "questions": [],
    "collected_data": {
      "crop_name": "گوجه‌فرنگی",
      "growth_stage": "گلدهی",
      "irrigation_method": "قطره‌ای",
      "water_amount_per_event": "18 لیتر برای هر بوته",
      "duration_minutes": 25,
      "frequency_text": "هر سه روز یک‌بار",
      "interval_days": 3,
      "preferred_time_of_day": "صبح زود",
      "start_date": "از امروز",
      "target_area": "کل مزرعه",
      "trigger_conditions": [],
      "notes": []
    },
    "final_plan": {
      "crop_name": "گوجه‌فرنگی",
      "growth_stage": "گلدهی",
      "irrigation_method": "قطره‌ای",
      "water_amount_per_event": "18 لیتر برای هر بوته",
      "duration_minutes": 25,
      "frequency_text": "هر سه روز یک‌بار",
      "interval_days": 3,
      "preferred_time_of_day": "صبح زود",
      "start_date": "از امروز",
      "target_area": "کل مزرعه",
      "trigger_conditions": [],
      "notes": []
    }
  }
}

فیلدهای data

فیلد نوع توضیح
status string یکی از completed یا needs_clarification
status_fa string نسخه فارسی وضعیت
summary string خلاصه قابل نمایش برای کاربر
missing_fields array[string] فیلدهای ناقص
questions array[object] سوال‌های تکمیلی
collected_data object داده‌ای که تا الان از متن و جواب‌ها استخراج شده
final_plan object/null برنامه نهایی؛ فقط در حالت completed

فیلدهای collected_data و final_plan

فیلد نوع توضیح
crop_name string نام محصول
growth_stage string مرحله رشد محصول
irrigation_method string روش آبیاری
water_amount_per_event string مقدار آب هر نوبت
duration_minutes number مدت هر نوبت آبیاری به دقیقه
frequency_text string توصیف متنی فاصله آبیاری
interval_days number فاصله آبیاری بر حسب روز
preferred_time_of_day string زمان مناسب اجرای آبیاری
start_date string زمان یا تاریخ شروع برنامه
target_area string محدوده هدف برنامه
trigger_conditions array[string] شرایط تریگر اختیاری
notes array[string] نکات تکمیلی

پاسخ موفق - حالت نیاز به سوال تکمیلی

اگر اطلاعات کامل نباشد:

{
  "code": 200,
  "msg": "موفق",
  "data": {
    "status": "needs_clarification",
    "status_fa": "نیازمند پرسش تکمیلی",
    "summary": "اطلاعات برنامه آبیاری برای ساخت JSON نهایی کافی نیست و به چند پاسخ تکمیلی نیاز است.",
    "missing_fields": [
      "growth_stage",
      "start_date",
      "target_area"
    ],
    "questions": [
      {
        "id": "growth_stage",
        "field": "growth_stage",
        "question": "محصول الان در چه مرحله رشدی قرار دارد؟",
        "rationale": "مرحله رشد برای کامل شدن برنامه لازم است."
      },
      {
        "id": "start_date",
        "field": "start_date",
        "question": "این برنامه از چه تاریخی یا از چه زمانی باید شروع شود؟",
        "rationale": "زمان شروع برنامه هنوز مشخص نشده است."
      },
      {
        "id": "target_area",
        "field": "target_area",
        "question": "این برنامه برای کل مزرعه است یا بخش/ناحیه خاصی از مزرعه؟",
        "rationale": "محدوده اجرای برنامه باید مشخص باشد."
      }
    ],
    "collected_data": {
      "crop_name": "گوجه‌فرنگی",
      "growth_stage": null,
      "irrigation_method": "قطره‌ای",
      "water_amount_per_event": "18 لیتر برای هر بوته",
      "duration_minutes": 25,
      "frequency_text": "هر سه روز یک‌بار",
      "interval_days": 3,
      "preferred_time_of_day": "صبح زود",
      "start_date": null,
      "target_area": null,
      "trigger_conditions": [],
      "notes": []
    },
    "final_plan": null
  }
}

ساختار questions

فیلد نوع توضیح
id string شناسه سوال
field string فیلدی که این سوال برای آن پرسیده شده
question string متن سوال برای نمایش به کاربر
rationale string توضیح کوتاه برای اینکه چرا این سوال لازم است

flow پیشنهادی فرانت‌اند برای آبیاری

مرحله 1

کاربر متن آزاد می‌فرستد:

{
  "message": "برای گوجه فرنگی هر سه روز یک بار آبیاری می کنم."
}

مرحله 2

اگر status = needs_clarification بود:

  • سوال‌ها را از data.questions به کاربر نمایش بده
  • پاسخ‌ها را جمع کن

مرحله 3

درخواست تکمیلی بزن:

{
  "partial_plan": {
    "crop_name": "گوجه فرنگی",
    "growth_stage": null,
    "irrigation_method": null,
    "water_amount_per_event": null,
    "duration_minutes": null,
    "frequency_text": "هر سه روز یک بار",
    "interval_days": 3,
    "preferred_time_of_day": null,
    "start_date": null,
    "target_area": null,
    "trigger_conditions": [],
    "notes": []
  },
  "answers": {
    "growth_stage": "گلدهی",
    "irrigation_method": "قطره ای",
    "water_amount_per_event": "18 لیتر برای هر بوته",
    "duration_minutes": 25,
    "preferred_time_of_day": "صبح زود",
    "start_date": "از امروز",
    "target_area": "کل مزرعه"
  }
}

مرحله 4

اگر status = completed شد:

  • از data.final_plan به عنوان JSON نهایی استفاده کن

2) API استخراج برنامه کودهی

Endpoint

POST /api/fertilization/plan-from-text/

کاربرد

این API متن آزاد کاربر درباره برنامه کودهی را به JSON ساختاریافته تبدیل می‌کند.

Request Body

{
  "message": "برای گندم در مرحله پنجه زنی هر 12 روز یک بار 20-20-20 به مقدار 35 کیلوگرم در هکتار از طریق کودآبیاری می دهم.",
  "answers": {
    "timing": "هر 12 روز یک بار"
  },
  "partial_plan": {
    "crop_name": "گندم"
  },
  "farm_uuid": "11111111-1111-1111-1111-111111111111"
}

فیلدهای request

فیلد نوع اجباری توضیح
message string خیر متن آزاد کاربر
answers object خیر پاسخ‌های تکمیلی کاربر
partial_plan object خیر داده استخراج شده مرحله قبل
farm_uuid string خیر برای context مزرعه

validation error

{
  "code": 400,
  "msg": "داده نامعتبر.",
  "data": {
    "non_field_errors": [
      "حداقل یکی از message، answers یا partial_plan باید ارسال شود."
    ]
  }
}

پاسخ موفق - حالت تکمیل شده

{
  "code": 200,
  "msg": "موفق",
  "data": {
    "status": "completed",
    "status_fa": "تکمیل شد",
    "summary": "برنامه کودهی برای گندم در مرحله پنجه زنی با کود 20-20-20 به صورت کودآبیاری هر 12 روز یک بار اجرا می شود.",
    "missing_fields": [],
    "questions": [],
    "collected_data": {
      "crop_name": "گندم",
      "growth_stage": "پنجه زنی",
      "objective": "تقویت رشد رویشی",
      "applications": [
        {
          "fertilizer_name": "کود کامل 20-20-20",
          "formula": "20-20-20",
          "amount": "35 کیلوگرم در هکتار",
          "application_method": "کودآبیاری",
          "timing": "هر 12 روز یک بار",
          "interval_days": 12,
          "purpose": "تقویت رشد رویشی"
        }
      ],
      "notes": []
    },
    "final_plan": {
      "crop_name": "گندم",
      "growth_stage": "پنجه زنی",
      "objective": "تقویت رشد رویشی",
      "applications": [
        {
          "fertilizer_name": "کود کامل 20-20-20",
          "formula": "20-20-20",
          "amount": "35 کیلوگرم در هکتار",
          "application_method": "کودآبیاری",
          "timing": "هر 12 روز یک بار",
          "interval_days": 12,
          "purpose": "تقویت رشد رویشی"
        }
      ],
      "notes": []
    }
  }
}

فیلدهای collected_data و final_plan

فیلد نوع توضیح
crop_name string نام محصول
growth_stage string مرحله رشد
objective string/null هدف برنامه
applications array[object] لیست نوبت‌ها یا اقلام کودی
notes array[string] نکات تکمیلی

ساختار هر application

فیلد نوع توضیح
fertilizer_name string نام کود
formula string فرمول یا آنالیز کود
amount string مقدار مصرف
application_method string روش مصرف
timing string زمان‌بندی مصرف
interval_days number فاصله بین نوبت‌ها
purpose string/null هدف آن نوبت

پاسخ موفق - حالت نیاز به سوال تکمیلی

{
  "code": 200,
  "msg": "موفق",
  "data": {
    "status": "needs_clarification",
    "status_fa": "نیازمند پرسش تکمیلی",
    "summary": "اطلاعات برنامه کودهی برای ساخت JSON نهایی کافی نیست و به چند پاسخ تکمیلی نیاز است.",
    "missing_fields": [
      "growth_stage",
      "formula",
      "interval_days"
    ],
    "questions": [
      {
        "id": "growth_stage",
        "field": "growth_stage",
        "question": "محصول الان در چه مرحله رشدی قرار دارد؟",
        "rationale": "مرحله رشد برای تکمیل برنامه لازم است."
      },
      {
        "id": "formula",
        "field": "formula",
        "question": "فرمول یا آنالیز کود چیست؟ مثلا 20-20-20.",
        "rationale": "ترکیب دقیق کود هنوز مشخص نشده است."
      },
      {
        "id": "interval_days",
        "field": "interval_days",
        "question": "فاصله بین نوبت های مصرف کود چند روز است؟",
        "rationale": "عدد فاصله بین نوبت ها برای JSON نهایی لازم است."
      }
    ],
    "collected_data": {
      "crop_name": "گندم",
      "growth_stage": null,
      "objective": null,
      "applications": [
        {
          "fertilizer_name": "کود کامل",
          "formula": null,
          "amount": "35 کیلوگرم در هکتار",
          "application_method": "کودآبیاری",
          "timing": "هر چند وقت یک بار",
          "interval_days": null,
          "purpose": null
        }
      ],
      "notes": []
    },
    "final_plan": null
  }
}

flow پیشنهادی فرانت‌اند برای کودهی

درخواست اولیه

{
  "message": "برای گندم از کود کامل استفاده می کنم."
}

اگر incomplete بود

  • از questions سوال‌ها را بگیر
  • در UI نمایش بده
  • پاسخ‌ها را جمع کن

درخواست تکمیلی

{
  "partial_plan": {
    "crop_name": "گندم",
    "growth_stage": null,
    "objective": null,
    "applications": [
      {
        "fertilizer_name": "کود کامل",
        "formula": null,
        "amount": null,
        "application_method": null,
        "timing": null,
        "interval_days": null,
        "purpose": null
      }
    ],
    "notes": []
  },
  "answers": {
    "growth_stage": "پنجه زنی",
    "formula": "20-20-20",
    "amount": "35 کیلوگرم در هکتار",
    "application_method": "کودآبیاری",
    "timing": "هر 12 روز یک بار",
    "interval_days": 12
  }
}

اگر complete شد

  • از final_plan استفاده کن

نکات مهم برای فرانت‌اند

1. به status تکیه کنید

مهم‌ترین فیلد برای کنترل flow:

  • completed
  • needs_clarification

2. اگر needs_clarification بود

باید:

  • questions را به کاربر نمایش دهید
  • partial_plan را نگه دارید
  • پاسخ‌های کاربر را در answers ارسال کنید

3. اگر completed بود

باید:

  • final_plan را به عنوان نسخه نهایی برنامه ذخیره یا نمایش دهید

4. collected_data همیشه مهم است

حتی اگر برنامه ناقص باشد، collected_data نشان می‌دهد سیستم تا این لحظه چه چیزهایی را فهمیده است.

5. null در حالت ناقص طبیعی است

در حالت needs_clarification ممکن است بعضی فیلدهای collected_data null باشند.
اما در حالت completed نباید فیلدهای اصلی ناقص باشند.

6. فرانت‌اند بهتر است سوال‌ها را به صورت step-by-step بپرسد

پیشنهاد:

  • سوال اول را نشان بده
  • جواب را بگیر
  • همه جواب‌ها را در answers جمع کن
  • دوباره API را صدا بزن

جمع‌بندی تفاوت دو API

API موضوع خروجی نهایی
/api/irrigation/plan-from-text/ استخراج برنامه آبیاری final_plan با ساختار آبیاری
/api/fertilization/plan-from-text/ استخراج برنامه کودهی final_plan با ساختار کودهی

مسیر فایل

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

docs/irrigation_fertilization_plan_parser_apis.md