Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 2m14s
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)
86 lines
4.8 KiB
Markdown
86 lines
4.8 KiB
Markdown
# Chantier « fondations produit » — relecture, équipes, XLIFF (2026-08-29)
|
|
|
|
> Décision de la session : **aucune intégration DeepL**. Tout ce qui suit est
|
|
> 100 % moteur maison/LLM existants.
|
|
|
|
## 1. Fondation : persistance des segments par job
|
|
|
|
- **Modèle `TranslationSegment`** (`database/models.py`) : paires (source,
|
|
traduction) par job et par utilisateur, avec statut de relecture
|
|
(`pending | approved | edited`), texte relu, index, horodatages.
|
|
- **Migration `f7e8d9c0b1a2`** (alembic) : `translation_segments`,
|
|
`workspaces`, `workspace_members`, `glossaries.workspace_id`. Appliquée et
|
|
vérifiée sur base vierge (chaîne complète 001→tête) et sur la base de dev.
|
|
- **Capture** (`translators/segments.py`) : un `SegmentRecorder` est injecté
|
|
par la route dans les 4 traducteurs (docx/xlsx/pptx/pdf). Il enregistre
|
|
chaque paire unique dans l'ordre du document ; les paires identiques
|
|
(non traduites) sont ignorées pour garder la liste actionnable.
|
|
- **Overrides** : `set_segment_overrides()` applique les traductions
|
|
**relues par l'humain** mot pour mot lors de la reconstruction — priorité
|
|
maximale (avant TM et provider), zéro appel API, zéro dérive.
|
|
- **Persistance** : après un job réussi, la route stocke les segments en
|
|
base (best-effort, n'échoue jamais le job).
|
|
|
|
## 2. API de relecture (`routes/review_routes.py`)
|
|
|
|
| Endpoint | Rôle |
|
|
|---|---|
|
|
| `GET /api/v1/translations/{job_id}/segments` | Liste des segments + compteurs (accès propriétaire ou token du job) |
|
|
| `PATCH /api/v1/segments/{id}` | Éditer (`reviewed_text` + `status=edited`) ou approuver — alimente aussi la TM par utilisateur (les traductions relues sont réutilisées dans les jobs suivants) |
|
|
| `POST /api/v1/translations/{job_id}/rebuild` | Reconstruit le document avec les segments approuvés/modifiés (le texte relu est appliqué tel quel) puis pointe le téléchargement dessus |
|
|
| `GET /api/v1/translations/{job_id}/xliff` | Export **XLIFF 1.2** (les segments modifiés exportent leur texte relu) |
|
|
| `POST /api/v1/translations/{job_id}/xliff` | Import XLIFF : met à jour les segments (cible ≠ machine → `edited`, sinon `approved`) |
|
|
|
|
Note UX : la reconstruction nécessite le fichier source encore présent
|
|
(rétention 30 min). Au-delà, le messageInvite à re-téléverser — et les
|
|
segments approuvés étant dans la TM, la nouvelle traduction les réutilise
|
|
automatiquement.
|
|
|
|
## 3. Éditeur de relecture (frontend)
|
|
|
|
- **`/dashboard/reviews/[jobId]`** — tableau côte à côte Source |
|
|
Traduction, édition inline, badges de statut, approbation unitaire ou
|
|
« Tout approuver », **Reconstruire et télécharger** (blob authentifié),
|
|
export/import XLIFF. Libellés 13 locales.
|
|
- **Lien « Relire et corriger la traduction »** sur l'écran de fin de
|
|
traduction (`TranslationComplete`).
|
|
|
|
## 4. Espaces de travail équipes (`routes/workspace_routes.py`)
|
|
|
|
- Modèles `Workspace` / `WorkspaceMember` (rôles `owner | admin | member`).
|
|
- Endpoints : création (plan **Business** requis), liste (avec rôle,
|
|
sièges utilisés/limite), ajout de membre **par e-mail** avec
|
|
**application de la limite de sièges** du plan du propriétaire
|
|
(Business = 5, Enterprise illimité), retrait (owner impossible à retirer).
|
|
- **Glossaires partagés** : `glossaries.workspace_id` — le contrôle d'accès
|
|
(`get_glossary_terms`, `validate_glossary_access`) accepte désormais le
|
|
propriétaire **et les membres du workspace**.
|
|
- **Page `/dashboard/teams`** : création d'espace, liste des membres,
|
|
invitation (e-mail + rôle), retrait, compteur de sièges, gate Business.
|
|
- Facturation multi-sièges : v1 = application de la limite de sièges du
|
|
plan. (La facturation au siège réel côté Stripe — subscription items —
|
|
reste un chantier facturation à part.)
|
|
|
|
## 5. Tests & vérifications
|
|
|
|
- Nouveaux tests (`tests/test_review_foundation.py`, 11) : recorder,
|
|
overrides, **capture→rebuild de bout en bout sur un vrai docx** (le texte
|
|
relu atterrit dans le fichier reconstruit, le reste reste machine),
|
|
structure XLIFF + échappement XML, sièges, CRUD workspace, glossaire
|
|
partagé (membre OK / extérieur refusé).
|
|
- Suite backend complète : voir résultat final ci-dessous.
|
|
- `tsc --noEmit` OK sur les deux frontends ; navigation « Équipe » (Pro+)
|
|
et lien « Relire » ajoutés.
|
|
|
|
## 6. Non livré (justifié)
|
|
|
|
- **IDML / DITA** : spécifications de formats complètes à part entière
|
|
(structure InDesign / arbres DITA) — nouveaux parseurs dédiés, à
|
|
chiffrer séparément.
|
|
- **Facturation Stripe au siège** (mètre temps réel des sièges) : la
|
|
limite plan est appliquée ; le mètre Stripe nécessite des subscription
|
|
items et un webhooks sièges.
|
|
- **Éditeur de relecture temps réel multi-utilisateur** (verrouillage de
|
|
segment, présence) : nécessite WebSocket + verrous — v1 = relecture
|
|
solo/équipe asynchrone.
|