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
Acceptance Criteria
Note: existing quality gates and thresholds must not be lowered — thresholds may only be added or raised.
Description
As a maintainer of php-service-template, I want the template to ship a working internationalization example — real translation catalogs,
Accept-Languagelocale 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 insrc/usesTranslatorInterfaceortrans(),config/packages/translation.yamlonly setsdefault_pathand anenfallback with commented-out Crowdin/Loco/Lokalise provider stubs, and noAccept-Languagelocale 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
translations/is empty and nothing demonstrates translated validation/error messages or locale negotiation — target 5/5.Accept-Language, so clients cannot negotiate localized error responses — target 5/5.This issue is part of the enterprise quality audit (report:
docs/audit/enterprise-quality-audit-2026-07.mdon branchclaude/enterprise-quality-audit-bc8jch).Tasks
translations/validators.en.yamlplus at least one non-English locale catalog (e.g.translations/validators.uk.yaml) with the validation messages used by the example resource.set_locale_from_accept_language: true(andset_content_language_from_locale) inconfig/packages/framework.yamlso the request locale is negotiated from theAccept-Languageheader.validatorsdomain) in the example resource's validation so/apierrors return localized RFC 7807detail.tests/Behat/asserting that the same invalid request returns a localized RFC 7807detailforAccept-Language: ukand the English message forAccept-Language: en(wire it intomake behat).config/packages/translation.yaml— in the README (or a dedicated i18n doc linked from it).make generate-openapi-spec,make generate-graphql-spec) if the API contract surface changes.Acceptance Criteria
translations/containsvalidators.en.yamland at least one non-English locale catalog, and the catalogs are loaded by the framework (no missing-translation fallback for the example messages).Accept-Language: ukreceive RFC 7807 error responses with a Ukrainiandetail; requests withAccept-Language: en(or no header) receive English, verified by a passing Behat scenario.config/packages/translation.yaml.make ci).Note: existing quality gates and thresholds must not be lowered — thresholds may only be added or raised.