- بکاند: ستون role برای admin_users (admin/creator) + author_id برای مقالهها
- نقشگارد روی کل روتر مدیریتی: creator فقط لیست/ساخت/خواندن/ویرایش
پیشنویسهای «خودش» را میبیند؛ بقیهٔ مسیرهای مدیریتی ۴۰۳
- ساخت توسط creator همیشه پیشنویس است و ویرایشش هرگز منتشر نمیشود
(حتی تلاش برای publish در payload نادیده گرفته میشود)
- حذف/ترتیببندی/پیامها/خبرنامه/سایر بخشها برای creator ممنوع
- لاگین نقش را برمیگرداند؛ پنل: AdminBar نویسنده فقط «نوشتن مقاله» +
زبان ویرایش + رمز + خروج دارد؛ دکمههای انتشار/حذف مقاله فقط برای admin
- ورود creator مستقیم به صفحهٔ نوشتن مقاله هدایت میشود
- Alt/Title تصویر شاخص اکنون ذخیره میشود (ستونهای جدید image_alt/image_title — قبلاً بیصدا دور ریخته میشد)
- Alt و Title تصاویر داخل متن پس از درج هم قابل ویرایشاند (کنار کپشن)
- نام فایل ذخیرهسازی خوانا: نام دلخواه هنگام درج یا نام خود فایل (بهجای UUID خالی)
- پنل پرسشوپاسخ پایان مقاله (ستونهای faqs/faqs_en) با ظاهر آکاردئونی سایت و اسکیمای FAQPage
- چسباندن از Outline و هر منبع خارجی: تصاویر خودکار دانلود و در Object Storage سایت میزبانی میشوند (endpoint جدید import-image با محافظ SSRF) + دکمه میزبانی مجدد روی تصاویر خارجی موجود
- مقالهها ستون 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 سرگردان فرانت
- body مقاله از لیست پاراگراف به سند ProseMirror تغییر کرد:
{"type": "doc", "content": [...]} — در In/Out/Patch schemas
- اعتبارسنجی ساختاری (type=doc + content لیست) با field_validator —
امنیت رندر بر عهده رندر استاتیک TipTap در فرانتاند است
- app/migrations.py: مهاجرتهای DDL و داده در یکجا؛ migrate_article_bodies
ردیفهای قدیمی (لیست پاراگراف) را idempotent به سند تبدیل میکند —
در startup و seed اجرا میشود، دیتابیس موجود بدون از دست رفتن داده ارتقا مییابد
- seed بدنههای لیستی را قبل از درج به سند تبدیل میکند
- README بکاند: فرمت بدنه و رفتار مهاجرت مستند شد