dbc4be305228e936ea65847e98e79129bd14a85f
لایه ویرایش بصری روی سایت واقعی (بدون داشبورد جدا): - ورود ادمین از مسیر پنهان /admin/login با توکن JWT (localStorage) و AdminContext شامل isEditMode و وضعیت ذخیره (همگام/در حال ذخیره/خطا) - AdminBar شناور پایین صفحه (فقط برای کاربر واردشده): کلید حالت ویرایش، وضعیت ذخیره، خروج — حالت ویرایش در sessionStorage میماند - InlineEdit: در حالت عادی دقیقاً همان HTML قبلی (بدون تغییر چیدمان)؛ در حالت ویرایش کادرخطچین + contentEditable با ذخیره خودکار در blur (Enter ذخیره، Esc لغو) — وایرایششده روی همه متنهای سایت: هیرو، تیتر بخشها، هیرو صفحات، داستان، فرم تماس، خبرنامه، فوتر، منو، برچسبهای وضعیت پروژه و... - کشوی عمومی EntityDrawer با پیکربندی متمرکز برای ۱۴ مجموعه (خدمات، پروژهها، مقالات، نظرات، سوالات، تیم، تایملاین، آمار، چرا آرامش، مدلهای سرمایهگذاری، مراحل کار، دفاتر، گالری، منو): ویرایش چندفیلدی، افزودن، حذف و جابهجایی ترتیب (▲▼) با ذخیره خودکار هر فیلد - دکمههای شناور ویرایش/حذف/ترتیب فقط در حالت ویرایش روی آیتمها - کشوهای یگانه: برند و لوگو، تنظیمات هیرو، فرم تماس، خبرنامه، فوتر، قبل/بعد و نقلقول داستان — آپلود تصویر به MinIO از همانجا - بهروزرسانی خوشبینانه SiteContext (updateSite) پس از هر PATCH؛ مسیرها در حالت ویرایش کلیک نمیشوند؛ breadcrumb محافظ beforeunload
گروه ساختمانی آرامش — پروژه کامل (فرانتاند + بکاند)
مونوریپوی سایت گروه ساختمانی آرامش شامل:
frontend/— سایت React + Vite + Tailwind (تمام متنها و تصاویر از API خوانده میشود)backend/— بکاند FastAPI + SQLAlchemy 2 + PostgreSQL + JWT + MinIO
معماری
Traefik (پورت ۵۱۷۳ — تنها نقطه ورود)
├── / → Caddy (فایلهای استاتیک SPA)
├── /api → FastAPI (بکاند)
└── /media → MinIO (باکت aramesh-media — تصاویر آپلودی)
- همه محتوای متنی سایت در PostgreSQL است — هیچ متنی در کد فرانتاند هاردکد نشده؛
با یک درخواست
GET /api/siteبارگذاری و از پنل مدیریت ویرایش میشود - تصاویر آپلودی در MinIO (Object Storage سازگار با S3) ذخیره میشوند و با مسیر نسبی
/media/...برگردانده میشوند — بکاند ذخیرهسازی بدون تغییر محتوای دیتابیس قابل تعویض است - مسیریابی همهچیز روی Traefik است (با Docker labels) — nginx در پروژه وجود ندارد
ساختار
├── frontend/ # سایت React
│ ├── src/ # کد منبع (api.tsx = لایه اتصال به بکاند)
│ ├── Dockerfile # بیلد Node + سرو استاتیک با Caddy
│ └── Caddyfile # فقط سرو فایلهای استاتیک (مسیریابی روی Traefik است)
├── backend/ # بکاند FastAPI
│ ├── app/ # کد منبع (آپلود تصویر: app/api/admin.py)
│ ├── requirements.txt
│ ├── Dockerfile
│ └── .env.example
└── docker-compose.yml # اجرای کامل با یک دستور
اجرا با Docker (سادهترین راه)
docker compose up --build
- سایت: http://localhost:5173 (از طریق Traefik)
- مستندات API: http://localhost:8001/docs (با
docker-compose.override.ymlمحلی) - کنسول MinIO: http://localhost:9001 — کاربر/رمز از متغیرهای
MINIO_ROOT_*در compose - دیتابیس PostgreSQL و آبجکتاستور MinIO هر دو در کانتینر جدا با volume دائمی
- بکاند هنگام شروع، خودش جداول را میسازد و فقط جدولهای خالی را seed میکند — ارتقای نسخه دادههای فعلی را از بین نمیبرد
- در اولین اجرا، سرویس
minio-setupباکتaramesh-mediaرا میسازد و خواندن عمومی را فعال میکند
اجرای محلی (توسعه)
بکاند
cd backend
python -m venv .venv
.venv\Scripts\activate # ویندوز — در لینوکس: source .venv/bin/activate
pip install -r requirements.txt
# فایل .env از روی .env.example بسازید و DATABASE_URL را تنظیم کنید
python -m app.seed # ساخت جداول + محتوای اولیه
uvicorn app.main:app --reload
فرانتاند
cd frontend
npm install
npm run dev
در حالت توسعه، Vite درخواستهای /api و /media را به Traefik (پورت ۵۱۷۳) پروکسی میکند؛
پس استک Docker باید در حال اجرا باشد. آدرس بکاند در frontend/src/config.ts از
VITE_API_URL خوانده میشود — پیشفرض خالی یعنی درخواستهای هممبدأ.
امکانات بکاند
- API عمومی: برند، منو، هیرو، خدمات، پروژهها، مقالات، نظرات، سوالات متداول، تیم، تایملاین، آمار، دفاتر، مدلهای سرمایهگذاری و... — همه در دیتابیس
- فرم تماس
POST /api/contactو خبرنامهPOST /api/newsletter - پنل مدیریت با JWT: ورود
POST /api/auth/login(پیشفرض:admin/aramesh123) و سپس CRUD کامل همه محتواها در/api/admin/... - آپلود تصویر
POST /api/admin/upload(فقط توکن ادمین، حداکثر ۱۰MB) — فایل در MinIO ذخیره و URL نسبی/media/...برمیگردد - همه محتوا در یک درخواست:
GET /api/site
در محیط واقعی حتماً
SECRET_KEY،ADMIN_PASSWORDوMINIO_ROOT_PASSWORDرا تغییر دهید.
نکات امنیتی
- فایل
.envهرگز commit نمیشود (در.gitignoreاست) - رمز عبور ادمین با bcrypt هش میشود
- توکنهای JWT امضا دارند و مدت اعتبارشان قابل تنظیم است
- تصاویر باکت MinIO عمومی (فقط خواندن) هستند؛ آپلود فقط با توکن ادمین ممکن است
Languages
TypeScript
53%
Python
37.6%
JavaScript
5.2%
Shell
2%
CSS
1.5%
Other
0.6%