شامل کارهای چند نشست موازی که تا اینجا فقط روی سرور بود:
- نقشهٔ دفتر مرکزی در فوتر (LazyOfficeMap) + MapViewport/LazyMaps/mapProjects
- صفحهٔ مدیریت مقالات (AdminArticlesPage) + میانبر ویرایش پیشنویس در وبلاگ
- مهاجرت ۰۰۰۴: updated_at مقالات/پروژهها
- chatbot/Dockerfile: نصب دومرحلهای torch (کاربردی برای PyPI فیلترشده)
- seed: خالیکردن آمارهای دموی story
- docker-compose: اصلاح پسوند @file میانافزارهای Traefik
- حذف فایل موقت frontend/.tmp-style.json و اصلاحات جزئی UI
با این کامیت، آنچه روی سرور اجرا میشود Exactly همان چیزی است که در مخزن ثبت شده.
سئوی سمت سرور (backend/app/seo_pages.py)
- متا/canonical/hreflang/JSON-LD برای همهٔ صفحات عمومی (شش صفحهٔ استاتیک فارسی که قبلاً پوستهٔ خالی بودند)
- canonical سمت سرور (قبلاً فقط با JS ست میشد)، ۴۰۴ واقعی برای مسیرهای ناموجود
- اسکیما: Organization با لوگوی ImageObject، FAQPage، LocalBusiness، BreadcrumbList،
CreativeWork پروژه با همهٔ تصاویر بهصورت ImageObject (نام/توضیح + موقعیت پروژه)
- hreflang فقط وقتی ترجمهٔ انگلیسی واقعاً وجود دارد؛ sitemap با URLهای درصدگذاریشده
- llms.txt و robots.txt تازهساز از دیتابیس؛ سیاست صریح خزندههای AI + Allow: /api/site
- _site_content_html: محتوای واقعی سایت بهصورت HTML خوانا در <noscript> —
خزندههای بدون جاوااسکریپت (GPTBot/OAI-SearchBot/ClaudeBot/PerplexityBot) از ۲۴۰ نویسه
به ۸٬۵۰۰+ نویسه محتوای معنایی میرسند
- Cache-Control: no-store روی HTML و llms.txt (جلوگیری از کش کهنهٔ CDN)، max-age روی sitemap
فرانتاند
- api.tsx: خواندن دادهٔ تزریقشدهٔ سرور (window.__SITE__) بهعنوان حالت اولیه — رندر بدون XHR
- App.tsx: اسکلت بارگذاری بهجای DOM خالی (رفع Soft 404 گوگل)
- index.html: فاوآیکون واقعی برند (قبلاً به vite.svg ناموجود اشاره میکرد) + preload فونت
زیرساخت
- Dockerfile: آینهٔ PyPI (Tsinghua/Aliyun) — PyPI برای IP ایران بلاک است
- Caddyfile: هر مسیر پسونددار بدون فایل واقعی ۴۰۴ میگیرد (قبلاً HTML اسپا برمیگرداند)
- docker-compose.prod.yml: مسیرهای seo برای صفحات استاتیک + llms.txt + کلیدهای IndexNow
داده
- seed_data*.py: حذف دفاتر و معرفیهای دمو (که در هر استقرار برمیگشتند)؛
تنها دفتر واقعی: اصفهان، ملاصدرا شمالی
داراییها
- فاوآیکون/آیکونهای برند از لوگوی رسمی + کلیدهای IndexNow
در پنجرهٔ تعویض کانتینر فرانتاند، درخواستِ هشِ جدید که در dist کانتینرِ در
حال اجرا نبود با fallback اسپا پاسخ 200ٔ text/html میگرفت؛ CDN (WCDN، SMART)
همین پاسخ HTML را زیر URL فایل جاوااسکریپت با هدر immutable یکساله کش میکرد
و اسکریپت ماژول برای همهٔ بازدیدکنندهها میشکست (سایت روی پریلودر قفل میشد).
حالا فایل ناموجود در assets واقعاً 404 میدهد که کش نمیشود.
- سرویس 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 برای هممبدأ بودن در توسعه