Le nouveau dessin montre une tarte aux pommes, comprise de tous,
présentée successivement en document Word, tableau Excel, présentation
PowerPoint et PDF : une onde de traduction traverse chaque document,
la langue change, la mise en page reste rigoureusement identique.
Contenu universel, plus aucun jargon de spécialiste.
Également : deux nettoyages DeepL restés non envoyés (commentaires
dans database/models.py et translators/word_translator.py).
Vérifié : construction réussie, 14/14 tests, aucune erreur d'analyse,
mode sombre et « réduire les animations » pris en charge.
Zone de dépôt : le contour s'allume en doré et la carte s'agrandit
quand on la survole avec un fichier (l'information existait, elle
n'était jamais affichée).
Or lisible : nouveau jeton « or encre » (#8B6F47) pour les textes,
l'or clair reste aux traits, fonds et au mode sombre ; 52 textes dorés
convertis, pastille comprises ; plus aucun texte sous 10 px
(8,5 px → 11 px dans le sélecteur de moteurs).
Tarifs : le choix redevient binaire — les trois abonnements payants en
grandes cartes, le gratuit en ligne discrète au-dessus, le sur mesure
en ligne dorée dessous. Le tableau comparatif complet reste dessous.
Accueil : le mur de six cartes génériques est remplacé par un vrai
avant/après — une page « Cahier des charges — Traitement d'air » à
côté de sa traduction anglaise, structure identique au mot près
(terme technique en gras des deux côtés), sceau « Même mise en page,
mot pour mot » entre les deux, et trois preuves précises (SmartArt
reconstruits, séries de graphiques traduites, tables des matières
régénérées) à la place des promesses vagues.
Deux pages de document côte à côte (source FR, traduction qui cycle
EN/ES/DE) : squelette identique (titre, lignes, tableau, graphique),
seuls les mots et les longueurs de lignes changent, avec balayage doré
à chaque changement et points animés sur le connecteur. Respecte le
réglage « réduire les animations ». Légende : « Même mise en page,
nouvelle langue — rien d'autre ne bouge ».
Batch upload: dropzone and inputs accept multiple files (cap 10/run,
validated + deduped); 2+ files switch the submit to a queue screen —
sequential jobs with per-file progress, failure messages through the
humanizer, per-file download/review links, staggered download-all,
real server-side stop (cancel API) plus between-files abort. The
one-file flow is untouched: files.length === 1 takes the exact
existing path.
Runner: standalone runTranslationJob (submit + poll + abort + cancel)
with injectable poll interval; 5 dedicated vitest cases covering
completed-with-progress, backend failure, submit HTTP error, mid-flight
abort with server cancel, and network-failure cutoff.
Context page close review: /dashboard/context is a clean redirect to
glossaries (no duplicate); the fake 300ms save delay removed (instant
zustand persist); suggestion chips now resolve their prompt bodies
through i18n (EN+FR — no more French prompts for English users); the
translate config column shows a 'Context guidelines active' chip that
links to the editor when a Pro LLM prompt is set.
Dead code: legacy file-uploader.tsx (+webllm.ts, its only consumer)
and the unused PRESETS/applyPreset/clearContext store block removed
(-14KB of glossary strings).
Verified: build exit 0, vitest 14/14 (9 prior + 5 runner), eslint 62
errors (vs 64 at HEAD), 0 missing i18n keys.
Pricing: full editorial redesign — serif card headers with accent pills
replace the colored font-black blocks, tone sweep across toggle/metrics/
features/CTAs, PLAN_COLORS removed; one design system app-wide.
Translate: decorative titles one step down (CTA hierarchy restored);
glossary and image-translation blocks hidden entirely for free users
(progressive disclosure — three controls for free).
Reviews: XLIFF hint line explains the exchange format; backend errors
routed through a friendly mapper (session/not-found/rate-limit/server).
Landing: fabricated hero UI cards (fake 'Context Engine' overlay)
removed — the photo no longer promises screens that don't exist.
Nav: single DashboardNavLinks component shared by sidebar and mobile
drawer (was duplicated markup).
API: GET /api/v1/translations (user job history, paginated; completed
jobs retained 24h) and POST /api/v1/translations/{id}/cancel —
cooperative cancellation with worker checkpoints before dispatch and
before finalisation, reserved quota released immediately. Translate
monitor now offers a real 'Cancel translation' next to 'Back to start';
recent-jobs list reads server history first, localStorage fallback.
DeepL purge (backend): provider module, registry registration, config
attrs/defaults, dispatch branch, admin settings schema + test branch,
legacy availability block, validation rules, plan provider lists,
error-code mappings, MCP enums, translator prompt mention, related
tests updated/removed. Fallback resolver skips unknown providers, so
stale chains containing 'deepl' degrade gracefully.
Verified: backend 110 tests passed; frontend build exit 0, vitest 9/9,
0 missing i18n keys, eslint 63 errors (vs 64 at HEAD).
Pricing: 'deepl' removed from plan provider lists and the comparison
table row. Landing and pricing copy (13 locales) no longer mention
DeepL (65 values cleaned, 39 dead keys deleted: pricing.comparison.deepl,
providerTheme.classic.deepl.*).
Providers: available-provider responses are filtered so a DeepL entry
from the backend can never surface in the engine picker or the services
page; DeepL theme entry and static lib/api.ts list entry removed.
Admin: DeepL config card, type fields, defaults and fallback-chain
mentions removed; stats/chart/status maps and mock data cleaned.
Backend adapter untouched — DeepL is invisible app-wide via the UI
filter; removing the Python adapter itself is a separate step if wanted.
Verified: build exit 0, vitest 9/9, eslint clean on touched files,
zero 'deepl' occurrences outside the two intentional UI filters.
The landing hardcoded 9/19/49 (monthly) and 7/15/39 (annual-equivalent)
while /pricing renders admin-configurable prices — the two surfaces
drifted apart whenever prices changed. The landing now fetches the same
live endpoint (no-store) with the previous values as load/failure
fallback, and shows the French '9 €' format like /pricing (was '€9').
Nav: teams/settings/services back out of the nav until product-ready (user
decision); teams page was already half-finished (UUID member display is a
backend limitation).
Payment: explicit confirmation dialog (plan, amount, billing period, Stripe
note) before any redirect; ?plan= URL now pre-opens the dialog instead of
triggering a silent checkout.
Contrast AA sweep (71 replacements): functional micro-labels raised to
>=60-65% opacity and >=10px across sidebar, header, pricing, landing;
decorative all-caps 'interface' label removed.
Design unification: new PageHeader component (accent pill + serif
base/accent title) applied to settings, services, reviews, teams; pricing
header returned to the editorial voice (serif + accent pill); dead
GlossaryCard deleted.
i18n residuals: suggestion chips, 'Standard' provider label, notification
close, model-combobox strings extracted (+broken bg-surface/border-border-
subtle tokens fixed); ~45 new keys EN+FR; 13 dead keys removed; zero
missing keys verified.
Reviews: icon-only row actions now carry visible text; 'Approve all' is
two-step armed-confirm.
Accelerators: Ctrl/Cmd+Enter submits; arrow-key navigation in the language
combobox; recent-jobs history cap 8->20 with per-job download; source=target
config rejected; empty 'Master Quality' badge removed.
Cookie consent: reopenable via footer link, emoji replaced with drawn icon.
Verified: build exit 0, vitest 9/9, eslint 64 errors = previous level,
0 missing i18n keys.
The landing page language switcher cycled to the next language on every
click. It is now a dropdown listing all 13 languages; the cycling button
variant is removed from the LanguageSwitcher component.
Replaced all references to "Office Translator" with "Wordly" across
i18n translations (13 locales), auth forms, layout components, admin
sidebar, and page metadata.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
New design system with cream/dark/copper palette (#FDFCF9, #1A1A1A, #C5A17A),
Inter font, rounded editorial cards, and dark mode support.
- globals.css: Rewritten from 1867→200 lines, new brand colors + editorial utilities
- Landing page: New editorial design with Hero, Steps, Features, Layout, Formats, Pricing, CTA, Footer
- Auth pages: Editorial card design with decorative blur blobs and back-to-home links
- Dashboard sidebar: New w-72 sidebar with Momento promo section
- Dashboard header: New h-20 topbar with editorial styling
- i18n: Added memento/common/dashboard keys for all 13 locales, cleaned duplicate landing keys
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The project uses a custom i18n provider, not next-intl directly.
This was causing a client-side crash on page load.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Cookie consent banner with accept all / essential only buttons
- Uses existing i18n messages (en/fr) and localStorage for persistence
- Animated with Framer Motion, respects dark/light theme
- Free tier users see "Passer Pro →" link next to their badge in sidebar
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>
- Fix MissingGreenlet: sync_engine now uses psycopg2 instead of asyncpg
- Fix bcrypt/passlib compat: pin bcrypt<4.1 in requirements
- Fix legacy password_hash NOT NULL: alter column to nullable in migration
- Add frontend password validation (uppercase + lowercase + digit)
- Add forgot-password and reset-password backend endpoints
- Add forgot-password and reset-password frontend pages
- Add email_service.py (SMTP via admin settings)
- Add reset_token/reset_token_expires columns to User model
- Migrate legacy JSON-only users to DB on password reset request
- Mount data/ volume in docker-compose.local.yml for persistence
- Add production deployment config (Dockerfile, nginx, deploy.sh)
Co-Authored-By: Claude Opus 4.5 <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>
Changes:
- Removed hardcoded admin credentials (now requires env vars)
- Added Redis session storage with in-memory fallback
- Improved CORS configuration with warnings for development mode
- Added retry_with_backoff decorator for translation API calls
- Updated pricing: Starter=, Pro=, Business=
- Stripe price IDs now loaded from environment variables
- Added redis to requirements.txt
- Updated .env.example with all new configuration options
- Created COMPREHENSIVE_REVIEW_AND_PLAN.md with deployment roadmap
- Frontend: Updated pricing page, new UI components