UPDATE
This commit is contained in:
@@ -0,0 +1,746 @@
|
||||
# راهنمای پیادهسازی API صفحه Yield & Harvest با PCSE و RAG
|
||||
|
||||
این فایل برای تیم بکاند نوشته شده تا صفحه `yield-harvest` را با تکیه بر:
|
||||
|
||||
- مستند `psce_doc.txt` پروژه
|
||||
- سرویسهای موجود در `crop_simulation/`
|
||||
- معماری فعلی RAG در `rag/`
|
||||
|
||||
به شکل قابل اتکا پیادهسازی کند.
|
||||
|
||||
نکته: فایل `psce_doc.txt` در عمل مستند PCSE است و در این سند هم با عنوان PCSE به آن اشاره میشود.
|
||||
|
||||
---
|
||||
|
||||
## جمعبندی سریع
|
||||
|
||||
برای این صفحه، بهترین معماری این است:
|
||||
|
||||
1. عددها، تاریخها، درصدها و سریهای نمودار از PCSE و دادههای مزرعه ساخته شوند.
|
||||
2. RAG فقط برای متنهای توضیحی، خلاصهسازی، و wording کاربرپسند استفاده شود.
|
||||
3. RAG اجازه نداشته باشد عدد جدید، تاریخ جدید، یا KPI جدید اختراع کند.
|
||||
4. یک endpoint خلاصه برای فرانت برگردانده شود:
|
||||
|
||||
`GET /api/yield-harvest/summary/?farm_uuid=<uuid>`
|
||||
|
||||
اگر لازم شد از نظر convention داخلی پروژه همهچیز داخل `crop_simulation` بماند، میتوانید معادل زیر را هم نگه دارید:
|
||||
|
||||
`GET /api/crop-simulation/yield-harvest-summary/?farm_uuid=<uuid>`
|
||||
|
||||
برای فرانت فعلی، مدل summary بهتر از چند endpoint پراکنده است.
|
||||
|
||||
---
|
||||
|
||||
## چیزی که همین الان در پروژه دارید
|
||||
|
||||
### لایه PCSE / شبیهسازی
|
||||
|
||||
الان پروژه این اجزا را دارد:
|
||||
|
||||
- `crop_simulation/services.py`
|
||||
- `crop_simulation/growth_simulation.py`
|
||||
- `crop_simulation/harvest_prediction.py`
|
||||
- `crop_simulation/yield_prediction.py`
|
||||
|
||||
و همین حالا از PCSE این خروجیها را میسازید:
|
||||
|
||||
- `yield` از `TWSO`
|
||||
- `biomass` از `TAGP`
|
||||
- `leaf_area_index` از `LAI`
|
||||
- `development_stage` از `DVS`
|
||||
- `soil_moisture` از `SM`
|
||||
|
||||
این دقیقاً با چیزی که در `psce_doc.txt` آمده همراستا است: PCSE برای state/rate variables و خروجی روزانه مناسب است و برای ساخت KPI، trend و harvest timing گزینه خوبی است.
|
||||
|
||||
### لایه RAG
|
||||
|
||||
الان پروژه الگوی خوبی برای سرویسهای ترکیبی deterministic + RAG دارد:
|
||||
|
||||
- `rag/services/irrigation.py`
|
||||
- `rag/services/fertilization.py`
|
||||
- `rag/chat.py`
|
||||
- `config/rag_config.yaml`
|
||||
|
||||
الگوی درست در این پروژه این است:
|
||||
|
||||
- اول عددها و تصمیمهای پایه از منطق deterministic ساخته میشوند
|
||||
- بعد RAG فقط متن نهایی را polish میکند
|
||||
- در صورت خراب شدن خروجی LLM، fallback ساختاریافته دارید
|
||||
|
||||
برای `yield-harvest` هم باید دقیقاً همین الگو تکرار شود.
|
||||
|
||||
---
|
||||
|
||||
## اصل طراحی مهم
|
||||
|
||||
### چه چیزی باید deterministic باشد
|
||||
|
||||
این فیلدها نباید از RAG بیایند:
|
||||
|
||||
- `daysUntil`
|
||||
- `readiness`
|
||||
- `share`
|
||||
- `series[].data`
|
||||
- `averageReadiness`
|
||||
- `predicted yield`
|
||||
- `harvest date`
|
||||
- هر عددی که در progress bar، chart، KPI یا sorting استفاده میشود
|
||||
|
||||
### چه چیزی میتواند از RAG بیاید
|
||||
|
||||
این فیلدها مناسب RAG هستند:
|
||||
|
||||
- `season_highlights_card.subtitle`
|
||||
- `season_highlights_card.spotlight.caption`
|
||||
- `harvest_prediction_card.description`
|
||||
- `harvest_operations_card.summary`
|
||||
- `steps[].note`
|
||||
- badgeها و labelهای توصیفی کوتاه
|
||||
|
||||
### قانون طلایی
|
||||
|
||||
RAG باید فقط روی context قطعی زیر کار کند:
|
||||
|
||||
- farm details
|
||||
- خروجیهای PCSE
|
||||
- دادههای آبوهوا
|
||||
- دادههای سنسور
|
||||
- در صورت وجود: داده کیفیت، آفات، اقتصاد، بازار
|
||||
|
||||
و prompt آن باید صریح بگوید:
|
||||
|
||||
- عدد جدید نساز
|
||||
- فقط از مقادیر دادهشده استفاده کن
|
||||
- اگر داده کافی نیست، کمبود را بگو
|
||||
- خروجی را در JSON معتبر برگردان
|
||||
|
||||
---
|
||||
|
||||
## پیشنهاد معماری برای این صفحه
|
||||
|
||||
بهترین راه این است که یک orchestrator service جدید بسازید:
|
||||
|
||||
- `crop_simulation/yield_harvest_summary.py`
|
||||
|
||||
و داخل آن چند builder کوچک داشته باشید:
|
||||
|
||||
- `_build_yield_prediction_block()`
|
||||
- `_build_harvest_prediction_block()`
|
||||
- `_build_yield_prediction_chart_block()`
|
||||
- `_build_harvest_readiness_zones_block()`
|
||||
- `_build_yield_quality_bands_block()`
|
||||
- `_build_harvest_operations_block()`
|
||||
- `_build_season_highlights_block()`
|
||||
|
||||
و یک facade نهایی:
|
||||
|
||||
- `YieldHarvestSummaryService.get_summary(farm_uuid, season_year=None, crop_name=None)`
|
||||
|
||||
این service باید:
|
||||
|
||||
1. داده مزرعه را از `farm_data.services.get_farm_details()` بگیرد.
|
||||
2. خروجی شبیهسازی را از `CurrentFarmChartSimulator` و سرویسهای فعلی بگیرد.
|
||||
3. بلوکهای deterministic را بسازد.
|
||||
4. اگر RAG فعال بود، متنهای narrative را enrich کند.
|
||||
5. یک payload نهایی برای فرانت برگرداند.
|
||||
|
||||
---
|
||||
|
||||
## Mapping پیشنهادی هر کارت به منبع داده
|
||||
|
||||
| بلوک | منبع اصلی | وضعیت امکان پیادهسازی |
|
||||
|---|---|---|
|
||||
| `yield_prediction` | `crop_simulation/yield_prediction.py` + chart metrics | قابل پیادهسازی همین الآن |
|
||||
| `harvest_prediction_card` | `crop_simulation/harvest_prediction.py` | قابل پیادهسازی همین الآن |
|
||||
| `yield_prediction_chart` | `CurrentFarmChartSimulator` + historical baseline | نیمهآماده، نیاز به تصمیم درباره سری مقایسهای |
|
||||
| `season_highlights_card` | aggregate از بقیه بلوکها + RAG | قابل پیادهسازی اگر بقیه بلوکها حاضر باشند |
|
||||
| `harvest_readiness_zones` | داده قطعه/زون + PCSE per zone | فعلاً gap دادهای دارد |
|
||||
| `yield_quality_bands` | quality model / grading rules / lab data | فعلاً gap دادهای دارد |
|
||||
| `harvest_operations_card` | rules + optimizer + RAG | قابل پیادهسازی بهصورت اولیه |
|
||||
|
||||
---
|
||||
|
||||
## نکته مهم: همه بلوکها را PCSE بهتنهایی تولید نمیکند
|
||||
|
||||
PCSE برای این بخشها خیلی مناسب است:
|
||||
|
||||
- زمان برداشت
|
||||
- روند رشد
|
||||
- عملکرد پیشبینیشده
|
||||
- stage / maturity / readiness proxy
|
||||
- trend chart
|
||||
|
||||
اما PCSE بهصورت پیشفرض برای اینها کافی نیست:
|
||||
|
||||
- `بریکس`
|
||||
- `گرید ممتاز / درجه یک / فرآوری`
|
||||
- `پتانسیل صادرات`
|
||||
- `قیمت فروش`
|
||||
- `premium`
|
||||
- readiness per block وقتی مدل block-level ندارید
|
||||
|
||||
پس برای صفحه کامل، باید سه لایه را از هم جدا ببینید:
|
||||
|
||||
1. `PCSE layer`: عددهای زیستی و رشد
|
||||
2. `Rules/Aggregation layer`: تبدیل خروجی PCSE به KPIهای محصولی
|
||||
3. `RAG layer`: توضیح، جمعبندی، و متن قابل نمایش
|
||||
|
||||
---
|
||||
|
||||
## طراحی endpoint پیشنهادی
|
||||
|
||||
### Route
|
||||
|
||||
پیشنهاد اصلی:
|
||||
|
||||
- `GET /api/yield-harvest/summary/?farm_uuid=<uuid>&season_year=1404&crop_name=wheat`
|
||||
|
||||
### Query params
|
||||
|
||||
- `farm_uuid`: اجباری
|
||||
- `season_year`: اختیاری
|
||||
- `crop_name`: اختیاری
|
||||
- `include_narrative`: اختیاری، پیشفرض `true`
|
||||
|
||||
### چرا `include_narrative` خوب است
|
||||
|
||||
چون اگر RAG کند یا موقتاً غیرفعال باشد، باز هم فرانت میتواند با داده deterministic رندر شود.
|
||||
|
||||
---
|
||||
|
||||
## ساختار پیشنهادی response
|
||||
|
||||
همان envelope فعلی پروژه مناسب است:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
||||
"season_highlights_card": {},
|
||||
"yield_prediction": {},
|
||||
"harvest_prediction_card": {},
|
||||
"harvest_readiness_zones": {},
|
||||
"yield_quality_bands": {},
|
||||
"harvest_operations_card": {},
|
||||
"yield_prediction_chart": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## پیشنهاد فنی برای ساخت هر بلوک
|
||||
|
||||
## 1) `yield_prediction`
|
||||
|
||||
### منبع
|
||||
|
||||
- `YieldPredictionService`
|
||||
- یا مستقیم `CurrentFarmChartSimulator.simulate()`
|
||||
|
||||
### منطق پیشنهادی
|
||||
|
||||
- `predicted yield` از `TWSO`
|
||||
- `harvest readiness` از `DVS` و فاصله تا maturity
|
||||
- `quality score` فعلاً rule-based، نه RAG-based
|
||||
- `loss risk` از ترکیب moisture/weather/pest signals اگر دارید، وگرنه با fallback ساده
|
||||
|
||||
### توصیه
|
||||
|
||||
اگر الآن فقط داده قطعی میخواهید:
|
||||
|
||||
- KPI اول را دقیق بسازید
|
||||
- KPIهای دوم تا چهارم را با rules ساده و شفاف بسازید
|
||||
- آنها را به عنوان `estimated` در کد داخلی mark کنید
|
||||
|
||||
---
|
||||
|
||||
## 2) `harvest_prediction_card`
|
||||
|
||||
### منبع
|
||||
|
||||
- `crop_simulation/harvest_prediction.py`
|
||||
|
||||
### وضعیت
|
||||
|
||||
این بلوک تقریباً آماده است.
|
||||
|
||||
### توصیه
|
||||
|
||||
- `dateFormatted` را از serializer-ready formatter بگیرید
|
||||
- `daysUntil` حتماً `number` بماند
|
||||
- متن `description` اگر خواستید با RAG بهتر شود، version deterministic را هم نگه دارید
|
||||
|
||||
یعنی بهتر است این دو فیلد را داشته باشید:
|
||||
|
||||
- `description`
|
||||
- `descriptionSource = "deterministic" | "rag"`
|
||||
|
||||
این source flag برای debugging خیلی کمک میکند.
|
||||
|
||||
---
|
||||
|
||||
## 3) `yield_prediction_chart`
|
||||
|
||||
### واقعیت فعلی
|
||||
|
||||
خروجی chart فعلی شما در `CurrentFarmChartSimulator` بیشتر اینها را میدهد:
|
||||
|
||||
- leaf count estimate
|
||||
- biomass
|
||||
- storage organ weight
|
||||
- lai
|
||||
- soil moisture
|
||||
|
||||
اما payload فرانت `yield-harvest` در سند شما نمودار `سال قبل / سال جاری` میخواهد.
|
||||
|
||||
### نتیجه
|
||||
|
||||
این بخش هنوز one-to-one با کد فعلی آماده نیست.
|
||||
|
||||
### راه درست
|
||||
|
||||
یکی از این دو مسیر را انتخاب کنید:
|
||||
|
||||
#### مسیر A - سریعتر
|
||||
|
||||
همان chart فعلی را به contract فرانت نزدیک کنید و فعلاً بهجای `سال قبل/سال جاری` از:
|
||||
|
||||
- `عملکرد تجمعی پیشبینیشده`
|
||||
- `بیوماس`
|
||||
|
||||
استفاده کنید.
|
||||
|
||||
#### مسیر B - محصولیتر
|
||||
|
||||
دو سری واقعی تولید کنید:
|
||||
|
||||
- `سال جاری`: از simulation جاری
|
||||
- `سال قبل`: از historical scenario یا historical harvest data
|
||||
|
||||
اگر داده سال قبل ندارید، این سری را fake نکنید.
|
||||
|
||||
### توصیه نهایی
|
||||
|
||||
برای production بهتر است تا وقتی historical source ندارید، label سریها را صادقانه تغییر دهید.
|
||||
|
||||
---
|
||||
|
||||
## 4) `harvest_readiness_zones`
|
||||
|
||||
### بزرگترین gap فعلی
|
||||
|
||||
مدل داده فعلی شما عمدتاً farm-level است:
|
||||
|
||||
- `SensorData`
|
||||
- `center_location`
|
||||
- `farm_details`
|
||||
|
||||
اما این کارت block-level data میخواهد:
|
||||
|
||||
- `A1`
|
||||
- `A2`
|
||||
- cultivar per block
|
||||
- readiness per block
|
||||
|
||||
### نتیجه
|
||||
|
||||
بدون model یا source جدید برای block/zone، این کارت را نباید fake کنید.
|
||||
|
||||
### راه درست
|
||||
|
||||
یا باید یکی از اینها را اضافه کنید:
|
||||
|
||||
1. مدل `FarmBlock` یا `FarmZone`
|
||||
2. چند sensor/polygon برای هر مزرعه
|
||||
3. block metadata در JSON مزرعه
|
||||
|
||||
### پیادهسازی پیشنهادی
|
||||
|
||||
برای هر block:
|
||||
|
||||
1. weather/location را resolve کنید
|
||||
2. crop parameters block-specific بسازید
|
||||
3. یک simulation جدا اجرا کنید
|
||||
4. `DVS`, `TWSO`, `SM`, `maturity date` را بگیرید
|
||||
5. readiness را از rule زیر بسازید
|
||||
|
||||
مثال rule:
|
||||
|
||||
```text
|
||||
readiness = clamp((current_dvs / 2.0) * 100, 0, 100)
|
||||
```
|
||||
|
||||
یا:
|
||||
|
||||
```text
|
||||
readiness = clamp(100 - days_until_harvest * 4, 0, 100)
|
||||
```
|
||||
|
||||
بهتر است این rule داخل code comment شفاف توضیح داده شود.
|
||||
|
||||
---
|
||||
|
||||
## 5) `yield_quality_bands`
|
||||
|
||||
### نکته مهم
|
||||
|
||||
PCSE بهصورت پیشفرض grade یا brix تولید نمیکند.
|
||||
|
||||
پس این کارت را باید از یکی از این منابع ساخت:
|
||||
|
||||
1. داده آزمایشگاهی
|
||||
2. rule engine بر اساس moisture + disease risk + maturity + crop profile
|
||||
3. مدل quality جدا
|
||||
|
||||
### چیزی که نباید انجام شود
|
||||
|
||||
اینکه RAG خودش بگوید:
|
||||
|
||||
- 46% گرید ممتاز
|
||||
- 34% گرید یک
|
||||
|
||||
بدون منطق deterministic
|
||||
|
||||
این کار برای dashboard اشتباه است.
|
||||
|
||||
### پیشنهاد عملی
|
||||
|
||||
فاز اول:
|
||||
|
||||
- اگر quality data ندارید، این کارت را با flag `unavailable` برگردانید
|
||||
- یا bands را از rule-based scoring بسازید و در backend صریح mark کنید که estimated هستند
|
||||
|
||||
مثلاً:
|
||||
|
||||
- `quality_score >= 85 -> premium`
|
||||
- `70..84 -> grade_1`
|
||||
- `< 70 -> processing`
|
||||
|
||||
اما این rule باید crop-specific باشد، نه universal.
|
||||
|
||||
---
|
||||
|
||||
## 6) `harvest_operations_card`
|
||||
|
||||
### بهترین جا برای ترکیب deterministic + RAG
|
||||
|
||||
این کارت candidate خیلی خوبی برای RAG است، چون:
|
||||
|
||||
- order و timing میتواند از rules و simulation بیاید
|
||||
- متن summary و noteها میتواند از RAG بیاید
|
||||
|
||||
### طراحی پیشنهادی
|
||||
|
||||
ابتدا backend یک payload قطعی بسازد:
|
||||
|
||||
```json
|
||||
{
|
||||
"recommended_shift_count": 2,
|
||||
"sorting_capacity_ton_per_day": 15,
|
||||
"required_workers": 12,
|
||||
"max_transfer_hours": 6,
|
||||
"priority_blocks": ["A1", "A2"],
|
||||
"reasoning": [
|
||||
"A1 readiness بالاتر دارد",
|
||||
"moisture در محدوده مناسب است"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
بعد این payload را به RAG بدهید تا فقط اینها را تولید کند:
|
||||
|
||||
- `summary`
|
||||
- `steps[].note`
|
||||
- `steps[].status`
|
||||
|
||||
و حتیالمقدور:
|
||||
|
||||
- `outputs[]` را deterministic نگه دارید
|
||||
|
||||
---
|
||||
|
||||
## 7) `season_highlights_card`
|
||||
|
||||
### بهترین روش
|
||||
|
||||
این کارت را از بقیه بلوکها derive کنید، نه از یک منبع مستقل.
|
||||
|
||||
یعنی:
|
||||
|
||||
- `seasonLabel` از ورودی season
|
||||
- `badges` از readiness/quality/risk
|
||||
- `spotlight.value` از harvest window یا best sale window
|
||||
- `metrics` از yield, grade, revenue estimate
|
||||
|
||||
### نکته
|
||||
|
||||
اگر هنوز economy data ندارید، فیلدهایی مثل:
|
||||
|
||||
- `درآمد هدف`
|
||||
- `پنجره طلایی فروش`
|
||||
|
||||
نباید با RAG اختراع شوند.
|
||||
|
||||
یا باید:
|
||||
|
||||
- حذف شوند
|
||||
- یا با `null`
|
||||
- یا با fallback business rule
|
||||
|
||||
برگردند.
|
||||
|
||||
---
|
||||
|
||||
## پیشنهاد برای RAG service جدید
|
||||
|
||||
مثل `irrigation` و `fertilization` یک سرویس جدید اضافه کنید:
|
||||
|
||||
- `rag/services/yield_harvest.py`
|
||||
|
||||
و در `config/rag_config.yaml` هم service جدید تعریف کنید:
|
||||
|
||||
- `yield_harvest`
|
||||
|
||||
### نقش این سرویس
|
||||
|
||||
این سرویس نباید خودش KPI بسازد.
|
||||
|
||||
فقط باید:
|
||||
|
||||
- summary بنویسد
|
||||
- subtitle بسازد
|
||||
- operation notes تولید کند
|
||||
- badge text را human-friendly کند
|
||||
|
||||
### ورودی پیشنهادی به RAG
|
||||
|
||||
```json
|
||||
{
|
||||
"farm_uuid": "...",
|
||||
"plant_name": "...",
|
||||
"deterministic_metrics": {
|
||||
"predicted_yield_tons": 42.8,
|
||||
"days_until_harvest": 18,
|
||||
"readiness_avg": 84,
|
||||
"quality_score": 91,
|
||||
"loss_risk_percent": 6.5
|
||||
},
|
||||
"operations": {
|
||||
"shift_count": 2,
|
||||
"required_workers": 12,
|
||||
"max_transfer_hours": 6
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### خروجی پیشنهادی از RAG
|
||||
|
||||
فقط این بخشها:
|
||||
|
||||
```json
|
||||
{
|
||||
"season_highlights_card": {
|
||||
"subtitle": "...",
|
||||
"spotlight": {
|
||||
"caption": "..."
|
||||
},
|
||||
"badges": ["...", "..."]
|
||||
},
|
||||
"harvest_prediction_card": {
|
||||
"description": "..."
|
||||
},
|
||||
"harvest_operations_card": {
|
||||
"summary": "...",
|
||||
"steps": [
|
||||
{
|
||||
"title": "...",
|
||||
"note": "...",
|
||||
"status": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Rule مهم
|
||||
|
||||
اگر JSON RAG خراب بود:
|
||||
|
||||
- fallback deterministic برگردان
|
||||
- endpoint fail نکند
|
||||
|
||||
---
|
||||
|
||||
## فایلهایی که پیشنهاد میشود تغییر کنند
|
||||
|
||||
### در `crop_simulation/`
|
||||
|
||||
- `crop_simulation/apps.py`
|
||||
- اضافه کردن getter برای summary service
|
||||
|
||||
- `crop_simulation/serializers.py`
|
||||
- serializer درخواست و پاسخ summary
|
||||
|
||||
- `crop_simulation/views.py`
|
||||
- view جدید برای summary
|
||||
|
||||
- `crop_simulation/urls.py`
|
||||
- route جدید
|
||||
|
||||
- `crop_simulation/yield_harvest_summary.py`
|
||||
- orchestrator اصلی
|
||||
|
||||
### در `Schemas/`
|
||||
|
||||
- `Schemas/crop_simulation_yield_harvest_summary.py`
|
||||
- contract برای مستندسازی route
|
||||
|
||||
- `Schemas/__init__.py`
|
||||
- register کردن contract جدید
|
||||
|
||||
### در `rag/`
|
||||
|
||||
- `rag/services/yield_harvest.py`
|
||||
- narrative enrichment
|
||||
|
||||
### در config
|
||||
|
||||
- `config/rag_config.yaml`
|
||||
- service جدید `yield_harvest`
|
||||
|
||||
- `config/tones/yield_harvest_tone.txt`
|
||||
- tone مخصوص summary صفحه
|
||||
|
||||
- در صورت نیاز:
|
||||
- `config/knowledge_base/yield_harvest/`
|
||||
|
||||
---
|
||||
|
||||
## ترتیب پیشنهادی پیادهسازی
|
||||
|
||||
### فاز 1 - سریع و قابل اتکا
|
||||
|
||||
فقط این بلوکها را واقعی کنید:
|
||||
|
||||
- `yield_prediction`
|
||||
- `harvest_prediction_card`
|
||||
- `yield_prediction_chart`
|
||||
- `harvest_operations_card` با rules ساده
|
||||
|
||||
و برای بقیه اگر داده ندارید:
|
||||
|
||||
- `null`
|
||||
- یا `available: false`
|
||||
|
||||
برگردانید.
|
||||
|
||||
### فاز 2 - RAG narrative
|
||||
|
||||
به summary و operation notes متن کاربرپسند اضافه کنید.
|
||||
|
||||
### فاز 3 - block-level readiness
|
||||
|
||||
بعد از اضافه شدن مدل zone/block، `harvest_readiness_zones` را واقعی کنید.
|
||||
|
||||
### فاز 4 - quality/economy
|
||||
|
||||
بعد از اضافه شدن منبع quality یا market:
|
||||
|
||||
- `yield_quality_bands`
|
||||
- revenue
|
||||
- sale window
|
||||
|
||||
را کامل کنید.
|
||||
|
||||
---
|
||||
|
||||
## توصیه مهم درباره contract
|
||||
|
||||
اگر بعضی بلوکها هنوز data source واقعی ندارند، بهتر است از همین حالا response را اینطور طراحی کنید:
|
||||
|
||||
```json
|
||||
{
|
||||
"harvest_readiness_zones": {
|
||||
"available": false,
|
||||
"reason": "block_level_data_missing",
|
||||
"averageReadiness": null,
|
||||
"blocks": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
این بهتر از mock پنهان است، چون:
|
||||
|
||||
- فرانت میفهمد چرا کارت کامل نیست
|
||||
- QA راحتتر تست میکند
|
||||
- بعداً migration سادهتر میشود
|
||||
|
||||
---
|
||||
|
||||
## ریسکهای اصلی
|
||||
|
||||
### 1. استفاده از RAG برای عددسازی
|
||||
|
||||
بزرگترین خطر این صفحه همین است. RAG فقط برای narrative مناسب است.
|
||||
|
||||
### 2. نبود داده block-level
|
||||
|
||||
`harvest_readiness_zones` بدون مدل block عملاً دقیق نمیشود.
|
||||
|
||||
### 3. نبود quality source
|
||||
|
||||
`yield_quality_bands` بدون مدل کیفیت یا rule engine crop-specific قابل اتکا نیست.
|
||||
|
||||
### 4. ناهماهنگی chart contract
|
||||
|
||||
chart فعلی backend دقیقاً همان chart مورد انتظار فرانت نیست.
|
||||
|
||||
---
|
||||
|
||||
## پیشنهاد نهایی من
|
||||
|
||||
اگر بخواهم برای همین repo کمریسکترین مسیر را انتخاب کنم:
|
||||
|
||||
1. یک summary service در `crop_simulation` بسازید.
|
||||
2. `yield_prediction` و `harvest_prediction_card` را از سرویسهای فعلی reuse کنید.
|
||||
3. `yield_prediction_chart` را فعلاً با داده واقعی current simulation برگردانید، نه مقایسه fake سال قبل.
|
||||
4. `harvest_operations_card` را با rules deterministic + optional RAG summary بسازید.
|
||||
5. `season_highlights_card` را از همین بلوکها aggregate کنید.
|
||||
6. `harvest_readiness_zones` و `yield_quality_bands` را فقط وقتی source واقعی دارید production کنید.
|
||||
|
||||
این مسیر با معماری فعلی پروژه، با `psce_doc.txt`، و با pattern موجود RAG بیشترین سازگاری را دارد.
|
||||
|
||||
---
|
||||
|
||||
## یک pseudo flow پیشنهادی
|
||||
|
||||
```text
|
||||
GET /api/yield-harvest/summary/?farm_uuid=...
|
||||
->
|
||||
load farm details
|
||||
->
|
||||
run/reuse PCSE simulation outputs
|
||||
->
|
||||
build deterministic blocks
|
||||
->
|
||||
optionally call RAG for narrative fields only
|
||||
->
|
||||
merge response
|
||||
->
|
||||
return code/msg/data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## نتیجه
|
||||
|
||||
برای این صفحه:
|
||||
|
||||
- PCSE باید موتور عددها باشد
|
||||
- rules باید موتور KPIهای محصولی باشد
|
||||
- RAG باید موتور متن و explanation باشد
|
||||
|
||||
اگر این مرزبندی رعایت شود، هم dashboard قابل اعتماد میشود، هم توسعه بعدی آن تمیز و قابل نگهداری میماند.
|
||||
Reference in New Issue
Block a user