# پیشنهاد معماری جدید: 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` جدا شوند.