UPDATE
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
# Pest Disease Risk Summary API Reference
|
||||
|
||||
این فایل برای فرانت آماده شده تا ساختار خروجی endpoint زیر مشخص و قابل استفاده باشد:
|
||||
|
||||
```http
|
||||
POST /api/pest-disease/risk-summary/
|
||||
```
|
||||
|
||||
## Purpose
|
||||
|
||||
این endpoint فقط `farm_uuid` میگیرد و در backend:
|
||||
|
||||
- مزرعه را پیدا میکند
|
||||
- اولین محصول ثبتشده روی همان مزرعه را برمیدارد
|
||||
- `plant_name` را از همان محصول پر میکند
|
||||
- `growth_stage` را فعلاً به صورت ثابت `گلدهی` به سرویس AI میفرستد
|
||||
- خروجی خلاصه ریسک آفت و بیماری را به فرانت برمیگرداند
|
||||
|
||||
---
|
||||
|
||||
## Request
|
||||
|
||||
### Body
|
||||
|
||||
```json
|
||||
{
|
||||
"farm_uuid": "11111111-1111-1111-1111-111111111111"
|
||||
}
|
||||
```
|
||||
|
||||
### Request Fields
|
||||
|
||||
| field | type | required | description |
|
||||
|---|---|---:|---|
|
||||
| `farm_uuid` | `string (uuid)` | yes | UUID مزرعه |
|
||||
|
||||
### Important Notes
|
||||
|
||||
- این endpoint فقط `farm_uuid` را از کلاینت قبول میکند.
|
||||
- `plant_name` نباید از فرانت ارسال شود.
|
||||
- `growth_stage` نباید از فرانت ارسال شود.
|
||||
- `plant_name` در backend از اولین محصول مزرعه استخراج میشود.
|
||||
- اگر مزرعه هیچ محصولی نداشته باشد، `plant_name` به صورت رشته خالی به AI ارسال میشود.
|
||||
- `growth_stage` فعلاً همیشه `گلدهی` است.
|
||||
|
||||
---
|
||||
|
||||
## Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
||||
"diseaseRisk": {
|
||||
"id": "disease-risk",
|
||||
"title": "ریسک بیماری",
|
||||
"subtitle": "فشار بیماری در حال افزایش است",
|
||||
"stats": "68%",
|
||||
"avatarColor": "warning",
|
||||
"avatarIcon": "tabler-biohazard",
|
||||
"chipText": "متوسط",
|
||||
"chipColor": "warning",
|
||||
"details": {
|
||||
"reason": "رطوبت بالا و تهویه ضعیف"
|
||||
}
|
||||
},
|
||||
"pestRisk": {
|
||||
"id": "pest-risk",
|
||||
"title": "ریسک آفت",
|
||||
"subtitle": "فعالیت آفات قابل توجه است",
|
||||
"stats": "41%",
|
||||
"avatarColor": "info",
|
||||
"avatarIcon": "tabler-bug",
|
||||
"chipText": "کم",
|
||||
"chipColor": "success",
|
||||
"details": {
|
||||
"reason": "شرایط محیطی نسبتاً پایدار"
|
||||
}
|
||||
},
|
||||
"drivers": {
|
||||
"humidity": "high",
|
||||
"temperature": "moderate"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Success Response Fields
|
||||
|
||||
### Top Level
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `code` | `number` | در حالت موفق مقدار `200` |
|
||||
| `msg` | `string` | در حالت موفق مقدار `success` |
|
||||
| `data` | `object` | محتوای اصلی پاسخ |
|
||||
|
||||
### `data`
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `farm_uuid` | `string` | UUID مزرعه |
|
||||
| `diseaseRisk` | `object` | کارت ریسک بیماری |
|
||||
| `pestRisk` | `object` | کارت ریسک آفت |
|
||||
| `drivers` | `object` | عوامل موثر روی ریسک |
|
||||
|
||||
### `diseaseRisk` / `pestRisk`
|
||||
|
||||
هر دو فیلد `diseaseRisk` و `pestRisk` یک ساختار مشابه دارند:
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `id` | `string` | شناسه کارت |
|
||||
| `title` | `string` | عنوان کارت |
|
||||
| `subtitle` | `string` | توضیح کوتاه |
|
||||
| `stats` | `string` | عدد یا درصد اصلی برای نمایش |
|
||||
| `avatarColor` | `string` | رنگ آیکن یا کارت |
|
||||
| `avatarIcon` | `string` | نام آیکن |
|
||||
| `chipText` | `string` | وضعیت متنی مثل `کم`، `متوسط`، `زیاد` |
|
||||
| `chipColor` | `string` | رنگ وضعیت مثل `success`، `warning`، `error` |
|
||||
| `details` | `object` | اطلاعات تکمیلی برای UI جزئیتر |
|
||||
|
||||
### `drivers`
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `drivers` | `object` | object آزاد از عوامل مؤثر مثل رطوبت، دما، باد، بارندگی و غیره |
|
||||
|
||||
نکته:
|
||||
- ساختار داخلی `drivers` ثابت و محدود نیست و بهتر است در فرانت به صورت dynamic render شود.
|
||||
|
||||
---
|
||||
|
||||
## Error Response - Missing `farm_uuid`
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"farm_uuid": ["This field is required."]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### When Happens
|
||||
|
||||
- وقتی `farm_uuid` در body ارسال نشده باشد
|
||||
|
||||
---
|
||||
|
||||
## Error Response - Farm Not Found
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"farm_uuid": ["Farm not found."]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### When Happens
|
||||
|
||||
- وقتی `farm_uuid` معتبر باشد ولی مزرعهای با آن پیدا نشود
|
||||
- یا مزرعه متعلق به کاربر فعلی نباشد
|
||||
|
||||
---
|
||||
|
||||
## Error Response - Upstream / AI Error
|
||||
|
||||
اگر سرویس AI خطا برگرداند، backend همان status code را با این ساختار پاس میدهد:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"message": "Upstream service error"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
نکته:
|
||||
- محتویات `data` در این حالت بسته به پاسخ upstream ممکن است متفاوت باشد.
|
||||
|
||||
---
|
||||
|
||||
## Frontend Notes
|
||||
|
||||
- فرم درخواست فقط باید `farm_uuid` بفرستد.
|
||||
- `diseaseRisk` و `pestRisk` را مثل card model در UI مصرف کنید.
|
||||
- `drivers` را optional و dynamic در نظر بگیرید.
|
||||
- اگر یکی از `diseaseRisk` یا `pestRisk` خالی بود، UI باید بدون crash کار کند.
|
||||
- متن خطا برای `400` و `404` را میتوانید از `data.farm_uuid[0]` بخوانید.
|
||||
|
||||
---
|
||||
|
||||
## Suggested TypeScript Interfaces
|
||||
|
||||
```ts
|
||||
export interface RiskCard {
|
||||
id?: string;
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
stats?: string;
|
||||
avatarColor?: string;
|
||||
avatarIcon?: string;
|
||||
chipText?: string;
|
||||
chipColor?: string;
|
||||
details?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface PestDiseaseRiskSummaryResponse {
|
||||
code: number;
|
||||
msg: string;
|
||||
data: {
|
||||
farm_uuid: string;
|
||||
diseaseRisk?: RiskCard;
|
||||
pestRisk?: RiskCard;
|
||||
drivers?: Record<string, unknown>;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example Frontend Handling
|
||||
|
||||
```ts
|
||||
const response = await api.post('/api/pest-disease/risk-summary/', {
|
||||
farm_uuid,
|
||||
});
|
||||
|
||||
const result = response.data;
|
||||
|
||||
if (result.code === 200) {
|
||||
const diseaseRisk = result.data.diseaseRisk;
|
||||
const pestRisk = result.data.pestRisk;
|
||||
const drivers = result.data.drivers;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,381 @@
|
||||
# Soil API Reference for Frontend
|
||||
|
||||
این فایل برای فرانت آماده شده تا ساختار پاسخ APIهای خاک را سریع و شفاف داشته باشید.
|
||||
|
||||
## Base Notes
|
||||
|
||||
- سه endpoint زیر `farm_uuid` را به صورت query param لازم دارند:
|
||||
- `GET /api/soil/anomalies/`
|
||||
- `GET /api/soil/moisture-heatmap/`
|
||||
- `GET /api/soil/summary/`
|
||||
- endpoint `GET /api/soil/avg-moisture/` بدون `farm_uuid` هم جواب میدهد، ولی اگر `farm_uuid` ارسال شود داده بر اساس همان مزرعه محاسبه میشود.
|
||||
- در سه endpoint اول و سوم، اگر `farm_uuid` ارسال نشود یا مزرعه پیدا نشود، پاسخ با ساختار `code/msg/data` برمیگردد.
|
||||
- پاسخ موفق `avg-moisture` با کلید `status` برمیگردد، ولی سه endpoint دیگر با کلیدهای `code`, `msg`, `data` برمیگردند.
|
||||
|
||||
---
|
||||
|
||||
## 1) Average Soil Moisture
|
||||
|
||||
### Endpoint
|
||||
|
||||
```http
|
||||
GET /api/soil/avg-moisture/?farm_uuid=<farm_uuid>
|
||||
```
|
||||
|
||||
### Query Params
|
||||
|
||||
| name | type | required | description |
|
||||
|---|---|---:|---|
|
||||
| `farm_uuid` | `string (uuid)` | no | UUID مزرعه |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"id": "avg_soil_moisture",
|
||||
"title": "میانگین رطوبت خاک",
|
||||
"subtitle": "کل مزرعه",
|
||||
"stats": "65%",
|
||||
"avatarColor": "primary",
|
||||
"avatarIcon": "tabler-plant-2",
|
||||
"chipText": "بهینه",
|
||||
"chipColor": "success"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Response Fields
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `status` | `string` | در حالت موفق مقدار `success` |
|
||||
| `data.id` | `string` | شناسه کارت |
|
||||
| `data.title` | `string` | عنوان کارت |
|
||||
| `data.subtitle` | `string` | زیرعنوان کارت |
|
||||
| `data.stats` | `string` | مقدار اصلی به صورت درصد، مثل `48%` |
|
||||
| `data.avatarColor` | `string` | رنگ آیکن/کارت |
|
||||
| `data.avatarIcon` | `string` | نام آیکن |
|
||||
| `data.chipText` | `string` | وضعیت متنی، مثل `بهینه`، `متوسط`، `کم` |
|
||||
| `data.chipColor` | `string` | رنگ وضعیت، مثل `success`، `warning`، `error` |
|
||||
|
||||
### Frontend Notes
|
||||
|
||||
- این endpoint برای ساخت یک KPI card مناسب است.
|
||||
- `stats` همیشه string است و بهتر است مستقیم render شود.
|
||||
- `chipText` و `chipColor` برای badge یا status pill استفاده شوند.
|
||||
|
||||
---
|
||||
|
||||
## 2) Soil Anomalies
|
||||
|
||||
### Endpoint
|
||||
|
||||
```http
|
||||
GET /api/soil/anomalies/?farm_uuid=<farm_uuid>
|
||||
```
|
||||
|
||||
### Query Params
|
||||
|
||||
| name | type | required | description |
|
||||
|---|---|---:|---|
|
||||
| `farm_uuid` | `string (uuid)` | yes | UUID مزرعه |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
||||
"summary": "Risk of localized soil imbalance detected.",
|
||||
"explanation": "One or more soil indicators are outside the expected range.",
|
||||
"likely_cause": "Uneven irrigation or nutrient distribution.",
|
||||
"recommended_action": "Inspect the affected zone and verify irrigation schedule.",
|
||||
"monitoring_priority": "high",
|
||||
"confidence": 0.89,
|
||||
"generated_at": "2025-01-01T10:30:00Z",
|
||||
"anomalies": [
|
||||
{
|
||||
"sensor": "رطوبت خاک زون 3",
|
||||
"value": "38%",
|
||||
"expected": "45-65%",
|
||||
"deviation": "-12%",
|
||||
"severity": "warning"
|
||||
}
|
||||
],
|
||||
"interpretation": {
|
||||
"risk_level": "medium"
|
||||
},
|
||||
"knowledge_base": null,
|
||||
"raw_response": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Response Fields
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `code` | `number` | در حالت موفق مقدار `200` |
|
||||
| `msg` | `string` | در حالت موفق مقدار `success` |
|
||||
| `data.farm_uuid` | `string` | UUID مزرعه |
|
||||
| `data.summary` | `string` | خلاصه کوتاه نتیجه anomaly detection |
|
||||
| `data.explanation` | `string` | توضیح readable برای فرانت |
|
||||
| `data.likely_cause` | `string` | علت احتمالی |
|
||||
| `data.recommended_action` | `string` | اقدام پیشنهادی |
|
||||
| `data.monitoring_priority` | `string` | سطح اهمیت پایش؛ مثل `low`, `medium`, `high`, `urgent` |
|
||||
| `data.confidence` | `number` | میزان اطمینان مدل |
|
||||
| `data.generated_at` | `string` | زمان تولید تحلیل |
|
||||
| `data.anomalies` | `array` | لیست anomalyها |
|
||||
| `data.anomalies[].sensor` | `string` | نام سنسور یا ناحیه |
|
||||
| `data.anomalies[].value` | `string` | مقدار فعلی |
|
||||
| `data.anomalies[].expected` | `string` | بازه یا مقدار مورد انتظار |
|
||||
| `data.anomalies[].deviation` | `string` | اختلاف با مقدار نرمال |
|
||||
| `data.anomalies[].severity` | `string` | شدت anomaly، مثل `warning` یا `error` |
|
||||
| `data.interpretation` | `object` | تفسیر ساختاریافته برای UI پیشرفته |
|
||||
| `data.knowledge_base` | `string \| null` | مرجع دانشی در صورت وجود |
|
||||
| `data.raw_response` | `string \| null` | متن خام upstream در صورت وجود |
|
||||
|
||||
### Error Response - Missing `farm_uuid`
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"farm_uuid": ["This field is required."]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Error Response - Farm Not Found
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"farm_uuid": ["Farm not found."]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Frontend Notes
|
||||
|
||||
- `anomalies` میتواند برای table، list یا alert cards استفاده شود.
|
||||
- اگر `anomalies` خالی بود، UI بهتر است empty state نمایش دهد.
|
||||
- `severity` را میتوانید به color map وصل کنید.
|
||||
|
||||
---
|
||||
|
||||
## 3) Soil Moisture Heatmap
|
||||
|
||||
### Endpoint
|
||||
|
||||
```http
|
||||
GET /api/soil/moisture-heatmap/?farm_uuid=<farm_uuid>
|
||||
```
|
||||
|
||||
### Query Params
|
||||
|
||||
| name | type | required | description |
|
||||
|---|---|---:|---|
|
||||
| `farm_uuid` | `string (uuid)` | yes | UUID مزرعه |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
||||
"location": {
|
||||
"name": "Zone A"
|
||||
},
|
||||
"current_sensor": {
|
||||
"name": "Sensor 7-in-1"
|
||||
},
|
||||
"soil_profile": [],
|
||||
"timestamp": "2025-01-01T10:30:00Z",
|
||||
"grid_resolution": {
|
||||
"rows": 10,
|
||||
"cols": 10
|
||||
},
|
||||
"grid_cells": [],
|
||||
"sensor_points": [],
|
||||
"quality_legend": {
|
||||
"low": "0-30",
|
||||
"medium": "31-60",
|
||||
"high": "61-100"
|
||||
},
|
||||
"depth_layers": [],
|
||||
"model_metadata": {},
|
||||
"summary": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Supported Response Shape in Current Backend
|
||||
|
||||
در serializer فعلی این فیلدها پشتیبانی میشوند:
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `data.farm_uuid` | `string` | UUID مزرعه |
|
||||
| `data.location` | `object` | اطلاعات مکانی |
|
||||
| `data.current_sensor` | `object` | اطلاعات سنسور فعال |
|
||||
| `data.soil_profile` | `array<object>` | داده لایههای خاک |
|
||||
| `data.timestamp` | `string \| null` | زمان تولید heatmap |
|
||||
| `data.grid_resolution` | `object` | رزولوشن grid |
|
||||
| `data.grid_cells` | `array<object>` | سلولهای grid |
|
||||
| `data.sensor_points` | `array<object>` | نقاط سنسور |
|
||||
| `data.quality_legend` | `object` | legend مقادیر |
|
||||
| `data.depth_layers` | `array<object>` | لایههای عمقی |
|
||||
| `data.model_metadata` | `object` | متادیتای مدل |
|
||||
| `data.summary` | `object` | خلاصه تفسیری |
|
||||
|
||||
### Legacy / Mock Shape You May Also See
|
||||
|
||||
در داده mock داخلی پروژه یک ساختار سادهتر هم وجود دارد:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"zones": ["زون 1", "زون 2"],
|
||||
"hours": ["6 ص", "8 ص"],
|
||||
"series": [
|
||||
{
|
||||
"name": "زون 1",
|
||||
"data": [
|
||||
{ "x": "6 ص", "y": 52 },
|
||||
{ "x": "8 ص", "y": 48 }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Error Response - Missing `farm_uuid`
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"farm_uuid": ["This field is required."]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Error Response - Farm Not Found
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"farm_uuid": ["Farm not found."]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Frontend Notes
|
||||
|
||||
- چون upstream shape ممکن است object-based یا series-based باشد، فرانت بهتر است defensive parsing داشته باشد.
|
||||
- اگر `grid_cells` وجود داشت، heatmap را از grid render کنید.
|
||||
- اگر `series` وجود داشت، میتوانید آن را به chart heatmap یا matrix chart بدهید.
|
||||
|
||||
---
|
||||
|
||||
## 4) Soil Summary
|
||||
|
||||
### Endpoint
|
||||
|
||||
```http
|
||||
GET /api/soil/summary/?farm_uuid=<farm_uuid>
|
||||
```
|
||||
|
||||
### Query Params
|
||||
|
||||
| name | type | required | description |
|
||||
|---|---|---:|---|
|
||||
| `farm_uuid` | `string (uuid)` | yes | UUID مزرعه |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
||||
"healthScore": 82,
|
||||
"profileSource": "Tomato",
|
||||
"healthScoreDetails": {},
|
||||
"healthLanguage": {},
|
||||
"avgSoilMoisture": 46,
|
||||
"avgSoilMoistureRaw": 46.0,
|
||||
"avgSoilMoistureStatus": "بهینه"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Response Fields
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `code` | `number` | در حالت موفق مقدار `200` |
|
||||
| `msg` | `string` | در حالت موفق مقدار `success` |
|
||||
| `data.farm_uuid` | `string` | UUID مزرعه |
|
||||
| `data.healthScore` | `number` | امتیاز سلامت کلی خاک |
|
||||
| `data.profileSource` | `string` | منبع پروفایل یا محصول مرجع |
|
||||
| `data.healthScoreDetails` | `object` | جزئیات محاسبه health score |
|
||||
| `data.healthLanguage` | `object` | متنها و labelهای قابل نمایش |
|
||||
| `data.avgSoilMoisture` | `number` | میانگین گرد شده رطوبت خاک |
|
||||
| `data.avgSoilMoistureRaw` | `number` | میانگین خام |
|
||||
| `data.avgSoilMoistureStatus` | `string` | وضعیت متنی رطوبت خاک |
|
||||
|
||||
### Error Response - Missing `farm_uuid`
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"farm_uuid": ["This field is required."]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Error Response - Farm Not Found
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"farm_uuid": ["Farm not found."]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Frontend Notes
|
||||
|
||||
- این endpoint برای summary card یا hero panel خیلی مناسب است.
|
||||
- `healthScoreDetails` و `healthLanguage` را optional در نظر بگیرید.
|
||||
- برای UI بهتر، `healthScore` را هم به صورت عدد و هم به صورت progress/gauge نمایش دهید.
|
||||
|
||||
---
|
||||
|
||||
## Suggested Frontend Handling
|
||||
|
||||
- برای `avg-moisture` انتظار `status/data` داشته باشید.
|
||||
- برای `anomalies`, `moisture-heatmap`, `summary` انتظار `code/msg/data` داشته باشید.
|
||||
- برای خطاهای 400 و 404، متن خطا را از `data.farm_uuid[0]` بخوانید.
|
||||
- در heatmap، parsing را flexible بنویسید چون shape داده ممکن است بسته به upstream تغییر کند.
|
||||
@@ -0,0 +1,381 @@
|
||||
# Water & Weather API Reference for Frontend
|
||||
|
||||
این فایل برای فرانت آماده شده تا ساختار پاسخ APIهای زیر مشخص باشد:
|
||||
|
||||
- `GET /api/water/card/`
|
||||
- `GET /api/water/need-prediction/`
|
||||
- `GET /api/water/summary/`
|
||||
- `POST /api/weather/farm-card/`
|
||||
|
||||
## Base Notes
|
||||
|
||||
- `GET /api/water/card/` و `GET /api/water/summary/` بدون `farm_uuid` هم جواب میدهند.
|
||||
- `GET /api/water/need-prediction/` هم بدون `farm_uuid` جواب میدهد، ولی اگر `farm_uuid` وجود داشته باشد ممکن است داده مزرعهمحور برگردد.
|
||||
- `POST /api/weather/farm-card/` نیاز به `farm_uuid` در body دارد.
|
||||
- response shapeها بین این endpointها یکدست نیستند:
|
||||
- بعضی endpointها با `status/data`
|
||||
- بعضی endpointها با `code/msg/data`
|
||||
|
||||
---
|
||||
|
||||
## 1) Water Card
|
||||
|
||||
### Endpoint
|
||||
|
||||
```http
|
||||
GET /api/water/card/?farm_uuid=<farm_uuid>
|
||||
```
|
||||
|
||||
### Query Params
|
||||
|
||||
| field | type | required | description |
|
||||
|---|---|---:|---|
|
||||
| `farm_uuid` | `string (uuid)` | no | UUID مزرعه |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"condition": "صاف",
|
||||
"temperature": 24,
|
||||
"unit": "°C",
|
||||
"humidity": 45,
|
||||
"windSpeed": 12,
|
||||
"windUnit": "km/h",
|
||||
"chartData": {
|
||||
"labels": ["۶ صبح", "۹ صبح", "۱۲ ظهر", "۳ بعدازظهر"],
|
||||
"series": [[18, 22, 26, 28]]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Response Fields
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `status` | `string` | در حالت موفق مقدار `success` |
|
||||
| `data.condition` | `string` | وضعیت فعلی آبوهوا |
|
||||
| `data.temperature` | `number` | دمای فعلی |
|
||||
| `data.unit` | `string` | واحد دما |
|
||||
| `data.humidity` | `number` | رطوبت نسبی |
|
||||
| `data.windSpeed` | `number` | سرعت باد |
|
||||
| `data.windUnit` | `string` | واحد سرعت باد |
|
||||
| `data.chartData.labels` | `string[]` | برچسبهای زمانی |
|
||||
| `data.chartData.series` | `number[][]` | سریهای نمودار |
|
||||
|
||||
### Frontend Notes
|
||||
|
||||
- این endpoint برای weather widget یا weather card مناسب است.
|
||||
- `chartData.series` به شکل آرایه دوبعدی است.
|
||||
- اگر `farm_uuid` ارسال شود، backend داده را از AI گرفته و log هم میکند.
|
||||
|
||||
---
|
||||
|
||||
## 2) Water Need Prediction
|
||||
|
||||
### Endpoint
|
||||
|
||||
```http
|
||||
GET /api/water/need-prediction/?farm_uuid=<farm_uuid>
|
||||
```
|
||||
|
||||
### Query Params
|
||||
|
||||
| field | type | required | description |
|
||||
|---|---|---:|---|
|
||||
| `farm_uuid` | `string (uuid)` | no | UUID مزرعه |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
||||
"totalNext7Days": 24.6,
|
||||
"unit": "mm",
|
||||
"categories": ["2025-01-01", "2025-01-02", "2025-01-03"],
|
||||
"series": [
|
||||
{
|
||||
"name": "نیاز آبی",
|
||||
"data": [3.2, 4.1, 2.8]
|
||||
}
|
||||
],
|
||||
"dailyBreakdown": [],
|
||||
"insight": {},
|
||||
"knowledge_base": "",
|
||||
"raw_response": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Response Fields
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `status` | `string` | در حالت موفق مقدار `success` |
|
||||
| `data.farm_uuid` | `string` | UUID مزرعه در حالت farm-based |
|
||||
| `data.totalNext7Days` | `number` | مجموع نیاز آبی 7 روز آینده |
|
||||
| `data.unit` | `string` | واحد نیاز آبی، مثل `mm` یا `m3` |
|
||||
| `data.categories` | `string[]` | روزها یا تاریخها |
|
||||
| `data.series` | `Array<{name: string, data: number[]}>` | دادههای نمودار |
|
||||
| `data.dailyBreakdown` | `object[]` | breakdown روزانه در صورت وجود |
|
||||
| `data.insight` | `object` | insight یا خلاصه تحلیلی |
|
||||
| `data.knowledge_base` | `string` | منبع دانشی در صورت وجود |
|
||||
| `data.raw_response` | `string` | پاسخ خام upstream در صورت وجود |
|
||||
|
||||
### Frontend Notes
|
||||
|
||||
- اگر `farm_uuid` معتبر باشد، backend داده را از AI میگیرد.
|
||||
- اگر `farm_uuid` ارسال نشود، backend از داده داخلی/mock استفاده میکند.
|
||||
- اگر `farm_uuid` ارسال شود ولی مزرعه پیدا نشود، فعلاً به fallback داخلی برمیگردد و خطا نمیدهد.
|
||||
|
||||
---
|
||||
|
||||
## 3) Water Summary
|
||||
|
||||
### Endpoint
|
||||
|
||||
```http
|
||||
GET /api/water/summary/?farm_uuid=<farm_uuid>
|
||||
```
|
||||
|
||||
### Query Params
|
||||
|
||||
| field | type | required | description |
|
||||
|---|---|---:|---|
|
||||
| `farm_uuid` | `string (uuid)` | no | UUID مزرعه |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"farmWeatherCard": {
|
||||
"condition": "صاف",
|
||||
"temperature": 24,
|
||||
"unit": "°C",
|
||||
"humidity": 45,
|
||||
"windSpeed": 12,
|
||||
"windUnit": "km/h",
|
||||
"chartData": {
|
||||
"labels": ["۶ صبح", "۹ صبح", "۱۲ ظهر"],
|
||||
"series": [[18, 22, 26]]
|
||||
}
|
||||
},
|
||||
"waterNeedPrediction": {
|
||||
"totalNext7Days": 3290,
|
||||
"unit": "m3",
|
||||
"categories": ["روز 1", "روز 2", "روز 3"],
|
||||
"series": [
|
||||
{
|
||||
"name": "نیاز آبی",
|
||||
"data": [420, 450, 480]
|
||||
}
|
||||
]
|
||||
},
|
||||
"waterStressIndex": {
|
||||
"id": "water_stress_index",
|
||||
"title": "شاخص تنش آبی",
|
||||
"subtitle": "فعلی",
|
||||
"stats": "12%",
|
||||
"avatarColor": "info",
|
||||
"avatarIcon": "tabler-droplet",
|
||||
"chipText": "پایین",
|
||||
"chipColor": "success"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Response Fields
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `status` | `string` | در حالت موفق مقدار `success` |
|
||||
| `data.farmWeatherCard` | `object` | اطلاعات کارت وضعیت آبوهوا |
|
||||
| `data.waterNeedPrediction` | `object` | پیشبینی نیاز آبی |
|
||||
| `data.waterStressIndex` | `object` | کارت شاخص تنش آبی |
|
||||
|
||||
### `waterStressIndex` Fields
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `id` | `string` | شناسه کارت |
|
||||
| `title` | `string` | عنوان کارت |
|
||||
| `subtitle` | `string` | زیرعنوان |
|
||||
| `stats` | `string` | مقدار اصلی برای نمایش |
|
||||
| `avatarColor` | `string` | رنگ کارت/آیکن |
|
||||
| `avatarIcon` | `string` | نام آیکن |
|
||||
| `chipText` | `string` | وضعیت متنی |
|
||||
| `chipColor` | `string` | رنگ وضعیت |
|
||||
|
||||
### Frontend Notes
|
||||
|
||||
- این endpoint برای dashboard overview مناسب است.
|
||||
- سه بخش اصلی summary را میتوانید مستقیم به سه widget مختلف map کنید.
|
||||
- `waterSummary` یک response ترکیبی است و برای یک صفحه dashboard خیلی کاربردی است.
|
||||
|
||||
---
|
||||
|
||||
## 4) Weather Farm Card
|
||||
|
||||
### Endpoint
|
||||
|
||||
```http
|
||||
POST /api/weather/farm-card/
|
||||
```
|
||||
|
||||
### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"farm_uuid": "11111111-1111-1111-1111-111111111111"
|
||||
}
|
||||
```
|
||||
|
||||
### Request Fields
|
||||
|
||||
| field | type | required | description |
|
||||
|---|---|---:|---|
|
||||
| `farm_uuid` | `string (uuid)` | yes | UUID مزرعه |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"condition": "صاف",
|
||||
"temperature": 28.0,
|
||||
"unit": "°C",
|
||||
"humidity": 45,
|
||||
"windSpeed": 12,
|
||||
"windUnit": "km/h",
|
||||
"chartData": {
|
||||
"labels": ["۶ صبح", "۹ صبح", "۱۲ ظهر", "۳ بعدازظهر"],
|
||||
"series": [[18, 22, 26, 28]]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Response Fields
|
||||
|
||||
| field | type | description |
|
||||
|---|---|---|
|
||||
| `code` | `number` | در حالت موفق مقدار `200` |
|
||||
| `msg` | `string` | در حالت موفق مقدار `success` |
|
||||
| `data.condition` | `string` | وضعیت فعلی آبوهوا |
|
||||
| `data.temperature` | `number` | دمای فعلی |
|
||||
| `data.unit` | `string` | واحد دما |
|
||||
| `data.humidity` | `number` | رطوبت نسبی |
|
||||
| `data.windSpeed` | `number` | سرعت باد |
|
||||
| `data.windUnit` | `string` | واحد سرعت باد |
|
||||
| `data.chartData.labels` | `string[]` | برچسبهای زمانی |
|
||||
| `data.chartData.series` | `number[][]` | دادههای نمودار |
|
||||
|
||||
### Error Response - Missing `farm_uuid`
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"farm_uuid": ["This field is required."]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Error Response - Farm Not Found
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"farm_uuid": ["Farm not found."]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Error Response - Upstream Error
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "error",
|
||||
"data": {
|
||||
"message": "Upstream service error"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Frontend Notes
|
||||
|
||||
- این endpoint نسخه authenticated و farm-specific برای weather card است.
|
||||
- اگر farm متعلق به کاربر فعلی نباشد، `404` برمیگردد.
|
||||
- response این endpoint با `code/msg/data` است، نه `status/data`.
|
||||
|
||||
---
|
||||
|
||||
## Suggested TypeScript Interfaces
|
||||
|
||||
```ts
|
||||
export interface WeatherChartData {
|
||||
labels?: string[];
|
||||
series?: number[][];
|
||||
}
|
||||
|
||||
export interface FarmWeatherCard {
|
||||
condition?: string;
|
||||
temperature?: number;
|
||||
unit?: string;
|
||||
humidity?: number;
|
||||
windSpeed?: number;
|
||||
windUnit?: string;
|
||||
chartData?: WeatherChartData;
|
||||
}
|
||||
|
||||
export interface WaterNeedSeries {
|
||||
name?: string;
|
||||
data?: number[];
|
||||
}
|
||||
|
||||
export interface WaterNeedPrediction {
|
||||
farm_uuid?: string;
|
||||
totalNext7Days?: number;
|
||||
unit?: string;
|
||||
categories?: string[];
|
||||
series?: WaterNeedSeries[];
|
||||
dailyBreakdown?: Record<string, unknown>[];
|
||||
insight?: Record<string, unknown>;
|
||||
knowledge_base?: string;
|
||||
raw_response?: string;
|
||||
}
|
||||
|
||||
export interface WaterStressCard {
|
||||
id?: string;
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
stats?: string;
|
||||
avatarColor?: string;
|
||||
avatarIcon?: string;
|
||||
chipText?: string;
|
||||
chipColor?: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Suggested Frontend Handling
|
||||
|
||||
- برای `GET /api/water/card/`, `GET /api/water/need-prediction/`, `GET /api/water/summary/` انتظار `status/data` داشته باشید.
|
||||
- برای `POST /api/weather/farm-card/` انتظار `code/msg/data` داشته باشید.
|
||||
- برای `POST /api/weather/farm-card/` خطاها را از `data.farm_uuid[0]` بخوانید.
|
||||
- برای chartها بهتر است `labels` و `series` را optional render کنید.
|
||||
Reference in New Issue
Block a user