Files
Logic/BACKEND_PLANTS_AI_FARMDATA_SYNC_PROPOSAL.md
2026-05-11 03:27:21 +03:30

522 lines
19 KiB
Markdown

# پیشنهاد معماری جدید: Backend-owned Plants + AI farm_data Sync
## خلاصه تصمیم
تصمیم جدید این است که مالک اصلی داده‌های گیاه در سیستم، `Backend` باشد و اپ `plants` در Backend به‌صورت کامل مسئول نگهداری catalog گیاه‌ها شود.
در این معماری:
- اپ `Backend/plants` منبع اصلی `Plant Catalog` خواهد بود
- اپ `Backend/farm_hub` رابطه‌ی فارم با گیاه‌ها را نگه می‌دارد
- اپ `Ai/farm_data` داده‌های مورد نیاز AI را از Backend دریافت می‌کند
- پس از هر تغییر در Backend، داده‌های مرتبط در `Ai/farm_data` به‌روزرسانی می‌شوند
- هرجایی در AI که به اطلاعات گیاه نیاز دارد، از داده‌های `farm_data` استفاده می‌کند
---
## هدف اصلی
این تغییر برای حل چند مسئله انجام می‌شود:
- متمرکز شدن catalog گیاه‌ها در Backend
- حذف پراکندگی ownership داده‌های گیاه
- واضح شدن source of truth
- ساده‌تر شدن استفاده‌ی ماژول‌های AI از اطلاعات گیاه
- فراهم شدن یک read-model مشخص در `Ai/farm_data`
---
## تصمیم domain-level
### 1) Backend مالک اصلی داده‌ی گیاه است
در این معماری، اطلاعات پایه‌ی گیاه باید در Backend نگهداری شود:
- نام گیاه
- مشخصات کاتالوگ
- ویژگی‌های رشد
- نور
- آب
- خاک
- دما
- فصل کاشت
- زمان برداشت
- spacing
- fertilizer
- و هر داده‌ی canonical دیگر
### 2) AI مصرف‌کننده‌ی داده‌ی گیاه است
در این معماری، AI دیگر owner داده‌های گیاه نیست، بلکه از Backend این اطلاعات را دریافت می‌کند.
### 3) `Ai/farm_data` لایه‌ی داده‌ای مورد استفاده‌ی AI می‌شود
در AI، داده‌ی گیاه مستقیماً از مدل canonical مستقل خوانده نمی‌شود، بلکه از داده‌هایی استفاده می‌شود که در `Ai/farm_data` ذخیره یا sync شده‌اند.
---
## ساختار پیشنهادی Backend
## اپ `plants`
اپ `Backend/plants` باید به اپ canonical برای catalog گیاه‌ها تبدیل شود.
### مسئولیت‌ها
- نگهداری لیست همه‌ی گیاه‌ها
- نگهداری اطلاعات catalog هر گیاه
- ارائه‌ی API برای خواندن catalog گیاه‌ها
- ارائه‌ی API برای دریافت جزئیات یک گیاه
- در صورت نیاز، ارائه‌ی endpointهای تغییرات برای sync با AI
### داده‌های این app
نمونه داده‌هایی که بهتر است در `plants` باشند:
- `id`
- `name`
- `slug`
- `icon`
- `description`
- `light`
- `watering`
- `soil`
- `temperature`
- `growth_stage_defaults`
- `planting_season`
- `harvest_time`
- `spacing`
- `fertilizer`
- `health_profile`
- `irrigation_profile`
- `growth_profile`
- `is_active`
- `updated_at`
---
## اپ `farm_hub`
در `Backend/farm_hub` باید رابطه‌ی فارم با گیاه نگهداری شود.
### پیشنهاد رابطه
در گام اول، چیزی که گفتی منطقی است:
- یک رابطه‌ی `ManyToMany` بین `FarmHub` و `Plant`
مثلاً در سطح مفهومی:
```python
class FarmHub(models.Model):
plants = models.ManyToManyField("plants.Plant", related_name="farms", blank=True)
```
این ساختار برای شروع خوب است اگر فقط بخواهی بدانی:
- هر فارم چه گیاه‌هایی دارد
### نکته تکمیلی مهم
اگر بعداً برای رابطه‌ی فارم و گیاه metadata خواستی، `ManyToMany` ساده کافی نیست.
مثلاً اگر این داده‌ها لازم شوند:
- تاریخ کاشت
- وضعیت فعلی رشد
- نوع کشت در آن فارم
- تنظیمات اختصاصی آبیاری
- health state
- مقدار هدف تولید
بهتر است بعداً رابطه به مدل واسط تبدیل شود:
```python
class FarmPlant(models.Model):
farm = models.ForeignKey(FarmHub, on_delete=models.CASCADE)
plant = models.ForeignKey("plants.Plant", on_delete=models.CASCADE)
planted_at = models.DateField(null=True, blank=True)
stage = models.CharField(max_length=64, blank=True)
```
### نتیجه
- برای فاز اول: `ManyToMany` ساده قابل قبول است
- برای فاز matureتر: `through model` بهتر است
---
## ساختار پیشنهادی AI
## نقش `Ai/farm_data`
در این تصمیم جدید، `Ai/farm_data` تبدیل به لایه‌ای می‌شود که داده‌های گیاه و داده‌های فارم-گیاه را برای مصرف ماژول‌های AI نگه می‌دارد.
یعنی:
- Backend source of truth است
- `Ai/farm_data` read/update replica برای use caseهای AI است
### وظایف `farm_data`
- دریافت داده‌ی گیاه از Backend
- دریافت relationهای فارم و گیاه از Backend
- ذخیره‌ی داده‌ی مورد نیاز برای AI
- به‌روزرسانی داده بعد از هر تغییر
- ارائه‌ی data access ساده برای سایر appهای AI
---
## جریان داده پیشنهادی
### مرحله 1: تغییر در Backend
هر تغییری که در این بخش‌ها رخ می‌دهد:
- ایجاد گیاه جدید
- ویرایش catalog گیاه
- حذف یا غیرفعال‌سازی گیاه
- تغییر گیاه‌های مرتبط با یک فارم
باید باعث شود `Ai/farm_data` نیز به‌روزرسانی شود.
### مرحله 2: sync به AI
بعد از تغییر، Backend از طریق API یا مکانیزم sync، داده را به `Ai/farm_data` می‌رساند.
### مرحله 3: مصرف در AI
هر app در AI که به داده‌ی گیاه نیاز دارد، به‌جای dependency مستقیم روی مدل‌های قدیمی یا منابع پراکنده، از `farm_data` می‌خواند.
---
## نکته مهم درباره `apps.py`
اگرچه در پیام قبلی بحث `Ai/farm_data/apps.py` مطرح بود، در این تصمیم جدید بهتر است منطق sync اصلی در `apps.py` قرار نگیرد.
### `apps.py` برای چه مناسب است؟
- app registration
- signal registration
- import سبک startup
### `apps.py` برای چه مناسب نیست؟
- orchestration سنگین sync
- HTTP fetch logic
- retry logic
- reconciliation logic
- business update flow
### پیشنهاد بهتر
منطق sync بهتر است در این فایل‌ها قرار بگیرد:
- `Ai/farm_data/services.py`
- `Ai/farm_data/tasks.py`
- `Ai/farm_data/clients/backend.py`
و `apps.py` فقط wiring را انجام دهد.
---
## دو نوع داده‌ای که باید تفکیک شوند
برای اینکه این معماری بعداً تمیز بماند، بهتر است از همین ابتدا دو نوع داده را از هم جدا ببینی.
### 1) Plant Catalog
داده‌های عمومی و canonical هر گیاه:
- نام
- مشخصات رشد
- پروفایل آبیاری
- نیازهای محیطی
این داده‌ها متعلق به `Backend/plants` هستند.
### 2) Farm Plant Assignment / Context
داده‌هایی که مشخص می‌کنند:
- یک فارم چه گیاهی دارد
- چه گیاهی برای آن فارم فعال است
- چه context یا تنظیمی روی آن اعمال شده
این داده‌ها از relation بین فارم و گیاه می‌آیند و در Backend تعریف می‌شوند، اما برای مصرف AI در `farm_data` sync می‌شوند.
---
## چه appهایی در AI باید update شوند؟
در این معماری جدید، همه appهای AI لزوماً نیاز به تغییر مستقیم ندارند؛ فقط appهایی که الان مستقیم یا غیرمستقیم به داده‌ی گیاه یا `SensorData.plants` وابسته‌اند باید update شوند.
### 1) `Ai/farm_data`
این app مهم‌ترین app برای تغییر است و باید به هسته‌ی integration جدید تبدیل شود.
#### فایل‌ها و بخش‌هایی که باید update شوند
- `Ai/farm_data/models.py`
- `Ai/farm_data/serializers.py`
- `Ai/farm_data/services.py`
- `Ai/farm_data/views.py`
- `Ai/farm_data/urls.py`
- `Ai/farm_data/apps.py`
- `Ai/farm_data/management/commands/seed_farm_data.py`
- `Ai/farm_data/tests/`
#### تغییرات مورد نیاز
- حذف وابستگی مستقیم `ManyToMany` به `plant.Plant` در صورت جایگزینی با replica data
- تعریف ساختار جدید برای نگهداری `plant catalog snapshot` یا `farm plant snapshot`
- افزودن service client برای خواندن data از Backend
- افزودن endpoint یا task برای sync داده از Backend
- تغییر serializerها تا payload جدید گیاه را برگردانند
- اصلاح تست‌ها بر اساس source جدید داده
#### نکته مهم
الان در `Ai/farm_data/models.py` فیلد `plants` به `plant.Plant` وصل است. این نقطه یکی از اصلی‌ترین جاهایی است که باید بازطراحی شود، چون در معماری جدید AI نباید برای catalog گیاه به مدل canonical داخلی تکیه کند.
---
### 2) `Ai/rag`
این app از مهم‌ترین مصرف‌کننده‌های اطلاعات گیاه است و باید update شود تا به‌جای مدل‌های قبلی، از `farm_data` بخواند.
#### فایل‌ها و بخش‌هایی که باید update شوند
- `Ai/rag/user_data.py`
- `Ai/rag/services/irrigation.py`
- `Ai/rag/services/fertilization.py`
- `Ai/rag/services/water_need_prediction.py`
- `Ai/rag/services/pest_disease.py`
- `Ai/rag/services/yield_harvest.py`
- `Ai/rag/tests/test_recommendation_services.py`
- هر فایل دیگری که مستقیم `Plant` یا `SensorData.plants` را می‌خواند
#### تغییرات مورد نیاز
- حذف import مستقیم از `plant.models`
- استفاده از facade یا service داخل `farm_data` برای دریافت plant context
- جایگزینی readهای مستقیم از مدل گیاه با read model جدید
- اصلاح تست‌ها بر اساس structure جدید داده
#### نکته مهم
در حال حاضر `Ai/rag/user_data.py` مستقیم به `Plant` وابستگی دارد. این وابستگی باید حذف شود و همه چیز از `farm_data` خوانده شود.
---
### 3) `Ai/irrigation`
این app احتمالاً از داده‌ی گیاه برای recommendation یا indicator استفاده می‌کند و باید با read model جدید سازگار شود.
#### فایل‌ها و بخش‌هایی که باید update شوند
- `Ai/irrigation/indicators.py`
- `Ai/irrigation/views.py`
- تست‌های `irrigation`
#### تغییرات مورد نیاز
- اگر منطق آبیاری به plant profile وابسته است، profile باید از `farm_data` خوانده شود
- حذف هر dependency متنی یا مستقیم به جدول `Plant`
- هماهنگی responseها با data contract جدید
---
### 4) `Ai/soile`
این app مستقیماً `SensorData` را می‌خواند و در queryها `plants` را prefetch می‌کند؛ بنابراین باید update شود.
#### فایل‌ها و بخش‌هایی که باید update شوند
- `Ai/soile/services.py`
- `Ai/soile/test_soil_moisture_heatmap_api.py`
#### تغییرات مورد نیاز
- بازنویسی queryهایی که `prefetch_related("plants")` دارند
- استفاده از plant data جدیدی که در `farm_data` ذخیره می‌شود
- اصلاح منطق‌هایی که فرض می‌کنند `plants` یک relation مستقیم ORM به مدل `Plant` است
---
### 5) `Ai/weather`
این app بیشتر weather-centric است، ولی برخی flowها از `SensorData` و در مواردی از context فارم/گیاه برای پیش‌بینی نیاز آبی استفاده می‌کنند.
#### فایل‌ها و بخش‌هایی که باید update شوند
- `Ai/weather/water_need_prediction.py`
- `Ai/weather/farm_weather.py`
- تست‌های مرتبط با farm weather
#### تغییرات مورد نیاز
- اگر plant context برای water need استفاده می‌شود، منبع آن باید `farm_data` باشد
- اگر serializer یا service فرض می‌کند relation قبلی `plants` برقرار است، باید اصلاح شود
---
### 6) `Ai/location_data`
این app بیشتر location-centric است و وابستگی مستقیم شدیدی به گیاه ندارد، اما چون با `SensorData` کار می‌کند باید از سازگاری model جدید مطمئن شویم.
#### فایل‌ها و بخش‌هایی که باید update شوند
- `Ai/location_data/ndvi.py`
- `Ai/location_data/views.py` در صورت استفاده از farm context
- تست‌های location مرتبط با farm
#### تغییرات مورد نیاز
- بیشتر در حد compatibility check با ساختار جدید `farm_data`
- اگر plant-aware response وجود دارد، باید با source جدید هماهنگ شود
---
### 7) `Ai/farm_alerts`
اگر alertها به نوع گیاه، stage، یا context گیاه متکی باشند، این app هم باید update شود.
#### فایل‌ها و بخش‌هایی که باید بررسی/آپدیت شوند
- `Ai/farm_alerts/services.py`
- `Ai/farm_alerts/alerts_tracker.py`
- `Ai/farm_alerts/views.py`
#### تغییرات مورد نیاز
- هرجا alert rule به plant info وابسته است، plant info باید از `farm_data` خوانده شود
- اگر فعلاً وابستگی مستقیم ندارد، فقط compatibility review کافی است
---
### 8) `Ai/economy`
این app ممکن است در بعضی سناریوها به نوع گیاه برای تحلیل اقتصادی وابسته شود.
#### فایل‌ها و بخش‌هایی که باید بررسی شوند
- `Ai/economy/services.py`
- `Ai/economy/views.py`
- تست‌های economy
#### تغییرات مورد نیاز
- اگر نوع گیاه یا catalog گیاه در محاسبات اقتصادی استفاده می‌شود، باید از `farm_data` خوانده شود
- اگر فعلاً استفاده‌ای ندارد، تنها review کافی است
---
## appهایی که احتمالاً بیشترین تغییر را دارند
اگر بخواهیم اولویت‌بندی کنیم، بیشترین تغییر در AI به‌ترتیب در این appها خواهد بود:
- `Ai/farm_data`
- `Ai/rag`
- `Ai/soile`
- `Ai/irrigation`
- `Ai/weather`
و این appها بیشتر نیاز به review و compatibility check دارند:
- `Ai/location_data`
- `Ai/farm_alerts`
- `Ai/economy`
---
## الگوی پیشنهادی برای جلوگیری از پخش شدن وابستگی‌ها
برای اینکه تغییرات در AI کنترل‌پذیر بماند، بهتر است appهای دیگر مستقیماً model جدید `farm_data` را تکه‌تکه query نزنند.
### پیشنهاد
یک لایه‌ی access مرکزی در `farm_data` تعریف شود، مثلاً:
- `Ai/farm_data/services.py`
- یا `Ai/farm_data/context.py`
و appهای دیگر فقط از همین interface استفاده کنند.
### مثال از مسئولیت این facade
- گرفتن plant catalog برای یک farm
- گرفتن primary plant یا active plants
- گرفتن irrigation profile گیاه
- گرفتن growth/health context گیاه
این کار باعث می‌شود اگر بعداً schema داخلی `farm_data` عوض شد، فقط یک لایه update شود.
---
## تغییرات مستندی که باید در AI انجام شوند
علاوه بر کد، این بخش‌های مستنداتی هم باید update شوند:
- `Ai/API_REFERENCE_FA.md`
- `Ai/APPS_URLS_AUDIT.md`
- `Ai/API_RELIABILITY_AUDIT_FA.md`
- هر doc مرتبط با `Plant API`
- هر doc مرتبط با `farm_data` payload
### دلیل
چون در وضعیت جدید:
- `Plant API` دیگر نباید به‌عنوان canonical داخل AI معرفی شود
- `farm_data` باید به‌عنوان plant consumer/read model معرفی شود
- endpointها و schemaهای response احتمالاً تغییر می‌کنند
---
## پیشنهاد فازبندی update اپ‌های AI
### فاز 1: هسته‌ی data layer
- update `Ai/farm_data`
- تعریف schema جدید data
- تعریف sync service با Backend
### فاز 2: مصرف‌کننده‌های اصلی
- update `Ai/rag`
- update `Ai/soile`
- update `Ai/irrigation`
- update `Ai/weather`
### فاز 3: مصرف‌کننده‌های ثانویه
- review/update `Ai/location_data`
- review/update `Ai/farm_alerts`
- review/update `Ai/economy`
### فاز 4: پاک‌سازی نهایی
- حذف dependency مستقیم به `plant.models`
- حذف endpointهای قدیمی یا deprecated در AI
- اصلاح تست‌ها و docs
---
## صورت‌بندی نهایی این تغییر
نسخه‌ی دقیق‌تر و کامل‌تر این تصمیم به این صورت است:
- یک app کامل `plants` در Backend نگهدارنده‌ی catalog همه‌ی گیاه‌ها باشد.
- در `Backend/farm_hub` رابطه‌ی `ManyToMany` بین `FarmHub` و `Plant` تعریف شود.
- بعد از هر تغییر در catalog گیاه یا رابطه‌ی فارم-گیاه، داده‌ها به `Ai/farm_data` sync شوند.
- `Ai/farm_data` به منبع مصرفی همه‌ی ماژول‌های AI برای اطلاعات گیاه تبدیل شود.
- در AI هرجا اطلاعات گیاه، catalog گیاه، یا نوع گیاه لازم است، از `farm_data` خوانده شود، نه از مدل‌های پراکنده یا منبع دیگری.
- appهای AI که الان به `Plant` یا `SensorData.plants` وابسته‌اند باید مرحله‌به‌مرحله به این مدل جدید مهاجرت کنند.
---
## نتیجه یک‌خطی
این تصمیم از نظر معماری قابل دفاع و قابل توسعه است، به شرطی که `Backend/plants` source of truth بماند، `farm_hub` رابطه‌ی فارم-گیاه را نگه دارد، `Ai/farm_data` لایه‌ی sync/read برای AI باشد، و تمام appهای وابسته در AI به‌صورت کنترل‌شده از dependency مستقیم به `Plant` جدا شوند.