شامل کارهای چند نشست موازی که تا اینجا فقط روی سرور بود: - نقشهٔ دفتر مرکزی در فوتر (LazyOfficeMap) + MapViewport/LazyMaps/mapProjects - صفحهٔ مدیریت مقالات (AdminArticlesPage) + میانبر ویرایش پیشنویس در وبلاگ - مهاجرت ۰۰۰۴: updated_at مقالات/پروژهها - chatbot/Dockerfile: نصب دومرحلهای torch (کاربردی برای PyPI فیلترشده) - seed: خالیکردن آمارهای دموی story - docker-compose: اصلاح پسوند @file میانافزارهای Traefik - حذف فایل موقت frontend/.tmp-style.json و اصلاحات جزئی UI با این کامیت، آنچه روی سرور اجرا میشود Exactly همان چیزی است که در مخزن ثبت شده.
بکاند گروه ساختمانی آرامش (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
سپس:
- مستندات API: http://localhost:8000/docs
- بررسی سلامت: http://localhost:8000/api/health
ورود به پنل مدیریت
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 # ورود و پنل مدیریت