452 lines
12 KiB
Markdown
452 lines
12 KiB
Markdown
|
|
# Farmer Todos Backend Requirements
|
||
|
|
|
||
|
|
این فایل قرارداد کامل دادهای برای صفحه `farmer-todos` را توضیح میدهد؛ یعنی همه اطلاعاتی که فرانت باید از بکاند دریافت کند یا به بکاند ارسال کند تا صفحه تودولیست مزرعه بهصورت کامل و قابل اتصال کار کند.
|
||
|
|
|
||
|
|
## Scope
|
||
|
|
|
||
|
|
این مستند بر اساس این فایلها تهیه شده است:
|
||
|
|
|
||
|
|
- `src/views/dashboards/farm/todos/FarmerTodoPage.tsx`
|
||
|
|
- `src/libs/api/services/todoService.ts`
|
||
|
|
- `src/libs/api/services/taskService.ts`
|
||
|
|
|
||
|
|
## Frontend Features Covered
|
||
|
|
|
||
|
|
بکاند باید از این قابلیتهای صفحه پشتیبانی کند:
|
||
|
|
|
||
|
|
- نمایش لیست تسکهای مزرعه
|
||
|
|
- ثبت سریع تسک جدید با `عنوان + محل اجرا + روز + ساعت + اولویت`
|
||
|
|
- نمایش تسکها بر اساس `همه / امروز / فوری / انجام شده`
|
||
|
|
- تغییر وضعیت تسک بین `باز` و `انجام شده`
|
||
|
|
- نمایش `note` و `tags`
|
||
|
|
- نمایش زمانبندی هر تسک با `scheduledDate` و `time`
|
||
|
|
- دریافت لیست محلهای اجرا برای select فرم
|
||
|
|
- دریافت لیست tagها برای توسعه بعدی یا prefill
|
||
|
|
|
||
|
|
## Page Data Model
|
||
|
|
|
||
|
|
مدلی که این صفحه واقعا با آن کار میکند به این شکل است:
|
||
|
|
|
||
|
|
```ts
|
||
|
|
type TaskPriority = "زیاد" | "متوسط" | "کم";
|
||
|
|
type TaskStatus = "open" | "done";
|
||
|
|
|
||
|
|
type FarmerTodoTask = {
|
||
|
|
id: number | string;
|
||
|
|
title: string;
|
||
|
|
zone: string;
|
||
|
|
scheduledDate: string;
|
||
|
|
time: string;
|
||
|
|
priority: TaskPriority;
|
||
|
|
note: string;
|
||
|
|
tags: string[];
|
||
|
|
status: TaskStatus;
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
## Required Fields For Frontend
|
||
|
|
|
||
|
|
| Field | Type | Required | Used For |
|
||
|
|
|---|---|---:|---|
|
||
|
|
| `id` | `number \| string` | yes | toggle/update/render key |
|
||
|
|
| `title` | `string` | yes | عنوان کارت تسک |
|
||
|
|
| `zone` | `string` | yes | نمایش محل اجرا و select فرم |
|
||
|
|
| `scheduledDate` | `string` | yes | فیلتر امروز، مرتبسازی، نمایش روز |
|
||
|
|
| `time` | `string` | yes | نمایش ساعت و مرتبسازی |
|
||
|
|
| `priority` | `"زیاد" \| "متوسط" \| "کم"` | yes | رنگ، آیکن، فیلتر فوری |
|
||
|
|
| `note` | `string` | no but recommended | متن توضیح داخل کارت |
|
||
|
|
| `tags` | `string[]` | yes | نمایش برچسبها |
|
||
|
|
| `status` | `"open" \| "done"` | yes | نمایش/فیلتر و checkbox |
|
||
|
|
|
||
|
|
## Date And Time Requirements
|
||
|
|
|
||
|
|
- `scheduledDate` باید برای فرانت قابل parse باشد
|
||
|
|
- فرمت پیشنهادی برای `scheduledDate`: `YYYY-MM-DD`
|
||
|
|
- `time` بهتر است فرمت `HH:mm` داشته باشد
|
||
|
|
- چون datepicker صفحه شمسی است، فرانت میتواند تاریخ را شمسی انتخاب کند اما بهتر است به بکاند معادل میلادی استاندارد بفرستد
|
||
|
|
- پیشنهاد نهایی: بکاند و فرانت روی ذخیره `scheduledDate` به شکل میلادی `YYYY-MM-DD` توافق کنند
|
||
|
|
|
||
|
|
## Recommended Task API
|
||
|
|
|
||
|
|
### 1) List Farmer Todo Tasks
|
||
|
|
|
||
|
|
`GET /api/farmer-todos`
|
||
|
|
|
||
|
|
#### Query Params
|
||
|
|
|
||
|
|
| Param | Type | Required | Description |
|
||
|
|
|---|---|---:|---|
|
||
|
|
| `status` | `open \| done` | no | فیلتر بر اساس وضعیت |
|
||
|
|
| `priority` | `high \| medium \| low` یا مقدار بومی | no | فیلتر اولویت |
|
||
|
|
| `date` | `YYYY-MM-DD` | no | فیلتر یک روز مشخص |
|
||
|
|
| `from` | `YYYY-MM-DD` | no | شروع بازه |
|
||
|
|
| `to` | `YYYY-MM-DD` | no | پایان بازه |
|
||
|
|
| `zone` | `string` | no | فیلتر بر اساس محل اجرا |
|
||
|
|
| `search` | `string` | no | جستجو در عنوان/یادداشت |
|
||
|
|
|
||
|
|
#### Success Response
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"tasks": [
|
||
|
|
{
|
||
|
|
"id": 101,
|
||
|
|
"title": "بررسی رطوبت ردیف شمالی",
|
||
|
|
"zone": "قطعه گندم - شمال مزرعه",
|
||
|
|
"scheduledDate": "2025-02-24",
|
||
|
|
"time": "06:30",
|
||
|
|
"priority": "زیاد",
|
||
|
|
"note": "اگر رطوبت کمتر از 28٪ بود، آبیاری دوباره بررسی شود.",
|
||
|
|
"tags": ["آبیاری", "صبح زود"],
|
||
|
|
"status": "open"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"meta": {
|
||
|
|
"total": 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Frontend Notes
|
||
|
|
|
||
|
|
- اگر `tasks` خالی باشد باید `[]` برگردد
|
||
|
|
- اگر بکاند enum داخلی دارد، بهتر است همینجا به مقادیر قابلاستفاده فرانت map شود
|
||
|
|
- اگر بخواهید با `todoService` فعلی سازگار بمانید، یک adapter در frontend هم میتواند این mapping را انجام دهد
|
||
|
|
|
||
|
|
### 2) Create New Farmer Todo Task
|
||
|
|
|
||
|
|
`POST /api/farmer-todos`
|
||
|
|
|
||
|
|
#### Request Body
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"title": "بازدید پمپ جنوب",
|
||
|
|
"zone": "قطعه گندم - شمال مزرعه",
|
||
|
|
"scheduledDate": "2025-02-24",
|
||
|
|
"time": "07:00",
|
||
|
|
"priority": "متوسط",
|
||
|
|
"note": "بعد از ثبت انجام، اگر موردی غیرعادی بود برای شیفت بعدی یادداشت بگذار.",
|
||
|
|
"tags": ["روزانه", "ثبت دستی"],
|
||
|
|
"status": "open"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Minimum Required Fields
|
||
|
|
|
||
|
|
- `title`
|
||
|
|
- `zone`
|
||
|
|
- `scheduledDate`
|
||
|
|
- `time`
|
||
|
|
- `priority`
|
||
|
|
|
||
|
|
#### Success Response
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"task": {
|
||
|
|
"id": 102,
|
||
|
|
"title": "بازدید پمپ جنوب",
|
||
|
|
"zone": "قطعه گندم - شمال مزرعه",
|
||
|
|
"scheduledDate": "2025-02-24",
|
||
|
|
"time": "07:00",
|
||
|
|
"priority": "متوسط",
|
||
|
|
"note": "بعد از ثبت انجام، اگر موردی غیرعادی بود برای شیفت بعدی یادداشت بگذار.",
|
||
|
|
"tags": ["روزانه", "ثبت دستی"],
|
||
|
|
"status": "open"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3) Update Task
|
||
|
|
|
||
|
|
`PUT /api/farmer-todos/:id`
|
||
|
|
|
||
|
|
#### Use Cases
|
||
|
|
|
||
|
|
- تغییر وضعیت `open/done`
|
||
|
|
- ویرایش عنوان
|
||
|
|
- ویرایش زمان و روز
|
||
|
|
- ویرایش اولویت
|
||
|
|
- ویرایش محل اجرا
|
||
|
|
- ویرایش note و tags
|
||
|
|
|
||
|
|
#### Request Body Example
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "done"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
یا:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"title": "نمونه برداری خاک",
|
||
|
|
"zone": "گلخانه شماره 2",
|
||
|
|
"scheduledDate": "2025-02-24",
|
||
|
|
"time": "09:15",
|
||
|
|
"priority": "زیاد",
|
||
|
|
"note": "سه نقطه برداشت شود.",
|
||
|
|
"tags": ["خاک", "آزمایش"],
|
||
|
|
"status": "open"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Success Response
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"task": {
|
||
|
|
"id": 102,
|
||
|
|
"title": "نمونه برداری خاک",
|
||
|
|
"zone": "گلخانه شماره 2",
|
||
|
|
"scheduledDate": "2025-02-24",
|
||
|
|
"time": "09:15",
|
||
|
|
"priority": "زیاد",
|
||
|
|
"note": "سه نقطه برداشت شود.",
|
||
|
|
"tags": ["خاک", "آزمایش"],
|
||
|
|
"status": "open"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4) Delete Task
|
||
|
|
|
||
|
|
اگرچه UI فعلی دکمه حذف ندارد، برای کامل شدن flow بهتر است endpoint حذف موجود باشد.
|
||
|
|
|
||
|
|
`DELETE /api/farmer-todos/:id`
|
||
|
|
|
||
|
|
#### Success Response
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"success": true
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Separate Zones API
|
||
|
|
|
||
|
|
در UI فعلی `zone`ها hardcoded هستند. برای اتصال واقعی بهتر است از بکاند دریافت شوند.
|
||
|
|
|
||
|
|
### 5) List Task Zones
|
||
|
|
|
||
|
|
`GET /api/farmer-todos/zones`
|
||
|
|
|
||
|
|
#### Success Response
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"zones": [
|
||
|
|
{
|
||
|
|
"id": "zone_north_wheat",
|
||
|
|
"label": "قطعه گندم - شمال مزرعه",
|
||
|
|
"value": "قطعه گندم - شمال مزرعه"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "greenhouse_2",
|
||
|
|
"label": "گلخانه شماره 2",
|
||
|
|
"value": "گلخانه شماره 2"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "central_warehouse",
|
||
|
|
"label": "انبار مرکزی",
|
||
|
|
"value": "انبار مرکزی"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Minimum Accepted Alternative
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"zones": [
|
||
|
|
"قطعه گندم - شمال مزرعه",
|
||
|
|
"گلخانه شماره 2",
|
||
|
|
"انبار مرکزی"
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Separate Tags API
|
||
|
|
|
||
|
|
این صفحه `tags` را نمایش میدهد و برای create/edit هم میتواند به لیست آماده نیاز داشته باشد، بنابراین بهتر است API جداگانه داشته باشد.
|
||
|
|
|
||
|
|
### 6) List Todo Tags
|
||
|
|
|
||
|
|
`GET /api/farmer-todos/tags`
|
||
|
|
|
||
|
|
#### Success Response
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"tags": [
|
||
|
|
{
|
||
|
|
"id": "tag_irrigation",
|
||
|
|
"label": "آبیاری",
|
||
|
|
"value": "آبیاری"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "tag_daily",
|
||
|
|
"label": "روزانه",
|
||
|
|
"value": "روزانه"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Optional Summary API
|
||
|
|
|
||
|
|
الان فرانت آمارهای زیر را از خود لیست taskها محاسبه میکند:
|
||
|
|
|
||
|
|
- تعداد کارهای امروز
|
||
|
|
- تعداد انجام شده
|
||
|
|
- تعداد فوری
|
||
|
|
- درصد پیشرفت
|
||
|
|
- اولین تسک بعدی
|
||
|
|
|
||
|
|
اگر بخواهید لود صفحه سبکتر شود، این API اختیاری مفید است:
|
||
|
|
|
||
|
|
### 7) Farmer Todos Summary
|
||
|
|
|
||
|
|
`GET /api/farmer-todos/summary`
|
||
|
|
|
||
|
|
#### Success Response
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"todayTasksCount": 3,
|
||
|
|
"completedCount": 1,
|
||
|
|
"urgentCount": 2,
|
||
|
|
"progressValue": 25,
|
||
|
|
"nextTask": {
|
||
|
|
"id": 101,
|
||
|
|
"title": "بررسی رطوبت ردیف شمالی",
|
||
|
|
"zone": "قطعه گندم - شمال مزرعه",
|
||
|
|
"scheduledDate": "2025-02-24",
|
||
|
|
"time": "06:30",
|
||
|
|
"priority": "زیاد",
|
||
|
|
"note": "اگر رطوبت کمتر از 28٪ بود، آبیاری دوباره بررسی شود.",
|
||
|
|
"tags": ["آبیاری", "صبح زود"],
|
||
|
|
"status": "open"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
این endpoint ضروری نیست، چون صفحه فعلی میتواند summary را از `GET /api/farmer-todos` بسازد.
|
||
|
|
|
||
|
|
## Validation Rules Recommended
|
||
|
|
|
||
|
|
- `title` نباید خالی باشد
|
||
|
|
- `zone` نباید خالی باشد
|
||
|
|
- `scheduledDate` باید تاریخ معتبر باشد
|
||
|
|
- `time` باید فرمت معتبر `HH:mm` داشته باشد
|
||
|
|
- `priority` باید یکی از `زیاد / متوسط / کم` یا enum معادل آن باشد
|
||
|
|
- `status` باید یکی از `open / done` باشد
|
||
|
|
- `tags` اگر ارسال میشود باید آرایهای از string باشد
|
||
|
|
|
||
|
|
## Error Handling
|
||
|
|
|
||
|
|
ساختار پیشنهادی خطا:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"code": "TASK_VALIDATION_ERROR",
|
||
|
|
"message": "Invalid farmer todo payload",
|
||
|
|
"details": {
|
||
|
|
"scheduledDate": "scheduledDate is required"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
فرانت حداقل به یک `message` قابلنمایش نیاز دارد.
|
||
|
|
|
||
|
|
## Mapping Notes If Reusing Existing Todo Service
|
||
|
|
|
||
|
|
اگر بخواهید از `todoService` فعلی استفاده کنید، این mapping لازم میشود:
|
||
|
|
|
||
|
|
| UI Field | Current `todoService` Field |
|
||
|
|
|---|---|
|
||
|
|
| `title` | `title` |
|
||
|
|
| `note` | `description` |
|
||
|
|
| `scheduledDate` | `startDate` یا `dueDate` |
|
||
|
|
| `time` | بهتر است field جداگانه داشته باشد؛ در `todoService` فعلی مستقیم وجود ندارد |
|
||
|
|
| `priority` | نیاز به mapping بین `high/medium/low` و `زیاد/متوسط/کم` |
|
||
|
|
| `status` | نیاز به mapping بین `pending/completed` و `open/done` |
|
||
|
|
| `tags` | `tags` |
|
||
|
|
| `zone` | field جداگانه لازم دارد؛ در `todoService` فعلی مستقیم وجود ندارد |
|
||
|
|
|
||
|
|
### Important Note
|
||
|
|
|
||
|
|
برای `farmer-todos` بهتر است endpoint/domain جداگانه داشته باشید، چون این صفحه به شکل صریح به `zone`, `scheduledDate`, `time` و اولویت محلی نیاز دارد و `todoService` عمومی فعلی دقیقاً این مدل را پوشش نمیدهد.
|
||
|
|
|
||
|
|
## Final Backend Checklist
|
||
|
|
|
||
|
|
- `GET /api/farmer-todos`
|
||
|
|
- `POST /api/farmer-todos`
|
||
|
|
- `PUT /api/farmer-todos/:id`
|
||
|
|
- `DELETE /api/farmer-todos/:id`
|
||
|
|
- `GET /api/farmer-todos/zones`
|
||
|
|
- `GET /api/farmer-todos/tags`
|
||
|
|
- پشتیبانی از `scheduledDate`
|
||
|
|
- پشتیبانی از `time`
|
||
|
|
- پشتیبانی از `zone`
|
||
|
|
- پشتیبانی از `priority`
|
||
|
|
- پشتیبانی از `status`
|
||
|
|
- پشتیبانی از `tags`
|
||
|
|
|
||
|
|
## Suggested Stable Response Shapes
|
||
|
|
|
||
|
|
### Tasks List
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"tasks": [
|
||
|
|
{
|
||
|
|
"id": 101,
|
||
|
|
"title": "بررسی رطوبت ردیف شمالی",
|
||
|
|
"zone": "قطعه گندم - شمال مزرعه",
|
||
|
|
"scheduledDate": "2025-02-24",
|
||
|
|
"time": "06:30",
|
||
|
|
"priority": "زیاد",
|
||
|
|
"note": "اگر رطوبت کمتر از 28٪ بود، آبیاری دوباره بررسی شود.",
|
||
|
|
"tags": ["آبیاری", "صبح زود"],
|
||
|
|
"status": "open"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"meta": {
|
||
|
|
"total": 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Zones List
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"zones": [
|
||
|
|
{
|
||
|
|
"id": "zone_north_wheat",
|
||
|
|
"label": "قطعه گندم - شمال مزرعه",
|
||
|
|
"value": "قطعه گندم - شمال مزرعه"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Tags List
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"tags": [
|
||
|
|
{
|
||
|
|
"id": "tag_daily",
|
||
|
|
"label": "روزانه",
|
||
|
|
"value": "روزانه"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|