Commit Graph
57 Commits
Author SHA1 Message Date
aramesh-site deploy ef619c635e fix(chatbot): کوتیشن desc در سه کوئری دیگر ایندکس
همان باگ قبلی در investment_models/process_steps/why_us/timeline هم بود؛
بدون این، سینک ایندکس ناقص می‌ماند و بخشی از محتوا هرگز بردار نمی‌گرفت.
2026-09-27 10:31:12 +00:00
aramesh-site deploy d55c8cc1e5 fix(chatbot): کوئری خدمات و نصب torch نسخهٔ CPU
- content.py: ستون desc در SQL بدون کوتیشن بود و PostgreSQL آن را کلمهٔ کلیدی
  می‌گیرد؛ نتیجه: «Initial index sync failed: syntax error at or near "desc"»
  در استارت و غیرقابل استفاده ماندن چت تا reindex. حالا "desc" کوتیشن شده.
- Dockerfile: با این‌که سرور GPU ندارد، pip نسخهٔ CUDA تورچ را از PyPI می‌گرفت
  (ایمیج ۹.۷GB با کتابخانه‌های nvidia). اول torch از ایندکس CPU نصب می‌شود.
2026-09-26 22:04:29 +00:00
aramesh-site deploy 9d0015808c feat(frontend): تحلیل رفتار با OpenPanel به‌جای اجرای نمونهٔ دوم Umami
نمونهٔ OpenPanel موجود (stats.*) با یک پروژهٔ دوم برای این سایت استفاده می‌شود؛
VITE_OPENPANEL_URL/VITE_OPENPANEL_CLIENT_ID در زمان بیلد تزریق می‌شوند و در
نبودشان همه‌چیز بی‌اثر است. API عمومی track() تغییر نکرده و مسیر Umami هم
برای عقب‌نشینی دست‌نخورده مانده.
2026-09-26 21:43:59 +00:00
aramesh-site deploy 8600d2d4a3 fix(scripts): جلوگیری از تولید راز خالی و اجرای اسکریپت پیش‌نمایش با python3
- gen-env.sh: rand با دو آرگومان صدا زده می‌شد ولی فقط $1 را می‌خواند؛
  openssl rand -hex بدون تعداد بایت خروجی خالی و کد ۰ می‌دهد، پس fallback
  هرگز اجرا نمی‌شد و .env با رازهای خالی ساخته می‌شد. حالا تعداد بایت
  رعایت می‌شود و اگر مقداری خالی بماند، اسکریپت با خطا متوقف می‌شود.
- preview-mode.sh: python روی اوبونتو ۲۴.۰۴ وجود ندارد (فقط python3).
2026-09-26 21:43:59 +00:00
MMD 846682ac4a صفحه تماس: حذف بخش دفاتر مطابق تصمیم تیم UI
CI / tests (push) Canceled after 0s
CI / images (push) Canceled after 0s
بازگرداندن من اشتباه بود — تیم UI عمداً این بخش را برداشته/جابه‌جا کرده است.
جای‌نگهدار خودشان (section خالی با aria-label) حفظ شد و فقط importهای
بی‌استفاده حذف شدند تا تایپ‌چک تمیز بماند.
2026-09-26 23:30:18 +03:30
MMD f7105a62cc بازگرداندن بخش دفاتر در صفحه تماس
شاخه UI این بخش را به یک section خالی تبدیل کرده بود (کار ناتمام)؛
ادغام خودکار آن را بی‌صدا حذف می‌کرد. محتوای دفاتر (شهر/نشانی/ساعات)
با همان چیدمان و ویرایش‌پذیری مدیریتی برگردانده شد.
2026-09-26 23:09:13 +03:30
MMD 0628344dcf Merge remote-tracking branch 'origin/feature/ui-updates-v1' into new-one 2026-09-26 23:04:15 +03:30
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
MMD 1d29e50852 وبلاگ: نام‌گذاری و متادیتای تصاویر، پرسش‌وپاسخ مقاله، میزبانی تصاویر چسبانده‌شده
- Alt/Title تصویر شاخص اکنون ذخیره می‌شود (ستون‌های جدید image_alt/image_title — قبلاً بی‌صدا دور ریخته می‌شد)
- Alt و Title تصاویر داخل متن پس از درج هم قابل ویرایش‌اند (کنار کپشن)
- نام فایل ذخیره‌سازی خوانا: نام دلخواه هنگام درج یا نام خود فایل (به‌جای UUID خالی)
- پنل پرسش‌وپاسخ پایان مقاله (ستون‌های faqs/faqs_en) با ظاهر آکاردئونی سایت و اسکیمای FAQPage
- چسباندن از Outline و هر منبع خارجی: تصاویر خودکار دانلود و در Object Storage سایت میزبانی می‌شوند (endpoint جدید import-image با محافظ SSRF) + دکمه میزبانی مجدد روی تصاویر خارجی موجود
2026-09-26 22:46:56 +03:30
fatemeh sane 853ad67db5 feat(ui): update UI v1 2026-09-25 22:49:30 +03:30
MMD 851e3fc2dc fix(compose): umami healthcheck via 127.0.0.1 — localhost resolves to ::1 and umami listens on IPv4 only 2026-09-19 01:24:15 +03:30
MMD 74770cd99d fix(stack): bring-up fixes from first local deployment
- traefik pin v3.3 -> v3.6: v3.3's old docker client fails against
  Engine 29 socket proxy (empty daemon errors, no routers)
- backend/minio/chatbot/umami: traefik.docker.network hint — Traefik
  picked the internal-network IP for multi-network services and replies
  were hairpin-dropped (all backend routes hung)
- db-init: psql needs an explicit -d arameshplaza (no default db 'aramesh'),
  set -e so failures actually fail; one-shot folded-YAML needs semicolons
- chatbot image: drop g++ (apt unreachable in build network; all wheels
  prebuilt) and mkdir /data before chown (VOLUME does not create it)
- frontend image: create caddy user (alpine image has none) with writable
  /config and /data
- monitoring: blackbox probes replace raw metric scrapes of JSON/HTML
  health endpoints (they reported 'down' while healthy); blackbox joins
  edge; SITE_URL passed via env (Prometheus has no ${VAR:-default}
  expansion); ContainerMemoryNearLimit PromQL fixed (comparison inside
  label braces); HostDiskAlmostFull filters WSL/Docker-Desktop
  pseudo-mounts
- alertmanager: config rendered by stack.sh (no env expansion in AM) and
  delivered to Bale (tapi.bale.ai); stack.sh monitoring command
- machine-local override: minio console/API moved to 29001/29000
2026-09-19 01:22:02 +03:30
MMD ce0735d775 feat(stack): full overhaul — hardening, ops tooling, monitoring, analytics, chatbot
Security: deep /api/health (DB+MinIO probes, 503 on failure) + /api/live;
rate-limited public forms with honeypots; real client IP behind Traefik
(--proxy-headers); TipTap URL sanitization on write (nh3); non-root
containers + slim .dockerignore; prod MinIO console bound to 127.0.0.1;
HSTS/nosniff on TLS routers; JWT 8h; no default credentials in code.

Reliability: Alembic migrations (create_all baseline); graceful shutdown
(exec uvicorn); hardened backups (checksums, sanity check, freshness gauge,
optional rclone off-site) + restore.sh + hourly db-backup sidecar (ops
profile); stack.sh ops tooling (deploy/logs/health/backup/restore/monitoring);
.gitattributes LF for shell scripts.

Orchestration: json-file log rotation, pinned images, per-service memory
limits, edge/internal networks, Traefik ping/accesslog/metrics + flood
limiter, conditional minio-setup, pgvector db image, one-shot db-init
(umami + aramesh_chatbot databases).

Chatbot: unified from site-chatbot branch (RAG + pgvector, SSE, ChatWidget).

Monitoring: Prometheus/Alertmanager/Loki/Promtail/Grafana + cAdvisor,
node/postgres/blackbox exporters, provisioned dashboards and 10 alert
rules; alerts delivered to Bale (tapi.bale.ai — Telegram-compatible).

Analytics: Umami on shared Postgres, build-time tracker injection, custom
events (contact/newsletter/phone/chat/lang) via frontend/src/analytics.ts.

Hygiene: CSV export for contact messages and subscribers; upload image
optimization (Pillow); CI script + GitHub-compatible workflow; audit.sh;
gen-env.sh for strong credentials.
2026-09-19 00:24:57 +03:30
MMD 805f4594d4 Merge remote-tracking branch 'origin/dashboard/blog-changes'
# Conflicts:
#	frontend/src/App.tsx
#	frontend/src/admin/ArticleWritePage.tsx
#	frontend/src/admin/EntityDrawer.tsx
#	frontend/src/pages/ArticleDetail.tsx
2026-09-17 12:31:04 +03:30
fatemeh sane 7a0defc3d4 fix(admin): resolve Tiptap editor bugs, dynamic RTL/LTR layout, sticky TOC, and equalize Bidi typography 2026-09-17 10:10:50 +03:30
MMD fe6957bf83 Merge remote-tracking branch 'origin/dashboard/blog-changes'
# Conflicts:
#	frontend/src/admin/ArticleWritePage.tsx
#	frontend/src/admin/EntityDrawer.tsx
#	frontend/src/admin/entities.ts
#	frontend/src/components/ArticleCard.tsx
#	frontend/src/index.css
2026-09-15 14:41:46 +03:30
fatemeh sane 049291c109 feat(admin): enhance editor UI (links, image captions) & fix categories
Added animated auto-opening link modal, custom image node with isolated caption deletion, fixed single-select category data binding, improved featured image layout, and updated README.
2026-09-15 11:33:04 +03:30
MMD 53673d0f9b Merge branch 'bilingual-en'
# Conflicts:
#	frontend/src/admin/ArticleWritePage.tsx
#	frontend/src/admin/EntityDrawer.tsx
#	frontend/src/admin/entities.ts
#	frontend/src/components/ArticleCard.tsx
#	frontend/src/index.css
#	frontend/src/pages/ArticleDetail.tsx
2026-09-13 18:45:06 +03:30
MMD 9d55f521a0 Merge remote-tracking branch 'origin/dashboard/blog-changes' 2026-09-13 18:29:51 +03:30
MMD 35c03ef35e اصلاح عنوان تب صفحات جزئیات — brand به‌جای brand.name 2026-09-13 18:29:34 +03:30
fatemeh sane bb6c586d99 Update blog editor features 2026-09-13 10:39:25 +03:30
MMD 4fb57dfd67 اصلاحات بازبینی: تطبیق backfill با متن فارسی، رفع باگ متای /blog (ستون image ناموجود)، پاک‌سازی og:locale و برند در پوسته سئو، محدودکردن Traefik به پروژه خود، اصلاح مسیریابی Routes و عنوان برند در صفحات جزئیات 2026-09-13 00:10:53 +03:30
MMD 6b49d035c2 فرانت‌اند: نسخه انگلیسی با مسیر /en/ — مسیریابی دوزبانه، دیکشنری رابط، بومی‌سازی داده، تغییر زبان در هدر، ویرایش انگلیسی در پنل و پشتیبانی LTR 2026-09-12 23:37:55 +03:30
MMD 6bb6226e06 بک‌اند: مدل دوزبانه — ستون‌های _en، ترجمه کامل seed انگلیسی، backfill خودکار و پوسته سئوی /en/ 2026-09-12 22:57:06 +03:30
MMD 9242b87677 ادغام site-v2: به‌روزرسانی رابط کاربری (صفحات پروژه‌ها، نمونه‌کارها، تایم‌لاین، سرمایه‌گذاری و کارت‌ها) 2026-09-12 20:08:11 +03:30
fatemeh sane 20c95e73b3 Merge branch 'site-v2' of https://git.bennu-api-bahrestan.ir/Behrad/aramesh-backend 2026-09-12 19:19:45 +03:30
fatemeh sane 5837e4b0d9 Update README file 2026-09-12 10:56:03 +03:30
MMD 1fb5d57da1 مستندات: راه‌اندازی روشن برای تازه‌واردها در README
- مرحله npm run build فرانت‌اند (لازم برای اولین اجرا) اضافه شد
- اشاره به seed شدن خودکار تصاویر از seed-media در بیلد تازه
- یادآوری اینکه هیچ فایل رمزدار در گیت نیست و فقط .env.example کپی شود
2026-09-12 10:52:34 +03:30
Behrad 8abc70dcf1 Add new updated site 2026-09-12 10:35:17 +03:30
MMD f2e5a9e58b فونت: آوردن فونت اصلی Pinar (۵ وزن) به‌جای جانشین Vazirmatn
فایل‌های اصلی Pinar از شاخه feature/frontend-updates گرفته شد (fatemeh sane آن‌ها را
سلف‌هاست کرده بود) — همان فونتی که پیش‌تر CDN از کار افتاده‌اش را سرو می‌کرد:
- ۵ وزن (Light 300، Regular 400، Bold 700، ExtraBold 800، Black 900) در
  frontend/public/fonts/pinar به‌صورت woff2 + ttf
- index.css: Pinar فونت اصلی و Vazirmatn جایگزین پشتیبان
- tailwind: کلاس pinar دوباره Pinar را اول می‌گذارد
2026-09-12 10:25:49 +03:30
MMD 5ae5421c5c رسانه: پیش‌بارگذاری تصاویر در بیلد تازه — seed-media + سینک خودکار MinIO
تا وقتی کسی کلون/بیلد تازه می‌گیرد، همان تصاویر را داشته باشد:
- seed-media شامل هر ۱۹ فایل تصویری است که در دیتابیس با پیشوند /media ثبت‌اند
- minio-setup بعد از ساخت باکت، محتوای seed-media را با mc mirror در bucket
  می‌گذارد — روی حجم موجود idempotent است و داده تازه را نمی‌خورد
2026-09-08 14:46:06 +03:30
MMD c169703a17 رسانه: اسکریپت انتقال تصاویر CDN به MinIO (migrate-media.py)
ابزار یک‌باره برای وقتی میزبان عکس (مثل i.postimg.cc) در دسترس است:
- از /api/site فهرست همه تصاویرِ URL خارجی را می‌گیرد، هرکدام را دانلود و از
  انتهای ادمین در MinIO آپلود می‌کند و مقدار فیلد را به /media/... بازنویسی می‌کند
- اعتبارسنجی فایل با هدر (تا HTML/خطا ذخیره نشود) + فرمت واقعی برای آپلود
- خروجی گزارش ردیف‌های ناتمام برای اجرای دوباره
دیتابیسِ همین سایت هم با آن منتقل شد: ۱۹ تصویر در باکت aramesh-media و دیگر
هیچ URL خارجی (postimg/housedesign) در محتوای سایت نیست.
2026-09-08 14:24:58 +03:30
MMD 07da45467b وبلاگ: دکمه «نوشتن مقاله جدید» فقط در حالت ویرایش ادمین دیده می‌شود
قبلاً برای بازدیدکننده عادی هم نمایش داده می‌شد
2026-09-08 13:27:40 +03:30
MMD 4b9cc13163 فونت: سلف‌هاست Vazirmatn — بدون دانلود هر بار از CDN
- فونت قبلی (Pinar) از fontcdn.ir دانلود می‌شد که از کار افتاده و گوگل‌فونت هم در ایران مسدود است؛ در نتیجه هر بار فونت دانلود می‌شد و در نهایت Tahoma نمایش داده می‌شد
- فایل‌های woff2 (Light/Regular/Bold) یک بار در public/fonts ذخیره شده و از همان سرور سرو می‌شوند — مرورگر کش می‌کند و هیچ وابستگی خارجی ندارد
- کلاس font-pinar برای سازگاری با کامپوننت‌ها نگه داشته شد
2026-09-08 13:27:40 +03:30
MMD f1046a6598 رفع: مقدار پیش‌فرض CORS_ORIGINS در compose بدون کوتیشن — بک‌اند بالا می‌آمد
پیش‌فرض داخل interpolate با کوتیشن تک، به‌صورت حرفی وارد env می‌شد و pydantic
JSON را پارس نمی‌کرد (SettingsError) — باعث restart-loop بک‌اند می‌شد
2026-09-08 12:22:40 +03:30
MMD 5731eda438 توسعه: برگرداندن پروکسی Vite و پورت‌های compose به مسیر Traefik
- vite.config.ts دوباره /api و /media را به Traefik (پورت 5173) پروکسی می‌کند
- compose: بدون پورت مستقیم 8000/9000 — بک‌اند لوکال اینجا روی 8001 است و پورت 8000 متعلق به استک دیگر
2026-09-08 12:14:56 +03:30
Behrad 17bddd3adf feat: update UI to glassmorphic design and copper theme 2026-09-08 12:07:34 +03:30
MMD 2ad3ad7367 زیرساخت: رمزهای اجباری از .env + لایه تولید با TLS + healthcheck و مسیر سئوی Traefik + پشتیبان‌گیری
- docker-compose.yml همه مقادیر محرمانه را با ${VAR:?} از .env می‌خواند — بدون .env استک بالا نمی‌آید
- docker-compose.prod.yml: ورودی 443 + ریدایرکت HTTP به HTTPS + گواهی Let's Encrypt و قواعد Host برای همه روترها
- healthcheck بک‌اند (api/health) و فرانت (wget) + سوار کردن frontend/dist در بک‌اند برای تزریق متا + روتر سئو (robots/sitemap/blog/projects) با اولویت 50
- سرویس mc با پروفایل tools + scripts/backup.sh (pg_dump + آینه MinIO با نگهداری ۱۴ روزه)
- .env.example ریشه + بروزرسانی READMEها
2026-09-07 04:26:18 +03:30
MMD b31124e1e4 وبلاگ و سئو: پیش‌نویس/انتشار مقاله + کلمه کلیدی سئو در دیتابیس + OG/canonical/JSON-LD و متای سمت سرور + تغییر رمز و محدودسازی ورود + تست‌ها
- مقاله‌ها ستون status (draft/published) گرفتند — GET /api/site و همه انتهای عمومی فقط منتشرشده را برمی‌گردانند؛ autosave دیگر پیش‌نویس نیمه‌کاره را زنده نمی‌کند
- کلمه کلیدی هدف چک‌لیست سئو فیلد seo_keyphrase شد (قبلاً localStorage بود)
- robots.txt و sitemap.xml از بک‌اند + سرو /blog و /projects با تزریق title/description/OG/JSON-LD از دیتابیس برای خزنده‌های بدون JS (app/seo_pages.py)
- فرانت: applySeo در seo.ts (OG/توییتر/canonical/JSON-LD)، ادغام پیش‌نویس برای ادمین، برچسب پیش‌نویس در وبلاگ، حالت خالی وبلاگ، دکمه انتشار در صفحه نوشتن
- تغییر رمز ادمین POST /api/auth/change-password + دیالوگ «رمز» در نوار مدیریت
- محدودسازی ورود: ۵ تلاش ناموفق در ۱۵ دقیقه از هر IP → 429
- ساخت دکمه + برای ردیف سئوی صفحه‌های بدون ردیف (SingletonPill)
- تست‌های pytest (۱۵ مورد) + پین‌کردن requirements + حذف package.json سرگردان فرانت
2026-09-07 04:26:18 +03:30
MMD a29deb8bb1 سئو: بررسی سئو در صفحه نوشتن + عنوان و توضیح متای هر صفحه
- پنل «بررسی سئو» در صفحه نوشتن مقاله — سبز/نارنجی/قرمز سازگار با فارسی:
  طول عنوان، کلمه کلیدی هدف (در عنوان/پاراگراف اول/تیتر H2)، طول چکیده،
  تعداد واژه، تیتربندی، متن جایگزین تصاویر، پیوندها و slug.
  کلمه کلیدی در localStorage نگه داشته می‌شود (راهنمای ویرایشگر است، نه محتوا)
- جدول seo_meta: عنوان و توضیح متای هر صفحه (page_key برای هر ۸ صفحه،
  seed خودکار، CRUD در /api/admin/seo-meta، خواندن در GET /api/site)
- تزریق عنوان/توضیح متا در فرانت‌اند: صفحه‌های فهرست از دیتابیس؛ صفحه
  مقاله و پروژه از محتوای خودشان (بدون تداخل با اثر سطح والد)
- دکمه سئو روی هیرو هر صفحه و کنار هیرو صفحه اصلی (فقط حالت ویرایش)
2026-09-07 03:12:12 +03:30
MMD 17345daa81 وبلاگ: صفحه تمام‌عرض «نوشتن مقاله» — محیط نوشتن متمرکز برای ادمین
- /admin/write (مقاله جدید) و /admin/write/:id (ویرایش) — صفحه کامل
  بدون چرخه سایت: نوار بالا (بازگشت، وضعیت ذخیره، ذخیره، دیدن در سایت،
  حذف)، عنوان بزرگ، تصویر شاخص، ویرایشگر TipTap تمام‌ارتفاع و بخش
  جزئیات انتشار (چکیده، دسته، تاریخ، زمان مطالعه، slug)
- ذخیره خودکار با debounce + flush هنگام خروج؛ اولین ذخیره مقاله را
  منتشر می‌کند و مسیر به /admin/write/:id تغییر می‌کند
- قلم‌ویژه مقاله‌ها (مداد روی کارت) ادمین را به همین صفحه می‌برد
  (editHref روی EditableItem)؛ لینک‌های data-admin-link در حالت ویرایش
  کار می‌کنند
- رفع: create-on-unmount حذف شد (با draft قدیمی مقاله سرگردانی
  می‌ساخت) — unmount فقط برای مقاله ساخته‌شده PATCH می‌زند
2026-09-07 02:35:41 +03:30
MMD 2c96562b66 وبلاگ: دکمه «نوشتن مقاله جدید» بالای صفحه + ویرایشگر متن در ابتدای کشو
- دکمه پررنگ «نوشتن مقاله جدید» بالای صفحه وبلاگ (فقط در حالت ویرایش) —
  ساخت مقاله جدید و باز شدن مستقیم کشوی نوشتن
- ترتیب فیلدهای کشوی مقاله: عنوان، سپس ویرایشگر WYSIWYG — نوشتن اول،
  متادیتا (دسته/تاریخ/اسلاگ و...) بعد
- رفع باگ: ساخت رکورد قبلاً کل درخت را reload می‌کرد و کشوی
  تازه‌ساخته‌شده بی‌درنگ بسته می‌شد؛ حالا آیتم ساخته‌شده به‌صورت
  خوش‌بینانه به لیست اضافه می‌شود و کشو باز می‌ماند
2026-09-07 02:09:17 +03:30
MMD 70cf9616c1 بیلد: انتقال بیلد فرانت‌اند به هاست + پیش‌فرض هم‌مبدأ API
- Dockerfile فرانت‌اند: npm ci داخل کانتینر بیلد به‌دلیل محدودیت شبکه
  (registry.npmjs.org از داخل VM داکر در دسترس نیست) غیرقابل‌اعتماد بود؛
  ایمیج حالا فقط Caddy است و خروجی بیلد هاست (npm run build → dist/) را
  سرو می‌کند — بیلد ایمیج از چند دقیقه آویزان به چند ثانیه رسید
- docker-compose.yml: حذف build args از سرویس frontend
- config.ts: پیش‌فرض VITE_API_URL خالی است (درخواست هم‌مبدأ از طریق
  Traefik) — مقدار قبلی http://localhost:8000 میراث معماری قبل بود و
  بیلد هاست را خراب می‌کرد
- README ریشه: بخش وبلاگ (ویرایشگر WYSIWYG، فرمت سند JSON، مهاجرت
  خودکار مقالات قدیمی) + یادداشت بیلد هاست برای فرانت‌اند
2026-09-06 23:33:28 +03:30
MMD cfe5512ec7 فرانت‌اند: ویرایشگر WYSIWYG وبلاگ (TipTap) با آپلود تصویر در متن
- ArticleEditor: ویرایشگر TipTap v3 راست‌به‌چسب با نوار ابزار فارسی —
  بولد/ایتالیک/زیرخط/خط‌خورده، تیتر H2/H3، لیست نقطه‌ای/شماره‌ای،
  نقل‌قول، لینک (مسدودسازی javascript: با isAllowedUri)، واگرد/ازنو
- درج تصویر داخل متن: دکمه آپلود، چسباندن یا کشیدن فایل — ذخیره در
  MinIO از طریق /api/admin/upload و درج URL نسبی /media/...
- ذخیره خودکار: debounce ۸۰۰ms + flush هنگام بستن کشو
- کشوی مقاله عریض‌تر (max-w-3xl)؛ فیلد body مقالات به‌جای لیست متنی،
  ویرایشگر WYSIWYG رندر می‌کند
- رندر صفحه مقاله: تبدیل سند به HTML با @tiptap/static-renderer
  (فقط تگ‌های شناخته‌شده — بدون ریسک XSS) + استایل‌های .article-body
  (تیتر با خط مسی، لیست، نقل‌قول، تصویر) + پشتیبانی از ردیف‌های قدیمی
- وابستگی‌های جدید: @tiptap/react، @tiptap/pm، @tiptap/starter-kit،
  @tiptap/extension-image، @tiptap/extension-link، @tiptap/static-renderer
2026-09-06 23:33:08 +03:30
MMD 8f11df99ea بک‌اند: بدنه مقاله به سند ساختاریافته TipTap (JSON) + مهاجرت داده
- body مقاله از لیست پاراگراف به سند ProseMirror تغییر کرد:
  {"type": "doc", "content": [...]} — در In/Out/Patch schemas
- اعتبارسنجی ساختاری (type=doc + content لیست) با field_validator —
  امنیت رندر بر عهده رندر استاتیک TipTap در فرانت‌اند است
- app/migrations.py: مهاجرت‌های DDL و داده در یک‌جا؛ migrate_article_bodies
  ردیف‌های قدیمی (لیست پاراگراف) را idempotent به سند تبدیل می‌کند —
  در startup و seed اجرا می‌شود، دیتابیس موجود بدون از دست رفتن داده ارتقا می‌یابد
- seed بدنه‌های لیستی را قبل از درج به سند تبدیل می‌کند
- README بک‌اند: فرمت بدنه و رفتار مهاجرت مستند شد
2026-09-06 23:32:52 +03:30
MMD b7d29d1028 مستندسازی ویرایش زنده و انتهای‌نقطه‌های جدید در README
- README ریشه: بخش «ویرایش زنده سایت» — ورود از /admin/login، حالت
  ویرایش، ذخیره خودکار هر فیلد، ویرایش/حذف/ترتیب مجموعه‌ها، آپلود تصویر
  و نامرئی بودن لایه برای بازدیدکنندگان
- README بک‌اند: افزودن PATCH (ویرایش جزئی) و reorder به جدول
  انتهای‌نقطه‌ها + فهرست منابع دارای ستون position و نحوه مهاجرت سبک
2026-09-06 22:30:17 +03:30
MMD 5ed082631e فرانت‌اند: ویرایش زنده درجا — دوقلوی دیجیتال سایت برای ادمین
لایه ویرایش بصری روی سایت واقعی (بدون داشبورد جدا):

- ورود ادمین از مسیر پنهان /admin/login با توکن JWT (localStorage) و
  AdminContext شامل isEditMode و وضعیت ذخیره (همگام/در حال ذخیره/خطا)
- AdminBar شناور پایین صفحه (فقط برای کاربر واردشده): کلید حالت ویرایش،
  وضعیت ذخیره، خروج — حالت ویرایش در sessionStorage می‌ماند
- InlineEdit: در حالت عادی دقیقاً همان HTML قبلی (بدون تغییر چیدمان)؛
  در حالت ویرایش کادرخط‌چین + contentEditable با ذخیره خودکار در blur
  (Enter ذخیره، Esc لغو) — وایرایش‌شده روی همه متن‌های سایت: هیرو،
  تیتر بخش‌ها، هیرو صفحات، داستان، فرم تماس، خبرنامه، فوتر، منو،
  برچسب‌های وضعیت پروژه و...
- کشوی عمومی EntityDrawer با پیکربندی متمرکز برای ۱۴ مجموعه (خدمات،
  پروژه‌ها، مقالات، نظرات، سوالات، تیم، تایم‌لاین، آمار، چرا آرامش،
  مدل‌های سرمایه‌گذاری، مراحل کار، دفاتر، گالری، منو): ویرایش چندفیلدی،
  افزودن، حذف و جابه‌جایی ترتیب (▲▼) با ذخیره خودکار هر فیلد
- دکمه‌های شناور ویرایش/حذف/ترتیب فقط در حالت ویرایش روی آیتم‌ها
- کشوهای یگانه: برند و لوگو، تنظیمات هیرو، فرم تماس، خبرنامه، فوتر،
  قبل/بعد و نقل‌قول داستان — آپلود تصویر به MinIO از همان‌جا
- به‌روزرسانی خوش‌بینانه SiteContext (updateSite) پس از هر PATCH؛
  مسیرها در حالت ویرایش کلیک نمی‌شوند؛ breadcrumb محافظ beforeunload
2026-09-06 21:57:46 +03:30
MMD 6e422ec3dc بک‌اند: ویرایش جزئی (PATCH) و ترتیب‌بندی مجموعه‌ها برای ویرایش زنده
- PATCH /api/admin/{resource}/{id} — ویرایش جزئی؛ فقط فیلدهای ارسال‌شده
  به‌روزرسانی می‌شوند (PUT قبلاً کل رکورد را جایگزین می‌کرد و برای
  ویرایش زنده قابل استفاده نبود). اسکیماهای Patch به‌صورت خودکار از
  اسکیماهای In با create_model ساخته می‌شوند (هر ۲۴ منبع).
- ستون position برای ۱۴ جدول مجموعه‌ای (خدمات، پروژه‌ها، مقالات، نظرات،
  سوالات، تیم، تایم‌لاین، آمار، چرا آرامش، مدل‌های سرمایه‌گذاری، مراحل کار،
  دفاتر، گالری، منو) — مهاجرت سبک idempotent در startup و seed
  (ALTER TABLE ADD COLUMN IF NOT EXISTS) تا دیتابیس‌های موجود هم ارتقا یابند
- POST /api/admin/{resource}/reorder — ذخیره ترتیب جدید بر اساس لیست id
- خواندن عمومی بر اساس (position, id) مرتب می‌شود؛ رکورد جدید در انتهای لیست
- seed فقط جدول‌های خالی را با position صحیح پر می‌کند
2026-09-06 21:57:07 +03:30
MMD bf3c67f405 به‌روزرسانی README ریشه: معماری جدید (Traefik + Caddy + MinIO)
- نمودار مسیریابی Traefik (/ و /api و /media) جایگزین توضیحات nginx
- مستندسازی «همه متن‌ها در دیتابیس» و آپلود تصویر به MinIO
- پورت‌های جدید: سایت ۵۱۷۳ (Traefik)، کنسول MinIO ۹۰۰۱
- رفتار seed در ارتقا (فقط جدول‌های خالی) و پروکسی dev فرانت‌اند
2026-09-06 20:51:26 +03:30
MMD 3a7c7b0908 زیرساخت: Traefik به‌جای nginx به‌عنوان نقطه ورود واحد + سرو MinIO
- سرویس traefik:v3 روی پورت ۵۱۷۳ (پورت هاست) — تنها نقطه ورود استک:
  /       → frontend (فایل‌های استاتیک SPA)
  /api    → backend:8000
  /media  → MinIO:9000 با rewrite به باکت aramesh-media
  مسیریابی با Docker labels در docker-compose.yml
- حذف کامل nginx: Caddy فقط فایل‌های استاتیک را سرو می‌کند
  (fallback به index.html برای SPA، کش یک‌ساله immutable برای assets/)
- سرویس minio + minio-setup (ساخت خودکار باکت و دسترسی عمومی خواندن —
  یک‌بار در اولین اجرا)؛ کنسول MinIO روی پورت ۹۰۰۱
- وابستگی backend به سلامت db و minio
- vite dev: پروکسی /api و /media به Traefik برای هم‌مبدأ بودن در توسعه
2026-09-06 20:49:17 +03:30