Files
Backend/FRONTEND_API_CHANGES.md
T
2026-04-02 23:25:39 +03:30

23 KiB

مستند تحویل تغییرات بک‌اند به فرانت

این فایل خلاصه و جمع‌بندی دقیقی از تغییرات انجام‌شده در بک‌اند است تا تیم فرانت بتواند بدون بررسی diffها، مصرف APIها را به‌روزرسانی کند.


جمع‌بندی خیلی کوتاه

بزرگ‌ترین تغییر این release این است که محور اصلی داده‌ها از sensor به farm منتقل شده است.

یعنی:

  • مسیر sensor-hub حذف شده و به farm-hub تغییر کرده است.
  • در endpointهای مختلف، sensor_uuid حذف و farm_uuid جایگزین شده است.
  • چند API که قبلا عمومی یا mock بودند، حالا per-farm و وابسته به مزرعه‌ی انتخاب‌شده هستند.
  • بعضی responseها فیلد farm_uuid را هم برمی‌گردانند تا state فرانت دقیق‌تر بماند.
  • بعضی endpointهایی که در داک قبلی/پست‌من وجود داشتند، الان route فعال ندارند و نباید از سمت فرانت صدا زده شوند.

اقدام لازم برای فرانت

فرانت باید از این به بعد یک farm_uuid فعال/انتخاب‌شده در state سراسری داشته باشد و آن را در درخواست‌های مرتبط ارسال کند.

در عمل:

  1. بعد از گرفتن لیست مزارع از GET /api/farm-hub/، یک مزرعه‌ی active/current انتخاب کنید.
  2. farm_uuid همان مزرعه را برای dashboard، crop zoning، AI assistant، irrigation recommendation و fertilization recommendation ارسال کنید.
  3. هر جایی که قبلا sensor_uuid استفاده می‌شد، باید با farm_uuid جایگزین شود.

Breaking Changes

1) تغییر مسیر اصلی ماژول مزرعه

  • قبلی: /api/sensor-hub/
  • جدید: /api/farm-hub/

اگر فرانت هنوز route قبلی را صدا بزند، دیگر کار نخواهد کرد.


2) حذف sensor_uuid از crop zoning

در crop zoning دیگر sensor_uuid معتبر نیست.

  • قبلی:
GET /api/crop-zoning/area/?sensor_uuid=<uuid>
  • جدید:
GET /api/crop-zoning/area/?farm_uuid=<uuid>

3) dashboard config و dashboard cards حالا per-farm هستند

این دو endpoint دیگر global نیستند و بدون farm_uuid نباید مصرف شوند:

  • GET /api/farm-dashboard-config/?farm_uuid=...
  • PATCH /api/farm-dashboard-config/
  • GET /api/farm-dashboard/?farm_uuid=...

نکته مهم:

  • در GET، farm_uuid باید در query باشد.
  • در PATCH، farm_uuid باید داخل body باشد.

4) Farm AI Assistant حالا کاملا farm-scoped است

تمام flow چت حالا به مزرعه گره خورده است.

یعنی:

  • لیست چت‌ها per-farm است.
  • ساخت conversation جدید بدون farm_uuid ممکن نیست.
  • گرفتن پیام‌ها و حذف conversation هم نیاز به farm_uuid دارد.
  • responseها در چند endpoint جدیدا farm_uuid برمی‌گردانند.

5) Recommendation APIها بدون farm_uuid معتبر نیستند

برای هر دو ماژول:

  • fertilization-recommendation
  • irrigation-recommendation

الان farm_uuid اجباری شده است:

  • در config به‌صورت query param
  • در recommend به‌صورت body
  • در status به‌صورت query param

نکته مهم درباره routeهای فعال

چند endpoint در کد view وجود دارند یا در داک‌های قدیمی/پست‌من دیده می‌شوند، ولی الان route فعال ندارند. فرانت نباید روی آن‌ها حساب کند.

routeهای غیرفعال فعلی

  • POST /api/farm-ai-assistant/chat/
  • GET /api/farm-dashboard/cards/
  • POST /api/crop-zoning/zones/initial/
  • POST /api/crop-zoning/zones/water-need/
  • POST /api/crop-zoning/zones/soil-quality/
  • POST /api/crop-zoning/zones/cultivation-risk/

routeهای فعال فعلی

فقط routeهایی که در این فایل آمده‌اند مبنای فرانت باشند.


1) Farm Hub

هدف

ماژول جدید farm-hub جایگزین sensor-hub شده و موجودیت اصلی فرانت برای انتخاب مزرعه، نمایش سنسورها، ساخت مزرعه و مدیریت فعال/غیرفعال بودن مزرعه است.

Base Path

/api/farm-hub/

endpointهای فعال

Method Path توضیح
GET /api/farm-hub/ لیست مزارع کاربر
POST /api/farm-hub/ ساخت مزرعه جدید
GET /api/farm-hub/{farm_uuid}/ جزئیات مزرعه
PATCH /api/farm-hub/{farm_uuid}/ آپدیت مزرعه
DELETE /api/farm-hub/{farm_uuid}/ حذف مزرعه
POST /api/farm-hub/active/ فعال‌کردن مزرعه
POST /api/farm-hub/deactive/ غیرفعال‌کردن مزرعه

ساختار response مزرعه

{
  "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "name": "مزرعه نمونه",
  "is_active": true,
  "customization": {},
  "farm_type": {
    "uuid": "11111111-1111-1111-1111-111111111111",
    "name": "زراعی",
    "description": "",
    "metadata": {}
  },
  "products": [
    {
      "uuid": "22222222-2222-2222-2222-222222222222",
      "name": "گندم",
      "description": "",
      "metadata": {}
    }
  ],
  "sensors": [
    {
      "uuid": "33333333-3333-3333-3333-333333333333",
      "name": "Station 1",
      "sensor_type": "weather_station",
      "is_active": true,
      "specifications": {},
      "power_source": {},
      "customization": {},
      "last_updated": "2025-02-18T12:00:00Z"
    }
  ],
  "last_updated": "2025-02-18T12:00:00Z"
}

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

  • شناسه اصلی مزرعه farm_uuid است.
  • هر مزرعه farm_type، products و sensors را به‌صورت nested برمی‌گرداند.
  • سنسورها دیگر top-level resource مستقل برای UI نیستند؛ داخل خود مزرعه برمی‌گردند.
  • endpoint جداگانه‌ای برای catalog نوع مزرعه/محصول در این diff اضافه نشده است.

ساخت مزرعه

نمونه body:

{
  "name": "farm-1",
  "farm_type_uuid": "11111111-1111-1111-1111-111111111111",
  "product_uuids": [
    "22222222-2222-2222-2222-222222222222"
  ],
  "customization": {
    "report_interval_sec": 300
  },
  "sensors": [
    {
      "name": "Station 1",
      "sensor_type": "weather_station",
      "is_active": true,
      "specifications": {
        "model": "FH-1"
      },
      "power_source": {
        "type": "battery"
      },
      "customization": {
        "report_interval_sec": 300
      }
    }
  ],
  "area_geojson": {
    "type": "Feature",
    "properties": {},
    "geometry": {
      "type": "Polygon",
      "coordinates": [
        [
          [51.418934, 35.706815],
          [51.423054, 35.691062],
          [51.384258, 35.689389],
          [51.418934, 35.706815]
        ]
      ]
    }
  }
}

تغییر مهم در create farm

اگر area_geojson ارسال شود:

  • مزرعه ساخته می‌شود
  • zoning اولیه هم برای همان مزرعه ساخته می‌شود
  • در response، فیلد zoning هم برمی‌گردد

این برای فرانت خیلی مهم است چون بعد از ساخت مزرعه می‌تواند مستقیم zoning اولیه را برای map استفاده کند و لازم نیست منتظر call جداگانه باشد.

فعال/غیرفعال کردن مزرعه

body هر دو endpoint:

{
  "farm_uuid": "550e8400-e29b-41d4-a716-446655440000"
}

2) Crop Zoning

Base Path

/api/crop-zoning/

endpointهای فعال

Method Path توضیح
GET /api/crop-zoning/area/?farm_uuid=...&page=1&page_size=10 گرفتن area + task status + zones
GET /api/crop-zoning/products/ گرفتن لیست محصولات قابل کشت
GET /api/crop-zoning/zones/{zone_id}/details/ جزئیات یک زون

breaking change

فقط farm_uuid معتبر است و request باید روی مزرعه‌ی متعلق به همان کاربر انجام شود.

نمونه request

GET /api/crop-zoning/area/?farm_uuid=<farm_uuid>&page=1&page_size=10

نمونه response

{
  "status": "success",
  "data": {
    "task": {
      "status": "SUCCESS",
      "stage": "completed",
      "stage_label": "پردازش همه زون‌ها کامل شده است",
      "area_uuid": "c0eaa4d7-92bf-4542-a60d-6010b45e7c96",
      "total_zones": 364,
      "completed_zones": 364,
      "processing_zones": 0,
      "pending_zones": 0,
      "failed_zones": 0,
      "remaining_zones": 0,
      "progress_percent": 100,
      "summary": {
        "done": 364,
        "in_progress": 0,
        "remaining": 0,
        "failed": 0
      },
      "message": "از مجموع 364 زون، 364 زون پردازش شده، 0 زون در حال پردازش و 0 زون باقی مانده است.",
      "failed_zone_errors": [],
      "cell_side_km": 0.1
    },
    "area": {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": []
      },
      "properties": {
        "center": {
          "latitude": 35.69575533,
          "longitude": 51.40874867
        },
        "area_sqm": 3109868.97,
        "cell_side_km": 0.1,
        "area_hectares": 310.9869
      }
    },
    "zones": [],
    "pagination": {
      "page": 1,
      "page_size": 10,
      "total_pages": 37,
      "total_zones": 364,
      "returned_zones": 10,
      "has_next": true,
      "has_previous": false
    }
  }
}

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

  • zones صفحه‌بندی‌شده است؛ کل زون‌ها در هر response برنمی‌گردند.
  • فرانت باید با task.status و task.stage polling را مدیریت کند.
  • page و page_size هنوز اختیاری هستند.
  • اگر مزرعه area نداشته باشد، بک‌اند خودش area/zones را برای همان مزرعه ایجاد می‌کند.

خطاها

نبودن farm_uuid

{
  "status": "error",
  "message": "farm_uuid is required."
}

پیدا نشدن مزرعه

{
  "status": "error",
  "message": "Farm not found."
}

3) Farm Dashboard

Base Path

/api/farm-dashboard/

Config Path

/api/farm-dashboard-config/

تغییر اصلی

dashboard config دیگر mock/global نیست و برای هر مزرعه جداگانه در دیتابیس ذخیره می‌شود.

endpointهای فعال

Method Path توضیح
GET /api/farm-dashboard-config/?farm_uuid=... گرفتن تنظیمات داشبورد همان مزرعه
PATCH /api/farm-dashboard-config/ آپدیت partial تنظیمات داشبورد همان مزرعه
GET /api/farm-dashboard/?farm_uuid=... گرفتن داده کارت‌های داشبورد برای همان مزرعه

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

  • GET /api/farm-dashboard/cards/ الان route فعال ندارد؛ فقط base path فعال است.
  • در response config، فیلد farm_uuid اضافه شده است.
  • در PATCH حتی اگر فقط یک فیلد را تغییر می‌دهید، باز هم باید farm_uuid را بفرستید.

GET config

GET /api/farm-dashboard-config/?farm_uuid=<farm_uuid>

GET config response

{
  "code": 200,
  "msg": "OK",
  "data": {
    "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "disabled_card_ids": [],
    "row_order": [
      "overviewKpis",
      "weatherAlerts",
      "sensorMonitoring",
      "sensorCharts",
      "alertsWater",
      "predictions",
      "soilHeatmap",
      "ndviRecommendations",
      "economic"
    ],
    "enable_drag_reorder": true
  }
}

PATCH config sample

{
  "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "disabled_card_ids": [
    "farmWeatherCard"
  ]
}

rule مهم PATCH

اگر body فقط این باشد:

{
  "farm_uuid": "..."
}

خطای validation می‌گیرید، چون باید حداقل یکی از این‌ها هم باشد:

  • disabled_card_ids
  • row_order
  • enable_drag_reorder

خطاهای متداول

نبودن farm_uuid

{
  "farm_uuid": [
    "This field is required."
  ]
}

مزرعه متعلق به کاربر نباشد

{
  "farm_uuid": [
    "Farm not found."
  ]
}

4) Farm AI Assistant

Base Path

/api/farm-ai-assistant/

endpointهای فعال

Method Path توضیح
GET /api/farm-ai-assistant/context/?farm_uuid=... گرفتن context مزرعه برای نوار/summary
GET /api/farm-ai-assistant/chats/?farm_uuid=... لیست conversationهای همان مزرعه
POST /api/farm-ai-assistant/chats/ ساخت conversation جدید
GET /api/farm-ai-assistant/chats/{conversation_id}/messages/?farm_uuid=... گرفتن پیام‌ها
DELETE /api/farm-ai-assistant/chats/{conversation_id}/?farm_uuid=... حذف conversation
POST /api/farm-ai-assistant/chat/task/ ایجاد task چت
GET /api/farm-ai-assistant/chat/task/{task_id}/status/?farm_uuid=... گرفتن وضعیت task

نکته خیلی مهم

POST /api/farm-ai-assistant/chat/ الان route فعال ندارد.

پس flow فعلی فرانت باید async باشد:

  1. POST /chat/task/
  2. polling روی GET /chat/task/{task_id}/status/

تغییرات مهم response

فیلد farm_uuid در این قسمت‌ها اضافه شده است:

  • conversation summary
  • لیست پیام‌ها
  • delete response
  • task create response
  • task status response
  • assistant payload نهایی

GET context

GET /api/farm-ai-assistant/context/?farm_uuid=<farm_uuid>

نمونه response:

{
  "status": "success",
  "data": {
    "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "soilType": "Loamy",
    "waterEC": "1.2 dS/m",
    "selectedCrop": "Tomato",
    "growthStage": "Flowering",
    "lastIrrigationStatus": "2 days ago"
  }
}

GET chats response

{
  "status": "success",
  "data": [
    {
      "id": "conv-123",
      "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
      "message_count": 4
    }
  ]
}

POST chats request

{
  "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "title": "New chat",
  "farm_context": {
    "soilType": "Loamy"
  }
}

POST chat task request

{
  "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "conversation_id": "7a26d99a-8d67-467d-a4a8-4c46b62b6bc2",
  "content": "What is the best irrigation plan?",
  "images": [],
  "farm_context": {
    "soilType": "Loamy"
  }
}

POST chat task response

{
  "status": "success",
  "data": {
    "task_id": "farm-ai-chat-task-123",
    "status": "PENDING",
    "status_url": "/api/tasks/farm-ai-chat-task-123/status/",
    "conversation_id": "7a26d99a-8d67-467d-a4a8-4c46b62b6bc2",
    "message_id": "2cbd4d61-363d-4f7c-a46a-a78cf28f6dd8",
    "farm_uuid": "550e8400-e29b-41d4-a716-446655440000"
  }
}

GET task status response در حالت success

{
  "status": "success",
  "data": {
    "task_id": "farm-ai-chat-task-123",
    "status": "SUCCESS",
    "conversation_id": "7a26d99a-8d67-467d-a4a8-4c46b62b6bc2",
    "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "result": {
      "message_id": "msg-001",
      "conversation_id": "7a26d99a-8d67-467d-a4a8-4c46b62b6bc2",
      "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
      "content": "Here is the recommended plan.",
      "sections": []
    }
  }
}

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

  • conversationها حالا per-farm هستند؛ لیست چت مزرعه A لزوما برای مزرعه B مشترک نیست.
  • برای گرفتن messages و delete هم باید farm_uuid در query بفرستید.
  • در response پیام‌ها، هم top-level و هم هر message شامل farm_uuid است.

خطاها

  • اگر farm_uuid نفرستید: 400
  • اگر مزرعه پیدا نشود: در این ماژول معمولا 404

5) Fertilization Recommendation

Base Path

/api/fertilization-recommendation/

endpointهای فعال

Method Path توضیح
GET /api/fertilization-recommendation/config/?farm_uuid=... گرفتن داده اولیه فرم
POST /api/fertilization-recommendation/recommend/ ساخت recommendation
GET /api/fertilization-recommendation/recommend/status/{task_id}/?farm_uuid=... وضعیت task

breaking change

farm_uuid برای این ماژول اجباری شده است.

GET config

GET /api/fertilization-recommendation/config/?farm_uuid=<farm_uuid>

response config

{
  "status": "success",
  "data": {
    "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "farmData": {
      "soilType": "Loamy",
      "organicMatter": "Medium (2.5%)",
      "waterEC": "1.2 dS/m"
    },
    "growthStages": [],
    "cropOptions": []
  }
}

POST recommend request

{
  "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "crop_id": "wheat",
  "growth_stage": "flowering",
  "farm_data": {
    "soilType": "Loamy",
    "organicMatter": "Medium (2.5%)",
    "waterEC": "1.2 dS/m"
  }
}

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

  • اگر farm_uuid نفرستید، validation error می‌گیرید.
  • در status endpoint هم farm_uuid باید query param باشد.
  • بک‌اند درخواست/پاسخ recommendation را برای هر مزرعه ذخیره می‌کند، ولی این persistence فعلا response shape فرانت را تغییر نمی‌دهد.

نمونه خطا

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

6) Irrigation Recommendation

Base Path

/api/irrigation-recommendation/

endpointهای فعال

Method Path توضیح
GET /api/irrigation-recommendation/config/?farm_uuid=... گرفتن داده اولیه فرم
POST /api/irrigation-recommendation/recommend/ ساخت recommendation
GET /api/irrigation-recommendation/recommend/status/{task_id}/?farm_uuid=... وضعیت task

breaking change

farm_uuid برای این ماژول هم اجباری شده است.

GET config

GET /api/irrigation-recommendation/config/?farm_uuid=<farm_uuid>

response config

{
  "status": "success",
  "data": {
    "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "farmInfo": {
      "soilType": "Loamy",
      "waterQuality": "Medium EC",
      "climateZone": "Temperate"
    },
    "cropOptions": []
  }
}

POST recommend request

{
  "farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "crop_id": "wheat",
  "farm_data": {
    "soilType": "Loamy",
    "waterQuality": "Medium EC",
    "climateZone": "Temperate"
  }
}

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

  • route جداگانه‌ای برای task create در urls فعال نیست؛ همان POST /recommend/ را استفاده کنید.
  • برای status هم حتما farm_uuid را در query بفرستید.
  • response نهایی ممکن است شامل plan، water_balance، raw_response و status باشد.

نمونه خطا

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

الگوی مشترک خطاها

بسته به ماژول، شکل خطا یکسان نیست. فرانت بهتر است هر دو الگوی زیر را پشتیبانی کند:

الگوی 1

{
  "status": "error",
  "message": "Farm not found."
}

الگوی 2

{
  "farm_uuid": [
    "Farm not found."
  ]
}

الگوی 3

{
  "detail": "Farm not found"
}

پس بهتر است parsing خطا فقط روی یک shape ثابت بسته نشود.


وضعیت احراز هویت

برای endpointهای این فایل، فرانت بهتر است همیشه این هدرها را بفرستد:

Authorization: Bearer <access_token>
Content-Type: application/json

به‌خصوص در این ماژول‌ها:

  • farm-hub
  • farm-dashboard
  • farm-ai-assistant
  • crop-zoning
  • fertilization-recommendation
  • irrigation-recommendation

چک‌لیست تغییرات لازم در فرانت

اجباری

  • همه referenceهای sensor_uuid را به farm_uuid تغییر دهید.
  • همه callهای sensor-hub را به farm-hub تغییر دهید.
  • یک state مرکزی برای selectedFarm یا currentFarm داشته باشید.
  • قبل از callهای dashboard/zoning/assistant/recommendation، farm_uuid مزرعه انتخابی را inject کنید.
  • flow چت را از sync به async task-based تغییر دهید.

مهم

  • GET /api/farm-dashboard/cards/ را با GET /api/farm-dashboard/?farm_uuid=... جایگزین کنید.
  • در dashboard config patch، farm_uuid را داخل body بفرستید.
  • اگر روی routeهای crop zoning قدیمی مثل zones/water-need حساب کرده‌اید، آن‌ها را از flow حذف کنید.

بهتر است

  • هندل خطا را tolerant بنویسید چون shape خطا بین ماژول‌ها یکسان نیست.
  • farm_uuid برگشتی responseها را با state فرانت sync نگه دارید.
  • بعد از create farm اگر response شامل zoning بود، مستقیم آن را برای map استفاده کنید.

جمع‌بندی نهایی

اگر بخواهیم خیلی عملی بگوییم، فرانت برای این release فقط باید این سه اصل را رعایت کند:

  1. همه چیز را بر اساس farm_uuid مصرف کند، نه sensor_uuid.
  2. تمام ماژول‌های اصلی را روی مزرعه‌ی انتخابی کاربر scope کند.
  3. فقط routeهای فعال فعلی را مصرف کند، نه routeهایی که در داک‌های قدیمی یا پست‌من قبلی دیده می‌شوند.

اگر لازم باشد، مرحله بعدی می‌تواند تولید یک نسخه‌ی کوتاه‌تر مخصوص frontend devها باشد که فقط شامل endpoint matrix و نمونه request/response باشد.