feat: publication IA (magazine/brief/essay) + fixes critique
Some checks failed
CI / Lint, Unit Tests & Build (push) Failing after 1m22s
CI / Deploy production (on server) (push) Has been skipped

Publication IA:
- 4 templates (magazine, brief, essay, simple) avec CSS riche
- Rewrite IA (article/exercises/tutorial/reference/mixed)
- Modération avec timeout 12s + fallback safe
- Quotas publish_enhance par tier (basic=2, pro=15, business=100)
- Détection contenu stale (hash)
- Migration DB publishedContent/publishedTemplate/publishedSourceHash

Fixes:
- cheerio v1.2: Element -> AnyNode (domhandler), decodeEntities cast
- _isShared ajouté au type Note (champ virtuel serveur)
- callout colors PDF export: extraction fonction pure testable
- admin/published: guard note.userId null
- Cmd+S fonctionne en mode dialog (pas seulement fullPage)

i18n:
- 23 clés publish* traduites dans les 15 locales
- Extension Web Clipper: 13 locales mise à jour

Tests:
- callout-colors.test.ts (6 tests)
- note-visible-in-view.test.ts (5 tests)
- entitlements.test.ts + byok-entitlements.test.ts: mock usageLog + unstubAllEnvs
- 199/199 tests passent

Tracker: user-stories.md sync avec sprint-status.yaml
This commit is contained in:
Antigravity
2026-06-28 07:32:57 +00:00
parent 902fe95a69
commit 96e7902f01
169 changed files with 5382 additions and 1527 deletions

View File

@@ -575,7 +575,7 @@
"noNoteId": "No note ID"
},
"openAssistant": "باز کردن دستیار هوش مصنوعی",
"poweredByMomento": "پشتیبانی شده توسط Momento AI",
"poweredByMomento": "پشتیبانی شده توسط Memento AI",
"welcomeMsg": "سلام! من دستیار هوش مصنوعی شما هستم. امروز چطور می‌توانم با یادداشت‌هایتان کمکتان کنم؟ می‌توانم لحن را بهبود دهم، پیام‌ها را بسط دهم یا محتوا را خلاصه کنم.",
"summaryLast5": "خلاصه ۵ یادداشت آخر",
"analyzingProgress": "در حال تحلیل...",
@@ -2219,7 +2219,30 @@
"importMarkdown": "وارد کردن Markdown",
"markdownExportSuccess": "یادداشت به فرمت Markdown صادر شد",
"markdownExportError": "خطا در صدور یادداشت",
"markdownImportSuccess": "Markdown با موفقیت وارد شد"
"markdownImportSuccess": "Markdown با موفقیت وارد شد",
"publishTitle": "انتشار عمومی",
"publishDesc": "این یادداشت را در یک URL عمومی منتشر کنید. هر کسی که پیوند را داشته باشد می‌تواند آن را بخواند.",
"publish": "انتشار",
"publishSuccess": "یادداشت منتشر شد!",
"publishLive": "برخط",
"unpublish": "لغو انتشار",
"unpublishSuccess": "یادداشت از انتشار خارج شد",
"publishBlocked": "انتشار رد شد",
"publishSimple": "انتشار به صورت موجود",
"publishSimpleHint": "رایگان — محتوای یادداشت شما همان‌گونه که هست",
"publishWithAi": "انتشار با هوش مصنوعی",
"publishWithAiHint": "چیدمان بهبودیافته · {count} اعتبار باقی‌مانده",
"publishWithAiLocked": "در طرح Pro موجود است",
"publishWithAiGenerating": "در حال تولید چیدمان…",
"publishTemplateMagazine": "مقاله مجله‌ای",
"publishTemplateBrief": "گزارش تخصصی",
"publishTemplateEssay": "انشا",
"publishAiSuccess": "صفحه بهبودیافته با هوش مصنوعی منتشر شد!",
"publishRewriteLabel": "بازنویسی برای وب",
"publishRewriteOnHint": "بلوک‌های ویرایشگر شما (تمرین‌ها، بخش‌های بازشونده، کادرهای اطلاع‌رسانی) را برای وب ساختاربندی می‌کند — هوش مصنوعی فقط مقدمه را می‌نویسد",
"publishRewriteOffHint": "متن اصلی شما حفظ می‌شود؛ هوش مصنوعی فقط قاب ویرایشی اضافه می‌کند",
"copyPublicLink": "کپی پیوند",
"openPublicPage": "باز کردن صفحه عمومی"
},
"brainstorm": {
"title": "Waves of Thought",
@@ -2743,14 +2766,14 @@
"necessaryDesc": "These cookies are required to authenticate your session, save your language and theme preferences. They cannot be turned off.",
"alwaysOn": "Always On",
"analyticsTitle": "Anonymous Analytics",
"analyticsDesc": "Help us improve Momento by sending completely anonymous usage statistics. No personal data is ever tracked.",
"analyticsDesc": "Help us improve Memento by sending completely anonymous usage statistics. No personal data is ever tracked.",
"cancel": "Cancel",
"save": "Save Preferences",
"saved": "Preferences updated successfully."
},
"ai": {
"modalTitle": "رضایت برای پردازش هوش مصنوعی لازم است",
"modalDescription": "برای تحلیل یادداشت‌ها، PDF یا جلسات طوفان فکری، Momento این داده‌ها را به‌صورت امن به APIهای هوش مصنوعی شخص ثالث (OpenAI، Gemini، DeepSeek) ارسال می‌کند. سیاست سختگیرانه عدم نگهداری داده را اعمال می‌کنیم. با پذیرش، این پردازش را مجاز می‌کنید.",
"modalDescription": "برای تحلیل یادداشت‌ها، PDF یا جلسات طوفان فکری، Memento این داده‌ها را به‌صورت امن به APIهای هوش مصنوعی شخص ثالث (OpenAI، Gemini، DeepSeek) ارسال می‌کند. سیاست سختگیرانه عدم نگهداری داده را اعمال می‌کنیم. با پذیرش، این پردازش را مجاز می‌کنید.",
"zeroRetentionTitle": "عدم نگهداری داده",
"zeroRetentionDesc": "همه درخواست‌های خروجی شامل پرچم‌های ممنوعیت آموزش مدل برای حفاظت از مالکیت فکری شما هستند.",
"rememberMe": "انتخاب من را به خاطر بسپار (دیگر نپرس)",
@@ -2764,10 +2787,10 @@
"statusActive": "فعال",
"statusInactive": "داده نشده",
"helpAriaLabel": "رضایت هوش مصنوعی یعنی چه؟",
"helpTooltip": "Momento داده‌های شما را نمی‌فروشد. این رضایت فقط هنگام اجرای عملیات هوش مصنوعی (عنوان، برچسب، چت، بازنویسی) اعمال می‌شود. بدون آن، بقیه برنامه عادی کار می‌کند.",
"helpTooltip": "Memento داده‌های شما را نمی‌فروشد. این رضایت فقط هنگام اجرای عملیات هوش مصنوعی (عنوان، برچسب، چت، بازنویسی) اعمال می‌شود. بدون آن، بقیه برنامه عادی کار می‌کند.",
"whatItMeansTitle": "این یعنی چه؟",
"inactiveHint": "بدون رضایت، فقط قابلیت‌های هوش مصنوعی غیرفعال می‌شوند. ایجاد، ویرایش و سازماندهی یادداشت‌ها مثل همیشه ممکن است.",
"noCommercialUse": "Momento داده‌های شخصی شما را نمی‌فروشد و از آن درآمدزایی نمی‌کند.",
"noCommercialUse": "Memento داده‌های شخصی شما را نمی‌فروشد و از آن درآمدزایی نمی‌کند.",
"affectedFeatures": "قابلیت‌های مرتبط: پیشنهاد عنوان، برچسب‌ها، چت دستیار، بازنویسی، Memory Echo و غیره.",
"dataPortabilityHint": "می‌توانید هر زمان همه داده‌ها را صادر یا حذف کنید (تنظیمات → داده‌ها).",
"dataPortabilityLink": "صدور داده‌های من",
@@ -2821,7 +2844,7 @@
},
"onboarding": {
"welcome_title": "حافظه شما با هوش مصنوعی",
"welcome_subtitle": "Momento آنچه فراموش می‌کنید را به یاد می‌آورد.",
"welcome_subtitle": "Memento آنچه فراموش می‌کنید را به یاد می‌آورد.",
"welcome_cta": "شروع",
"skip": "رد کردن",
"step_notes_title": "یادداشت‌های شما",
@@ -2833,7 +2856,7 @@
"step_aha_title": "چیزی که فراموش کرده‌اید را پیدا کنید",
"step_aha_subtitle": "سوال بپرسید. یادداشت فراموش شده را پیدا کنید.",
"step_aha_placeholder": "یادداشت‌های بهره‌وری...",
"step_aha_cta": "کشف Momento",
"step_aha_cta": "کشف Memento",
"progress": "{current} از {total}",
"creating_demo_notes": "در حال ایجاد یادداشت‌های نمونه...",
"demo_notes_ready": "۵ یادداشت نمونه ایجاد شد!",
@@ -2937,4 +2960,4 @@
"copyRefNoNote": "Save the note before copying a block reference",
"copyRefUnsupported": "This block type cannot be referenced yet"
}
}
}