From 97127d5772a327c0a12f212e1b5fe2a1243bcb96 Mon Sep 17 00:00:00 2001 From: Shayan Azadi Date: Thu, 16 Jul 2026 17:32:04 +0330 Subject: [PATCH] Keep a single README and remove extra markdown docs EOF Co-authored-by: Cursor --- API_DOCS_FA.md | 584 ----------------------------------------------- DOCKER_README.md | 221 ------------------ README.md | 10 +- 3 files changed, 2 insertions(+), 813 deletions(-) delete mode 100644 API_DOCS_FA.md delete mode 100644 DOCKER_README.md diff --git a/API_DOCS_FA.md b/API_DOCS_FA.md deleted file mode 100644 index ea43d36..0000000 --- a/API_DOCS_FA.md +++ /dev/null @@ -1,584 +0,0 @@ -
- -# مستندات API (Zoneco ORG) - -این سند نحوهٔ کارکرد APIهای بک‌اند پروژه Zoneco ORG را به زبان فارسی توضیح می‌دهد. - ---- - -## وضعیت تست‌ها - -``` -Ran 31 tests — OK (0 failures) -``` - -| تعداد تست | گروه | -|-----------|------| -| ۷ تست | Admin Login | -| ۶ تست | 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`) | - ---- - -## ۰. ورود ادمین (Admin Login) - -| مقدار | مورد | -|--------|------| -| `{{admin_username}}` از env (`ADMIN_USERNAME`) | نام کاربری | -| `{{admin_password}}` از env (`ADMIN_PASSWORD`) | رمز عبور | -| `{{base_url}}/admin/` | پنل جنگو ادمین | -| `POST {{base_url}}/api/admin/login/` | ورود از طریق API | - -> نام کاربری و رمز در کد هاردکد نمی‌شوند. روی سرور در فایل `.env` تنظیم کنید. - -### ورود و دریافت توکن - -``` -POST {{base_url}}/api/admin/login/ -Content-Type: application/json -``` - -```json -{ - "username": "{{admin_username}}", - "password": "{{admin_password}}" -} -``` - -**پاسخ نمونه:** - -```json -{ - "token": "", - "user": { - "id": 1, - "username": "", - "is_staff": true, - "is_superuser": true - } -} -``` - -در درخواست‌های محافظت‌شده این هدر را بفرستید: - -``` -Authorization: Token -``` - -### اطلاعات ادمین فعلی - -``` -GET {{base_url}}/api/admin/me/ -Authorization: Token -``` - -### خروج (حذف توکن) - -``` -POST {{base_url}}/api/admin/logout/ -Authorization: Token -``` - -برای درخواست‌های ادمین در Postman، ابتدا login کنید، سپس توکن را در متغیر `admin_token` بگذارید. - ---- - -## ۱. تماس با ما (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/admin/login/` | POST | 1 | -| ادمین | `/api/admin/logout/` | POST | 2 | -| ادمین | `/api/admin/me/` | GET | 3 | -| عمومی | `/api/contact-us/` | GET | 4 | -| عمومی | `/api/contact-us/` | POST | 5 | -| عمومی | `/api/contact-us/{id}/` | GET | 6 | -| عمومی | `/api/contact-us/by_category/?category=...` | GET | 7 | -| ادمین | `/api/contact-us/{id}/` | PUT/PATCH/DELETE | 8 | -| عمومی | `/api/compositions/` | GET | 9 | -| عمومی | `/api/compositions/` | POST | 10 | -| عمومی | `/api/compositions/{id}/` | GET | 11 | -| عمومی | `/api/compositions/by-created-at/?from=...&to=...` | GET | 12 | -| ادمین | `/api/compositions/{id}/add-images/` | POST | 13 | -| ادمین | `/api/compositions/{id}/set-main-image/` | POST | 14 | -| ادمین | `/api/compositions/{id}/images/{image_id}/` | DELETE | 15 | -| ادمین | `/api/compositions/{id}/` | PUT/PATCH/DELETE | 16 | -| عمومی | `/api/campaigns/` | GET | 17 | -| عمومی | `/api/campaigns/` | POST | 18 | -| عمومی | `/api/campaigns/{id}/` | GET | 19 | -| عمومی | `/api/campaigns/active/` | GET | 20 | -| عمومی | `/api/campaigns/upcoming/` | GET | 21 | -| عمومی | `/api/campaigns/ended/` | GET | 22 | -| ادمین | `/api/campaigns/{id}/` | PUT/PATCH/DELETE | 23 | - -> **توجه:** در Postman قبل از هر مسیر، مقدار `{{base_url}}` را قرار دهید. -> مثال: `{{base_url}}/api/campaigns/active/` - -
diff --git a/DOCKER_README.md b/DOCKER_README.md deleted file mode 100644 index 589208e..0000000 --- a/DOCKER_README.md +++ /dev/null @@ -1,221 +0,0 @@ -# Docker Setup for Zoneco ORG Backend - -This document provides instructions for running the Zoneco ORG backend using Docker and Docker Compose. - -## Prerequisites - -- Docker Engine 20.10 or higher -- Docker Compose 2.0 or higher - -## Quick Start - -1. **Navigate to the backend directory:** - ```bash - cd backend - ``` - -2. **Create a `.env` file** (copy from the template below): - ```bash - # Copy and modify as needed - SECRET_KEY=your-secret-key-here-change-in-production - DEBUG=False - ALLOWED_HOSTS=localhost,127.0.0.1,YOUR_SERVER_IP - POSTGRES_DB=Zoneco_ORG - POSTGRES_USER=postgres - POSTGRES_PASSWORD=change-me - POSTGRES_HOST=db - POSTGRES_PORT=5432 - DJANGO_PORT=8000 - ADMIN_USERNAME=your-admin-username - ADMIN_PASSWORD=your-admin-password - CORS_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000,http://YOUR_SERVER_IP:9123 - ``` - -3. **Build and start the containers:** - ```bash - docker-compose up --build - ``` - -4. **The application will be available at:** - - API: `http://localhost:8000/api/` - - Admin: `http://localhost:8000/admin/` - -## Docker Commands - -### Start services -```bash -docker-compose up -``` - -### Start services in detached mode -```bash -docker-compose up -d -``` - -### Stop services -```bash -docker-compose down -``` - -### Stop services and remove volumes (⚠️ deletes database data) -```bash -docker-compose down -v -``` - -### View logs -```bash -docker-compose logs -f -``` - -### View logs for specific service -```bash -docker-compose logs -f web -docker-compose logs -f db -``` - -### Rebuild containers -```bash -docker-compose build --no-cache -``` - -### Execute commands in running container -```bash -# Django shell -docker-compose exec web python manage.py shell - -# Create superuser -docker-compose exec web python manage.py createsuperuser - -# Run migrations manually -docker-compose exec web python manage.py migrate - -# Collect static files -docker-compose exec web python manage.py collectstatic --noinput -``` - -## Architecture - -The Docker setup consists of: - -1. **Web Service** (`web`): - - Django application running with Gunicorn - - Multi-stage Dockerfile for optimized image size - - Non-root user for security - - Automatic migrations and static file collection on startup - - Health checks enabled - -2. **Database Service** (`db`): - - PostgreSQL 15 Alpine (lightweight) - - Persistent data volume - - Health checks to ensure readiness - -## Features - -### Security Best Practices -- ✅ Multi-stage build for smaller image size -- ✅ Non-root user execution -- ✅ Environment variable configuration -- ✅ No hardcoded secrets -- ✅ Health checks for both services - -### Production Ready -- ✅ Gunicorn WSGI server -- ✅ Automatic database migrations -- ✅ Static file collection -- ✅ Database connection retry logic -- ✅ Proper logging - -### Development Friendly -- ✅ Volume mounts for media and static files -- ✅ Hot-reload capability (with proper setup) -- ✅ Easy access to Django management commands - -## Environment Variables - -| Variable | Description | Default | -|----------|-------------|---------| -| `SECRET_KEY` | Django secret key | (required in production) | -| `DEBUG` | Enable debug mode | `False` | -| `ALLOWED_HOSTS` | Comma-separated allowed hosts | `localhost,127.0.0.1` | -| `POSTGRES_DB` | Database name | `Zoneco_ORG` | -| `POSTGRES_USER` | Database user | `postgres` | -| `POSTGRES_PASSWORD` | Database password | `postgres` | -| `POSTGRES_HOST` | Database host | `db` | -| `POSTGRES_PORT` | Database port | `5432` | -| `DJANGO_PORT` | Django application port | `8000` | -| `CORS_ALLOWED_ORIGINS` | Comma-separated CORS origins | (see .env.example) | - -## Volumes - -- `postgres_data`: Persistent PostgreSQL data -- `./media`: Media files (images, uploads) -- `./staticfiles`: Collected static files - -## Troubleshooting - -### Database connection errors -```bash -# Check if database is healthy -docker-compose ps - -# Check database logs -docker-compose logs db - -# Restart services -docker-compose restart -``` - -### Permission issues -```bash -# Fix media/staticfiles permissions -sudo chown -R $USER:$USER media staticfiles -``` - -### Port already in use -```bash -# Change port in .env file -DJANGO_PORT=8001 -# Then update docker-compose.yml or restart -``` - -### Clear everything and start fresh -```bash -docker-compose down -v -docker-compose build --no-cache -docker-compose up -``` - -## Production Deployment - -For production deployment: - -1. **Set strong SECRET_KEY:** - ```bash - python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())" - ``` - -2. **Set DEBUG=False** in `.env` - -3. **Configure proper ALLOWED_HOSTS** - -4. **Use strong database passwords** - -5. **Consider using:** - - Reverse proxy (nginx) - - SSL/TLS certificates - - Separate database server - - Backup strategy - - Monitoring and logging - -## File Structure - -``` -backend/ -├── Dockerfile # Multi-stage production Dockerfile -├── docker-compose.yml # Service orchestration -├── .dockerignore # Files to exclude from build -├── entrypoint.sh # Startup script -├── requirements.txt # Python dependencies -└── DOCKER_README.md # This file -``` - diff --git a/README.md b/README.md index a75f8cd..055cb3e 100644 --- a/README.md +++ b/README.md @@ -299,15 +299,9 @@ DB constraint: only one `is_main=True` per composition. ## Postman Collection -Import `backend/Zoneco_ORG_API.postman_collection.json` into Postman. +Import `Zoneco_ORG_API.postman_collection.json` into Postman. -Set the `base_url` collection variable to your server address. - ---- - -## Persian Documentation - -Full Persian API documentation: `backend/API_DOCS_FA.md` +Set collection variables: `base_url`, `admin_username`, `admin_password`. ---