Files
site_backend/API_DOCS_FA.md
Shayan Azadi 7e71d922d3 Add multi-image compositions, docker setup, tests, and docs
- Add CompositionImage model with multi-image upload and main image flag
- Add composition endpoints: add-images, set-main-image, delete image, by-created-at filter
- Make contact-us by_category public
- Add 24 API tests covering all endpoints
- Add Dockerfile, docker-compose, entrypoint and docker docs
- Add Persian API docs and update README and Postman collection

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-24 13:43:34 +03:30

520 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div dir="rtl" lang="fa">
# مستندات API (Zoneco ORG)
این سند نحوهٔ کارکرد APIهای بک‌اند پروژه Zoneco ORG را به زبان فارسی توضیح می‌دهد.
---
## وضعیت تست‌ها
```
Ran 24 tests — OK (0 failures)
```
| تعداد تست | گروه |
|-----------|------|
| ۶ تست | Contact Us |
| ۱۱ تست | Compositions |
| ۷ تست | Campaigns |
اجرای تست‌ها:
```bash
cd backend
python manage.py test api -v 2
```
---
## اطلاعات پایه
| مقدار | مورد |
|--------|------|
| `{{base_url}}` | آدرس پایه |
| `/api/` | پیشوند API |
| JSON | فرمت پاسخ |
| ۲۰ آیتم در هر صفحه | صفحه‌بندی |
| `/admin/` | پنل ادمین |
### متغیر Postman
در فایل Postman از متغیر `{{base_url}}` استفاده شده است.
مقدار آن را مطابق محیط اجرا (لوکال، سرور تست یا پروداکشن) تنظیم کنید.
**نمونهٔ آدرس کامل یک endpoint:**
```
{{base_url}}/api/contact-us/
```
---
## سطح دسترسی
| دسترسی | عملیات |
|--------|--------|
| عمومی — بدون نیاز به ورود | لیست و جزئیات (متد `GET`) |
| عمومی — بدون نیاز به ورود | ایجاد (متد `POST`) |
| فقط ادمین — نیاز به احراز هویت | ویرایش و حذف (متدهای `PUT`، `PATCH`، `DELETE`) |
برای درخواست‌های ادمین در Postman می‌توانید از **Basic Auth** با نام کاربری و رمز ادمین استفاده کنید.
---
## ۱. تماس با ما (Contact Us)
**مسیر پایه:**
```
/api/contact-us/
```
### فیلدها
| توضیح | الزامی | نوع | فیلد |
|-------|--------|-----|------|
| نام و نام خانوادگی | بله | string | `name` |
| ایمیل یا شماره تماس | بله | string | `email_or_phone` |
| متن پیام | بله | string | `description` |
| دسته‌بندی | بله | string | `category` |
**مقادیر مجاز برای `category`:**
- همکاری
- فروش
- پشتیبانی
- درخواست مشاور
- سایر
---
### دریافت لیست تماس‌ها
```
GET {{base_url}}/api/contact-us/
```
**پاسخ نمونه:**
```json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": "احمد محمدی",
"email_or_phone": "ahmad@example.com",
"description": "سلام، سوالی دارم.",
"category": "پشتیبانی",
"created_at": "2025-12-17T12:00:00Z",
"updated_at": "2025-12-17T12:00:00Z"
}
]
}
```
---
### دریافت یک تماس
```
GET {{base_url}}/api/contact-us/{id}/
```
---
### ثبت تماس جدید
```
POST {{base_url}}/api/contact-us/
Content-Type: application/json
```
**بدنه درخواست:**
```json
{
"name": "احمد محمدی",
"email_or_phone": "09121234567",
"description": "می‌خواهم در مورد محصولات اطلاعات بگیرم.",
"category": "فروش"
}
```
**کد پاسخ:** `201 Created`
---
### فیلتر بر اساس دسته‌بندی
```
GET {{base_url}}/api/contact-us/by_category/?category=پشتیبانی
```
| توضیح | الزامی | پارامتر |
|-------|--------|---------|
| یکی از دسته‌های مجاز | بله | `category` |
اگر پارامتر `category` ارسال نشود، خطای `400` برمی‌گردد.
---
### ویرایش و حذف (ادمین)
```
PUT {{base_url}}/api/contact-us/{id}/
PATCH {{base_url}}/api/contact-us/{id}/
DELETE {{base_url}}/api/contact-us/{id}/
```
نیاز به احراز هویت ادمین دارد.
---
## ۲. ترکیبات (Compositions)
**مسیر پایه:**
```
/api/compositions/
```
هر ترکیب می‌تواند **چند تصویر** داشته باشد.
یکی از تصاویر با فیلد `is_main: true` به‌عنوان **تصویر اصلی** مشخص می‌شود.
### فیلدها
| توضیح | الزامی | نوع | فیلد |
|-------|--------|-----|------|
| نام ترکیب | بله | string | `name` |
| توضیحات | بله | string | `description` |
| یک یا چند فایل تصویر (فقط در ایجاد/ویرایش) | خیر | file[] | `uploaded_images` |
| ایندکس تصویر اصلی (شمارش از ۰) | خیر | integer | `main_image_index` |
### محدودیت تصاویر
- فرمت‌های مجاز: JPEG، PNG، WebP، GIF
- حداکثر حجم هر فایل: **۵ مگابایت**
- مسیر ذخیره: `media/compositions/`
---
### دریافت لیست ترکیبات
```
GET {{base_url}}/api/compositions/
```
---
### دریافت یک ترکیب
```
GET {{base_url}}/api/compositions/{id}/
```
**پاسخ نمونه:**
```json
{
"id": 1,
"name": "ترکیب A",
"description": "توضیحات ترکیب",
"image": null,
"image_url": null,
"images": [
{
"id": 2,
"image": "/media/compositions/img2.jpg",
"image_url": "{{base_url}}/media/compositions/img2.jpg",
"is_main": true,
"created_at": "2025-12-17T12:00:00Z"
},
{
"id": 1,
"image": "/media/compositions/img1.jpg",
"image_url": "{{base_url}}/media/compositions/img1.jpg",
"is_main": false,
"created_at": "2025-12-17T11:00:00Z"
}
],
"main_image": {
"id": 2,
"image_url": "{{base_url}}/media/compositions/img2.jpg",
"is_main": true,
"created_at": "2025-12-17T12:00:00Z"
},
"created_at": "2025-12-17T10:00:00Z",
"updated_at": "2025-12-17T12:00:00Z"
}
```
---
### فیلتر بر اساس تاریخ ایجاد
```
GET {{base_url}}/api/compositions/by-created-at/?from=2026-06-01T00:00:00Z&to=2026-06-30T23:59:59Z
```
| توضیح | الزامی | پارامتر |
|-------|--------|---------|
| برگشت ترکیب‌هایی که `created_at >= from` | حداقل یکی | `from` |
| برگشت ترکیب‌هایی که `created_at <= to` | حداقل یکی | `to` |
فرمت تاریخ: ISO 8601 — مثال: `2026-06-01T00:00:00Z`
اگر هیچ پارامتری ارسال نشود، خطای `400` برمی‌گردد.
---
### ایجاد ترکیب (بدون تصویر)
```
POST {{base_url}}/api/compositions/
Content-Type: application/json
```
```json
{
"name": "ترکیب تست",
"description": "توضیحات ترکیب"
}
```
---
### ایجاد ترکیب با چند تصویر
```
POST {{base_url}}/api/compositions/
Content-Type: multipart/form-data
```
| مقدار نمونه | نوع | فیلد |
|-------------|-----|------|
| ترکیب A | text | `name` |
| توضیحات | text | `description` |
| image1.jpg | file | `uploaded_images` |
| image2.jpg | file | `uploaded_images` |
| 1 | text | `main_image_index` |
**نکته:** فیلد `uploaded_images` را برای هر تصویر یک‌بار تکرار کنید.
**نکته:** اگر `main_image_index` ارسال نشود، **اولین تصویر** به‌عنوان تصویر اصلی انتخاب می‌شود.
---
### افزودن تصویر به ترکیب موجود (ادمین)
```
POST {{base_url}}/api/compositions/{id}/add-images/
Content-Type: multipart/form-data
```
| نوع | فیلد |
|-----|------|
| file (یک یا چند فایل) | `uploaded_images` |
| text (اختیاری) | `main_image_index` |
---
### تنظیم تصویر اصلی (ادمین)
```
POST {{base_url}}/api/compositions/{id}/set-main-image/
Content-Type: application/json
```
```json
{
"image_id": 3
}
```
---
### حذف یک تصویر (ادمین)
```
DELETE {{base_url}}/api/compositions/{id}/images/{image_id}/
```
**کد پاسخ:** `204 No Content`
---
### ویرایش و حذف ترکیب (ادمین)
```
PUT {{base_url}}/api/compositions/{id}/
PATCH {{base_url}}/api/compositions/{id}/
DELETE {{base_url}}/api/compositions/{id}/
```
---
## ۳. کمپین‌ها (Campaigns)
**مسیر پایه:**
```
/api/campaigns/
```
### فیلدها
| توضیح | الزامی | نوع | فیلد |
|-------|--------|-----|------|
| نام کمپین | بله | string | `name` |
| توضیحات | بله | string | `description` |
| زمان شروع (ISO 8601) | بله | datetime | `start_time` |
| زمان پایان (باید بعد از `start_time` باشد) | بله | datetime | `end_time` |
| تصویر کمپین | خیر | file | `image` |
### فیلدهای محاسباتی (فقط خواندنی)
| توضیح | فیلد |
|-------|------|
| آیا کمپین الان فعال است | `is_active` |
| آیا کمپین هنوز شروع نشده | `is_upcoming` |
| آیا کمپین تمام شده | `is_ended` |
---
### دریافت لیست کمپین‌ها
```
GET {{base_url}}/api/campaigns/
```
---
### دریافت یک کمپین
```
GET {{base_url}}/api/campaigns/{id}/
```
---
### ایجاد کمپین
```
POST {{base_url}}/api/campaigns/
Content-Type: application/json
```
```json
{
"name": "کمپین نوروز",
"description": "تخفیف ویژه نوروز",
"start_time": "2026-03-01T00:00:00Z",
"end_time": "2026-03-31T23:59:59Z"
}
```
---
### کمپین‌های فعال
```
GET {{base_url}}/api/campaigns/active/
```
کمپین‌هایی که زمان فعلی بین `start_time` و `end_time` قرار دارد.
---
### کمپین‌های آینده
```
GET {{base_url}}/api/campaigns/upcoming/
```
کمپین‌هایی که هنوز شروع نشده‌اند.
---
### کمپین‌های پایان‌یافته
```
GET {{base_url}}/api/campaigns/ended/
```
---
### ویرایش و حذف (ادمین)
```
PUT {{base_url}}/api/campaigns/{id}/
PATCH {{base_url}}/api/campaigns/{id}/
DELETE {{base_url}}/api/campaigns/{id}/
```
---
## کدهای وضعیت HTTP
| معنی | کد |
|------|-----|
| موفق | `200` |
| ایجاد شد | `201` |
| حذف شد (بدون بدنه) | `204` |
| داده نامعتبر | `400` |
| دسترسی ندارید | `403` |
| یافت نشد | `404` |
---
## فایل Postman
مجموعه Postman در مسیر زیر قرار دارد:
```
backend/Zoneco_ORG_API.postman_collection.json
```
### نحوه import
1. Postman را باز کنید
2. گزینه **Import** را بزنید
3. فایل `Zoneco_ORG_API.postman_collection.json` را انتخاب کنید
4. متغیر `{{base_url}}` را مطابق محیط خود تنظیم کنید
5. برای درخواست‌های ادمین، در تب **Authorization** گزینه **Basic Auth** را فعال کنید
---
## خلاصه endpointها
| دسترسی | Endpoint | Method | # |
|--------|----------|--------|---|
| عمومی | `/api/contact-us/` | GET | 1 |
| عمومی | `/api/contact-us/` | POST | 2 |
| عمومی | `/api/contact-us/{id}/` | GET | 3 |
| عمومی | `/api/contact-us/by_category/?category=...` | GET | 4 |
| ادمین | `/api/contact-us/{id}/` | PUT/PATCH/DELETE | 5 |
| عمومی | `/api/compositions/` | GET | 6 |
| عمومی | `/api/compositions/` | POST | 7 |
| عمومی | `/api/compositions/{id}/` | GET | 8 |
| عمومی | `/api/compositions/by-created-at/?from=...&to=...` | GET | 9 |
| ادمین | `/api/compositions/{id}/add-images/` | POST | 10 |
| ادمین | `/api/compositions/{id}/set-main-image/` | POST | 11 |
| ادمین | `/api/compositions/{id}/images/{image_id}/` | DELETE | 12 |
| ادمین | `/api/compositions/{id}/` | PUT/PATCH/DELETE | 13 |
| عمومی | `/api/campaigns/` | GET | 14 |
| عمومی | `/api/campaigns/` | POST | 15 |
| عمومی | `/api/campaigns/{id}/` | GET | 16 |
| عمومی | `/api/campaigns/active/` | GET | 17 |
| عمومی | `/api/campaigns/upcoming/` | GET | 18 |
| عمومی | `/api/campaigns/ended/` | GET | 19 |
| ادمین | `/api/campaigns/{id}/` | PUT/PATCH/DELETE | 20 |
> **توجه:** در Postman قبل از هر مسیر، مقدار `{{base_url}}` را قرار دهید.
> مثال: `{{base_url}}/api/campaigns/active/`
</div>