- page-heroes به فهرست موجودیتهای پنل اضافه شد و PageHero یک دکمهٔ واضح
«عنوان، سرآغاز و تصویر هیروی این صفحه» گرفت (پیشتر فقط ویرایش درجای
نامرئی روی خود متن بود).
- صفحهٔ پروژهها و صفحهٔ جزئیات پروژه حالا از دیتابیس خوانده میشوند
(فایل استاتیک projectsData فقط جانشین دیتابیس خالی/اسلاگهای قدیمی است) —
پیشتر ویرایش پنل روی این دو صفحه اصلاً نمایش داده نمیشد.
- روی لیست پروژهها دکمهٔ ویرایش/جابهجایی/حذف و «افزودن پروژه» اضافه شد و
روی صفحهٔ جزئیات هر پروژه دکمهٔ ویرایش همان پروژه.
- کپشن: قاعدهٔ وسطچینِ .article-body figcaption با قاعدههای [data-dir=...] برای
راست/چپچین بازنویسی میشد و عملاً وسطچین نمیشد؛ figcaption از آن فهرستها
برداشته شد. متن کپشن در ویرایشگر هم وسطچین شد تا با خروجی سایت یکی باشد.
- نام تصویر: نامی که پیش از بارگذاری نوشته میشود، حالا همان Alt تصویر میشود
(پیشتر نام فایل مبنا بود و باید دستی در جعبهٔ زیر تصویر اصلاح میشد).
- فهرست مطالب: H3 با ps-4 فقط ۴ پیکسل بیشتر از H2 تورفتگی داشت (عملاً نامرئی)؛
حالا ps-6 با فونت یک پله کوچکتر.
نمونهٔ OpenPanel موجود (stats.*) با یک پروژهٔ دوم برای این سایت استفاده میشود؛
VITE_OPENPANEL_URL/VITE_OPENPANEL_CLIENT_ID در زمان بیلد تزریق میشوند و در
نبودشان همهچیز بیاثر است. API عمومی track() تغییر نکرده و مسیر Umami هم
برای عقبنشینی دستنخورده مانده.
بازگرداندن من اشتباه بود — تیم UI عمداً این بخش را برداشته/جابهجا کرده است.
جاینگهدار خودشان (section خالی با aria-label) حفظ شد و فقط importهای
بیاستفاده حذف شدند تا تایپچک تمیز بماند.
شاخه UI این بخش را به یک section خالی تبدیل کرده بود (کار ناتمام)؛
ادغام خودکار آن را بیصدا حذف میکرد. محتوای دفاتر (شهر/نشانی/ساعات)
با همان چیدمان و ویرایشپذیری مدیریتی برگردانده شد.
- Alt/Title تصویر شاخص اکنون ذخیره میشود (ستونهای جدید image_alt/image_title — قبلاً بیصدا دور ریخته میشد)
- Alt و Title تصاویر داخل متن پس از درج هم قابل ویرایشاند (کنار کپشن)
- نام فایل ذخیرهسازی خوانا: نام دلخواه هنگام درج یا نام خود فایل (بهجای UUID خالی)
- پنل پرسشوپاسخ پایان مقاله (ستونهای faqs/faqs_en) با ظاهر آکاردئونی سایت و اسکیمای FAQPage
- چسباندن از Outline و هر منبع خارجی: تصاویر خودکار دانلود و در Object Storage سایت میزبانی میشوند (endpoint جدید import-image با محافظ SSRF) + دکمه میزبانی مجدد روی تصاویر خارجی موجود
- 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
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.
فایلهای اصلی 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 را اول میگذارد
- فونت قبلی (Pinar) از fontcdn.ir دانلود میشد که از کار افتاده و گوگلفونت هم در ایران مسدود است؛ در نتیجه هر بار فونت دانلود میشد و در نهایت Tahoma نمایش داده میشد
- فایلهای woff2 (Light/Regular/Bold) یک بار در public/fonts ذخیره شده و از همان سرور سرو میشوند — مرورگر کش میکند و هیچ وابستگی خارجی ندارد
- کلاس font-pinar برای سازگاری با کامپوننتها نگه داشته شد
- vite.config.ts دوباره /api و /media را به Traefik (پورت 5173) پروکسی میکند
- compose: بدون پورت مستقیم 8000/9000 — بکاند لوکال اینجا روی 8001 است و پورت 8000 متعلق به استک دیگر
- مقالهها ستون 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 سرگردان فرانت
- پنل «بررسی سئو» در صفحه نوشتن مقاله — سبز/نارنجی/قرمز سازگار با فارسی:
طول عنوان، کلمه کلیدی هدف (در عنوان/پاراگراف اول/تیتر H2)، طول چکیده،
تعداد واژه، تیتربندی، متن جایگزین تصاویر، پیوندها و slug.
کلمه کلیدی در localStorage نگه داشته میشود (راهنمای ویرایشگر است، نه محتوا)
- جدول seo_meta: عنوان و توضیح متای هر صفحه (page_key برای هر ۸ صفحه،
seed خودکار، CRUD در /api/admin/seo-meta، خواندن در GET /api/site)
- تزریق عنوان/توضیح متا در فرانتاند: صفحههای فهرست از دیتابیس؛ صفحه
مقاله و پروژه از محتوای خودشان (بدون تداخل با اثر سطح والد)
- دکمه سئو روی هیرو هر صفحه و کنار هیرو صفحه اصلی (فقط حالت ویرایش)
- /admin/write (مقاله جدید) و /admin/write/:id (ویرایش) — صفحه کامل
بدون چرخه سایت: نوار بالا (بازگشت، وضعیت ذخیره، ذخیره، دیدن در سایت،
حذف)، عنوان بزرگ، تصویر شاخص، ویرایشگر TipTap تمامارتفاع و بخش
جزئیات انتشار (چکیده، دسته، تاریخ، زمان مطالعه، slug)
- ذخیره خودکار با debounce + flush هنگام خروج؛ اولین ذخیره مقاله را
منتشر میکند و مسیر به /admin/write/:id تغییر میکند
- قلمویژه مقالهها (مداد روی کارت) ادمین را به همین صفحه میبرد
(editHref روی EditableItem)؛ لینکهای data-admin-link در حالت ویرایش
کار میکنند
- رفع: create-on-unmount حذف شد (با draft قدیمی مقاله سرگردانی
میساخت) — unmount فقط برای مقاله ساختهشده PATCH میزند
- دکمه پررنگ «نوشتن مقاله جدید» بالای صفحه وبلاگ (فقط در حالت ویرایش) —
ساخت مقاله جدید و باز شدن مستقیم کشوی نوشتن
- ترتیب فیلدهای کشوی مقاله: عنوان، سپس ویرایشگر WYSIWYG — نوشتن اول،
متادیتا (دسته/تاریخ/اسلاگ و...) بعد
- رفع باگ: ساخت رکورد قبلاً کل درخت را reload میکرد و کشوی
تازهساختهشده بیدرنگ بسته میشد؛ حالا آیتم ساختهشده بهصورت
خوشبینانه به لیست اضافه میشود و کشو باز میماند
- 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، مهاجرت
خودکار مقالات قدیمی) + یادداشت بیلد هاست برای فرانتاند
لایه ویرایش بصری روی سایت واقعی (بدون داشبورد جدا):
- ورود ادمین از مسیر پنهان /admin/login با توکن JWT (localStorage) و
AdminContext شامل isEditMode و وضعیت ذخیره (همگام/در حال ذخیره/خطا)
- AdminBar شناور پایین صفحه (فقط برای کاربر واردشده): کلید حالت ویرایش،
وضعیت ذخیره، خروج — حالت ویرایش در sessionStorage میماند
- InlineEdit: در حالت عادی دقیقاً همان HTML قبلی (بدون تغییر چیدمان)؛
در حالت ویرایش کادرخطچین + contentEditable با ذخیره خودکار در blur
(Enter ذخیره، Esc لغو) — وایرایششده روی همه متنهای سایت: هیرو،
تیتر بخشها، هیرو صفحات، داستان، فرم تماس، خبرنامه، فوتر، منو،
برچسبهای وضعیت پروژه و...
- کشوی عمومی EntityDrawer با پیکربندی متمرکز برای ۱۴ مجموعه (خدمات،
پروژهها، مقالات، نظرات، سوالات، تیم، تایملاین، آمار، چرا آرامش،
مدلهای سرمایهگذاری، مراحل کار، دفاتر، گالری، منو): ویرایش چندفیلدی،
افزودن، حذف و جابهجایی ترتیب (▲▼) با ذخیره خودکار هر فیلد
- دکمههای شناور ویرایش/حذف/ترتیب فقط در حالت ویرایش روی آیتمها
- کشوهای یگانه: برند و لوگو، تنظیمات هیرو، فرم تماس، خبرنامه، فوتر،
قبل/بعد و نقلقول داستان — آپلود تصویر به MinIO از همانجا
- بهروزرسانی خوشبینانه SiteContext (updateSite) پس از هر PATCH؛
مسیرها در حالت ویرایش کلیک نمیشوند؛ breadcrumb محافظ beforeunload
- سرویس 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 برای هممبدأ بودن در توسعه
- data/site.ts: نام برند، ایمیل تماس (info@arameshplaza.com به info@arameshbuildinggroup.com)، تیتر تایملاین، نقلقول تستیمونیال و سؤال FAQ
- کامپوننتها: کپی فوتر و کپیرایت، aria-label تماس شناور، معرفی و alt تصویر هیرو، لید و alt گالری، کپی بخش داستان، تیتر خبرنامه، تیتر «چرا گروه ساختمانی آرامش»، لید مقالات
- صفحات: لید درباره ما، کپی مشارکت در سرمایهگذاری، لید وبلاگ
- index.html: عنوان صفحه
- اتصال کامل فرانت به API: همه محتوای سایت (پروژهها، مقالات، خدمات، برند و...) از بکاند خوانده میشود (SiteProvider + useSite)
- فرم تماس و خبرنامه متصل به بکاند و تستشده در مرورگر
- ساختار مونوریپو: frontend/ + backend/
- Dockerfile برای هر دو بخش + docker-compose (PostgreSQL + FastAPI + nginx)
- nginx با پروکسی /api — بدون نیاز به CORS در حالت داکر
- README کامل فارسی