دستیارها نمیتوانند دکمههای UI را کلیک کنند؛ برای همین نمیتوانستند تصاویر یک پروژه را
بررسی کنند. اکنون:
- /projects/{slug}/images.zip — آرشیو تصاویر هر پروژه + manifest.json
(مشخصات کامل پروژه: زمین/زیربنا/طبقات/واحدها/کاربری/سال + برای هر تصویر: نام،
caption با موقعیت پروژه، و لینک منبع)
- /projects-images.json — فهرست ماشینخوان هر ۶۵ پروژه با لینک ZIP (ItemList)
- هر دو مسیر در قاعدهٔ seo ترویک (prod + override) اضافه شدند
رفع باگها در مسیر ساخت آرشیو:
- _fetch_media: unquote روی کلیدِ از قبل دیکدشده، نام فایلهای فارسی را خراب میکرد
(حالا هر دو شکل امتحان میشود + سقوط به واکشی از سایت)
- UnboundLocalError: import محلی urllib.request نام urllib را محلی میکرد
- تصاویر تکراری (تصویر شاخص = اولین عکس گالری) با هش MD5 حذف میشوند —
۱۷ از ۱۹ پروژهٔ نمونه یک تصویر تکراری داشتند
سئوی سمت سرور (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
- گیت ورود 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
- 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ها