# Farmer Calendar Backend Requirements این فایل قرارداد کامل داده‌ای برای صفحه `farmer-calendar` را توضیح می‌دهد؛ یعنی هر چیزی که فرانت برای نمایش، ساخت، ویرایش و حذف رویدادهای تقویم نیاز دارد باید از بک‌اند دریافت یا به بک‌اند ارسال کند. ## Scope این مستند بر اساس این فایل‌ها تهیه شده است: - `src/views/dashboards/farm/FarmerCalendarPage.tsx` - `src/views/dashboards/farm/FarmerCalendarEventModal.tsx` - `src/views/dashboards/farm/FarmerCalendarEventDetails.tsx` - `src/views/apps/calendar/Calendar.tsx` - `src/redux-store/slices/calendar.ts` - `src/libs/api/services/eventService.ts` ## Frontend Features Covered بک‌اند باید از این قابلیت‌های صفحه پشتیبانی کند: - نمایش لیست رویدادهای تقویم - فیلتر رویدادها بر اساس بازه زمانی و نوع تقویم - نمایش جزییات رویداد - ساخت رویداد جدید - ویرایش رویداد - حذف رویداد - دریافت جداگانه‌ی لیست `tag`ها برای فرم ساخت/ویرایش - پشتیبانی از drag/drop و resize رویدادها در تقویم ## Domain Model هر رویداد تقویم باید حداقل ساختار زیر را داشته باشد: ```ts type CalendarEvent = { id: string; title: string; description: string; deadline?: number | null; tags: string[]; start: string; end: string; extendedProps?: Record; }; ``` ## Required Event Fields For Frontend فیلدهای زیر برای عملکرد درست فرانت لازم هستند: | Field | Type | Required | Used For | |---|---|---:|---| | `id` | `string` | yes | شناسایی رویداد برای edit/delete/update | | `title` | `string` | yes | عنوان رویداد در تقویم، کارت‌ها، مودال جزییات | | `description` | `string` | no but recommended | نمایش توضیح در کارت‌ها و جزییات | | `start` | `ISO 8601 string` | yes | نمایش زمان شروع، تقویم، محاسبه امروز/این هفته | | `end` | `ISO 8601 string` | yes | نمایش بازه زمانی، resize/drop | | `tags` | `string[]` | yes | نمایش tag در جزییات، انتخاب مقدار در فرم | | `deadline` | `number` | no | فعلا در state نگه‌داری می‌شود، بهتر است برگردد | | `extendedProps` | `object` | no | برای توسعه آینده و سازگاری با FullCalendar | ## Endpoints ### 1) List Events برای لود اولیه‌ی صفحه و رفرش رویدادها. `GET /api/events` #### Query Params | Param | Type | Required | Description | |---|---|---:|---| | `start` | `string` | no | شروع بازه به فرمت ISO 8601 | | `end` | `string` | no | پایان بازه به فرمت ISO 8601 | #### Success Response ```json { "events": [ { "id": "evt_101", "title": "آبیاری بلوک شمالی", "description": "کنترل فشار و مدت زمان آبیاری", "deadline": 1734942600, "tags": ["آبیاری"], "start": "2025-02-24T06:30:00Z", "end": "2025-02-24T08:00:00Z", "extendedProps": {} } ] } ``` #### Frontend Notes - اگر `events` خالی باشد باید `[]` برگردد، نه `null` - تاریخ‌ها باید قابل parse شدن با `new Date(...)` و `parseISO(...)` باشند - `start` و `end` برای همه رویدادها لازم‌اند ### 2) Get Event Details برای سناریوهای آینده یا lazy loading جزییات. `GET /api/events/:id` #### Success Response ```json { "event": { "id": "evt_101", "title": "آبیاری بلوک شمالی", "description": "کنترل فشار و مدت زمان آبیاری", "deadline": 1734942600, "tags": ["آبیاری"], "start": "2025-02-24T06:30:00Z", "end": "2025-02-24T08:00:00Z", "extendedProps": {} } } ``` ### 3) Create Event برای ساخت تسک/رویداد روزانه‌ی جدید. `POST /api/events` #### Request Body ```json { "title": "بازدید آفت در گلخانه", "description": "بررسی وضعیت برگ‌ها و ثبت گزارش", "deadline": 1734971400, "tags": ["آفت"], "start": "2025-02-24T14:00:00Z", "end": "2025-02-24T15:00:00Z", "extendedProps": {} } ``` #### Required Create Fields - `title` - `start` - `end` #### Success Response ```json { "event": { "id": "evt_102", "title": "بازدید آفت در گلخانه", "description": "بررسی وضعیت برگ‌ها و ثبت گزارش", "deadline": 1734971400, "tags": ["آفت"], "start": "2025-02-24T14:00:00Z", "end": "2025-02-24T15:00:00Z", "extendedProps": {} } } ``` ### 4) Update Event برای ویرایش دستی، drag/drop و resize. `PUT /api/events/:id` #### Request Body ```json { "title": "بازدید آفت در گلخانه", "description": "اولویت بالا", "deadline": 1734971400, "tags": ["آفت", "فوری"], "start": "2025-02-24T15:00:00Z", "end": "2025-02-24T16:00:00Z", "extendedProps": {} } ``` #### Success Response ```json { "event": { "id": "evt_102", "title": "بازدید آفت در گلخانه", "description": "اولویت بالا", "deadline": 1734971400, "tags": ["آفت", "فوری"], "start": "2025-02-24T15:00:00Z", "end": "2025-02-24T16:00:00Z", "extendedProps": {} } } ``` #### Important Update Notes - این endpoint باید برای هر دو حالت `form edit` و `calendar drag/resize` جواب بدهد - تغییر `start` و `end` باید سریع و idempotent باشد ### 5) Delete Event `DELETE /api/events/:id` #### Success Response ```json { "success": true } ``` ## Separate Tags API طبق نیاز این صفحه، لیست `tag`ها نباید از `events` استخراج شود و باید از یک API جداگانه دریافت شود. ### 6) List Event Tags `GET /api/events/tags` #### Purpose - پر کردن `select` مربوط به tag در فرم ساخت/ویرایش - جلوگیری از وابستگی UI به استخراج `tags` از event list - بهینه‌تر شدن لود مودال افزودن رویداد #### Success Response ```json { "tags": [ { "id": "tag_irrigation", "label": "آبیاری", "value": "آبیاری" }, { "id": "tag_pest", "label": "آفت", "value": "آفت" }, { "id": "tag_harvest", "label": "برداشت", "value": "برداشت" } ] } ``` #### Minimum Accepted Alternative اگر نخواهید آبجکت کامل برگردانید، این ساختار هم برای فرانت کافی است: ```json { "tags": ["آبیاری", "آفت", "برداشت"] } ``` #### Recommendation فرمت آبجکتی بهتر است، چون بعدا این قابلیت‌ها را ساده‌تر می‌کند: - مرتب‌سازی - disabled state - رنگ یا آیکن برای هر tag - localization ## Error Handling برای همه endpointها بهتر است خطاها ساختار ثابت داشته باشند: ```json { "code": "EVENT_VALIDATION_ERROR", "message": "Invalid event payload", "details": { "start": "start is required" } } ``` فرانت فعلی حداقل به یک `message` قابل‌نمایش نیاز دارد. ## Validation Rules Recommended - `title` نباید خالی باشد - `start` باید تاریخ معتبر باشد - `end` باید تاریخ معتبر باشد - `end` نباید قبل از `start` باشد - `tags` اگر موجود است باید آرایه‌ای از string باشد ## Date/Time Requirements - فرمت ترجیحی: `ISO 8601 UTC`, مثال: `2025-02-24T06:30:00Z` - timezone باید در پاسخ‌ها صریح و قابل پیش‌بینی باشد - بک‌اند نباید تاریخ مبهم بدون timezone برگرداند ## What Frontend Actually Renders Today این فیلدها همین الان در UI استفاده می‌شوند: - `title` - `description` - `start` - `end` - `tags[0]` این فیلدها فعلا بیشتر برای سازگاری یا توسعه بعدی نگه‌داری می‌شوند: - `deadline` - `extendedProps` ## Performance Recommendations - `GET /api/events` باید pagination یا date-range filtering را پشتیبانی کند، حتی اگر فعلا فرانت از آن به‌صورت کامل استفاده نکند - `GET /api/events/tags` باید سبک و cacheable باشد - پاسخ `GET /api/events/tags` بهتر است کوچک و بدون payload اضافی باشد ## Final Backend Checklist - `GET /api/events` - `GET /api/events/:id` - `POST /api/events` - `PUT /api/events/:id` - `DELETE /api/events/:id` - `GET /api/events/tags` - پشتیبانی از `tags` به صورت آرایه - بازگرداندن تاریخ‌ها با فرمت ISO 8601 ## Suggested Stable Response Shapes اگر بخواهید قرارداد بک‌اند کاملا پایدار و توسعه‌پذیر باشد، این دو response shape پیشنهاد می‌شوند: ### Events List ```json { "events": [ { "id": "evt_101", "title": "آبیاری بلوک شمالی", "description": "کنترل فشار و مدت زمان آبیاری", "deadline": 1734942600, "tags": ["آبیاری"], "start": "2025-02-24T06:30:00Z", "end": "2025-02-24T08:00:00Z", "extendedProps": {} } ], "meta": { "total": 1 } } ``` ### Tags List ```json { "tags": [ { "id": "tag_irrigation", "label": "آبیاری", "value": "آبیاری" } ], "meta": { "total": 1 } } ```