Files
office_translator/docs/marketing/PLAN-ALIGNEMENT-CODE.md
sepehr 526c87348f
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m20s
feat(translation): quality pipeline overhaul + new features (audit 2026-08-29)
Translation quality & format preservation:
- Word: merge adjacent same-format runs into one unit (sentence-level
  coherence like inline-tag handling); translate comments/balloons;
  dedupe textbox collection (was translated twice); RTL no longer
  overrides center/justify alignment; CJK/Arabic font hints (eastAsia/cs)
- PPTX: chart translations now actually reach the output file
  (ChartPart.blob is read-only — rewrite chart XML in the saved ZIP);
  CJK typeface hints (a:ea)
- Excel: sheet renames no longer break references — rewrite cell
  formulas (3D/quoted), defined names, data validations, cond. formats
- PDF: bold/italic honored (hebo/heit/hebi); table cells never merge;
  unchanged blocks left untouched (typography preserved, fixes duplicate
  hyperlinks); attempted/changed stats + route gate now cover PDF;
  CJK font paths; scanned PDFs via Mistral OCR (detection + admin settings)

Features:
- formality param (formal/informal) + automatic regional-variant prompts
- output_mode=bilingual docx (source above translation)
- per-user translation memory on Redis (falls back to LRU), context-hashed
- QA report + 0-100 confidence score in job status; L0 on by default
- OpenAI-compatible providers: whole chunk in ONE numbered-JSON request
  (~15x fewer calls) with per-item fallback; base prompt always present
  (custom prompt no longer replaces translation instructions)

Infra & marketing alignment:
- plan-based engine gating + vision gating (closes paid-engine leak);
  /providers/available filtered per plan; 107 languages exposed
- zh-CN/zh-TW validation fixed; libmagic disabled on Windows (native crash)
- admin: Mistral OCR settings + engine status dashboard; httpx<0.28 pin
  (TestClient breakage); Prometheus test fixture fixed
- marketing docs aligned with code (PDF+OCR, retention, engines, pricing)
- security: .env.ionos/.env.production/provider_settings.json removed

Tests: 1173 passed / 0 failed (6 network tests deselected: free Google
endpoint temporarily blocked from this machine)
2026-08-29 18:38:09 +02:00

9.5 KiB
Raw Blame History

Plan d'alignement Marketing ↔ Code — wordly.art

Analyse effectuée le 2026-08-29, croisée ligne à ligne avec le code backend, la landing et les docs de lancement. Principe : le lancement (Product Hunt / Show HN) attire des relecteurs techniques — chaque promesse non tenue y sera testée publiquement. Ce plan sépare ce qu'il faut corriger dans les textes (rapide) de ce qu'il faut corriger dans le code (pour tenir les promesses).

Statut au 2026-08-29 : vagues A et B appliquées et testées (442 tests backend passent, tsc --noEmit landing OK). Restent les items P2 de la vague C.


1. Ce qui est déjà conforme

Affirmation marketing Vérification code Statut
Prix 0/9/19/49 €, annuel 20 % (7,20/15,20/39,20) models/subscription.py:39-155 (86,40/182,40/470,40 €/an) exact
Quotas 2/50/200/1 000 docs, pages 10/50/200/500, fichiers 5/10/25/50 Mo idem exact
API Business 10 000 appels/mois, 5 sièges api_calls_per_month: 10_000, team_seats: 5 exact
Crédits 50/5 € · 100/9 € · 250/20 € · 500/35 € · 1 000/60 € (0,060,10 €) CREDIT_PACKAGES (models/subscription.py:316) exact
Landing : sections pricing/FAQ/preuve/waitlist + Vercel Analytics + waitlist endpoint + compteur app/page.tsx, components/*, routes/waitlist_routes.py en place
Événements analytics (translation_started, pricing_cta_click, waitlist_joined, waitlist_error) présents dans les 3 composants branchés
Footer sans « SOC 2 » app/page.tsx — mention absente corrigé
Blog Docker : « CORS * refuse de démarrer en prod » main.py:379-386 (sys.exit) vrai
« DeepL moteur des plans payants » Starter+ : providers: ["google","deepl",…] exact
Blog 1 : « à partir de 0,06 €/page » cohérent avec les crédits (1 page = 1 crédit de base)

2. Écarts détectés — promesses non tenues par le code

E1. 🔴 « PDF is on the roadmap » (Show HN + Product Hunt) — FAUX, et ça cache une feature

  • Show HN : « (PDF is the obvious next one.) » · Product Hunt : « PDF is on the roadmap ».
  • Réel : le PDF est déjà supporté (.pdf dans SUPPORTED_EXTENSIONS, mode layout/text_only, pdf2docx fallback) et depuis le 2026-08-29 les PDF scannés passent par OCR Mistral (services/mistral_ocr.py) — ce que DeepL et Azure refusent.
  • C'est l'inverse : c'est un argument de vente majeur à ajouter. Telle quelle, la phrase invite les relecteurs HN à trouver une fonctionnalité qui existe déjà dans le dashboard.

E2. 🔴 « Files auto-deleted after 60 min » (landing, FAQ, Show HN, PH, Reddit, X, blogs 1/3) — inexact

  • Réel (config.py) : uploads 30 min, résultats 120 min, TTL générique 60.
  • Deux options : corriger le texte (« uploads deleted after 30 min, results within 2 h ») ou passer OUTPUT_FILE_TTL_MINUTES à 60. Recommandation : garder 120 min (l'utilisateur doit pouvoir re-télécharger) et corriger les textes.

E3. 🔴 « Encrypted at rest » (FAQ §sécurité, X-thread, blog 3 §données) — non implémenté

  • Aucun chiffrement des fichiers au repos dans le code (uploads/outputs en clair). TLS : dépend du reverse-proxy (vrai en prod nginx+HSTS).
  • À retirer des textes tant que non implémenté (ou implémenter, cf. §3-C5).

E4. 🟠 « 60+ langues » (landing stats, PH, X-thread) — l'app en expose 35

  • Réel : /api/v1/languages = 35 langues ; le sélecteur UI = 35. (Le validateur accepte ~100 codes, mais invisibles pour l'utilisateur.)
  • Options : (a) corriger le chiffre en « 35 », (b) exposer les ~60-100 langues déjà validées côté API/UI — recommandé, c'est un travail faible et les LLM couvrent ces langues.

E5. 🟠 « 7 moteurs » avec Minimax et DeepSeek cités (FAQ, Show HN) — incohérent avec les plans

  • Réel (models/subscription.py) : Business = google, google_cloud, deepl, openrouter, openrouter_premium, openai, zaini Minimax ni DeepSeek direct (DeepSeek n'est que le modèle IA « essentiel » interne).
  • Harmoniser : retirer Minimax/DeepSeek des listes, ou les ajouter au plan Business (l'endpoint /providers/available les expose déjà à l'UI !).

E6. 🟡 « 100 % formatting preserved » (landing, comparatif, x-thread) — survendu

  • Cas limites réels : PDF scannés (sortie re-mise en page, pas d'« in place »), placeholders [translation overflow] sur débordements, texte dans images non traduit sans l'option vision.
  • Recommandation : garder la promesse forte mais crédible (« formatting preserved — formulas, merges, styles ») + publier une page « limites connues ». Sur HN, un contre-exemple suffira à casser le « 100 % ».

E7. 🟠 Blog Docker (auto-hébergement) : 4 erreurs factuelles

  1. GOOGLE_TRANSLATE_API_KEY=... : cette variable n'existe pas — le moteur Google gratuit n'a pas de clé ; le moteur payant = GOOGLE_CLOUD_API_KEY. Remplacer par un exempilaire réel du .env.example.
  2. pg_dump -U wordly wordly : les défauts du compose sont translate / translate_db.
  3. « L'API sur :8000 » : le compose publie 8001:8000 → c'est :8001 côté hôte.
  4. git clone https://gitea.parsanet.org/... : repo privé → rendre public ou générer (github.com/<org>/office-translator).

E8. 🟠 Le backend n'applique PAS la grille « moteurs par plan » (fuite de revenus)

  • Dans translate_document_v1, seul google_cloud est rétrogradé pour les non-Pro. Un Free peut envoyer provider=openai ou openrouter_premium et consommer les moteurs vendus 49 €/mois. La grille existe pourtant dans PLANS[plan]["providers"].
  • Idem : translate_images (vision) n'est pas gated, alors que la FAQ dit « Pro and Business plans ».

3. Plan d'action

Vague A — Avant lancement (textes, ~½ journée) — P0 APPLIQUÉE

# Action Fichiers Statut
A1 Remplacer « PDF on the roadmap » par la feature : « PDF supported — incl. scanned PDFs via OCR » launch/show-hn.md, launch/product-hunt.md
A2 Corriger la rétention : « uploads deleted after 30 min, results auto-deleted within 2 h » landing social-proof-section.tsx, faq-section.tsx, show-hn.md, product-hunt.md, reddit-posts.md, x-thread.md, blog/1, blog/3, MARKETING_PLAN.md
A3 Supprimer « encrypted at rest » / « at rest » faq-section.tsx, x-thread.md, blog/3
A4 Blog Docker : clé GOOGLE_CLOUD_API_KEY, pg_dump translate/translate_db, port hôte 8001, URL de dépôt générique, + mention MISTRAL_API_KEY blog/5-auto-heberger-traduction-docker.md
A5 Ajouter PDF (+ OCR scannés) aux formats annoncés : hero, badges .pdf, drag & drop + accept PDF, FAQ formats hero-section.tsx, translation-card.tsx, faq-section.tsx

Vague B — Semaine 1 (code, ~2-3 j) — P1 APPLIQUÉE

# Action Détail Statut
B1 Gating moteurs par plan : translate_document_v1 rejette (403 PRO_FEATURE_REQUIRED) tout provider hors PLANS[tier]["providers"] ; helpers testés (tests/test_plan_gating.py) ; /providers/available filtré par plan (l'UI ne propose plus un moteur refusé) ferme la fuite de revenus E8
B2 Gater translate_images aux plans Pro+ la FAQ redevient exacte
B3 Langues : /api/v1/languages expose désormais 107 langues nommées (35 populaires d'abord, puis ordre alphabétique ; LANGUAGE_NAMES complété) → la promesse « 60+ » est tenue E4 résolu par le code
B4 Moteurs harmonisés : Minimax/DeepSeek retirés des listes marketing (DeepSeek présenté « via OpenRouter ») ; cohérent avec le filtrage du catalogue résout E5

Vague C — Avant le scale — P2

# Action Détail
C1 Remplacer « 100 % » par une promesse démontrable + page « limites connues » (PDF scannés re-mis en page, overflow, images) E6
C2 Si l'argument « chiffré au repos » est voulu : chiffrer uploads/+outputs/ (clé env FILES_ENCRYPTION_KEY, chiffrement AES au write/read) alors seulement réintroduire la mention E3
C3 Mettre à jour MARKETING_PLAN.md : ajouter PDF + OCR scannés aux différenciateurs (vs DeepL/Azure qui refusent les scannés), mentionner webhooks & API keys valorise l'existant
C4 Décider TTL outputs : si la promesse « 60 min » est gardée, passer OUTPUT_FILE_TTL_MINUTES=60 au lieu de changer 9 textes alternative à A2
C5 NPS « enquête post-traduction » (source KPI dans MARKETING_PLAN §6) : non implémenté — retirer la ligne ou créer le mini-formulaire post-download KPIs honnêtes

Decision needed (propriétaire) — TRANCHÉES LE 2026-08-29

  • Rétention : textes corrigés (A2) — les TTL code restent 30 min / 120 min.
  • Langues : 107 exposées via /languages (B3) — la promesse « 60+ » est tenue.
  • Minimax/DeepSeek : retirés du discours commercial (DeepSeek mentionné « via OpenRouter ») ; plans inchangés.

4. Résumé

Le socle commercial du document marketing est fiable (prix, quotas, crédits, API, landing, waitlist, analytics : tout correspond au code). Les écarts se concentrent sur 6 chiffres/affirmations répétées (60 min, 60+ langues, 7 moteurs, 100 %, chiffrement au repos, « PDF à venir ») et 2 trous d'application côté code (gating moteurs et vision par plan). Les vagues A (textes) et B (code) suffisent pour un lancement PH/HN sans Vulnerabilité factuelle.