UPDATE
This commit is contained in:
@@ -0,0 +1,677 @@
|
||||
# سیاست منبع داده و تجمیع کلاستر برای APIهای AI
|
||||
|
||||
این سند مشخص میکند هر API از کجا داده میگیرد، آیا الان خروجی آن بر اساس میانگین داده سنسور کلاسترها و میانگین داده ماهوارهای کلاسترهای `location_data` هست یا نه، و برای یکپارچهسازی چه policyای باید رعایت شود.
|
||||
|
||||
این سند بر اساس کد فعلی پروژه نوشته شده و مخصوص APIهای زیر است:
|
||||
|
||||
- `POST /api/rag/chat/`
|
||||
- `POST /api/soile/anomaly-detection/`
|
||||
- `POST /api/soile/health-summary/`
|
||||
- `POST /api/soile/moisture-heatmap/`
|
||||
- `POST /api/weather/farm-card/`
|
||||
- `POST /api/weather/water-need-prediction/`
|
||||
- `POST /api/pest-disease/detect/`
|
||||
- `POST /api/pest-disease/risk/`
|
||||
- `POST /api/irrigation/plan-from-text/`
|
||||
- `POST /api/irrigation/recommend/`
|
||||
- `POST /api/farm-data/parameters/`
|
||||
- `POST /api/fertilization/plan-from-text/`
|
||||
- `POST /api/fertilization/recommend/`
|
||||
- `POST /api/crop-simulation/current-farm-chart/`
|
||||
- `POST /api/crop-simulation/growth/`
|
||||
- `GET /api/crop-simulation/growth/{task_id}/status/`
|
||||
- `POST /api/crop-simulation/harvest-prediction/`
|
||||
- `GET /api/crop-simulation/yield-harvest-summary/`
|
||||
- `POST /api/crop-simulation/yield-prediction/`
|
||||
- `POST /api/economy/overview/`
|
||||
- `POST /api/farm-alerts/tracker/`
|
||||
|
||||
---
|
||||
|
||||
## 1) قانون هدف کسبوکاری
|
||||
|
||||
قانون مطلوبی که باید برای محاسبههای عمومی AI رعایت شود این است:
|
||||
|
||||
1. برای محاسبههای عمومی AI مثل `RAG`، `crop_simulation`، `irrigation`، `fertilization`، `farm_alerts` و سرویسهای تحلیلی خاک، مبنای داده باید `میانگین داده سنسورهای کلاسترها` و `میانگین داده ماهوارهای کلاسترهای location_data` باشد.
|
||||
2. این تجمیع باید در سطح `بلوکهای بزرگ کشاورز` انجام شود؛ یعنی اول هر block اصلی جداگانه محاسبه شود، بعد در صورت نیاز یک خلاصه کل مزرعه از روی blockهای اصلی ساخته شود.
|
||||
3. اگر کشاورز هنوز block تعریف نکرده باشد، حالت پیشفرض دامنه باید این باشد:
|
||||
- `1 بلوک بزرگ` برای کل مزرعه
|
||||
- `1 بلوک کوچک` داخل همان بلوک بزرگ
|
||||
4. هر API که فقط `farm_uuid` میگیرد و رفتار عمومی مزرعه را تحلیل میکند، باید از snapshot تجمیعشدهی مبتنی بر block/sub-block استفاده کند، نه از یک سنسور خام یا یک location خام.
|
||||
|
||||
---
|
||||
|
||||
## 2) وضعیت فعلی مدل داده
|
||||
|
||||
### 2.1) لایه مزرعه
|
||||
|
||||
رکورد canonical مزرعه در `farm_data.SensorData` نگهداری میشود:
|
||||
|
||||
- شناسه اصلی: `farm_uuid`
|
||||
- اتصال مکانی: `center_location -> location_data.SoilLocation`
|
||||
- سنسورها: `sensor_payload`
|
||||
- آبوهوا: `weather_forecast`
|
||||
- گیاه: `plant_assignments` و `plant_snapshots`
|
||||
- روش آبیاری: `irrigation_method`
|
||||
|
||||
### 2.2) لایه مکانی
|
||||
|
||||
رکورد canonical مکانی در `location_data.SoilLocation` است:
|
||||
|
||||
- `farm_boundary`
|
||||
- `input_block_count`
|
||||
- `block_layout`
|
||||
- `block_subdivisions`
|
||||
- `remote_sensing_runs`
|
||||
|
||||
### 2.3) لایه کلاستر و سنجش از دور
|
||||
|
||||
در `location_data` عملاً دو سطح تجمیع وجود دارد:
|
||||
|
||||
- `block` = بلوک اصلی که کشاورز تعریف کرده
|
||||
- `sub-block / cluster` = بخشهای کوچکتر داخل هر block
|
||||
|
||||
منطق فعلی تجمیع در `location_data/satellite_snapshot.py` پیاده شده است:
|
||||
|
||||
- `build_block_sensor_summary(...)`
|
||||
- داده سنسورهای منتسب به sub-blockها را جمع میکند
|
||||
- ابتدا برای هر sub-block میانگین میسازد
|
||||
- سپس از روی sub-blockها میانگین block را میسازد
|
||||
- `summarize_block_satellite_metrics(...)`
|
||||
- دادههای grid/cell ماهوارهای را برای cluster blockها خلاصه میکند
|
||||
- سپس میانگین block را میسازد
|
||||
- `build_location_block_satellite_snapshots(...)`
|
||||
- برای هر block اصلی یک snapshot میسازد
|
||||
- `build_farmer_block_aggregated_snapshot(...)`
|
||||
- از روی blockهای اصلی یک خلاصه کل مزرعه میسازد
|
||||
|
||||
پس زیرساخت فنی برای policy موردنظر تا حد زیادی در پروژه وجود دارد.
|
||||
|
||||
---
|
||||
|
||||
## 3) رفتار پیشفرض blockها
|
||||
|
||||
### رفتار فعلی در کد
|
||||
|
||||
تابع `build_block_layout()` در `location_data/models.py` وقتی blockی داده نشود، این رفتار را دارد:
|
||||
|
||||
- `input_block_count = 1`
|
||||
- فقط `1 بلوک اصلی` با `block-1` ساخته میشود
|
||||
- `sub_blocks = []`
|
||||
|
||||
یعنی الان بخش دوم rule شما کامل اعمال نشده، چون:
|
||||
|
||||
- `1 بلوک بزرگ` وجود دارد
|
||||
- ولی `1 بلوک کوچک داخل آن` بهصورت default ساخته نمیشود
|
||||
|
||||
### رفتار مطلوب پیشنهادی
|
||||
|
||||
برای سازگاری با خواسته شما، policy پیشنهادی این است:
|
||||
|
||||
- اگر هیچ block و هیچ subdivisionی تعریف نشده بود:
|
||||
- `block_layout.blocks = [block-1]`
|
||||
- داخل `block-1.sub_blocks` یک sub-block پیشفرض ساخته شود
|
||||
- این sub-block پیشفرض میتواند چیزی شبیه این داشته باشد:
|
||||
|
||||
```json
|
||||
{
|
||||
"sub_block_code": "block-1-sub-1",
|
||||
"cluster_label": 0,
|
||||
"source": "default",
|
||||
"boundary": {},
|
||||
"cluster_uuid": null
|
||||
}
|
||||
```
|
||||
|
||||
این policy باعث میشود تمام APIهای downstream همیشه حداقل یک سطح `sub-block` داشته باشند و منطق aggregation یکنواخت بماند.
|
||||
|
||||
---
|
||||
|
||||
## 4) منبع canonical پیشنهادی برای همه APIهای AI
|
||||
|
||||
برای APIهای عمومی AI، منبع canonical باید این ترتیب باشد:
|
||||
|
||||
### 4.1) سنسورها
|
||||
|
||||
منبع اصلی:
|
||||
|
||||
- `farm_data.SensorData.sensor_payload`
|
||||
|
||||
اما نه به صورت خام. باید از مسیر زیر مصرف شود:
|
||||
|
||||
- assign سنسورها به `cluster/sub-block`
|
||||
- میانگینگیری در سطح sub-block
|
||||
- میانگینگیری مجدد در سطح block اصلی
|
||||
- در صورت نیاز میانگینگیری در سطح کل مزرعه
|
||||
|
||||
### 4.2) ماهواره و remote sensing
|
||||
|
||||
منبع اصلی:
|
||||
|
||||
- `location_data.RemoteSensingRun`
|
||||
- `location_data.AnalysisGridObservation`
|
||||
- `location_data.RemoteSensingSubdivisionResult`
|
||||
- `location_data.RemoteSensingClusterBlock`
|
||||
- `location_data.RemoteSensingClusterAssignment`
|
||||
|
||||
و باز هم باید از مسیر زیر مصرف شود:
|
||||
|
||||
- میانگین متریک هر cluster/sub-block
|
||||
- میانگین متریک هر block اصلی
|
||||
- در صورت نیاز میانگین کل مزرعه
|
||||
|
||||
### 4.3) آبوهوا
|
||||
|
||||
منبع اصلی آبوهوا فعلاً cluster-based نیست و از اینجا میآید:
|
||||
|
||||
- `farm.weather_forecast`
|
||||
- یا آخرین `center_location.weather_forecasts`
|
||||
|
||||
یعنی weather فعلاً location-center based است، نه cluster based.
|
||||
|
||||
### 4.4) source of truth نهایی برای APIهای عمومی
|
||||
|
||||
برای APIهایی که `farm_uuid` میگیرند، بهتر است `source of truth` نهایی یکی از این دو باشد:
|
||||
|
||||
- `get_farm_details(farm_uuid)` بعد از ارتقا به policy جدید
|
||||
- یا یک service جدید مثل `build_ai_farm_snapshot(farm_uuid)`
|
||||
|
||||
این snapshot باید شامل این بخشها باشد:
|
||||
|
||||
- `farm_level_aggregated_metrics`
|
||||
- `block_level_metrics`
|
||||
- `sub_block_level_metrics`
|
||||
- `weather`
|
||||
- `plants`
|
||||
- `irrigation_method`
|
||||
- `source_metadata`
|
||||
|
||||
---
|
||||
|
||||
## 5) وضعیت فعلی هر API
|
||||
|
||||
در این بخش برای هر API مشخص شده:
|
||||
|
||||
- آیا الان مبتنی بر میانگین سنسور کلاسترها و میانگین ماهوارهای کلاسترها هست یا نه
|
||||
- اگر نیست، الان داده را از کجا میگیرد
|
||||
- وضعیت انطباق آن با policy جدید
|
||||
|
||||
---
|
||||
|
||||
## 5.1) RAG
|
||||
|
||||
### `POST /api/rag/chat/`
|
||||
|
||||
وضعیت فعلی: `نیمهمنطبق`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- متن خاک کاربر در `rag/user_data.py -> build_user_soil_text()`
|
||||
- از `SensorData` و `center_location` میخواند
|
||||
- از `build_farmer_block_aggregated_snapshot(...)` استفاده میکند
|
||||
- از `build_location_block_satellite_snapshots(...)` هم برای blockهای اصلی استفاده میکند
|
||||
|
||||
نتیجه:
|
||||
|
||||
- برای summary کلی مزرعه، از aggregation مبتنی بر block استفاده میکند
|
||||
- برای satellite و sensor summary تا حدی با policy شما سازگار است
|
||||
- اما RAG chat هنوز یک contract رسمی و واحد برای `cluster mean only` ندارد و متن embed شده ممکن است ترکیبی از دادههای سطح farm و block باشد
|
||||
|
||||
نیاز به اصلاح:
|
||||
|
||||
- canonical snapshot باید صریحاً از `block mean` و `sub-block mean` ساخته شود
|
||||
- prompt/context باید روشن بگوید که اعداد از `cluster averages` آمدهاند
|
||||
|
||||
### `POST /api/soile/anomaly-detection/`
|
||||
|
||||
وضعیت فعلی: `غیرمنطبق مستقیم، منطبق غیرمستقیم`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- anomaly payload از request میآید
|
||||
- اطلاعات مزرعه از `farm_data.services.get_farm_details()`
|
||||
- سپس به `rag/services/soil_anomaly.py` داده میشود
|
||||
|
||||
نتیجه:
|
||||
|
||||
- خود anomaly ممکن است از هر منبعی آمده باشد و API آن را enforce نمیکند
|
||||
- اما farm context از `get_farm_details()` میآید که فعلاً `latest_satellite + sensor_payload` را ترکیب میکند
|
||||
- `get_farm_details()` هنوز خلاصه soil را از `build_location_satellite_snapshot(center_location)` میگیرد، نه از `build_farmer_block_aggregated_snapshot()`
|
||||
|
||||
نیاز به اصلاح:
|
||||
|
||||
- `get_farm_details()` باید خلاصه soil اصلی را از `farmer-level aggregated snapshot` بگیرد
|
||||
- anomaly input هم اگر داخلی تولید میشود، باید بر پایه cluster mean باشد
|
||||
|
||||
---
|
||||
|
||||
## 5.2) Soile
|
||||
|
||||
### `POST /api/soile/health-summary/`
|
||||
|
||||
وضعیت فعلی: `احتمالاً نیمهمنطبق`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- از `farm_data.context.load_farm_context()` و سرویسهای soil استفاده میکند
|
||||
- `load_farm_context()` از `build_location_block_satellite_snapshots(location)` استفاده میکند
|
||||
- بخشی از context block-based است
|
||||
|
||||
اما:
|
||||
|
||||
- اگر در summary نهایی از metrics خام سنسور یا latest weather/location استفاده شود، خروجی کاملاً cluster-mean-only نیست
|
||||
|
||||
نیاز به اصلاح:
|
||||
|
||||
- health summary باید صریحاً از `block_level` و `farm_level` aggregated metrics استفاده کند
|
||||
- هیچ metric خام سنسور بدون عبور از منطق sub-block mean وارد پاسخ نشود
|
||||
|
||||
### `POST /api/soile/moisture-heatmap/`
|
||||
|
||||
وضعیت فعلی: `منطبق نیست`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- heatmap ذاتاً spatial است و معمولاً از grid/cell یا location-level moisture data ساخته میشود
|
||||
- برای heatmap، میانگینگیری کامل روی clusterها کافی نیست چون heatmap نیاز به توزیع مکانی دارد
|
||||
|
||||
نتیجه:
|
||||
|
||||
- این API نباید به خروجی تکعددی farm average تقلیل داده شود
|
||||
- بلکه باید داده خام grid/cell یا cluster-level map را نگه دارد
|
||||
|
||||
policy صحیح:
|
||||
|
||||
- برای کارت summary یا average moisture بله، از cluster mean استفاده شود
|
||||
- اما برای heatmap خودِ خروجی باید `cluster map` یا `grid map` باشد، نه صرفاً میانگین کل مزرعه
|
||||
|
||||
---
|
||||
|
||||
## 5.3) Weather
|
||||
|
||||
### `POST /api/weather/farm-card/`
|
||||
|
||||
وضعیت فعلی: `غیرمنطبق`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- از `weather_forecast` مرتبط با `center_location`
|
||||
- یا آخرین forecast همان location
|
||||
|
||||
نتیجه:
|
||||
|
||||
- weather فعلاً بر اساس clusterهای `location_data` نیست
|
||||
- چون مدل weather cluster-based ندارد
|
||||
|
||||
نیاز به اصلاح:
|
||||
|
||||
- اگر قرار است cluster-based شود، باید weather در سطح block/sub-block تعریف شود
|
||||
- در غیر این صورت، این API باید در سند بهعنوان `location-centered weather` ثبت شود
|
||||
|
||||
### `POST /api/weather/water-need-prediction/`
|
||||
|
||||
وضعیت فعلی: `نیمهمنطبق`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- در `rag/services/water_need_prediction.py` از `get_farm_details(farm_uuid)` استفاده میشود
|
||||
- همچنین از weather forecast مزرعه استفاده میکند
|
||||
|
||||
نتیجه:
|
||||
|
||||
- بخش خاک/سنسور میتواند از snapshot مزرعه بیاید
|
||||
- اما چون `get_farm_details()` هنوز fully farmer-block-aggregated نیست، خروجی کامل منطبق نیست
|
||||
- بخش weather هم location-level است
|
||||
|
||||
نیاز به اصلاح:
|
||||
|
||||
- خاک و ماهواره از farmer aggregated snapshot
|
||||
- weather تا زمان توسعه مدل cluster-weather، بهصورت location-level باقی بماند ولی source آن شفاف اعلام شود
|
||||
|
||||
---
|
||||
|
||||
## 5.4) Pest & Disease
|
||||
|
||||
### `POST /api/pest-disease/detect/`
|
||||
|
||||
وضعیت فعلی: `غیرمنطبق مفهومی`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- ورودی اصلی: تصویر
|
||||
- context کمکی: `farm_uuid` و داده مزرعه از `get_farm_details()`
|
||||
|
||||
نتیجه:
|
||||
|
||||
- هسته این API image-based است، نه cluster average based
|
||||
- context مزرعه میتواند cluster-based شود، اما خروجی نهایی وابسته به تصویر است
|
||||
|
||||
policy صحیح:
|
||||
|
||||
- context مزرعه برای کمک به تشخیص از snapshot تجمیعی بیاید
|
||||
- اما این API ذاتاً APIِ میانگینمحور نیست
|
||||
|
||||
### `POST /api/pest-disease/risk/`
|
||||
|
||||
وضعیت فعلی: `نیمهمنطبق`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- `rag/services/pest_disease.py`
|
||||
- اطلاعات مزرعه از `get_farm_details()`
|
||||
- داده RAG و پایگاه دانش تخصصی
|
||||
|
||||
نتیجه:
|
||||
|
||||
- risk API باید از context مزرعه استفاده کند
|
||||
- اگر `get_farm_details()` اصلاح شود، این API هم خودبهخود نزدیک به policy مطلوب میشود
|
||||
|
||||
---
|
||||
|
||||
## 5.5) Irrigation
|
||||
|
||||
### `POST /api/irrigation/plan-from-text/`
|
||||
|
||||
وضعیت فعلی: `غیرمنطبق ذاتی`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- ورودی اصلی: متن آزاد
|
||||
- مدل parser متنی
|
||||
|
||||
نتیجه:
|
||||
|
||||
- این API parser است، نه تحلیل agronomic مبتنی بر sensor/satellite
|
||||
- بنابراین لازم نیست خروجیاش بر پایه cluster average باشد
|
||||
|
||||
policy صحیح:
|
||||
|
||||
- فقط اگر farm context کمکی به parser اضافه شود، آن context باید از snapshot تجمیعی بیاید
|
||||
|
||||
### `POST /api/irrigation/recommend/`
|
||||
|
||||
وضعیت فعلی: `نیمهمنطبق`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- از farm context و سرویس RAG irrigation استفاده میکند
|
||||
- بخشی از سنسور را ممکن است مستقیماً از `sensor.sensor_payload` بخواند
|
||||
|
||||
نتیجه:
|
||||
|
||||
- اگر بعضی metricها مستقیم از payload خام خوانده شوند، با policy شما ناسازگار است
|
||||
|
||||
نیاز به اصلاح:
|
||||
|
||||
- recommendation فقط باید از aggregated block/sub-block metrics تغذیه شود
|
||||
- fallback مستقیم به اولین سنسور یا payload خام باید حذف یا محدود شود
|
||||
|
||||
---
|
||||
|
||||
## 5.6) Farm Parameters
|
||||
|
||||
### `POST /api/farm-data/parameters/`
|
||||
|
||||
وضعیت فعلی: `خارج از دامنه این policy`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- این API داده را ایجاد/ویرایش میکند
|
||||
- `farm_boundary` را میگیرد
|
||||
- `center_location` را resolve میکند
|
||||
- `sensor_payload` را ذخیره میکند
|
||||
- weather/location sync را trigger میکند
|
||||
|
||||
نتیجه:
|
||||
|
||||
- این API تولیدکننده داده است، نه consumer تحلیلی
|
||||
- بنابراین قرار نیست خروجی analytic آن بر پایه cluster mean باشد
|
||||
|
||||
اما نقش مهم:
|
||||
|
||||
- باید sensorها را طوری ذخیره کند که assignment به `cluster/sub-block` ممکن باشد
|
||||
- اگر cluster_uuid یا sub_block_code در payload نیاید، aggregation دقیق محدود میشود
|
||||
|
||||
---
|
||||
|
||||
## 5.7) Fertilization
|
||||
|
||||
### `POST /api/fertilization/plan-from-text/`
|
||||
|
||||
وضعیت فعلی: `غیرمنطبق ذاتی`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- parser متن آزاد
|
||||
|
||||
نتیجه:
|
||||
|
||||
- مانند irrigation text parser، این API ماهیتاً cluster-average consumer نیست
|
||||
|
||||
### `POST /api/fertilization/recommend/`
|
||||
|
||||
وضعیت فعلی: `نیمهمنطبق`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- context مزرعه و RAG fertilization
|
||||
- معمولاً از `get_farm_details()` و contextهای وابسته استفاده میکند
|
||||
|
||||
نتیجه:
|
||||
|
||||
- با اصلاح منبع canonical مزرعه، این API هم میتواند کاملاً منطبق شود
|
||||
|
||||
---
|
||||
|
||||
## 5.8) Crop Simulation
|
||||
|
||||
### `POST /api/crop-simulation/current-farm-chart/`
|
||||
### `POST /api/crop-simulation/growth/`
|
||||
### `POST /api/crop-simulation/harvest-prediction/`
|
||||
### `GET /api/crop-simulation/yield-harvest-summary/`
|
||||
### `POST /api/crop-simulation/yield-prediction/`
|
||||
|
||||
وضعیت فعلی: `غیرمنطبق تا نیمهمنطبق`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- سرویسهای `crop_simulation/services.py`
|
||||
- بخشی از دادهها از farm context و بخشی از سنسور یا weather فعلی میآیند
|
||||
- در بعضی helperها متریکها ممکن است مستقیماً از `sensor_payload` یا propertyهای سنسور resolve شوند
|
||||
|
||||
نتیجه:
|
||||
|
||||
- با rule شما که گفته بودی برای `crop_simulation` باید از داده کل بلوکهای بزرگ استفاده شود، وضعیت فعلی هنوز کامل نیست
|
||||
- چون منبع canonical شبیهسازی هنوز بهصورت صریح farmer-block aggregation enforced نشده
|
||||
|
||||
نیاز به اصلاح:
|
||||
|
||||
- ورودی تمام simulation endpointها باید از farm aggregated snapshot بیاید
|
||||
- یعنی متریکهای soil moisture, temperature, ndvi, ndwi, slope, nitrogen, phosphorus, potassium از `cluster mean -> block mean -> farm mean` ساخته شوند
|
||||
- weather فعلاً جداگانه location-level میماند مگر بعداً block-weather اضافه شود
|
||||
|
||||
### `GET /api/crop-simulation/growth/{task_id}/status/`
|
||||
|
||||
وضعیت فعلی: `وابسته به منبع run اولیه`
|
||||
|
||||
نتیجه:
|
||||
|
||||
- این endpoint فقط status/result job را برمیگرداند
|
||||
- اگر `growth` هنگام شروع از داده غیرمنطبق استفاده کرده باشد، status endpoint هم همان خروجی را reflect میکند
|
||||
|
||||
---
|
||||
|
||||
## 5.9) Economy
|
||||
|
||||
### `POST /api/economy/overview/`
|
||||
|
||||
وضعیت فعلی: `منطبق نیست و حتی منبع واقعی ندارد`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- `economy/services.py`
|
||||
- پیام صریح دارد که منبع واقعی تنظیم نشده است
|
||||
|
||||
نتیجه:
|
||||
|
||||
- این API فعلاً نه cluster-based است و نه حتی data-backed
|
||||
|
||||
نیاز به اصلاح:
|
||||
|
||||
- اگر قرار است فعال شود، باید از snapshot مزرعه + هزینهها + yield prediction + irrigation/fertilization plan استفاده کند
|
||||
|
||||
---
|
||||
|
||||
## 5.10) Farm Alerts
|
||||
|
||||
### `POST /api/farm-alerts/tracker/`
|
||||
|
||||
وضعیت فعلی: `نیمهمنطبق`
|
||||
|
||||
منبع داده فعلی:
|
||||
|
||||
- `farm_alerts/services.py`
|
||||
- از `load_farm_context(farm_uuid)` و `get_farm_details(farm_uuid)` استفاده میکند
|
||||
|
||||
نتیجه:
|
||||
|
||||
- چون farm context بخشی از snapshotهای block-based را میخواند، تا حدی با policy سازگار است
|
||||
- اما اگر context نهایی هنوز metric خام یا latest non-aggregated را ترجیح بدهد، کامل منطبق نیست
|
||||
|
||||
نیاز به اصلاح:
|
||||
|
||||
- همه alert ruleها باید روی block/farm aggregated metrics سوار شوند
|
||||
- در صورت نیاز، هشدارهای spatial باید روی cluster-level breakdown هم نمایش داده شوند
|
||||
|
||||
---
|
||||
|
||||
## 6) جمعبندی سریع انطباق APIها
|
||||
|
||||
### APIهایی که ماهیتاً باید cluster-aggregated باشند
|
||||
|
||||
اینها باید به policy جدید مهاجرت کنند:
|
||||
|
||||
- `POST /api/rag/chat/`
|
||||
- `POST /api/soile/anomaly-detection/`
|
||||
- `POST /api/soile/health-summary/`
|
||||
- `POST /api/weather/water-need-prediction/`
|
||||
- `POST /api/pest-disease/risk/`
|
||||
- `POST /api/irrigation/recommend/`
|
||||
- `POST /api/fertilization/recommend/`
|
||||
- `POST /api/crop-simulation/current-farm-chart/`
|
||||
- `POST /api/crop-simulation/growth/`
|
||||
- `POST /api/crop-simulation/harvest-prediction/`
|
||||
- `GET /api/crop-simulation/yield-harvest-summary/`
|
||||
- `POST /api/crop-simulation/yield-prediction/`
|
||||
- `POST /api/farm-alerts/tracker/`
|
||||
|
||||
### APIهایی که ماهیتاً parser/input/image/weather هستند و کامل cluster-based نیستند
|
||||
|
||||
- `POST /api/pest-disease/detect/` -> image-first
|
||||
- `POST /api/irrigation/plan-from-text/` -> text parser
|
||||
- `POST /api/fertilization/plan-from-text/` -> text parser
|
||||
- `POST /api/farm-data/parameters/` -> data ingestion/upsert
|
||||
- `POST /api/weather/farm-card/` -> location-centered weather
|
||||
- `POST /api/economy/overview/` -> فعلاً منبع واقعی ندارد
|
||||
|
||||
### APIهایی که spatial map هستند و نباید صرفاً average شوند
|
||||
|
||||
- `POST /api/soile/moisture-heatmap/`
|
||||
|
||||
این API باید cluster/grid-aware بماند، نه فقط average-based.
|
||||
|
||||
---
|
||||
|
||||
## 7) مهمترین mismatch فعلی در کد
|
||||
|
||||
مهمترین mismatch فعلی این است که `farm_data.services.get_farm_details()` برای `soil.resolved_metrics` این کار را میکند:
|
||||
|
||||
- `latest_satellite = build_location_satellite_snapshot(center_location)`
|
||||
- سپس `latest_satellite.resolved_metrics` را به عنوان soil_metrics میگیرد
|
||||
|
||||
این یعنی:
|
||||
|
||||
- خلاصه اصلی soil بر اساس یک snapshot location/block واحد ساخته میشود
|
||||
- نه بر اساس `build_farmer_block_aggregated_snapshot(center_location, sensor_payload=...)`
|
||||
|
||||
در حالی که برای policy موردنظر شما بهتر است این کار انجام شود:
|
||||
|
||||
- `farm_level_snapshot = build_farmer_block_aggregated_snapshot(...)`
|
||||
- `soil.resolved_metrics = farm_level_snapshot.resolved_metrics`
|
||||
- `soil.satellite_snapshots = block-level snapshots`
|
||||
- در صورت نیاز `sub_block snapshots` هم در context بمانند
|
||||
|
||||
---
|
||||
|
||||
## 8) پیشنهاد ساختار استاندارد پاسخ داده برای AI
|
||||
|
||||
برای همه سرویسهای AI بهتر است یک snapshot واحد با این ساختار وجود داشته باشد:
|
||||
|
||||
```json
|
||||
{
|
||||
"farm_uuid": "...",
|
||||
"aggregation_policy": {
|
||||
"sensor": "cluster_mean_then_block_mean_then_farm_mean",
|
||||
"satellite": "cluster_mean_then_block_mean_then_farm_mean",
|
||||
"weather": "center_location_latest_forecast",
|
||||
"default_block_policy": "1_main_block + 1_default_sub_block_when_missing"
|
||||
},
|
||||
"farm_metrics": {},
|
||||
"block_metrics": [],
|
||||
"sub_block_metrics": [],
|
||||
"weather": {},
|
||||
"plants": [],
|
||||
"irrigation_method": {}
|
||||
}
|
||||
```
|
||||
|
||||
مزیت این طراحی:
|
||||
|
||||
- همه APIها source of truth یکسان دارند
|
||||
- اختلاف بین RAG، crop simulation، irrigation و alerts کم میشود
|
||||
- تستپذیری سادهتر میشود
|
||||
|
||||
---
|
||||
|
||||
## 9) نتیجه نهایی
|
||||
|
||||
### الان کدام APIها دقیقاً مطابق خواسته شما نیستند؟
|
||||
|
||||
تقریباً همه APIهای تحلیلی هنوز `کاملاً` مطابق policy شما نیستند، چون منبع canonical یکپارچهای که صریحاً بر پایه `cluster mean sensor + cluster mean satellite` باشد هنوز همهجا enforce نشده است.
|
||||
|
||||
بیشترین فاصله با policy مطلوب در این بخشهاست:
|
||||
|
||||
- `crop_simulation`
|
||||
- `irrigation/recommend`
|
||||
- `fertilization/recommend`
|
||||
- `weather/farm-card`
|
||||
- `economy/overview`
|
||||
- بخشی از `soile` و `farm_alerts`
|
||||
|
||||
### الان کدام APIها از همین حالا تا حدی نزدیک هستند؟
|
||||
|
||||
- `rag/chat`
|
||||
- `farm_alerts/tracker`
|
||||
- `soile/health-summary`
|
||||
- `pest-disease/risk`
|
||||
|
||||
چون بهصورت مستقیم یا غیرمستقیم از snapshotهای block-based و `get_farm_details()` استفاده میکنند.
|
||||
|
||||
### الان کدام APIها ماهیتاً نباید صرفاً average-based شوند؟
|
||||
|
||||
- `soile/moisture-heatmap`
|
||||
- `pest-disease/detect`
|
||||
- parserهای `plan-from-text`
|
||||
|
||||
---
|
||||
|
||||
## 10) پیشنهاد اجرای فنی در کد
|
||||
|
||||
ترتیب پیشنهادی برای پیادهسازی:
|
||||
|
||||
1. `get_farm_details()` را به `farmer aggregated snapshot` مهاجرت بده.
|
||||
2. یک service جدید مثل `build_ai_farm_snapshot()` بساز.
|
||||
3. default block policy را به `1 main block + 1 default sub-block` ارتقا بده.
|
||||
4. همه APIهای تحلیلی را وادار کن فقط از snapshot جدید بخوانند.
|
||||
5. برای APIهای spatial مثل heatmap، علاوه بر average summary، خروجی cluster/grid breakdown نگه دار.
|
||||
|
||||
Reference in New Issue
Block a user