Status: placeholder
This epic captures intent; the detailed spec will be added in a follow-up update before any sub-issues are filed or work begins.
Problem (high level)
The app stores translatable content (Page, Archetype, MenuCategory, HomepageLayout — all via the Knp `*Translation` pattern) but offers no way to delegate translation work to a non-editor user.
A volunteer translator currently either needs full CMS-editor rights (overkill, lets them touch business data) or has to send patches out-of-band. There is also no record of which version of the source a translation was based on — so when an English page changes, the French translation goes silently stale.
Scope (skeleton — to be refined)
1. New role `ROLE_TRANSLATOR`
- Inherits `ROLE_USER`.
- Grants access to a new `/admin/translations` namespace.
- Can read source-language content (read-only), edit non-default-locale translations only.
- No access to entity-level CRUD outside translations.
2. Version reference
Each `*Translation` row gets a `sourceVersion` reference — one of:
- a content-hash of the source-language fields at save time (lightweight, no new bundle), or
- an FK to a future `Page::version` / `Archetype::version` counter.
When the source changes, the translation is flagged as "outdated against source vN" so reviewers see staleness at a glance.
No versioning bundle is currently installed; decision on hash-vs-counter is part of the detailed spec.
3. Moderation
- Translator submits → translation enters `PENDING_REVIEW` state.
- CMS editor (or a new `ROLE_TRANSLATION_MODERATOR`) approves or rejects.
- Approved translations replace the published locale field; rejected ones return with a comment.
- Symfony Workflow is already used for `Borrow` (`config/packages/workflow.yaml`) — a new `translation_review` state machine fits naturally.
4. Open questions (resolve before sub-issues)
- Which entities are in scope at v1? (suggested: Page + Archetype; defer MenuCategory + HomepageLayout)
- Separate `ROLE_TRANSLATION_MODERATOR`, or do existing CMS editors moderate by default?
- Translator UX: pick from a list, or a queue of pending-source-changes?
- Audit log: store every transition with actor + timestamp? (recommended yes)
- UI: standalone `/admin/translations` console, or per-entity translation panels in existing edit screens?
Files likely touched (informational, no work yet)
- `config/packages/security.yaml` — new role
- `config/packages/workflow.yaml` — `translation_review` workflow
- `src/Entity/PageTranslation.php`, `src/Entity/ArchetypeTranslation.php` — state + sourceVersion fields
- `src/Workflow/` — new translation workflow
- `templates/admin/translation/` — new admin UI
- `src/Entity/User.php` — new role constant
Dependency
Sequence-wise this should come after F18.29 (locale-prefixed URL routing) — having stable per-locale URLs makes the translator UX much more obvious.
Status: placeholder
This epic captures intent; the detailed spec will be added in a follow-up update before any sub-issues are filed or work begins.
Problem (high level)
The app stores translatable content (Page, Archetype, MenuCategory, HomepageLayout — all via the Knp `*Translation` pattern) but offers no way to delegate translation work to a non-editor user.
A volunteer translator currently either needs full CMS-editor rights (overkill, lets them touch business data) or has to send patches out-of-band. There is also no record of which version of the source a translation was based on — so when an English page changes, the French translation goes silently stale.
Scope (skeleton — to be refined)
1. New role `ROLE_TRANSLATOR`
2. Version reference
Each `*Translation` row gets a `sourceVersion` reference — one of:
When the source changes, the translation is flagged as "outdated against source vN" so reviewers see staleness at a glance.
No versioning bundle is currently installed; decision on hash-vs-counter is part of the detailed spec.
3. Moderation
4. Open questions (resolve before sub-issues)
Files likely touched (informational, no work yet)
Dependency
Sequence-wise this should come after F18.29 (locale-prefixed URL routing) — having stable per-locale URLs makes the translator UX much more obvious.