Files
Backend/NOTIFICATIONS_FRONTEND_API.md
T

215 lines
6.6 KiB
Markdown
Raw Normal View History

2026-04-05 05:10:17 +03:30
# راهنمای استفاده فرانت از APIهای Notifications
این فایل برای تیم فرانت نوشته شده تا بدون بررسی کد بک‌اند، بتواند APIهای ماژول `notifications` را مصرف کند.
---
## خلاصه خیلی کوتاه
- تمام APIهای فعلی نوتیفیکیشن بر اساس `farm_uuid` کار می‌کنند.
- برای گرفتن نوتیفیکیشن‌ها باید `GET /api/notifications/long-poll/` را صدا بزنید.
- در هر آیتم نوتیفیکیشن، فیلد `since_id` برگردانده می‌شود.
- برای علامت‌زدن نوتیفیکیشن‌ها به‌عنوان خوانده‌شده باید `POST /api/notifications/mark-as-read/` را با `farm_uuid` و `slice_id` صدا بزنید.
- هر نوتیفیکیشن دارای وضعیت `is_read` است:
- `false` یعنی خوانده نشده
- `true` یعنی خوانده شده
---
## Base Path
```text
/api/notifications/
```
---
## احراز هویت
هر دو API فعلی نیاز به کاربر لاگین‌شده دارند.
یعنی فرانت باید توکن کاربر را مثل بقیه endpointهای protected ارسال کند.
---
## 1) گرفتن نوتیفیکیشن‌ها
### Endpoint
```http
GET /api/notifications/long-poll/?farm_uuid=<farm_uuid>&since_id=<since_id>&timeout=<seconds>
```
### Query Params
| نام | اجباری | توضیح |
|---|---|---|
| `farm_uuid` | بله | شناسه مزرعه انتخاب‌شده |
| `since_id` | خیر | فقط نوتیفیکیشن‌های جدیدتر از این مقدار برگردانده می‌شوند |
| `timeout` | خیر | زمان long-poll بر حسب ثانیه، بین `0` تا `60` |
### رفتار
- اگر `since_id` ارسال نشود، همه نوتیفیکیشن‌های مزرعه برمی‌گردند.
- اگر `since_id` ارسال شود، فقط نوتیفیکیشن‌هایی که `id > since_id` دارند برمی‌گردند.
- اگر نوتیفیکیشن جدیدی وجود نداشته باشد، تا زمان `timeout` منتظر می‌ماند و بعد آرایه خالی برمی‌گرداند.
- این endpoint فقط برای مزرعه‌ای جواب می‌دهد که متعلق به همان کاربر باشد.
### نمونه درخواست
```http
GET /api/notifications/long-poll/?farm_uuid=550e8400-e29b-41d4-a716-446655440000&since_id=12&timeout=15
```
### نمونه response موفق
```json
{
"code": 200,
"msg": "success",
"data": [
{
"uuid": "0d4f68d0-8a49-4d5c-9d1c-1d4fd6d5e3a1",
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
"since_id": 13,
"title": "هشدار آبیاری",
"message": "رطوبت خاک پایین است",
"level": "warning",
"is_read": false,
"metadata": {
"sensor": "soil-1"
},
"created_at": "2025-02-20T10:30:00Z"
}
]
}
```
### معنی فیلدهای مهم
| فیلد | توضیح |
|---|---|
| `since_id` | شناسه ترتیبی نوتیفیکیشن برای polling بعدی |
| `is_read` | وضعیت خوانده‌شدن نوتیفیکیشن |
| `level` | سطح نوتیفیکیشن مثل `info`، `warning`، `critical` |
| `metadata` | اطلاعات تکمیلی برای UI یا رفتارهای خاص |
### نکته مهم برای فرانت
بعد از هر بار دریافت response:
1. اگر `data` خالی نبود، `since_id` آخرین آیتم را نگه دارید.
2. در درخواست بعدی، همان مقدار را به‌عنوان `since_id` بفرستید.
3. برای badge یا شمارنده unread، از `is_read` استفاده کنید.
---
## 2) خوانده‌کردن نوتیفیکیشن‌ها
### Endpoint
```http
POST /api/notifications/mark-as-read/
```
### Body
```json
{
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
"slice_id": 13
}
```
### معنی `slice_id`
`slice_id` یعنی:
- همه نوتیفیکیشن‌های همان مزرعه که `id <= slice_id` دارند
- و هنوز `is_read=false` هستند
- به `is_read=true` تغییر می‌کنند
به بیان ساده، اگر کاربر تا یک نقطه از لیست نوتیفیکیشن‌ها را دیده، فرانت می‌تواند `since_id` آخرین آیتم دیده‌شده را به‌عنوان `slice_id` ارسال کند.
### نمونه response موفق
```json
{
"code": 200,
"msg": "success",
"marked_count": 4
}
```
### معنی `marked_count`
تعداد نوتیفیکیشن‌هایی که واقعا در دیتابیس از unread به read تغییر کرده‌اند.
---
## خطاهای رایج
### مزرعه پیدا نشد
اگر `farm_uuid` متعلق به کاربر نباشد یا وجود نداشته باشد:
```json
{
"code": 404,
"msg": "Farm not found."
}
```
### جدول نوتیفیکیشن آماده نیست
اگر migrationهای بک‌اند اجرا نشده باشند:
```json
{
"code": 503,
"msg": "Notifications table is not ready. Run migrations."
}
```
---
## پیشنهاد Flow برای فرانت
### سناریوی پیشنهادی
1. کاربر یک مزرعه active انتخاب می‌کند.
2. فرانت `farm_uuid` آن مزرعه را در state نگه می‌دارد.
3. اولین بار:
```http
GET /api/notifications/long-poll/?farm_uuid=<farm_uuid>&timeout=0
```
4. آخرین `since_id` را ذخیره می‌کند.
5. بعد از آن polling را با `since_id` ادامه می‌دهد:
```http
GET /api/notifications/long-poll/?farm_uuid=<farm_uuid>&since_id=<last_since_id>&timeout=15
```
6. وقتی کاربر نوتیفیکیشن‌ها را دید، فرانت آخرین آیتم دیده‌شده را با `slice_id` به endpoint خوانده‌شدن می‌فرستد.
---
## پیشنهاد پیاده‌سازی در فرانت
- برای هر `farm_uuid` یک `last_since_id` جدا نگه دارید.
- لیست نوتیفیکیشن‌ها را per-farm در state نگه دارید.
- unread count را از روی آیتم‌هایی که `is_read=false` دارند محاسبه کنید.
- وقتی کاربر صفحه نوتیفیکیشن را باز کرد یا لیست را تا انتها دید، `slice_id` آخرین آیتم دیده‌شده را ارسال کنید.
---
## routeهای فعال فعلی
| Method | Path | توضیح |
|---|---|---|
| GET | `/api/notifications/long-poll/` | دریافت نوتیفیکیشن‌ها با پشتیبانی از `since_id` |
| POST | `/api/notifications/mark-as-read/` | خوانده‌کردن نوتیفیکیشن‌ها تا `slice_id` |