Files
aramesh-backend/backend
MMD d25db9367c پیش‌نمایش خصوصی: سایت آنلاین اما غیرعمومی تا زمان انتشار
- گیت ورود Traefik (Basic Auth) روی همه مسیرها: سایت، API، تصاویر و چت — بدون رمز فقط ۴۰۱
- لایه دوم noindex: هدر X-Robots-Tag روی همه پاسخ‌ها + robots.txt مسدودکننده + نقشه سایت خالی
- اسکریپت scripts/preview-mode.sh on|off|status — ساخت خودکار نام کاربری/رمز و هماهنگ‌کردن .env
- دو دامنه (DOMAIN + DOMAIN_ALIAS) با گواهی TLS و ریدایرکت ۳۰۱ دامنه دوم به اصلی در زمان انتشار
- اسکیمای FAQPage در پوسته سئوی سمت سرور (فارسی و انگلیسی) برای خزنده‌های بدون جاوااسکریپت
- مستندسازی جریان پیش‌نمایش و چک‌لیست انتشار در README و .env.example
2026-09-26 22:47:04 +03:30
..

بک‌اند گروه ساختمانی آرامش (Aramesh Building Group API)

بک‌اند سایت گروه ساختمانی آرامش — ساخته‌شده با FastAPI + PostgreSQL + SQLAlchemy 2 + JWT + MinIO (ذخیره تصاویر) + Traefik (مسیریابی).

امکانات

  • API عمومی محتوا: برند، منو، هیرو، داستان، تیتر بخش‌ها، هیرو صفحات، خدمات، پروژه‌ها، مقالات، نظرات مشتریان، سوالات متداول، تیم، تایم‌لاین، آمار، چرا آرامش، قبل/بعد، مدل‌های سرمایه‌گذاری، مراحل کار، دفاتر، گالری، فرم تماس، خبرنامه و فوتر — تمام متن‌های سایت در دیتابیس است
  • فرم تماس: ثبت پیام مشتریان از سایت (POST /api/contact)
  • خبرنامه: عضویت و مدیریت مشترکین (POST /api/newsletter)
  • پنل مدیریت: ورود با نام کاربری/رمز عبور و دریافت توکن JWT، سپس CRUD کامل همه محتواها، مدیریت پیام‌های تماس و مشترکین
  • آپلود تصویر: POST /api/admin/upload — فایل در MinIO ذخیره و URL نسبی /media/... برمی‌گردد
  • Seed خودکار: همه محتوای فعلی سایت با یک دستور در دیتابیس قرار می‌گیرد (فقط جدول‌های خالی پر می‌شوند — ارتقا بدون از دست رفتن داده)
  • مستندات تعاملی Swagger در مسیر /docs

راه‌اندازی

۱. پیش‌نیازها

  • Python 3.11 یا جدیدتر
  • PostgreSQL در حال اجرا (پورت پیش‌فرض 5432)

۲. نصب وابستگی‌ها

cd arameshplaza-backend
python -m venv .venv

# ویندوز
.venv\Scripts\activate
# لینوکس / مک
source .venv/bin/activate

pip install -r requirements.txt

۳. تنظیمات

فایل .env.example را به نام .env کپی کنید و مقادیر را تنظیم کنید:

cp .env.example .env        # لینوکس / مک
copy .env.example .env      # ویندوز

مهم‌ترین تنظیم DATABASE_URL است:

DATABASE_URL=postgresql+psycopg://postgres:YOUR_PASSWORD@localhost:5432/arameshplaza_api

۴. ساخت دیتابیس و Seed

# ساخت دیتابیس (یک‌بار):
psql -U postgres -c "CREATE DATABASE arameshplaza_api;"

# ساخت جداول + وارد کردن محتوای سایت + ساخت ادمین پیش‌فرض:
python -m app.seed

# بازنشانی کامل داده‌ها در صورت نیاز:
python -m app.seed --force

۵. اجرا

uvicorn app.main:app --reload

سپس:

ورود به پنل مدیریت

POST /api/auth/login
{ "username": "admin", "password": "aramesh123" }

پاسخ شامل access_token است. توکن را در هدر همه درخواست‌های مدیریتی قرار دهید:

Authorization: Bearer <access_token>

نام کاربری و رمز عبور پیش‌فرض از تنظیمات .env خوانده می‌شود — حتماً در محیط تولید تغییرشان دهید.

تغییر رمز (با توکن):

POST /api/auth/change-password
{ "current_password": "...", "new_password": "..." }

فهرست انتهاپوینت‌ها

عمومی (بدون نیاز به توکن)

متد مسیر توضیح
GET /api/health وضعیت سرور
GET /api/brand اطلاعات برند و تماس
GET /api/services خدمات
GET /api/projects همه پروژه‌ها
GET /api/projects/{slug} جزئیات یک پروژه
GET /api/articles مقاله‌های منتشرشده (پیش‌نویس نمی‌آید)
GET /api/articles/{slug} جزئیات یک مقاله منتشرشده
GET /api/testimonials نظرات مشتریان
GET /api/faqs سوالات متداول
GET /api/team اعضای تیم
GET /api/timeline تایم‌لاین شرکت
GET /api/stats آمار
GET /api/why-us چرا گروه ساختمانی آرامش
GET /api/before-after بخش قبل/بعد
GET /api/site همه محتوا در یک درخواست
POST /api/contact ثبت پیام تماس
POST /api/newsletter عضویت در خبرنامه
POST /api/auth/login ورود ادمین و دریافت توکن — بعد از ۵ تلاش ناموفق در ۱۵ دقیقه، 429
GET /robots.txt قوانین خزنده‌ها
GET /sitemap.xml نقشه سایت — مقاله/پروژه‌های منتشرشده
GET /blog/{slug} HTML صفحه مقاله با متای سئوی تزریق‌شده
GET /projects/{slug} HTML صفحه پروژه با متای سئوی تزریق‌شده

مدیریت (نیاز به توکن Bearer)

برای هر یک از این مسیرها، CRUD کامل در دسترس است: brand، services، projects، articles، testimonials، faqs، team، timeline، stats، why-us، before-after

متد مسیر توضیح
GET/POST /api/admin/{resource} لیست / ساخت
GET/PUT/DELETE /api/admin/{resource}/{id} دریافت / ویرایش کامل / حذف
PATCH /api/admin/{resource}/{id} ویرایش جزئی — فقط فیلدهای ارسال‌شده به‌روزرسانی می‌شوند
POST /api/admin/{resource}/reorder ذخیره ترتیب: {"ids": [3, 1, 2, ...]}
GET /api/admin/messages پیام‌های تماس (با ?unread_only=true فقط خوانده‌نشده‌ها)
PATCH /api/admin/messages/{id} تغییر وضعیت خوانده‌شدن
DELETE /api/admin/messages/{id} حذف پیام
GET /api/admin/subscribers مشترکین خبرنامه
DELETE /api/admin/subscribers/{id} حذف مشترک
POST /api/admin/upload آپلود تصویر (multipart، حداکثر ۱۰MB — jpg/png/webp/gif/avif) → {"url": "/media/..."}

بدنه مقاله — سند TipTap

body مقاله یک سند ساختاریافته TipTap (ProseMirror JSON) است: {"type": "doc", "content": [...]}.

  • فقط ساختار اعتبارسنجی می‌شود (type: "doc" + content لیست)؛ امنیت رندر بر عهده رندر استاتیک TipTap در فرانت‌اند است که فقط تگ‌های شناخته‌شده تولید می‌کند
  • ردیف‌های قدیمی (لیست پاراگراف) با مهاجرت idempotent migrate_article_bodies در startup/seed خودکار به سند تبدیل می‌شوند
  • seed هم بدنه‌های لیستی را قبل از درج تبدیل می‌کند

| POST/PATCH | /api/admin/seo-meta | عنوان و توضیح متای صفحات — page_key: home / about / services / projects / investment / blog / faq / contact |

منابعی که reorder دارند (ستون position): services، projects، articles، testimonials، faqs، team، timeline، stats، why-us، investment-models، process-steps، offices، gallery، nav. ستون با مهاجرت سبک idempotent هنگام startup/seed به دیتابیس‌های موجود اضافه می‌شود.

تصاویر و MinIO

فایل‌های آپلودشده در باکت aramesh-media روی MinIO ذخیره می‌شوند و با مسیر نسبی /media/<سال>/<ماه>/<فایل> برگردانده می‌شوند. Traefik مسیر /media را به MinIO می‌برد، پس URLها مستقل از بک‌اند ذخیره‌سازی هستند — بعداً برای مهاجرت به R2/S3 فقط تنظیمات را عوض کنید، نه محتوای دیتابیس را.

  • کنسول MinIO: http://localhost:9001 (کاربر/رمز از MINIO_ROOT_USER / MINIO_ROOT_PASSWORD در compose)
  • تصاویر عمومی و قابل نمایش‌اند؛ آپلود فقط با توکن ادمین انجام می‌شود.

اتصال به فرانت‌اند

در پروژه React (پوشه ArameshPlaza)، فایل src/config.ts آدرس بک‌اند را نگه می‌دارد:

export const API_URL = import.meta.env.VITE_API_URL ?? 'http://localhost:8000'

در محیط تولید مقدار VITE_API_URL را روی آدرس عمومی API تنظیم کنید و مطمئن شوید آدرس سایت در CORS_ORIGINS فایل .env بک‌اند قرار دارد.

ساختار پروژه

app/
├── main.py        # نقطه ورود FastAPI، CORS، ثبت روترها
├── config.py      # تنظیمات از .env
├── database.py    # اتصال PostgreSQL و نشست‌ها
├── models.py      # مدل‌های SQLAlchemy
├── schemas.py     # اسکیماهای Pydantic (ورودی/خروجی)
├── auth.py        # هش رمز عبور و JWT
├── seed.py        # اسکریپت seed
├── seed_data.py   # داده‌های اولیه سایت
└── api/
    ├── public.py  # انتهای عمومی محتوا
    ├── forms.py   # فرم تماس و خبرنامه
    └── admin.py   # ورود و پنل مدیریت