# Translation Manager — Improvement & Growth Plan

> Package: capell-app/translation-manager · Kind: package · Tier: premium · Product group: Capell Admin · Bundle: admin · Status: Draft

## 1. Snapshot

Translation Manager is an admin-only Filament package (single surface: `admin`) that turns Laravel language files into an editable source-vs-target comparison grid at `/admin/translation-manager`. All domain behaviour lives in 17 thin Actions (`src/Actions`) that delegate to two pluggable contracts — `TranslationSourceResolver` (default `ConfigTranslationSourceResolver`, discovers app + Composer-package + vendor `resources/lang` dirs) and `TranslationFileStore` (default `FileTranslationFileStore`, reads/writes PHP and JSON lang files with override-path safety) — plus an optional `TranslationAITranslator` (default `NullTranslationAITranslator`). It owns no migrations, settings, or DB tables (`database.migrations: false`), and produces no frontend output. Third-party deps are minimal: `lorisleiva/laravel-actions`, `spatie/laravel-data`, `spatie/laravel-package-tools`. Nine Data classes (`src/Data`) carry every boundary payload — no anonymous arrays leak between layers.

The `supports` / soft-dependency pattern is implemented correctly and is worth highlighting. `composer.json` lists `capell-app/ai-orchestrator` under `suggest` (not `require`); `capell.json` lists it under `dependencies.supports`. `TranslationManagerServiceProvider::registerOptionalAIOrchestratorModule()` guards with `interface_exists(AIOrchestratorModule::class)` and `class_exists(AIOrchestratorModuleRegistry::class)` and only registers inside an `afterResolving(AIOrchestratorModuleRegistry::class, …)` callback, so the AIOrchestrator-typed classes in `src/Integrations/AI/` are never autoloaded when the orchestrator is absent. This is the clean inversion of a hard dependency: the package runs standalone with a Null translator and lights up AI drafting only when the orchestrator is installed and binds a real `TranslationAITranslator`.

Current marketplace `summary`: _"Manage Capell language files from one Filament page with side-by-side locale editing, missing and stale key checks, safe override writes, and optional reviewed AI drafting."_ Screenshot coverage now matches the package contract: the marketplace card plus all five `docs/screenshots.json` captures are committed and declared in `capell.json` (`empty state`, `comparison grid`, `create locale`, `duplicate locale`, and optional `AI translate selected`).

## 2. Improvements (existing functionality)

- **CSV/XLIFF/PO import-export and publish-readiness are surfaced in the UI** — `TranslationManagerPage::getHeaderActions()` now exposes CSV, XLIFF, and PO export actions, an import action with format selection, a publish-readiness notification action, a missing-key scan action, and Save. Coverage exercises those header actions through the page state and verifies streamed export/import/readiness behavior. — `src/Filament/Pages/TranslationManagerPage.php`, `tests/Feature/Filament/TranslationManagerPageTest.php` — Shipped

- **Needs-attention filtering is available** — the page filter supports `needs_attention` and `filteredEntries()` returns missing, stale, and changed entries as the translator work queue. The filter selection is persisted between visits with the rest of the browser state. — `src/Filament/Pages/TranslationManagerPage.php`, `resources/views/filament/pages/translation-manager.blade.php`, `tests/Feature/Filament/TranslationManagerPageTest.php` — Shipped

- **Done/Shipped: raw grid controls were replaced with Filament-native controls.** The page now wraps source/file/filter selectors in `x-filament::input.wrapper` + `x-filament::input.select`, uses `x-filament::input.checkbox` for selectable entries, wraps editable target textareas in Filament input wrappers, and receives stable entry indexes from `TranslationManagerPage::loadEntries()` instead of doing per-row `array_search` work in Blade. — `resources/views/filament/pages/translation-manager.blade.php`, `src/Filament/Pages/TranslationManagerPage.php`.

- **Source/locale/file/filter selection persists between visits** — `TranslationManagerPage` stores the selected source, source locale, target locale, file, and filter in session, restores valid selections on `mount()`, and refreshes the readiness matrix without resetting the translator's working context. — `src/Filament/Pages/TranslationManagerPage.php`, `tests/Feature/Filament/TranslationManagerPageTest.php` — Shipped

- **Done/Shipped: AIOrchestrator module registration is typed.** `registerOptionalAIOrchestratorModule()` checks the optional AI Orchestrator classes exist, then registers inside an `afterResolving(AIOrchestratorModuleRegistry::class, ...)` callback against the typed registry and calls `$registry->register(...)` directly. — `src/Providers/TranslationManagerServiceProvider.php` — S

- **Accepted residual risk: large XLIFF exports are in-memory.** `exportCsv()` uses `php://temp`; `ExportTranslationEntriesToXliffAction` builds a full `DOMDocument` and returns a string. This is acceptable for current admin language-file sizes and documented as an assumption; chunked XLIFF output should be a future scale task only if real translation sets exceed practical memory. — `src/Actions/ExportTranslationEntriesToXliffAction.php` — S

## 3. Missing Features (gaps)

Tie-back to `capabilities[]` (16 declared) and standard translation-workflow norms:

- **Done/Shipped: inline missing-key detection / app scanning.** `ScanMissingTranslationKeysAction` scans configured code paths for `__()` / `@lang()` references missing from language files, the page exposes a "Scan missing keys" header action, and the manifest declares the `translation.files.code-missing-key-scan` capability. — `src/Actions/ScanMissingTranslationKeysAction.php`, `src/Filament/Pages/TranslationManagerPage.php`, `tests/Feature/TranslationManagerActionsTest.php`.

- **Done/Shipped: translation memory / glossary.** `BuildTranslationMemorySuggestionsAction` reuses exact source-value translations across files, `TranslateSelectedEntriesAction` returns memory suggestions before AI calls, and save-time glossary validation enforces configured terms per locale. — `src/Actions/BuildTranslationMemorySuggestionsAction.php`, `src/Actions/TranslateSelectedEntriesAction.php`, `src/Support/FileTranslationFileStore.php`, `tests/Feature/TranslationManagerActionsTest.php`.

- **Done/Shipped: machine-translation review/approval workflow.** AI/memory suggestions land in `pendingAiSuggestions` instead of immediately overwriting target values; translators must accept or reject each suggestion before Save writes it. Coverage verifies rejected suggestions do not change target values. — `src/Filament/Pages/TranslationManagerPage.php`, `tests/Feature/Filament/TranslationManagerPageTest.php`.

- **Done/Shipped: PO / gettext import-export.** The package ships `ExportTranslationEntriesToPoAction` and `ImportTranslationEntriesFromPoAction`, declares them in `capell.json`, exposes PO import/export in the page header action set, and covers round-trip import/export behavior. — `src/Actions/*PoAction.php`, `src/Filament/Pages/TranslationManagerPage.php`, `tests/Feature/TranslationManagerActionsTest.php`.

- **Done/Shipped: per-locale completeness dashboard.** `TranslationManagerPage` builds `readinessMatrix` across target locales and the Blade page renders locale-level file, entry, missing, stale, changed, extra, fallback, and ready/needs-work state. — `src/Filament/Pages/TranslationManagerPage.php`, `resources/views/filament/pages/translation-manager.blade.php`, `tests/Feature/Filament/TranslationManagerPageTest.php`.

- **Done/Shipped: fallback-chain awareness.** Comparison reads the configured Laravel fallback locale, marks empty target keys as `fallback` when fallback content exists, exposes a fallback filter/status label, and includes fallback counts in publish readiness. — `src/Support/FileTranslationFileStore.php`, `resources/views/filament/pages/translation-manager.blade.php`, `tests/Feature/TranslationManagerActionsTest.php`.

- **Done/Shipped: pluralization / parameter validation.** Save validates that translated strings preserve source placeholders and pipe-delimited plural-form structure before writing. — `src/Support/FileTranslationFileStore.php`, `tests/Feature/TranslationManagerActionsTest.php`.

- **Done/Shipped: partial-override merge.** Read-side comparison merges source and Laravel override files so per-key overrides match runtime behavior instead of fully shadowing the source file. — `src/Support/FileTranslationFileStore.php`, `tests/Feature/TranslationManagerActionsTest.php`.

Table-stakes already shipped: source/target grid, key-level stale detection when source-hash metadata exists, CSV/XLIFF/PO import-export, locale create/duplicate, safe override-path writes, fallback awareness, publish readiness, and optional reviewed AI drafting.

## 4. Issues / Risks

- **Done/Shipped: partial override files merge with source files.** `FileTranslationFileStore::readMerged()` now combines package source values with Laravel override values for read/comparison paths, while write paths still target the safe override location unless package source writes are explicitly enabled. Coverage proves a partial `lang/vendor/<ns>/<locale>/<file>.php` override no longer hides un-overridden source keys. — `src/Support/FileTranslationFileStore.php`, `tests/Feature/TranslationManagerActionsTest.php`.

- **Done/Shipped: stale detection is key-level when metadata exists.** Writes store per-key source hashes in sidecar metadata, and comparison prefers those hashes to decide `changed` versus `stale`, falling back to file mtime only when legacy metadata is unavailable. — `src/Support/FileTranslationFileStore.php`, `tests/Feature/TranslationManagerActionsTest.php`.

- **Done/Shipped: health label and admin query budget match reality.** `TranslationManagerHealthCheck` now runs real diagnostics for the admin surface, service bindings, and required configuration, so the manifest health label names those exact checks instead of a generic install-health promise. The package remains file-backed and database-free, so `performance.adminQueryBudget` correctly stays at `0`. — `src/Health/TranslationManagerHealthCheck.php`, `capell.json`, `tests/Unit/ManifestRequirementsTest.php`.

- **Accepted residual risk: file writes share the admin page permission.** `canAccess()` gates on `ExtensionsPage::canManageExtensions()`, `package_source_writes` defaults to `false`, and package/vendor writes go through safe Laravel override paths. Finer-grained per-source write permissions would harden larger teams, but the current package scope treats translation editing as an extension-management permission. — `src/Filament/Pages/TranslationManagerPage.php`, `capell.json` permissions — security.

- **Done/Shipped: filesystem scans are request-local cached and invalidated after writes.** `FileTranslationFileStore` now memoizes locale discovery, file listings, and comparison data per source/locale/file during the request, then flushes that source cache whenever translations are written. Source discovery was already memoized separately. Evidence: `TranslationManagerActionsTest` uses `CountingFilesystem` to prove repeat file/comparison reads do not rescan until `SaveTranslationEntriesAction` writes and invalidates the cache. — `src/Support/FileTranslationFileStore.php`, `tests/Feature/TranslationManagerActionsTest.php`, `tests/Fixtures/CountingFilesystem.php` — performance budget.

- **Done/Shipped: source discovery is request-local memoized.** `ConfigTranslationSourceResolver::sources()` caches its resolved source list in `resolvedSources`, and the service provider binds the resolver as a singleton, so Composer package discovery and provider reflection run once per request. — `src/Support/ConfigTranslationSourceResolver.php`, `src/Providers/TranslationManagerServiceProvider.php` — performance.

- **Public-output safety: N/A but worth a guard test** — the package has `surfaces: ["admin"]` and emits no frontend HTML, so the Capell public-output rules do not apply. No risk found; no action needed beyond noting it in the manifest (already `frontend: []`, `cacheable: false`).

- **Accepted residual risk: package UI strings ship in English only.** The package is itself translatable through Laravel language files, but this repository only ships `resources/lang/en/*`. Additional bundled locales are a product/content task rather than an implementation blocker for the current package plan. — `resources/lang/en` — i18n.

- **Accepted residual risk: scale/concurrency tests remain future hardening.** Coverage is genuinely strong across Actions, file store, page Livewire state, AI module, manifest, and Data boundaries, including path-traversal rejection, override-write defaults, partial-override merge, placeholder/plural/glossary validation, fallback status, translation memory, PO import/export, and page header actions. Remaining gaps are concurrent-write / last-write-wins on `write()` and very large file export memory. — `tests/` — test debt.

## 5. Marketplace & Selling

**Critique.** The current `summary` and composer `description` diverge. `capell.json` summary is a 40-word feature dump (editor, workflow actions, stale detection, CSV+XLIFF, publish readiness, AI drafting, override writes) — comprehensive but unreadable as a one-liner, and it advertises CSV/XLIFF/publish-readiness that have no UI entry point (see §2), risking a "where is it?" support load. The composer `description` ("File-based Laravel translation management for Capell and Filament admin panels.") is accurate but generic and undersells the differentiators (override safety, AI drafting, no-DB footprint).

**Improved one-sentence summary:** _Edit, translate, and ship your Capell language files from one Filament screen — with side-by-side source/target comparison, stale-key detection, and AI drafting that never touches a database._

**Improved 3–4 sentence description:** _Translation Manager gives admins a file-based editor for every Laravel language file in your Capell app and its packages, without migrations or new tables. Compare source and target locales side by side, spot missing and stale keys at a glance, and create or duplicate locales in one click. Edits to package and vendor strings are written safely to Laravel's override paths, so upgrades never clobber your translations. Install AI Orchestrator to add one-click AI drafting for selected keys, with review before anything is saved._

**Screenshot/media coverage.** The marketplace card plus all five `docs/screenshots.json` captures are now committed and declared in `capell.json`: empty state, comparison grid, create-locale modal, duplicate-locale modal, and AI translate-selected. A short GIF of the create→translate→save loop would still improve the listing, but the static Marketplace screenshot contract is reconciled.

**Pricing / tier / bundle.** `tier: premium`, `bundle: admin`, `proposedLicense: paid`, `requestedCertification: first-party`, `supportPolicy: priority` — appropriate for a developer/agency tool. Position inside the **admin bundle** as the localisation utility. The no-DB, override-safe footprint is a genuine premium justification (low risk to install).

**Cross-sell.** Hard requires `capell-app/admin` + `capell-app/core`. Soft `supports capell-app/ai-orchestrator` — make this the headline upsell: "Add AI Orchestrator for AI translation drafting." Bundle into an **Extension Suite** alongside **seo-suite** (translated SEO metadata per locale) and **ai-orchestrator** (MT). Cross-link the README's "Best Used With" (currently Welcome Tour / Diagnostics / Foundation Theme) to add ai-orchestrator and seo-suite, which are far more relevant to the localisation buyer.

**Differentiators / value props / target buyer.** Differentiators: upgrade-safe override writes; zero database footprint; clean optional-AI integration via `supports`; XLIFF interop. Target buyer: agencies and developers running multi-locale Capell sites who need to localise package/vendor strings without forking vendor files. Value prop: "localise your whole app — including third-party packages — without migrations and without losing edits on upgrade."

**Keywords/tags (8–12):** `translation`, `localization`, `i18n`, `l10n`, `language-files`, `xliff`, `csv-import`, `filament`, `multilingual`, `ai-translation`, `vendor-overrides`, `capell-admin`.

## 6. Prioritized Roadmap

| Item                                                                                                                                                                                                                                                                                                                                                                             | Bucket | Effort | Impact | Section ref |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ | ------ | ----------- |
| Wire CSV/XLIFF import-export + publish-readiness into page header actions                                                                                                                                                                                                                                                                                                        | Done   | M      | High   | §2, §3      |
| Ship the 4 required + 1 optional screenshots (fix screenshots.json mismatch)                                                                                                                                                                                                                                                                                                     | Done   | S      | High   | §1, §5      |
| Fix partial-override merge so editor view matches Laravel runtime                                                                                                                                                                                                                                                                                                                | Done   | M      | High   | §4          |
| Done/Shipped: Correct manifest healthChecks label / adminQueryBudget to match reality                                                                                                                                                                                                                                                                                            | Done   | S      | Med    | §4          |
| Done/Shipped: Memoize source discovery + locale/comparison filesystem scans. Evidence: file-listing and comparison caches are request-local and flush after translation writes, with focused filesystem-count coverage.                                                                                                                                                          | Done   | S      | Med    | §4          |
| Done/Shipped: Rewrite summary + composer description; add ai-orchestrator/seo-suite cross-sell. Evidence: `capell.json` and package `composer.json` now use conservative editor-focused copy, declare/suggest AI Orchestrator and SEO Suite as optional pairings, README/docs copy matches shipped behavior, and `ManifestRequirementsTest` locks the manifest/composer wording. | Done   | S      | Med    | §5          |
| Add placeholder/plural preservation validation on save                                                                                                                                                                                                                                                                                                                           | Done   | M      | High   | §3          |
| Add MT review gate (accept/reject AI drafts before write)                                                                                                                                                                                                                                                                                                                        | Done   | M      | High   | §3          |
| Per-locale completeness/coverage matrix view (uses existing readiness data)                                                                                                                                                                                                                                                                                                      | Done   | M      | Med    | §3          |
| Key-level stale detection (replace file-mtime heuristic)                                                                                                                                                                                                                                                                                                                         | Done   | M      | Med    | §4          |
| Persist last source/locale/file selection per user                                                                                                                                                                                                                                                                                                                               | Done   | S      | Med    | §2          |
| Fallback-chain awareness ("covered by fallback" status)                                                                                                                                                                                                                                                                                                                          | Done   | M      | Med    | §3          |
| Missing-key detection via code scanning of `__()`/`@lang()`                                                                                                                                                                                                                                                                                                                      | Done   | L      | High   | §3          |
| Translation memory / glossary for consistent reuse                                                                                                                                                                                                                                                                                                                               | Done   | L      | Med    | §3          |
| PO/gettext import-export for Crowdin/Weblate/Poedit interop                                                                                                                                                                                                                                                                                                                      | Done   | M      | Med    | §3          |
| Done/Shipped: Replace raw blade grid controls with Filament-native selector, checkbox, and input-wrapper components, with stable page-provided row indexes instead of per-row Blade lookup                                                                                                                                                                                       | Done   | L      | Med    | §2          |