- PowerPoint beneficie du garde-fou de retentative (arabe livre pour du
persan etc.), comme Word, Excel et PDF
- l'interface : la liste des locales RTL renvoie desormais explicitement
a la reference serveur (core/languages.py) pour eviter tout oubli
lors d'un futur ajout de langue d'affichage
Les runs adjacents d'un paragraphe PowerPoint portant le meme style
(empreinte du a:rPr serialise, comme dans le traducteur Word) sont
fusionnes en une seule unite de traduction. Une phrase coupee en
plusieurs segments de meme style est desormais traduite entiere ; la
traduction va dans le premier run, les suivants sont vides (les
elements restent en place). Les sauts de ligne (a:br) et champs (a:fld)
ferment le groupe : jamais de fusion a travers un saut de ligne.
5 tests nouveaux (TestRunMerging).
- Word: sous w:bidi, w:jc est logique (left=dbut=droite visuelle,
right=fin=gauche visuelle) ; forcer jc=right alignait donc les
paragraphes a gauche et crasait le centrage hrit du style.
Dsormais le RTL pose w:bidi et w:rtl sans jamais toucher w:jc,
comme le fait Word lui-mme pour un document RTL.
- PowerPoint: algn n'est plus crit quand le paragraphe n'en dfinit
pas, afin de respecter l'alignement hrit du masque (titres centrs) ;
algn=l explicite reste converti en r (algn est visuel en DrawingML).
- tests: centrage par style Word prserv, aucun w:jic crit, algn
absent non cras côté PowerPoint
- source unique RTL_LANGUAGES/is_rtl dans core/languages.py (fin des 3 copies)
- Word: bidi partout (corps, tableaux bidiVisual, notes/fin/commentaires,
zones de texte, 6 zones d'en-tetes/pieds), insertion OOXML ordonnee,
polices cs elargies aux 11 langues
- PowerPoint: alignements explicites preserves, notes du presentateur,
indice de police <a:cs> insert a sa place
- Excel: feuilles affichees de droite a gauche, feuilles graphiques ignorees
- PDF: faconnage bidi (arabic-reshaper + python-bidi), polices par ecriture
(arabe/hebreu), TTF enregistree pour le PDF recompose
- 46 tests nouveaux (tests/test_translators/test_rtl_layout.py), 253 au total
Foundations:
- TranslationSegment model + migration f7e8d9c0b1a2 (segments, workspaces,
workspace_members, glossaries.workspace_id)
- SegmentRecorder injected into all 4 translators: unique (source,
translation) pairs captured per job and persisted (best-effort)
- set_segment_overrides: human-reviewed translations applied verbatim on
rebuild — top priority over TM and provider, zero API calls
Review API (routes/review_routes.py):
- GET /translations/{id}/segments (owner or job token)
- PATCH /segments/{id} edit/approve — feeds the per-user TM so approved
translations are reused in later jobs
- POST /translations/{id}/rebuild — rebuild document with reviewed text
- GET/POST /translations/{id}/xliff — XLIFF 1.2 export/import (edited
segments export their reviewed text)
Review editor (frontend /dashboard/reviews/[jobId]):
- side-by-side source/translation table, inline edit, approve (single or
all), rebuild & download (auth blob), XLIFF export/import, 13 locales
- 'Relire et corriger' link on the translation-complete screen
Team workspaces (routes/workspace_routes.py + /dashboard/teams):
- Workspace/WorkspaceMember models, roles owner/admin/member
- create (Business plan), list with seat usage, invite by email with
seat-limit enforcement (Business=5, Enterprise unlimited), removal
- shared glossaries: workspace members can use a glossary shared to their
workspace (access check extended)
Tests: 1184 passed / 0 failed (11 new: recorder, overrides, docx
capture->rebuild e2e, XLIFF structure/escaping, seats, workspace CRUD,
shared glossary access)
Two critical fixes:
1. Provider "google" (default classic mode) now checks for a Google Cloud
API key (GOOGLE_CLOUD_API_KEY in env or admin settings). If present,
uses GoogleCloudTranslationProvider (official API). Previously it
always fell through to deep_translator (free scraper) which gets
blocked in production, silently returning untranslated text.
2. Added translation verification: each translator now tracks how many
texts were attempted vs actually changed. If 0 texts were translated,
the job is marked as FAILED with a clear error message instead of
returning the original file as "completed".
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Restructured docker-compose for Nginx Proxy Manager (no custom nginx)
- Added domain wordly.art configuration
- Added Prometheus + Grafana monitoring stack with pre-configured dashboards
- Added PostgreSQL backup script to NAS (daily/weekly/monthly rotation)
- Added alert rules for backend, system, and Docker metrics
- Updated deployment guide for NPM + IONOS DNS homelab setup
- Added marketing plan document
- PDF translator and watermark support
- Enhanced middleware, routes, and translator modules
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Major changes across backend, frontend, infrastructure:
- Provider system with model selection (Google, DeepL, OpenAI, Ollama, Google Cloud)
- Admin panel: user management, pricing, settings
- Glossary system with CSV import/export
- Subscription and tier quota management
- Security hardening (rate limiting, API key auth, path traversal fixes)
- Docker compose for dev, prod, and IONOS deployment
- Alembic migrations for new tables
- Frontend: dashboard, pricing page, landing page, i18n (en/fr)
- Test suite and verification scripts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>