- endpoint هم در این حالت `503` میدهد: `plant/views.py:292`
- نتیجه: `POST /api/plants/fetch-info/` فعلا هیچ داده واقعی از سرویس خارجی نمیگیرد.
### 3) Weather داده نمونه seeded دارد
- migration داده آبوهوای نمونه 7 روزه برای همه `SoilLocation`ها میسازد: `weather/migrations/0003_seed_weather_forecasts.py:1`
- نتیجه: در محیطی که migration اجرا شده باشد، بخشی از خروجیهای Weather ممکن است از sample data بیایند نه API واقعی.
---
## خروجیهایی که mock مستقیم نیستند ولی fallback / تقریبی میدهند
### 1) Weather API از نظر مستندات و رفتار واقعی کد ناهماهنگ است
- داکاسترینگ هنوز نوشته `TODO: پیادهسازی اتصال واقعی به API`: `weather/services.py:23`
- اما خود تابع در عمل `requests.get(...)` میزند و `response.json()` برمیگرداند: `weather/services.py:67`
- مسیر `no_data` در کد وجود دارد، ولی با پیادهسازی فعلی بیشتر یک branch دفاعی/قدیمی است تا رفتار اصلی: `weather/services.py:149`
- در `farm_data` اگر نتیجه weather برابر `no_data` باشد، خطا محسوب نمیشود و فرایند ادامه پیدا میکند: `farm_data/services.py:143`
- نتیجه: طراحی فعلی هنوز اجازه میدهد مزرعه بدون weather قابل اتکا ثبت/آپدیت شود، و این ابهام با وجود دادههای seed شده شدیدتر میشود.
### 2) NDVI در نبود تنظیمات ماهوارهای خروجی unavailable میدهد
- اگر `SATELLITE_NDVI_ENDPOINT` و `SATELLITE_NDVI_API_KEY` تنظیم نشده باشد، client عملا داده نمیآورد: `location_data/remote_sensing.py:77`
- در این حالت کارت NDVI با `vegetation_health_class = "Unavailable"` و پیام نبود داده ماهوارهای برمیگردد: `location_data/ndvi.py:33`
- نتیجه: `POST /api/soil-data/ndvi-health/` ممکن است پاسخ موفق بدهد ولی داده واقعی NDVI نداشته باشد.
### 3) Farm Alerts در خطای LLM fallback میسازد
- اگر LLM خطا بدهد، خروجی خالی برمیگردد: `farm_alerts/services.py:353`
- سپس tracker و timeline از fallback داخلی ساخته میشوند: `farm_alerts/services.py:376`, `farm_alerts/services.py:413`
- نتیجه: خروجی این endpointها همیشه ممکن است LLM-native نباشد و از هشدارهای ساختاریافته داخلی ساخته شده باشد.
### 4) Soil Anomaly در خطای LLM fallback تحلیلی میدهد
- در exception خروجی fallback بازگردانده میشود: `rag/services/soil_anomaly.py:181`
- حتی اگر JSON مدل نامعتبر باشد، fallback جایگزین میشود: `rag/services/soil_anomaly.py:192`
- نتیجه: `POST /api/soile/anomaly-detection/` ممکن است تحلیل واقعی مدل زبانی نباشد.
### 5) Pest & Disease detect/risk در خطای LLM fallback دارند
- تشخیص تصویر در failure به fallback برمیگردد: `rag/services/pest_disease.py:321`
- ریسک آفات/بیماری هم در failure به fallback برمیگردد: `rag/services/pest_disease.py:388`
- نتیجه: پاسخ ممکن است ساختاری و معتبر باشد، اما برآمده از rule/fallback باشد نه inference کامل مدل.
### 6) Water Need Prediction insight در failure fallback میدهد
- در خطای LLM fallback summary برمیگردد: `rag/services/water_need_prediction.py:165`
- نتیجه: لایه insight توضیحی همیشه تضمین نمیکند که از مدل آمده باشد.
### 7) توصیههای آبیاری و کودهی merge با fallback میشوند
- پاسخ آبیاری با fallback merge میشود: `rag/services/irrigation.py:147`
- پاسخ کودهی هم با fallback merge میشود: `rag/services/fertilization.py:130`
- نتیجه: حتی وقتی LLM جواب میدهد، بخشهایی از خروجی ممکن است از template/fallback آمده باشد.
### 8) Crop Simulation در failure از projection fallback استفاده میکند
- اگر engine اصلی خطا بدهد، `_run_projection_engine` استفاده میشود: `crop_simulation/growth_simulation.py:404`
- نتیجه: بعضی نتایج crop simulation ممکن است تقریبی باشند نه خروجی engine اصلی.
---
## ضعفهای مهم پیادهسازی
### 1) باگ واضح در route جزئیات Irrigation
- route جزئیات به `IrrigationMethodDetailView` وصل است: `irrigation/urls.py:12`
- اما متدهای `put/patch/delete` داخل `WaterStressView` تعریف شدهاند، نه داخل `IrrigationMethodDetailView`: `irrigation/views.py:231`, `irrigation/views.py:287`, `irrigation/views.py:326`, `irrigation/views.py:360`
- علاوه بر این، `WaterStressView` اصلا `_get_method` ندارد و این کد از نظر ساختاری اشتباه است.
- اثر عملی: `PUT/PATCH/DELETE /api/irrigation/<pk>/` به احتمال زیاد `405 Method Not Allowed` میدهند و CRUD کامل عملا شکسته است.
### 2) محاسبه تنش آبی بیش از حد سادهسازی شده
- فرمول فقط از `soil_moisture` استفاده میکند: `irrigation/indicators.py:8`
- فرمول هم یک clamp ساده است: `clamp(round(35 - (soil_moisture / 2)), 0, 100)`: `irrigation/indicators.py:16`
- عوامل مهمی مثل ET0، نوع گیاه، مرحله رشد، ظرفیت مزرعه، بافت خاک، بارش، عمق ریشه و روند زمانی لحاظ نشدهاند.
- اثر عملی: `POST /api/irrigation/water-stress/` برای KPI واقعی یا تصمیم آبیاری دقیق کافی نیست.
### 3) مرکز مزرعه با average ساده محاسبه میشود، نه centroid هندسی دقیق
- مرکز boundary با میانگین نقاط محاسبه میشود: `farm_data/services.py:100`
- برای polygonهای نامتقارن یا concave، این روش میتواند مرکز واقعی زمین را اشتباه بدهد.
- اثر عملی: داده خاک و هوا ممکن است برای نقطهای غیرواقعی از مزرعه واکشی شوند.
### 4) ادغام داده چند سنسور باعث overwrite خاموش میشود
- در `farm_data`, متریکهای همه sensorها flat میشوند و کلیدهای تکراری روی هم overwrite میشوند: `farm_data/services.py:155`
- هیچ تفکیک زمانی/مکانی/اولویتبندی بین سنسورها وجود ندارد.
- اثر عملی: در مزرعه چند سنسوره، `resolved_metrics` ممکن است فقط آخرین سنسور iterate شده را منعکس کند.
### 5) Weather card و Weather need کاملا وابسته به داده forecast موجود هستند
- اگر forecast نباشد، card خروجی صفر/نامشخص میدهد: `weather/farm_weather.py:42`
- build payload پیشبینی نیاز آبی هم در نبود forecast خروجی صفر میدهد: `weather/water_need_prediction.py:19`
- اثر عملی: endpoint ممکن است 200 بدهد اما محتوای عملیاتی نداشته باشد.
### 6) NDVI بدون boundary واقعی از bbox پیشفرض استفاده میکند
- اگر boundary وجود نداشته باشد، bbox کوچک پیشفرض تولید میشود: `location_data/remote_sensing.py:57`
- اثر عملی: NDVI ممکن است برای محدوده تقریبی اطراف center محاسبه شود، نه مرز واقعی مزرعه.
### 7) Heatmap رطوبت خاک مدل مکانی ساده دارد
- فقط latest measurement هر sensor استفاده میشود: `soile/services.py:22`, `soile/services.py:32`
- درونیابی از نوع IDW ساده است: `soile/services.py:46`
- history واقعی، drift سنسور، عدم قطعیت، zoning مزرعه یا depth-specific map در آن لحاظ نشدهاند.
- اثر عملی: heatmap برای visualization خوب است ولی برای تصمیم agronomy دقیق کافی نیست.