Skip to content

Ship a working i18n example: translation catalogs, locale negotiation, localized RFC 7807 errors #194

Description

@Kravalg

Description

As a maintainer of php-service-template, I want the template to ship a working internationalization example — real translation catalogs, Accept-Language locale negotiation, and localized RFC 7807 error responses — so that downstream services start from a proven i18n baseline instead of empty scaffolding.

Today the i18n surface is scaffolding only: the translations/ directory is completely empty, no code in src/ uses TranslatorInterface or trans(), config/packages/translation.yaml only sets default_path and an en fallback with commented-out Crowdin/Loco/Lokalise provider stubs, and no Accept-Language locale negotiation is configured for the API. There is also no Behat scenario demonstrating that validation/error messages come back localized through the RFC 7807 error pipeline, and no documented translation workflow.

Affected quality attributes

  • Localizability — current score 2/5, translations/ is empty and nothing demonstrates translated validation/error messages or locale negotiation — target 5/5.
  • Compatibility — current score 4/5, API content negotiation does not honor Accept-Language, so clients cannot negotiate localized error responses — target 5/5.
  • Evolvability — current score 4/5, translation providers exist only as commented stubs with no documented workflow for evolving catalogs — target 5/5.

This issue is part of the enterprise quality audit (report: docs/audit/enterprise-quality-audit-2026-07.md on branch claude/enterprise-quality-audit-bc8jch).

Tasks

  • Add translations/validators.en.yaml plus at least one non-English locale catalog (e.g. translations/validators.uk.yaml) with the validation messages used by the example resource.
  • Enable set_locale_from_accept_language: true (and set_content_language_from_locale) in config/packages/framework.yaml so the request locale is negotiated from the Accept-Language header.
  • Use translatable constraint messages (translation keys resolved via the validators domain) in the example resource's validation so /api errors return localized RFC 7807 detail.
  • Add a Behat scenario under tests/Behat/ asserting that the same invalid request returns a localized RFC 7807 detail for Accept-Language: uk and the English message for Accept-Language: en (wire it into make behat).
  • Document the translation workflow — catalog layout, adding a locale, and enabling one of the commented-out translation providers (Crowdin/Loco/Lokalise) in config/packages/translation.yaml — in the README (or a dedicated i18n doc linked from it).
  • Regenerate and commit the exported specs (make generate-openapi-spec, make generate-graphql-spec) if the API contract surface changes.

Acceptance Criteria

  • translations/ contains validators.en.yaml and at least one non-English locale catalog, and the catalogs are loaded by the framework (no missing-translation fallback for the example messages).
  • Requests with Accept-Language: uk receive RFC 7807 error responses with a Ukrainian detail; requests with Accept-Language: en (or no header) receive English, verified by a passing Behat scenario.
  • The translation-provider workflow is documented and references the provider stubs in config/packages/translation.yaml.
  • Domain classes remain free of Symfony/Doctrine/API Platform attributes; framework concerns stay in YAML/XML configuration.
  • All existing quality gates still pass (make ci).
  • The linked PR passes GitHub CI checks and CodeRabbit review feedback is addressed.

Note: existing quality gates and thresholds must not be lowered — thresholds may only be added or raised.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestphpPull requests that update Php code

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions