localize.ts فیلد usage را نگاشت نمیکرد و نوع Project هم آن را نداشت؛ نتیجه:
صفحهٔ /en/projects/... همچنان «مسکونی» فارسی را نشان میداد. usage و project_type
به نوع + نگاشت بومیسازی اضافه شدند.
نشانی انگلیسی ترانویسیشده از ۱۲۸ نویسه بلندتر میشود (بلندترین: ۱۶۱) و درج
ترجمهٔ ۶۵ پروژه با خطای StringDataRightTruncation شکست خورد. مدل + مهاجرت
ALTER COLUMN TYPE (idempotent) اضافه شد.
با افزودن title_en به سه پروژه، فیلتر FEATURED_TITLES (عنوان فارسی) در نسخهٔ
انگلیسی دیگر مطابقت نمیکرد و بخش «پروژههای شاخص» بدون کارت رندر میشد.
- تطبیق با slug (زبانمستقل) + لینک کارتها با href() بومیسازی شد
- لینک نشان پروژهٔ فعال هیرو هم بومیسازی شد (در /en به نسخهٔ فارسی نمیرود)
گزارش Coverage Drilldown گوگل (۱۰ اکتبر): ۳۶ صفحه «Crawled - currently not indexed»
که غالباً /en/projects/... بودند — صفحهٔ انگلیسی با محتوای فارسی (۰/۶۵ پروژه ترجمه دارد)
یعنی نسخهٔ تکراری صفحهٔ فارسی، و گوگل درست ردش کرده بود.
اکنون صفحات /en که ترجمه ندارند متای noindex,follow میگیرند (کاربر عادی سالم
میبیند؛ با افزودن ترجمه خودکار برمیگردد). صفحههای فارسی و /en صفحههای اصلی
ترجمهدار دستنخورده و ایندکسپذیرند.
سیگنال تمایز هویت برند: شرکت جعلیای که از نام «آرامش» استفاده میکند تأسیس ۱۳۹۱ را
ادعا میکند؛ سایت رسمی حالا سند ساختیافتهٔ سابقهٔ واقعی (۲۴ سال) را در اختیار
گوگل و دستیارهای AI قرار میدهد.
NavLink برای «خانه» (مسیر / و /en) چون پیشوند همهٔ مسیرهاست، در هر صفحهای
active میماند (در انگلیسی واضح بود: Home و Projects همزمان روشن).
با end={item.href === '/'} دقیق شد — بقیهٔ آیتمها مثل Projects روی
صفحههای جزئیات همچنان فعال میمانند (رفتار درست).
- هدر: لوگو در موبایل h-14 (دسکتاپ h-20 مثل قبل) — ارتفاع هدر از ۱۱۲ به ۸۸ پیکسل
- PageHero: h ثابت ۵۸vh → min-h + pt-32؛ اگر محتوا (مثل سرآغاز بلند انگلیسی درباره ما)
بلندتر باشد، بخش بلندتر میشود و بردکرامب هرگز زیر لوگوی ثابت نمیرود
- Hero صفحهٔ اصلی: pt-28 تا بلوک وسطچین هم با هدر تداخل نکند؛ min-h بهجای h-screen
با iOS Safari (آیفون) تست شد
کاربر نشان «47 / پروژه فعال آرامش الیسیان» را در هیرو دید — عدد دموی seed.
- badge_value/badge_value_en: «۴۷»/«47» → خالی (برچسب واقعی میماند)
- تایملاین: «پرتفوی ۴۷ پروژه، دفاتر در سه شهر» → «پرتفوی ۶۵ پروژه، دفتر مرکزی در اصفهان»
- تایملاین lead: «تا ۴۷ پروژه» → «تا ۶۵ پروژه»
- متای دموی seed: «21 years / 47 delivered» → «24 years / 65 delivered»
- بخش تماس: «تیم ما در سه شهر» → «تیم ما» (فقط یک دفتر واقعی داریم: اصفهان)
بررسی کامل دیتابیس زنده: هیچ ادعای ناسازگاری باقی نمانده (نه ۴۷، نه سه شهر، نه
دفاتر/افراد دمو). seed اصلاح شد تا در استقرار بعدی برنگردند.
گزارش منابع صفحهٔ GSC: «Googlebot blocked by robots.txt → /api/site».
robots.txt قاعدهٔ «آخرین تطابق» ندارد؛ افزودن Allow: /api/site داخل همان گروه
Disallow: /api توسط برخی خزندهها نادیده گرفته میشد. حالا فقط /admin و
/api/admin مسدود میشوند و /api/site آزاد است.
دستیار AI گفت «تصاویر سایت را نتوانستم دریافت کنم» — آرشیو ZIP وجود داشت و از
چهار کشور ۲۰۰ میداد، اما هیچ پیوندی به آن در صفحات نبود: llms.txt فقط الگو
داده بود و مدلها الگو را جایگذاری نمیکنند. اکنون:
- صفحهٔ هر پروژه: <a href=.../images.zip>دانلود همهٔ تصاویر (ZIP)</a>
- فهرست /projects: هر ردیف پیوند «تصاویر (ZIP)» همان پروژه را دارد (۶۵ پیوند)
تا خزندهها با دنبالکردن پیوند واقعی به آرشیو برسند.
دستیار AI گفت «/projects باز نمیشود» و «برای الیسیان و زنیت متراژ پیدا نکردم» — درست بود:
فهرست پروژهها فقط نام/موقعیت/سال را میداد و زیربنا و طبقات فقط در صفحهٔ جزئیات بود.
اکنون هر ردیف فهرست شامل زمین/زیربنا/طبقات/واحد است و نام پروژه به صفحهٔ جزئیات
پیوند دارد، تا خزنده بتواند مشخصات کامل را دنبال کند.
دستیارها نمیتوانند دکمههای 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 حذف میشوند —
۱۷ از ۱۹ پروژهٔ نمونه یک تصویر تکراری داشتند
پاسخ به اینکه دستیارهای AI «متراژ پروژه را پیدا نمیکنند» در حالی که در پنل ثبت شده است:
- _project_content_html فقط ۴ فیلد (موقعیت/سال/زیربنا/کارفرما) را منتشر میکرد و
زیربنا را روی نسخهٔ انگلیسی بهخاطر نبود *_en حذف میکرد. حالا همهٔ فیلدهای فنی
(زمین، زیربنا، طبقات، پیلوت، واحدهای مسکونی/تجاری/اداری، کاربری، نوع، کارفرما، وضعیت)
منتشر میشوند؛ اعداد زبانمستقلاند و در نبود ترجمه هم مقدار فارسی میآید.
- _project_schema: همان مشخصات بهصورت additionalProperty (PropertyValue) اضافه شد
تا بهعنوان دادهٔ ساختیافته قابل استناد باشد.
نمونهٔ زنده (آرامش الیسیان): زمین ۱۵۵۰، زیربنا ۸۷۰۰، طبقات ۷، ۳۱ واحد مسکونی، ۶ تجاری.
۶۵/۶۵ پروژه زیربنا و طبقات دارند — پیش از این هیچکدام منتشر نمیشد.
سئوی سمت سرور (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