241 lines
12 KiB
Markdown
241 lines
12 KiB
Markdown
# Farm Dashboard API Reference
|
|
|
|
این سند، API های `dashboard` را بهصورت کامل توضیح میدهد و برای هر بخش مشخص میکند داده از کجا دریافت میشود.
|
|
|
|
## Endpoint ها
|
|
|
|
### 1) دریافت کارتهای داشبورد
|
|
- **Method:** `GET`
|
|
- **Path:** `/api/farm-dashboard/`
|
|
- **View:** `dashboard/views.py:118`
|
|
- **URL config:** `dashboard/urls.py:5`
|
|
- **Query param الزامی:** `farm_uuid`
|
|
- **Auth:** `IsAuthenticated`
|
|
|
|
### 2) دریافت تنظیمات داشبورد
|
|
- **Method:** `GET`
|
|
- **Path:** `/api/farm-dashboard-config/`
|
|
- **View:** `dashboard/views.py:67`
|
|
- **URL config:** `dashboard/urls_config.py:5`
|
|
- **Query param الزامی:** `farm_uuid`
|
|
- **Auth:** `IsAuthenticated`
|
|
|
|
### 3) ویرایش تنظیمات داشبورد
|
|
- **Method:** `PATCH`
|
|
- **Path:** `/api/farm-dashboard-config/`
|
|
- **View:** `dashboard/views.py:67`
|
|
- **Body:** `farm_uuid` + هرکدام از `disabled_card_ids`، `row_order`، `enable_drag_reorder`
|
|
- **Auth:** `IsAuthenticated`
|
|
|
|
## نحوه شناسایی مزرعه
|
|
- مزرعه از طریق `farm_uuid` و مالک کاربر لاگینشده پیدا میشود.
|
|
- پیادهسازی در `dashboard/views.py:20` و `dashboard/views.py:22` است.
|
|
- اگر `farm_uuid` ارسال نشود یا مزرعه برای آن کاربر پیدا نشود، خطای validation برمیگردد.
|
|
|
|
## تنظیمات داشبورد
|
|
تنظیمات داشبورد per-farm در دیتابیس ذخیره میشود.
|
|
|
|
### فیلدها
|
|
- `disabled_card_ids`: لیست کارتهای غیرفعال
|
|
- `row_order`: ترتیب ردیفها
|
|
- `enable_drag_reorder`: فعال/غیرفعال بودن drag reorder
|
|
|
|
### مدل ذخیرهسازی
|
|
- مدل: `FarmDashboardConfig`
|
|
- فایل: `dashboard/models.py:6`
|
|
- جدول: `farm_dashboard_configs`
|
|
|
|
### مقادیر پیشفرض
|
|
- از `dashboard/defaults.py:4` و `dashboard/defaults.py:30` میآید.
|
|
- کارتهای معتبر در `dashboard/defaults.py:16`
|
|
- ردیفهای معتبر در `dashboard/defaults.py:4`
|
|
|
|
### اعتبارسنجی
|
|
- serializer اصلی: `dashboard/serializers.py:6`
|
|
- serializer patch: `dashboard/serializers.py:43`
|
|
- `disabled_card_ids` فقط باید از `VALID_CARD_IDS` باشد.
|
|
- `row_order` باید تمام `VALID_ROW_IDS` را دقیقاً یکبار داشته باشد.
|
|
|
|
## نقطه تجمیع اصلی دادهها
|
|
تمام کارتها در تابع زیر assemble میشوند:
|
|
- `dashboard/services.py:85`
|
|
|
|
این تابع خروجی چند app مختلف را جمع میکند و response نهایی dashboard را میسازد.
|
|
|
|
## منبع داده هر کارت
|
|
|
|
### `farmOverviewKpis`
|
|
- **از کجا ساخته میشود:** `dashboard/services.py:41`
|
|
- **نوع:** aggregator
|
|
- **منابع ورودی:**
|
|
- `farmHealthScore` از `crop_health.services.get_crop_health_summary_data`
|
|
- `waterStressIndex` از `water.services.get_water_stress_index_data`
|
|
- `avgSoilMoisture` از `device_hub.services.get_sensor_7_in_1_summary_data`
|
|
- `disease_risk` و `pest_risk` از `pest_detection.services.get_risk_summary_data`
|
|
- `yield_prediction_card` از `yield_harvest.services.get_yield_harvest_summary_data`
|
|
- **نکته مهم:** این کارت جدول یا مدل مستقل ندارد؛ از چند سرویس ترکیب میشود.
|
|
|
|
### `farmWeatherCard`
|
|
- **از کجا پر میشود:** `water/services.py:9`
|
|
- **مدل اصلی:** `WeatherForecastLog`
|
|
- **فایل مدل:** `water/models.py:8`
|
|
- **جدول:** `weather_forecast_logs`
|
|
- **منطق:** جدیدترین رکورد هواشناسی برای همان `farm` خوانده میشود.
|
|
|
|
### `farmAlertsTracker`
|
|
- **از کجا پر میشود:** `farm_alerts/services.py:379`
|
|
- **مدل اصلی:** `FarmAlert`
|
|
- **فایل مدل:** `farm_alerts/models.py:16`
|
|
- **جدول:** `farm_alerts`
|
|
- **منطق:** هشدارهای active مزرعه خوانده میشوند و از روی آنها summary ساخته میشود.
|
|
- **نکته:** با اینکه مدل `FarmAlertTrackerSnapshot` هم وجود دارد در `farm_alerts/models.py:76`، endpoint فعلی کارت tracker مستقیم از `FarmAlert` میسازد، نه از snapshot.
|
|
|
|
### `sensorValuesList`
|
|
- **از کجا پر میشود:** `device_hub/services.py:495`
|
|
- **جزء داخلی:** `device_hub/services.py:334`
|
|
- **مدلها:**
|
|
- `FarmDevice` در `device_hub/models.py:45`
|
|
- `SensorExternalRequestLog` در `device_hub/models.py:94`
|
|
- **جداول:**
|
|
- `farm_sensors`
|
|
- `sensor_external_request_logs`
|
|
- **منطق:**
|
|
- اول سنسور اصلی خاک مزرعه پیدا میشود.
|
|
- بعد history لاگهای همان device خوانده میشود.
|
|
- از payload لاگها، مقادیر سنسورها استخراج میشود.
|
|
|
|
### `sensorRadarChart`
|
|
- **از کجا پر میشود:** `device_hub/services.py:389`
|
|
- **منبع داده:** همان `SensorExternalRequestLog` و `FarmDevice`
|
|
- **منطق:** آخرین reading سنسور 7-in-1 گرفته میشود و بر اساس ideal range برای هر فیلد score ساخته میشود.
|
|
|
|
### `sensorComparisonChart`
|
|
- **از کجا پر میشود:** `device_hub/services.py:412`
|
|
- **منبع داده:** `SensorExternalRequestLog`
|
|
- **منطق:** history چند reading آخر برای رطوبت خاک گرفته میشود و series نمودار ساخته میشود.
|
|
|
|
### `anomalyDetectionCard`
|
|
- **از کجا پر میشود:** `device_hub/services.py:451`
|
|
- **منبع داده:** `SensorExternalRequestLog`
|
|
- **منطق:** آخرین reading با بازههای ideal مقایسه میشود و anomaly های out-of-range ساخته میشود.
|
|
- **نکته:** در app `farm_alerts` یک مدل `AnomalyDetection` در `farm_alerts/models.py:41` هم وجود دارد، اما dashboard فعلی این کارت را از آن مدل نمیخواند.
|
|
|
|
### `farmAlertsTimeline`
|
|
- **از کجا پر میشود:** `farm_alerts/services.py:410`
|
|
- **مدل اصلی:** `FarmAlert`
|
|
- **فایل مدل:** `farm_alerts/models.py:16`
|
|
- **جدول:** `farm_alerts`
|
|
- **منطق:** حداکثر 10 alert آخر مزرعه خوانده میشود.
|
|
|
|
### `waterNeedPrediction`
|
|
- **از کجا پر میشود:** `water/services.py:58`
|
|
- **مدل اصلی:** `IrrigationRecommendationRequest`
|
|
- **فایل مدل:** `irrigation/models.py:9`
|
|
- **جدول:** `irrigation_requests`
|
|
- **منطق:**
|
|
- از `response_payload` آخرین درخواست آبیاری، بخش `water_balance.daily` استخراج میشود.
|
|
- سپس `gross_irrigation_mm` ها تبدیل به series نمودار میشوند.
|
|
- **نکته:** این کارت در app `water` assemble میشود ولی source واقعیاش دادهی persisted آبیاری است.
|
|
|
|
### `harvestPredictionCard`
|
|
- **از کجا پر میشود:** `yield_harvest/services.py:7`
|
|
- **مدل اصلی:** `YieldHarvestPredictionLog`
|
|
- **فایل مدل:** `yield_harvest/models.py:8`
|
|
- **جدول:** `yield_harvest_prediction_logs`
|
|
- **منطق:** جدیدترین لاگ برداشت/عملکرد مزرعه خوانده میشود.
|
|
|
|
### `yieldPredictionChart`
|
|
- **از کجا پر میشود:** `yield_harvest/services.py:7`
|
|
- **مدل اصلی:** `YieldHarvestPredictionLog`
|
|
- **فایل مدل:** `yield_harvest/models.py:8`
|
|
- **جدول:** `yield_harvest_prediction_logs`
|
|
- **منطق:** `chart_data` از همان لاگ برداشت/عملکرد برگردانده میشود.
|
|
|
|
### `soilMoistureHeatmap`
|
|
- **از کجا پر میشود:** `device_hub/services.py:469`
|
|
- **منبع داده:** `SensorExternalRequestLog`
|
|
- **مدل کمکی device:** `FarmDevice`
|
|
- **منطق:** چند reading آخر رطوبت خاک به فرمت heatmap/chart تبدیل میشود.
|
|
|
|
### `ndviHealthCard`
|
|
- **از کجا پر میشود:** `crop_health/services.py:6`
|
|
- **منبع داده فعلی:** mock data
|
|
- **فایل:** `crop_health/mock_data.py` از طریق `crop_health/services.py:3`
|
|
- **منطق:** فعلاً از دیتابیس یا external log خوانده نمیشود؛ مستقیم از mock برمیگردد.
|
|
|
|
### `recommendationsList`
|
|
- **از کجا ساخته میشود:** `dashboard/services.py:54`
|
|
- **نوع:** aggregator
|
|
- **منابع ورودی:**
|
|
- recommendationهای ذخیرهشده در `Recommendation` از `farm_alerts/services.py:459`
|
|
- پیشنهاد آبیاری از `irrigation/services.py:289`
|
|
- پیشنهاد کوددهی از `fertilization/services.py:79`
|
|
- بازه برداشت از `yield_harvest.services.get_yield_harvest_summary_data`
|
|
- **مدلهای اصلی:**
|
|
- `Recommendation` در `farm_alerts/models.py:59`
|
|
- `IrrigationRecommendationRequest` در `irrigation/models.py:9`
|
|
- `FertilizationRecommendationRequest` در `fertilization/models.py:9`
|
|
- `YieldHarvestPredictionLog` در `yield_harvest/models.py:8`
|
|
- **نکته:** این کارت داده چند domain مختلف را یکی میکند و duplicate titleها را حذف میکند.
|
|
|
|
### `economicOverview`
|
|
- **از کجا پر میشود:** `economic_overview/services.py:7`
|
|
- **مدل اصلی:** `EconomicOverviewLog`
|
|
- **فایل مدل:** `economic_overview/models.py:8`
|
|
- **جدول:** `economic_overview_logs`
|
|
- **منطق:** آخرین لاگ اقتصادی مزرعه خوانده میشود.
|
|
|
|
## منابعی که فعلاً mock هستند
|
|
این بخش مهم است، چون user خواسته بداند اطلاعات از کجا میآید:
|
|
|
|
- `ndviHealthCard` از mock میآید: `crop_health/services.py:6`
|
|
- `farmHealthScore` که داخل `farmOverviewKpis` استفاده میشود هم از mock میآید: `crop_health/services.py:6`
|
|
- `disease_risk` و `pest_risk` که داخل `farmOverviewKpis` استفاده میشوند از mock میآیند: `pest_detection/services.py:6`
|
|
|
|
## منابعی که از دیتابیس میآیند
|
|
- تنظیمات dashboard از `FarmDashboardConfig`
|
|
- weather از `WeatherForecastLog`
|
|
- alerts/timeline از `FarmAlert`
|
|
- recommendationهای ذخیرهشده از `Recommendation`
|
|
- داده آبیاری از `IrrigationRecommendationRequest`
|
|
- داده کوددهی برای recommendation card از `FertilizationRecommendationRequest`
|
|
- برداشت/عملکرد از `YieldHarvestPredictionLog`
|
|
- overview اقتصادی از `EconomicOverviewLog`
|
|
- سنسورها از `FarmDevice` و `SensorExternalRequestLog`
|
|
|
|
## وابستگی بین app ها در dashboard
|
|
تجمیع dashboard در `dashboard/services.py:85` به این app ها وابسته است:
|
|
- `water`
|
|
- `crop_health`
|
|
- `economic_overview`
|
|
- `farm_alerts`
|
|
- `fertilization`
|
|
- `irrigation`
|
|
- `pest_detection`
|
|
- `device_hub`
|
|
- `yield_harvest`
|
|
|
|
## نمونه flow برای `GET /api/farm-dashboard/`
|
|
1. کاربر `farm_uuid` را میفرستد.
|
|
2. در `dashboard/views.py:127` مزرعه متعلق به user پیدا میشود.
|
|
3. `dashboard/services.py:85` صدا زده میشود.
|
|
4. این تابع به سرویسهای appهای مختلف call میزند.
|
|
5. هر سرویس یا از DB میخواند یا از mock/template.
|
|
6. پاسخ نهایی بهصورت یک object شامل تمام cardها برمیگردد.
|
|
|
|
## نکات مهم عملی
|
|
- endpoint کارتها فقط config را برنمیگرداند؛ payload کامل تمام cardها را یکجا برمیگرداند.
|
|
- config dashboard از خود کارتها جداست و در endpoint جداگانه مدیریت میشود.
|
|
- بعضی کارتها production data دارند، بعضی transitional هستند، و بعضی هنوز mock دارند.
|
|
- اگر برای مزرعه دادهای در بعضی جدولها نباشد، معمولاً fallback/template خالی برمیگردد.
|
|
|
|
## فایلهای مرجع مهم
|
|
- `dashboard/views.py:67`
|
|
- `dashboard/views.py:118`
|
|
- `dashboard/services.py:85`
|
|
- `dashboard/defaults.py:4`
|
|
- `dashboard/serializers.py:6`
|
|
- `dashboard/models.py:6`
|
|
- `docs/dashboard_card_service_map.md:1`
|
|
|