UPDATE
This commit is contained in:
@@ -0,0 +1,328 @@
|
||||
# گزارش بررسی منبع داده APIها
|
||||
|
||||
تاریخ بررسی: 2026-04-26
|
||||
|
||||
## جمعبندی خیلی کوتاه
|
||||
z
|
||||
- در این repo، بیشتر endpointهایی که `external_api_request("ai", ...)` صدا میزنند **از mock داخلی این backend استفاده نمیکنند** و بهصورت HTTP به سرویس AI میروند.
|
||||
- دلیلش این است که در `external_api_adapter/adapter.py` شرط mock اینطور نوشته شده: `USE_EXTERNAL_API_MOCK and service_name != "ai"`.
|
||||
- در `.env` فعلی، `USE_EXTERNAL_API_MOCK=true` است، اما چون سرویس این endpointها `ai` است، باز هم درخواستها به سرویس واقعیِ تنظیمشده در `AI_SERVICE_BASE_URL=http://ai-web:8000` میروند.
|
||||
- پس برای endpointهای proxy شده به `ai`، از نگاه این backend، **منبع فعلی داده = سرویس واقعی AI** است، نه فایلهای mock همین repo.
|
||||
- بعضی endpointها اصلاً external call ندارند و فقط از `mock_data.py` یا از دیتابیس خود Django استفاده میکنند.
|
||||
|
||||
## مبنای تشخیص
|
||||
|
||||
### تنظیمات سراسری
|
||||
|
||||
- `USE_EXTERNAL_API_MOCK=true`
|
||||
- `AI_SERVICE_BASE_URL=http://ai-web:8000`
|
||||
- `AI_SERVICE_HOST_HEADER=localhost`
|
||||
|
||||
### رفتار adapter
|
||||
|
||||
در `external_api_adapter/adapter.py`:
|
||||
|
||||
```python
|
||||
use_mock = getattr(settings, "USE_EXTERNAL_API_MOCK", False) and service_name != "ai"
|
||||
```
|
||||
|
||||
یعنی:
|
||||
|
||||
- برای `farm_hub` و سرویسهای غیر `ai` امکان mock داخلی هست.
|
||||
- برای `ai` **حتی اگر** `USE_EXTERNAL_API_MOCK=true` باشد، درخواست mock نمیشود و مستقیم HTTP call زده میشود.
|
||||
|
||||
> نکته: این گزارش فقط نشان میدهد این backend داده را از کجا میگیرد. اینکه خود سرویس `ai-web:8000` پشت صحنه mock برگرداند یا داده واقعی تولید کند، از داخل این repo قابل اثبات نیست.
|
||||
|
||||
---
|
||||
|
||||
## 1) Pest Detection
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `POST /api/pest-detection/analyze/` | سرویس AI خارجی | واقعی از دید backend | `http://ai-web:8000/api/pest-detection/analyze/` |
|
||||
| `POST /api/pest-detection/risk/` | سرویس AI خارجی | واقعی از دید backend | `http://ai-web:8000/api/pest-detection/risk/` |
|
||||
| `GET /api/pest-detection/risk-summary/` | سرویس AI خارجی | واقعی از دید backend | `http://ai-web:8000/api/pest-detection/risk-summary/` |
|
||||
|
||||
### توضیح
|
||||
|
||||
- هر 3 endpoint در `pest_detection/views.py` مستقیم `external_api_request("ai", ...)` صدا میزنند.
|
||||
- فایل `pest_detection/services.py` یک mock به نام `get_risk_summary_data` دارد، ولی **در endpoint واقعی `risk-summary` استفاده نمیشود**.
|
||||
- نتیجه: در وضعیت فعلی این 3 endpoint **mock محلی backend نیستند**.
|
||||
|
||||
---
|
||||
|
||||
## 2) Plant Simulator
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `GET /api/plant-simulator/config/` | `yield_harvest.mock_data.CONFIG_SLIDERS_ONLY` | mock/static | internal |
|
||||
| `PATCH /api/plant-simulator/environment/` | پاسخ ثابت success | mock/static | internal |
|
||||
| `POST /api/plant-simulator/reset/` | پاسخ ثابت success | mock/static | internal |
|
||||
| `POST /api/plant-simulator/start/` | `yield_harvest.mock_data.START_RESPONSE_DATA` | mock/static | internal |
|
||||
| `GET /api/plant-simulator/state/` | `yield_harvest.mock_data.STATE_RESPONSE_DATA` | mock/static | internal |
|
||||
| `POST /api/plant-simulator/stop/` | پاسخ ثابت success | mock/static | internal |
|
||||
|
||||
### توضیح
|
||||
|
||||
- routeهای `plant-simulator` داخل `yield_harvest/views.py` تعریف شدهاند.
|
||||
- هیچکدام external API call ندارند.
|
||||
- همه این endpointها فعلاً **ماک/استاتیک** هستند.
|
||||
|
||||
---
|
||||
|
||||
## 3) Soil
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `GET /api/soil/anomalies/` | دیتابیس مدل `farm_alerts.AnomalyDetection` در صورت وجود farm و رکورد، وگرنه `soil.mock_data.ANOMALY_DETECTION_CARD` | ترکیبی: DB / mock | internal DB |
|
||||
| `GET /api/soil/avg-moisture/` | محاسبه از `get_soil_moisture_heatmap_data()` که خودش از mock میآید | mock-derived | internal |
|
||||
| `GET /api/soil/moisture-heatmap/` | سرویس AI خارجی | واقعی از دید backend | `http://ai-web:8000/api/soile/moisture-heatmap/` |
|
||||
| `GET /api/sensor-7-in-1/sensor-comparison-chart/` | `sensor_7_in_1.services.get_sensor_comparison_chart_data` | sensor 7 in 1 | internal |
|
||||
| `GET /api/sensor-7-in-1/sensor-radar-chart/` | `sensor_7_in_1.services.get_sensor_radar_chart_data` | sensor 7 in 1 | internal |
|
||||
| `GET /api/soil/summary/` | سرویس AI خارجی | واقعی از دید backend | `http://ai-web:8000/api/soile/health-summary/` |
|
||||
|
||||
### توضیح
|
||||
|
||||
- `avg-moisture` داده واقعی sensor یا external API نمیخواند؛ فقط از heatmap ماک میانگین میگیرد.
|
||||
- `anomalies` تنها endpoint این گروه است که **میتواند** از DB داخلی بخواند.
|
||||
- `summary` فقط wrapper همین سرویسهای داخلی است و خودش external call ندارد.
|
||||
|
||||
---
|
||||
|
||||
## 4) WATER
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `GET /api/water/card/` | سرویس AI خارجی + ذخیره در `water.WeatherForecastLog` | واقعی از دید backend | `http://ai-web:8000/weather-forecast/card` |
|
||||
| `GET /api/water/need-prediction/` | اگر `farm_uuid` معتبر باشد: سرویس AI خارجی؛ اگر نباشد: داده مشتقشده از `irrigation_recommendation.IrrigationRecommendationRequest` یا mock | ترکیبی | `http://ai-web:8000/api/weather/water-need-prediction/` یا internal DB/mock |
|
||||
| `GET /api/water/stress-index/` | سرویس AI خارجی | واقعی از دید backend | `http://ai-web:8000/api/water/stress-index/` |
|
||||
| `GET /api/water/summary/` | local aggregation از `WeatherForecastLog` + `IrrigationRecommendationRequest` + mock fallback | ترکیبی | internal DB/mock |
|
||||
|
||||
### توضیح
|
||||
|
||||
- `water/card` در لحظه درخواست از AI میخواند و نتیجه را در `WeatherForecastLog` ذخیره میکند.
|
||||
- `water/need-prediction` رفتار دوحالته دارد:
|
||||
- اگر `farm_uuid` داده شود و farm پیدا شود: مستقیم به AI میرود.
|
||||
- اگر farm نداشته باشد: از آخرین `IrrigationRecommendationRequest` میسازد؛ اگر چیزی نباشد، از `water.mock_data` میدهد.
|
||||
- `water/summary` خودش به AI زنگ نمیزند؛ فقط داده cached/local را assemble میکند.
|
||||
|
||||
---
|
||||
|
||||
## 5) WEATHER
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `POST /api/weather/farm-card/` | سرویس AI خارجی + ذخیره در `WeatherForecastLog` | واقعی از دید backend | `http://ai-web:8000/weather-forecast/card` |
|
||||
### توضیح
|
||||
|
||||
- در namespace `weather` فقط `POST /api/weather/farm-card/` باقی مانده است.
|
||||
- endpoint `POST /api/weather/water-need-prediction/` حذف شده است.
|
||||
|
||||
---
|
||||
|
||||
## 6) Yield & Harvest Prediction
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `GET /api/yield-harvest/summary/` | سرویس AI خارجی + ذخیره در `yield_harvest.YieldHarvestPredictionLog` | واقعی از دید backend | `http://ai-web:8000/yield-harvest/summary` |
|
||||
|
||||
### توضیح
|
||||
|
||||
- این endpoint در `yield_harvest/views.py` مستقیماً AI را صدا میزند.
|
||||
- سپس نتیجه در `YieldHarvestPredictionLog` ذخیره میشود.
|
||||
- سرویس `yield_harvest/services.py` برای خواندن از log و fallback mock وجود دارد، اما خود endpoint `summary` در حال حاضر **آن سرویس را استفاده نمیکند**.
|
||||
|
||||
---
|
||||
|
||||
## 7) Fertilization Recommendation
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `GET /api/fertilization/config/` | `fertilization_recommendation.mock_data.CONFIG_RESPONSE_DATA` | mock/static | internal |
|
||||
| `POST /api/fertilization/recommend/` | سرویس AI خارجی + ذخیره در `FertilizationRecommendationRequest` | واقعی از دید backend | `http://ai-web:8000/api/fertilization/recommend/` |
|
||||
|
||||
### توضیح
|
||||
|
||||
- `config` فعلاً فقط config ثابت برمیگرداند.
|
||||
- `recommend` واقعی از نگاه backend است و پاسخ خام AI در DB ذخیره میشود.
|
||||
|
||||
---
|
||||
|
||||
## 8) Irrigation Recommendation
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `GET /api/irrigation/` | سرویس AI خارجی | واقعی از دید backend | `http://ai-web:8000/api/irrigation/` |
|
||||
| `GET /api/irrigation/config/` | `irrigation_recommendation.mock_data.CONFIG_RESPONSE_DATA` | mock/static | internal |
|
||||
| `POST /api/irrigation/recommend/` | سرویس AI خارجی + ذخیره در `IrrigationRecommendationRequest` | واقعی از دید backend | `http://ai-web:8000/api/irrigation/recommend/` |
|
||||
|
||||
### نکته مهم درباره مسیر درخواستی شما
|
||||
|
||||
مسیر `POST /api/irrigation/water-stress/farm-alerts` در این backend **وجود ندارد**.
|
||||
|
||||
مسیرهای نزدیک و واقعی اینها هستند:
|
||||
|
||||
- `POST /api/irrigation/water-stress/`
|
||||
- منبع فعلی: سرویس AI خارجی
|
||||
- آدرس upstream: `http://ai-web:8000/api/water/stress-index/`
|
||||
- endpointهای `farm-alerts` جدا هستند و زیر prefix دیگری قرار دارند:
|
||||
- `/api/farm-alerts/...`
|
||||
|
||||
---
|
||||
|
||||
## 9) Farm Alerts
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `GET /api/farm-alerts/anomalies/` | `farm_alerts.mock_data.ANOMALY_DETECTION_CARD` | mock/static | internal |
|
||||
| `POST /api/farm-alerts/create/` | دیتابیس داخلی (`FarmAlert`) + ساخت `FarmNotification` | internal DB | internal DB |
|
||||
| `GET /api/farm-alerts/recommendations/` | `farm_alerts.mock_data.RECOMMENDATIONS_LIST` | mock/static | internal |
|
||||
| `GET /api/farm-alerts/timeline/` | `farm_alerts.mock_data.FARM_ALERTS_TIMELINE` | mock/static | internal |
|
||||
|
||||
### نکته مهم درباره مسیر درخواستی شما
|
||||
|
||||
مسیر `GET /api/farm-alerts/tracker/economy` در این backend **وجود ندارد**.
|
||||
|
||||
مسیر درست موجود:
|
||||
|
||||
- `GET /api/farm-alerts/tracker/`
|
||||
- منبع فعلی: `farm_alerts.mock_data.ARM_ALERTS_TRACKER`
|
||||
- نوع: mock/static
|
||||
|
||||
### توضیح
|
||||
|
||||
- با اینکه در `farm_alerts/services.py` توابعی برای خواندن tracker/timeline/anomalies/recommendations از DB وجود دارد، viewهای فعلی از آنها استفاده نمیکنند.
|
||||
- بنابراین در وضعیت فعلی:
|
||||
- `tracker` = mock
|
||||
- `timeline` = mock
|
||||
- `anomalies` = mock
|
||||
- `recommendations` = mock
|
||||
- فقط `create` واقعاً به DB داخلی مینویسد.
|
||||
|
||||
---
|
||||
|
||||
## 10) Economy
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `POST /api/economy/overview/` | سرویس AI خارجی + ذخیره در `economic_overview.EconomicOverviewLog` | واقعی از دید backend | `http://ai-web:8000/api/economy/overview/` |
|
||||
|
||||
### توضیح
|
||||
|
||||
- endpoint تکراری `GET /api/economy/summary/` حذف شده است.
|
||||
- endpoint canonical اقتصادی فقط این است:
|
||||
- `POST /api/economy/overview/`
|
||||
- این endpoint داده را از AI میگیرد و در `EconomicOverviewLog` ذخیره میکند.
|
||||
|
||||
---
|
||||
|
||||
## 11) Crop Health
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `POST /api/crop-health/ndvi-health/` | `crop_health.mock_data.NDVI_HEALTH_CARD` | mock/static | internal |
|
||||
| `GET /api/crop-health/summary/` | `crop_health.mock_data.NDVI_HEALTH_CARD` + `crop_health.mock_data.FARM_HEALTH_SCORE` | mock/static | internal |
|
||||
|
||||
### توضیح
|
||||
|
||||
- `get_crop_health_summary_data(farm=None)` در `crop_health/services.py` پارامتر farm را نادیده میگیرد.
|
||||
- پس حتی نسخه POST که farm را validate میکند هم در نهایت داده mock برمیگرداند.
|
||||
|
||||
---
|
||||
|
||||
## 12) Soil Data
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `POST /api/soil/health/ndvi-health/` | همان `crop_health` | mock/static | internal |
|
||||
| `GET /api/soil/health/summary/` | همان `crop_health` | mock/static | internal |
|
||||
|
||||
### توضیح
|
||||
|
||||
- در `config/urls.py` مسیرهای `crop_health` زیر `api/soil/health/` هم mount شدهاند.
|
||||
- یعنی این دو endpoint عملاً alias همان endpointهای `crop-health` هستند.
|
||||
- بنابراین هر دو فعلاً **mock/static** هستند.
|
||||
|
||||
---
|
||||
|
||||
## 13) Crop Simulation
|
||||
|
||||
| Endpoint | منبع داده فعلی | نوع داده فعلی | آدرس/منبع دقیق |
|
||||
|---|---|---|---|
|
||||
| `POST /api/yield-harvest/crop-simulation/current-farm-chart/` | سرویس AI خارجی | واقعی از دید backend | `http://ai-web:8000/api/crop-simulation/current-farm-chart/` |
|
||||
| `POST /api/yield-harvest/crop-simulation/harvest-prediction/` | سرویس AI خارجی | واقعی از دید backend | `http://ai-web:8000/api/crop-simulation/harvest-prediction/` |
|
||||
| `POST /api/yield-harvest/crop-simulation/yield-prediction/` | سرویس AI خارجی | واقعی از دید backend | `http://ai-web:8000/api/crop-simulation/yield-prediction/` |
|
||||
|
||||
### توضیح
|
||||
|
||||
- هر سه endpoint در `yield_harvest/views.py` هستند.
|
||||
- هر سه مستقیماً `external_api_request("ai", ...)` صدا میزنند.
|
||||
|
||||
---
|
||||
|
||||
## جدول نهایی وضعیت فعلی
|
||||
|
||||
### endpointهایی که الان از سرویس AI میگیرند
|
||||
|
||||
- `POST /api/pest-detection/analyze/`
|
||||
- `POST /api/pest-detection/risk/`
|
||||
- `GET /api/pest-detection/risk-summary/`
|
||||
- `GET /api/water/card/`
|
||||
- `GET /api/water/stress-index/`
|
||||
- `POST /api/weather/farm-card/`
|
||||
- `GET /api/yield-harvest/summary/`
|
||||
- `POST /api/fertilization/recommend/`
|
||||
- `GET /api/irrigation/`
|
||||
- `POST /api/irrigation/recommend/`
|
||||
- `POST /api/irrigation/water-stress/`
|
||||
- `POST /api/yield-harvest/crop-simulation/current-farm-chart/`
|
||||
- `POST /api/yield-harvest/crop-simulation/harvest-prediction/`
|
||||
- `POST /api/yield-harvest/crop-simulation/yield-prediction/`
|
||||
|
||||
### endpointهایی که الان mock/static هستند
|
||||
|
||||
- همه `plant-simulator`
|
||||
- `GET /api/soil/moisture-heatmap/`
|
||||
- `GET /api/sensor-7-in-1/sensor-comparison-chart/`
|
||||
- `GET /api/sensor-7-in-1/sensor-radar-chart/`
|
||||
- `GET /api/fertilization/config/`
|
||||
- `GET /api/irrigation/config/`
|
||||
- `GET /api/farm-alerts/tracker/`
|
||||
- `GET /api/farm-alerts/timeline/`
|
||||
- `GET /api/farm-alerts/anomalies/`
|
||||
- `GET /api/farm-alerts/recommendations/`
|
||||
- `POST /api/economy/overview/`
|
||||
- `POST /api/crop-health/ndvi-health/`
|
||||
- `GET /api/crop-health/summary/`
|
||||
- `POST /api/soil/health/ndvi-health/`
|
||||
- `GET /api/soil/health/summary/`
|
||||
|
||||
### endpointهایی که ترکیبی هستند
|
||||
|
||||
- `GET /api/soil/anomalies/` → DB اگر data باشد، وگرنه mock
|
||||
- `GET /api/soil/avg-moisture/` → derived from mock heatmap
|
||||
- `GET /api/soil/summary/` → سرویس AI خارجی
|
||||
- `GET /api/water/need-prediction/` → با `farm_uuid` معتبر معمولاً AI، بدون آن local/mock
|
||||
- `GET /api/water/summary/` → local DB/cache/mock
|
||||
|
||||
### مسیرهایی که در این backend وجود ندارند
|
||||
|
||||
- `POST /api/irrigation/water-stress/farm-alerts`
|
||||
- `GET /api/farm-alerts/tracker/economy`
|
||||
|
||||
---
|
||||
|
||||
## پیشنهاد برای اصلاح اگر هدف شما «داده واقعی» است
|
||||
|
||||
اگر بخواهید این endpointها واقعاً از داده واقعی backend خودشان بخوانند، اولویت اصلاح منطقی اینهاست:
|
||||
|
||||
1. `farm_alerts/views.py`
|
||||
- بهجای mock مستقیم، از توابع `farm_alerts/services.py` استفاده شود.
|
||||
2. `economic_overview/views.py`
|
||||
- `summary` از `get_economic_overview_data()` استفاده کند، نه mock ثابت.
|
||||
3. `crop_health/services.py`
|
||||
- بهجای mock ثابت، از منبع واقعی NDVI یا cache/database استفاده کند.
|
||||
4. `soil/services.py`
|
||||
- heatmap/radar/comparison از sensor logs واقعی ساخته شوند.
|
||||
5. `water/summary`
|
||||
- در صورت نیاز، بهجای cache/log فقط، امکان refresh مستقیم از AI داشته باشد.
|
||||
Reference in New Issue
Block a user