All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m49s
Frontend:
- Fix Framer Motion / motion-dom build error by pinning framer-motion to
11.18.2 (compatible with React 19 and Next.js 16).
- Add cross-env and build:local script to bypass standalone symlink errors
on Windows without Developer Mode.
- Allow NEXT_OUTPUT=default to disable standalone output for local builds.
- Refactor i18n: split 14,177-line src/lib/i18n.tsx into per-locale,
per-namespace JSON files under src/lib/i18n/messages/.
- Load English synchronously; other locales loaded on demand via dynamic
imports (reduces initial bundle, improves maintainability).
- Remove unused next-intl message files src/messages/en.json and fr.json.
Backend:
- Remove insecure legacy /api/v1/download/{filename} and /api/v1/cleanup/{filename}
endpoints. The job-based /api/v1/download/{job_id} already enforces ownership.
- Deduplicate texts in TranslationService.translate_batch before sending them
to the provider, reducing API calls for repeated strings.
- Pin httpx to <0.28 to fix TestClient incompatibility with starlette 0.35.1.
- Add pytest-cov and ruff dev dependencies/config.
DevOps:
- Remove hardcoded Grafana password from docker-compose.yml and
docker-compose.monitoring.yml; use GRAFANA_PASSWORD env var.
- Change default TRANSLATION_SERVICE from ollama to google in
docker-compose.yml (Ollama is an optional profile).
- Add GRAFANA_PASSWORD to .env.example.
- Add .coverage and frontend/pnpm-workspace.yaml to .gitignore.
Tests:
- Update API versioning tests for removed legacy endpoints.
- Add tests/test_translation_service.py for deduplication behavior.
Verified:
- pnpm run build:local passes.
- uv run pytest tests/test_providers/* tests/test_translation_service.py
tests/test_story_3_5_api_versioning.py tests/test_download_endpoint.py
tests/test_translators/test_excel_translator.py: provider/translator tests
pass; one pre-existing French error-message test still fails (message is
returned in English, unrelated to this change).
59 lines
3.7 KiB
JSON
59 lines
3.7 KiB
JSON
{
|
|
"profile.header.title": "ملفي الشخصي",
|
|
"profile.header.subtitle": "إدارة حسابك وتفضيلاتك.",
|
|
"profile.tabs.account": "الحساب",
|
|
"profile.tabs.subscription": "الاشتراك",
|
|
"profile.tabs.preferences": "التفضيلات",
|
|
"profile.account.user": "المستخدم",
|
|
"profile.account.memberSince": "عضو منذ",
|
|
"profile.plan.label": "الخطة",
|
|
"profile.plan.free": "Free",
|
|
"profile.plan.starter": "Starter",
|
|
"profile.plan.pro": "Pro",
|
|
"profile.plan.business": "Business",
|
|
"profile.plan.enterprise": "Enterprise",
|
|
"profile.plan.pricePerMonth": "{price} €/شهر",
|
|
"profile.subscription.canceling": "جارٍ الإلغاء",
|
|
"profile.subscription.active": "نشط",
|
|
"profile.subscription.unknown": "غير معروف",
|
|
"profile.subscription.accessUntil": "الوصول حتى",
|
|
"profile.subscription.renewalOn": "التجديد في",
|
|
"profile.subscription.upgradePlan": "الترقية إلى خطة مدفوعة",
|
|
"profile.subscription.changePlan": "تغيير الخطة",
|
|
"profile.subscription.manageBilling": "إدارة الفوترة",
|
|
"profile.subscription.billingUnavailable": "بوابة الفوترة غير متاحة.",
|
|
"profile.subscription.billingError": "خطأ في الوصول إلى بوابة الفوترة.",
|
|
"profile.subscription.cancelSuccess": "تم إلغاء الاشتراك. تحتفظ بالوصول حتى نهاية الفترة.",
|
|
"profile.subscription.cancelError": "حدث خطأ أثناء الإلغاء.",
|
|
"profile.subscription.networkError": "خطأ في الشبكة.",
|
|
"profile.usage.title": "الاستخدام هذا الشهر",
|
|
"profile.usage.resetOn": "إعادة التعيين في",
|
|
"profile.usage.documents": "المستندات",
|
|
"profile.usage.pages": "الصفحات",
|
|
"profile.usage.extraCredits": "رصيد إضافي",
|
|
"profile.usage.extraCreditsPlural": "أرصدة إضافية",
|
|
"profile.usage.quotaReached": "تم بلوغ الحصة",
|
|
"profile.usage.quotaReachedDesc": "قم بالترقية إلى خطة أعلى للمتابعة.",
|
|
"profile.usage.unlockMore": "احصل على المزيد من الترجمات مع خطة مدفوعة.",
|
|
"profile.usage.viewPlans": "عرض الخطط",
|
|
"profile.usage.includedInPlan": "مضمن في خطتك",
|
|
"profile.danger.title": "منطقة الخطر",
|
|
"profile.danger.description": "يتم تطبيق الإلغاء في نهاية الفترة الحالية. تحتفظ بالوصول حتى ذلك التاريخ.",
|
|
"profile.danger.confirm": "هل أنت متأكد؟ لا يمكن التراجع عن هذا الإجراء.",
|
|
"profile.danger.confirmCancel": "تأكيد الإلغاء",
|
|
"profile.danger.cancelSubscription": "إلغاء اشتراكي",
|
|
"profile.danger.keep": "لا، إبقاء",
|
|
"profile.prefs.interfaceLang": "لغة الواجهة",
|
|
"profile.prefs.interfaceLangDesc": "يتم اكتشاف اللغة تلقائيًا بناءً على متصفحك. يمكنك تغييرها يدويًا.",
|
|
"profile.prefs.defaultTargetLang": "اللغة الهدف الافتراضية",
|
|
"profile.prefs.selectLanguage": "اختر لغة",
|
|
"profile.prefs.defaultTargetLangDesc": "سيتم تحديد هذه اللغة مسبقًا لترجماتك.",
|
|
"profile.prefs.save": "حفظ",
|
|
"profile.prefs.theme": "المظهر",
|
|
"profile.prefs.themeDesc": "اختر مظهر الواجهة",
|
|
"profile.prefs.cache": "ذاكرة التخزين المؤقت",
|
|
"profile.prefs.cacheDesc": "مسح ذاكرة التخزين المؤقت المحلية قد يحل بعض مشاكل العرض.",
|
|
"profile.prefs.clearing": "جارٍ المسح...",
|
|
"profile.prefs.clearCache": "مسح ذاكرة التخزين المؤقت"
|
|
}
|