chore: همگام‌سازی وضعیت زندهٔ سرور با مخزن
CI / tests (push) Waiting to run
CI / images (push) Blocked by required conditions

شامل کارهای چند نشست موازی که تا این‌جا فقط روی سرور بود:
- نقشهٔ دفتر مرکزی در فوتر (LazyOfficeMap) + MapViewport/LazyMaps/mapProjects
- صفحهٔ مدیریت مقالات (AdminArticlesPage) + میان‌بر ویرایش پیش‌نویس در وبلاگ
- مهاجرت ۰۰۰۴: updated_at مقالات/پروژه‌ها
- chatbot/Dockerfile: نصب دومرحله‌ای torch (کاربردی برای PyPI فیلترشده)
- seed: خالی‌کردن آمارهای دموی story
- docker-compose: اصلاح پسوند @file میان‌افزارهای Traefik
- حذف فایل موقت frontend/.tmp-style.json و اصلاحات جزئی UI

با این کامیت، آن‌چه روی سرور اجرا می‌شود Exactly همان چیزی است که در مخزن ثبت شده.
This commit is contained in:
aramesh-site deploy
2026-10-26 12:28:28 +00:00
parent 884902e054
commit 14660586c4
23 changed files with 488 additions and 2137 deletions
+7 -4
View File
@@ -322,10 +322,13 @@ STORY = {
],
"quote": "«ساختمان برای ما فقط آجر و بتن نیست؛ بلکه تعهدی است به کیفیت زندگی ساکنان. ما فضاهایی می‌سازیم که در گذر زمان ارزش و هویت خود را حفظ کنند.»",
"quote_author": "کامران آرامش — مدیرعامل شرکت ساختمانی آرامش",
"stat1_value": "۹۴٪",
"stat1_label": "تحویل به‌موقع پروژه‌ها",
"stat2_value": "۵ سال",
"stat2_label": "پشتیبانی پس از تحویل",
# آمارهای دموی «۹۴٪ تحویل به‌موقع» و «۵ سال پشتیبانی» خالی شدند — ادعای
# بدون پشتوانه بودند و در سایت واقعی هم پاک شده‌اند؛ این‌جا هم خالی می‌مانند
# تا اگر روزی جدول story خالی شود، seed آن‌ها را برنگرداند
"stat1_value": "",
"stat1_label": "",
"stat2_value": "",
"stat2_label": "",
"link_label": "داستان کامل ما",
"link_href": "/about",
"bento": [
+11 -8
View File
@@ -396,14 +396,17 @@ STORY = {
"quote_en": "\u201cA building, for us, is not just brick and concrete; it is a commitment to the quality of life of its residents. We build spaces that keep their value and identity as time passes.\u201d",
"quote_author": "کامران آرامش — مدیرعامل شرکت ساختمانی آرامش",
"quote_author_en": "Kamran Aramesh — CEO, Aramesh Construction Group",
"stat1_value": "۹۴٪",
"stat1_value_en": "94%",
"stat1_label": "تحویل به‌موقع پروژه‌ها",
"stat1_label_en": "On-time project delivery",
"stat2_value": "۵ سال",
"stat2_value_en": "5 years",
"stat2_label": "پشتیبانی پس از تحویل",
"stat2_label_en": "Post-handover support",
# Demo stats «94% on-time» / «5 years support» emptied — unsupported claims,
# removed from the live site too; kept empty here so a future reseed of an
# empty story table cannot bring them back
"stat1_value": "",
"stat1_value_en": "",
"stat1_label": "",
"stat1_label_en": "",
"stat2_value": "",
"stat2_value_en": "",
"stat2_label": "",
"stat2_label_en": "",
"link_label": "داستان کامل ما",
"link_label_en": "Our full story",
"bento": [],
@@ -0,0 +1,39 @@
"""زمان آخرین به‌روزرسانی مقاله‌ها و پروژه‌ها — ستون updated_at برای lastmod نقشه سایت.
نقشه سایت lastmod معتبر لازم دارد که آخرین تغییر معنادار محتوا را نشان دهد؛
تاریخ نمایشی مقاله‌ها (شمسی دست‌نویس) برای این کار مناسب نیست. ردیف‌های قدیمی
NULL می‌مانند و lastmod فقط برای ردیف‌هایی صادر می‌شود که بعداً در پنل ذخیره شده‌اند —
تاریخ جعلی همگن (همه = امروز) به‌عنوان سیگنال منفی شناخته می‌شود.
Revision ID: 0004
Revises: 0003
Create Date: 2026-10-11
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
revision: str = "0004"
down_revision: Union[str, None] = "0003"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
_TABLES = ("articles", "projects")
def upgrade() -> None:
for table in _TABLES:
cols = {c["name"] for c in sa.inspect(op.get_bind()).get_columns(table)}
if "updated_at" not in cols:
op.add_column(
table,
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=True),
)
def downgrade() -> None:
for table in _TABLES:
cols = {c["name"] for c in sa.inspect(op.get_bind()).get_columns(table)}
if "updated_at" in cols:
op.drop_column(table, "updated_at")