- در `location_data/data_driven_subdivision.py` اگر بعد از ساخت dataset، هیچ observation قابل استفاده برای clustering باقی نماند، این exception پرتاب میشود:
-`هیچ observation قابل استفادهای برای خوشهبندی باقی نماند.`
این یعنی pipeline به این نقطه رسیده:
1. cellها ساخته شدهاند
2. metricها از openEO درخواست شدهاند
3. observationها در DB ذخیره شدهاند
4. اما در زمان ساخت dataset برای clustering، ردیف قابل مصرفی پیدا نشده است
### معنی عملی این خطا
یعنی برای همه observationهای این run، سیستم نتوانسته feature vector قابل استفاده بسازد.
در کد فعلی، observation وقتی از clustering حذف میشود که:
- همه featureهای انتخابشده برای آن observation برابر `None` باشند
پس این خطا معمولاً یعنی:
- یا تمام metricهای لازم برای همه cellها `null` شدهاند
- یا feature set انتخابی با دادههایی که واقعاً ذخیره شدهاند mismatch دارد
- یا persistence / selection طوری انجام شده که clustering به داده قابل استفاده دسترسی پیدا نکرده است
---
## 10) محتملترین علتها برای همین run
### علت 1: featureهای حذفشده هنوز در pipeline زنده هستند
در payload میبینیم:
-`selected_features` هنوز شامل `dem_m` و `slope_deg` است
- اما در `location_data/openeo_service.py` این metricها از محاسبه حذف شدهاند
نتیجه:
- API و metadata هنوز فکر میکنند این دو feature بخشی از clustering هستند
- ولی openEO دیگر آنها را تولید نمیکند
- بنابراین در observationها این فیلدها عملاً `None` میمانند
نکته مهم:
- فقط `None` بودن `dem_m` و `slope_deg` بهتنهایی برای تولید این خطا کافی نیست
- اما این mismatch یکی از مهمترین نشانههای ناسازگاری pipeline است
### علت 2: metricهای اصلی احتمالاً برای همه cellها مقدار قابل استفاده نداشتهاند
چون این خطا فقط وقتی رخ میدهد که هیچ observation usable باقی نماند، محتمل است که برای همه 12 cell:
-`ndvi`
-`ndwi`
-`soil_vv_db`
هم عملاً `None` شده باشند یا آنطور که clustering انتظار دارد قابل مصرف نبوده باشند.
این حالت ممکن است از اینجا آمده باشد:
- داده خام provider برای این محدوده/بازه تهی یا نامعتبر بوده
- masking یا aggregation مقدار usable تولید نکرده
- یا در persistence، featureهای محاسبهشده بهدرستی به ستونهای clustering نرسیدهاند
### علت 3: progress tracker با metricهای واقعی sync نیست
در payload:
-`completed_metrics` شامل `soil_vv` است
- ولی `states` شامل `soil_vv_db` به حالت `pending` است
یعنی tracker با metric واقعی اجراشده sync نیست:
- metric واقعی remote: `soil_vv`
- metric مشتقشده محلی: `soil_vv_db`
این باعث میشود progress ظاهراً ناقص دیده شود، حتی وقتی داده remote کامل شده است.
### علت 4: وضعیت DB و Celery با هم متناقضاند
در payload:
-`data.status = failed`
- ولی `task.celery.state = RETRY`
یعنی:
- از نظر DB، run شکست خورده ثبت شده
- از نظر Celery، task هنوز در حال retry است و failure نهایی نشده
این برای client گیجکننده است، چون معلوم نیست باید run را تمامشده و fail شده بداند یا منتظر retry بماند.
---
## 11) مشکلات فعلی `location_data` که از کد مشخص هستند
### مشکل 1: `DEFAULT_CLUSTER_FEATURES` هنوز metricهای حذفشده را نگه داشته
فایل:
-`location_data/data_driven_subdivision.py`
وضعیت فعلی:
-`dem_m`
-`slope_deg`
هنوز داخل `DEFAULT_CLUSTER_FEATURES` هستند.
اثر:
-`selected_features` اشتباه در run metadata
- progress tracker اشتباه
- clustering contract قدیمی باقی میماند
### مشکل 2: serializer و summary هنوز `dem_m` و `slope_deg` را به API برمیگردانند
فایلها:
-`location_data/serializers.py`
-`location_data/views.py`
اثر:
- response API هنوز metricهای حذفشده را نمایش میدهد
- summary میانگین `dem_m_mean` و `slope_deg_mean` میسازد
- مصرفکننده API فکر میکند این metricها هنوز پشتیبانی میشوند
### مشکل 3: `_upsert_grid_observations` هنوز فیلدهای حذفشده را persist میکند
فایل:
-`location_data/tasks.py`
اثر:
- ستونهای `dem_m` و `slope_deg` همچنان نوشته میشوند، اما عملاً با `None`
- metadata هنوز `slope_supported` را ذخیره میکند، در حالی که openEO service دیگر این مفهوم را برنمیگرداند
### مشکل 4: progress metricها با metricهای واقعی اجراشده mismatch دارد
فایل:
-`location_data/tasks.py`
نمونه mismatch:
- remote metric واقعی: `soil_vv`
- feature مورد انتظار برای clustering: `soil_vv_db`
اثر:
-`completed_metrics` و `states` با هم ناسازگار میشوند
-`soil_vv_db` در response به شکل `pending` دیده میشود، با اینکه از `soil_vv` مشتق میشود
### مشکل 5: stage و status همیشه هماهنگ نیستند
در payload فعلی:
-`run.status_label = failed`
-`run.stage = observations_persisted`
اثر:
- client نمیفهمد خطا دقیقاً در کدام stage رخ داده
-`task.current_stage` هم گمراهکننده میشود
### مشکل 6: DB failure و Celery retry همزمان به client داده میشود
اثر:
- API برای یک run همزمان پیام `failed` و `RETRY` میدهد
- از نگاه UX، کاربر نمیداند باید retry خودکار را صبر کند یا خطا را final بداند
6. اما Celery هنوز task را در حالت `RETRY` نگه داشته
---
## 13) پیشنهادهای اصلاح
### اصلاح ضروری
1.`dem_m` و `slope_deg` را از این نقاط هم حذف کنید:
-`location_data/data_driven_subdivision.py`
-`location_data/serializers.py`
-`location_data/views.py`
-`location_data/tasks.py`
2.`DEFAULT_CLUSTER_FEATURES` را با metricهای واقعی sync کنید:
-`ndvi`
-`ndwi`
-`soil_vv_db`
3. progress tracker را طوری اصلاح کنید که:
- completion `soil_vv` به completion `soil_vv_db` هم map شود
- metricهای حذفشده اصلاً در state دیده نشوند
4. منطق status endpoint را طوری تنظیم کنید که:
- اگر Celery در `RETRY` است، status client نهایی `failed` نباشد
- یا حداقل یک فیلد صریح مثل `final_status=false` برگردد
5. قبل از clustering، یک diagnostic بهتر ذخیره شود:
- تعداد observationهای usable
- تعداد observationهای all-null
- تعداد null برای هر feature
### اصلاح پیشنهادی برای debug بهتر
در `stage_details` این موارد اضافه شود:
-`usable_observation_count`
-`all_features_missing_cell_codes`
-`feature_null_counts`
-`selected_features_effective`
---
## 14) نتیجه نهایی
این run به احتمال زیاد به خاطر ناسازگاری بین featureهای مورد انتظار pipeline و featureهای واقعاً تولید/ذخیرهشده شکست خورده است، و علاوه بر آن چند inconsistency مهم در `location_data` وجود دارد:
- metricهای حذفشده هنوز در feature contract حضور دارند
- progress report با metricهای واقعی sync نیست
- DB status و Celery status با هم تناقض دارند
- stage نهایی برای failure به شکل واضح و قابل اتکا به client نمایش داده نمیشود
اگر بخواهید، مرحله بعدی میتواند این باشد که همین موارد را در کد هم اصلاح کنیم، نه فقط مستندسازی.