perf+security: fix build, secure downloads, dedupe translations, refactor i18n
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m49s
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).
This commit is contained in:
151
frontend/src/lib/i18n/messages/it/pricing.json
Normal file
151
frontend/src/lib/i18n/messages/it/pricing.json
Normal file
@@ -0,0 +1,151 @@
|
||||
{
|
||||
"pricing.nav.back": "Indietro",
|
||||
"pricing.nav.home": "Home",
|
||||
"pricing.nav.mySubscription": "Il mio abbonamento",
|
||||
"pricing.header.badge": "Modelli IA aggiornati — Marzo 2026",
|
||||
"pricing.header.title": "Un piano per ogni esigenza",
|
||||
"pricing.header.subtitle": "Traduci i tuoi documenti Word, Excel e PowerPoint mantenendo la formattazione originale. Nessuna chiave API richiesta.",
|
||||
"pricing.billing.monthly": "Mensile",
|
||||
"pricing.billing.yearly": "Annuale",
|
||||
"pricing.plans.free.name": "Gratuito",
|
||||
"pricing.plans.starter.name": "Starter",
|
||||
"pricing.plans.pro.name": "Pro",
|
||||
"pricing.plans.business.name": "Business",
|
||||
"pricing.plans.enterprise.name": "Enterprise",
|
||||
"pricing.plans.free.description": "Perfetto per scoprire l'app",
|
||||
"pricing.plans.starter.description": "Per privati e piccoli progetti",
|
||||
"pricing.plans.pro.description": "Per professionisti e team in crescita",
|
||||
"pricing.plans.business.description": "Per team e organizzazioni",
|
||||
"pricing.plans.enterprise.description": "Soluzioni personalizzate per grandi organizzazioni",
|
||||
"pricing.plans.pro.highlight": "Il più popolare",
|
||||
"pricing.plans.pro.badge": "POPOLARE",
|
||||
"pricing.plans.enterprise.badge": "SU RICHIESTA",
|
||||
"pricing.plans.free.feat1": "5 documenti / mese",
|
||||
"pricing.plans.free.feat2": "Fino a 15 pagine per documento",
|
||||
"pricing.plans.free.feat3": "Google Traduttore incluso",
|
||||
"pricing.plans.free.feat4": "Tutte le lingue (130+)",
|
||||
"pricing.plans.free.feat5": "Supporto della community",
|
||||
"pricing.plans.starter.feat1": "50 documenti / mese",
|
||||
"pricing.plans.starter.feat2": "Fino a 50 pagine per documento",
|
||||
"pricing.plans.starter.feat3": "Google Traduttore + DeepL",
|
||||
"pricing.plans.starter.feat4": "File fino a 10 MB",
|
||||
"pricing.plans.starter.feat5": "Supporto via e-mail",
|
||||
"pricing.plans.starter.feat6": "Cronologia di 30 giorni",
|
||||
"pricing.plans.pro.feat1": "200 documenti / mese",
|
||||
"pricing.plans.pro.feat2": "Fino a 200 pagine per documento",
|
||||
"pricing.plans.pro.feat3": "Traduzione IA Essenziale",
|
||||
"pricing.plans.pro.feat4": "Google Traduttore + DeepL",
|
||||
"pricing.plans.pro.feat5": "File fino a 25 MB",
|
||||
"pricing.plans.pro.feat6": "Glossari personalizzati",
|
||||
"pricing.plans.pro.feat7": "Supporto prioritario",
|
||||
"pricing.plans.pro.feat8": "Cronologia di 90 giorni",
|
||||
"pricing.plans.business.feat1": "1 000 documenti / mese",
|
||||
"pricing.plans.business.feat2": "Fino a 500 pagine per documento",
|
||||
"pricing.plans.business.feat3": "IA Essenziale + Premium (Claude Haiku)",
|
||||
"pricing.plans.business.feat4": "Tutti i provider di traduzione",
|
||||
"pricing.plans.business.feat5": "File fino a 50 MB",
|
||||
"pricing.plans.business.feat6": "Accesso API (10 000 chiamate/mese)",
|
||||
"pricing.plans.business.feat7": "Webhook di notifica",
|
||||
"pricing.plans.business.feat8": "Supporto dedicato",
|
||||
"pricing.plans.business.feat9": "Cronologia di 1 anno",
|
||||
"pricing.plans.business.feat10": "Analisi avanzate",
|
||||
"pricing.plans.enterprise.feat1": "Documenti illimitati",
|
||||
"pricing.plans.enterprise.feat2": "Tutti i modelli IA (GPT-5, Claude Opus 4.6…)",
|
||||
"pricing.plans.enterprise.feat3": "Distribuzione on-premise o cloud dedicato",
|
||||
"pricing.plans.enterprise.feat4": "SLA 99,9 % garantito",
|
||||
"pricing.plans.enterprise.feat5": "Supporto dedicato 24/7",
|
||||
"pricing.plans.enterprise.feat6": "White-label",
|
||||
"pricing.plans.enterprise.feat7": "Team illimitati",
|
||||
"pricing.plans.enterprise.feat8": "Integrazioni personalizzate",
|
||||
"pricing.card.onRequest": "Su richiesta",
|
||||
"pricing.card.free": "Gratuito",
|
||||
"pricing.card.perMonth": "/mese",
|
||||
"pricing.card.billedYearly": "Fatturato {price} € / anno",
|
||||
"pricing.card.documents": "Documenti",
|
||||
"pricing.card.pagesMax": "Pagine max",
|
||||
"pricing.card.aiTranslation": "Traduzione IA",
|
||||
"pricing.card.unlimited": "Illimitato",
|
||||
"pricing.card.perMonthStat": "/ mese",
|
||||
"pricing.card.perDoc": "p / doc",
|
||||
"pricing.card.aiEssential": "Essenziale",
|
||||
"pricing.card.aiEssentialPremium": "Essenziale + Premium",
|
||||
"pricing.card.aiCustom": "Personalizzato",
|
||||
"pricing.card.myPlan": "Il mio piano",
|
||||
"pricing.card.managePlan": "Gestisci il mio piano",
|
||||
"pricing.card.startFree": "Inizia gratuitamente",
|
||||
"pricing.card.contactUs": "Contattaci",
|
||||
"pricing.card.choosePlan": "Scegli questo piano",
|
||||
"pricing.card.processing": "Elaborazione…",
|
||||
"pricing.comparison.title": "Confronto dettagliato",
|
||||
"pricing.comparison.subtitle": "Tutto ciò che include ogni piano",
|
||||
"pricing.comparison.feature": "Funzionalità",
|
||||
"pricing.comparison.docsPerMonth": "Documenti / mese",
|
||||
"pricing.comparison.pagesMaxPerDoc": "Pagine max / documento",
|
||||
"pricing.comparison.maxFileSize": "Dimensione max file",
|
||||
"pricing.comparison.googleTranslation": "Google Traduttore",
|
||||
"pricing.comparison.deepl": "DeepL",
|
||||
"pricing.comparison.aiEssential": "Traduzione IA Essenziale",
|
||||
"pricing.comparison.aiPremium": "Traduzione IA Premium",
|
||||
"pricing.comparison.apiAccess": "Accesso API",
|
||||
"pricing.comparison.priorityProcessing": "Elaborazione prioritaria",
|
||||
"pricing.comparison.support": "Supporto",
|
||||
"pricing.comparison.support.community": "Community",
|
||||
"pricing.comparison.support.email": "E-mail",
|
||||
"pricing.comparison.support.priority": "Prioritario",
|
||||
"pricing.comparison.support.dedicated": "Dedicato",
|
||||
"pricing.comparison.mb": "MB",
|
||||
"pricing.credits.title": "Crediti aggiuntivi",
|
||||
"pricing.credits.subtitle": "Ne serve di più? Acquista crediti singoli, senza abbonamento.",
|
||||
"pricing.credits.perPage": "1 credito = 1 pagina tradotta.",
|
||||
"pricing.credits.bestValue": "Miglior rapporto qualità-prezzo",
|
||||
"pricing.credits.unit": "crediti",
|
||||
"pricing.credits.centsPerCredit": "cts / credito",
|
||||
"pricing.credits.buy": "Acquista",
|
||||
"pricing.trust.encryption.title": "Crittografia end-to-end",
|
||||
"pricing.trust.encryption.sub": "TLS 1.3 + AES-256 a riposo",
|
||||
"pricing.trust.languages.title": "130+ lingue",
|
||||
"pricing.trust.languages.sub": "Tra cui arabo, persiano, ebraico (RTL)",
|
||||
"pricing.trust.parallel.title": "Elaborazione parallela",
|
||||
"pricing.trust.parallel.sub": "IA multi-thread ultraveloce",
|
||||
"pricing.trust.availability.title": "Disponibile 24/7",
|
||||
"pricing.trust.availability.sub": "99,9 % di uptime garantito",
|
||||
"pricing.aiModels.title": "I nostri modelli IA — Marzo 2026",
|
||||
"pricing.aiModels.essential.title": "Traduzione IA Essenziale",
|
||||
"pricing.aiModels.essential.plan": "Piano Pro",
|
||||
"pricing.aiModels.essential.descPrefix": "Basato su",
|
||||
"pricing.aiModels.essential.descSuffix": "— il modello IA più conveniente del 2026. Qualità paragonabile ai modelli frontier a una frazione del costo.",
|
||||
"pricing.aiModels.essential.modelName": "il nostro modello IA Essenziale",
|
||||
"pricing.aiModels.essential.context": "163K token di contesto",
|
||||
"pricing.aiModels.essential.value": "Eccellente rapporto qualità-prezzo",
|
||||
"pricing.aiModels.premium.title": "Traduzione IA Premium",
|
||||
"pricing.aiModels.premium.plan": "Piano Business",
|
||||
"pricing.aiModels.premium.descPrefix": "Basato su",
|
||||
"pricing.aiModels.premium.descSuffix": "di Anthropic — preciso su documenti legali, medici e tecnici complessi.",
|
||||
"pricing.aiModels.premium.context": "200K token di contesto",
|
||||
"pricing.aiModels.premium.precision": "Massima precisione",
|
||||
"pricing.faq.title": "Domande frequenti",
|
||||
"pricing.faq.q1": "Posso cambiare piano in qualsiasi momento?",
|
||||
"pricing.faq.a1": "Sì. Il passaggio a un piano superiore è immediato e proporzionale. Il downgrade sarà attivo alla fine del periodo corrente.",
|
||||
"pricing.faq.q2": "Cos'è la «Traduzione IA Essenziale»?",
|
||||
"pricing.faq.a2": "È il nostro motore IA. Comprende il contesto dei vostri documenti, preserva il layout e gestisce i termini tecnici molto meglio della traduzione classica.",
|
||||
"pricing.faq.q3": "Qual è la differenza tra IA Essenziale e IA Premium?",
|
||||
"pricing.faq.a3": "La IA Essenziale usa un modello ottimizzato (eccellente rapporto qualità/prezzo). La IA Premium usa Claude 3.5 Haiku di Anthropic, più precisa su documenti legali, medici e tecnici complessi.",
|
||||
"pricing.faq.q4": "I miei documenti vengono conservati dopo la traduzione?",
|
||||
"pricing.faq.a4": "I file tradotti sono disponibili secondo il tuo piano (30 giorni Starter, 90 giorni Pro, 1 anno Business). Sono crittografati a riposo e in transito.",
|
||||
"pricing.faq.q5": "Cosa succede se supero la quota mensile?",
|
||||
"pricing.faq.a5": "Puoi acquistare crediti aggiuntivi singolarmente o fare upgrade del piano. Riceverai una notifica al raggiungimento dell'80 % di utilizzo.",
|
||||
"pricing.faq.q6": "C'è un periodo di prova gratuito per i piani a pagamento?",
|
||||
"pricing.faq.a6": "Il piano Gratuito è permanente e non richiede carta di credito. Per i piani Pro e Business, contattaci per una prova di 14 giorni.",
|
||||
"pricing.faq.q7": "Quali formati di file sono supportati?",
|
||||
"pricing.faq.a7": "Word (.docx), Excel (.xlsx/.xls), PowerPoint (.pptx) e presto PDF. Tutti i piani supportano gli stessi formati.",
|
||||
"pricing.cta.title": "Pronto per iniziare?",
|
||||
"pricing.cta.subtitle": "Inizia gratuitamente, senza carta di credito. Fai upgrade quando ne hai bisogno.",
|
||||
"pricing.cta.createAccount": "Crea un account gratuito",
|
||||
"pricing.cta.login": "Accedi",
|
||||
"pricing.toast.demo": "Modalità demo — Stripe non è ancora configurato. In produzione, saresti reindirizzato al pagamento per attivare il piano {planId}.",
|
||||
"pricing.toast.networkError": "Errore di rete. Riprova.",
|
||||
"pricing.toast.paymentError": "Errore durante la creazione del pagamento.",
|
||||
"pricing.dashboard": "Dashboard",
|
||||
"pricing.okSymbol": "✓",
|
||||
"pricing.errSymbol": "✕"
|
||||
}
|
||||
Reference in New Issue
Block a user