4.8 KiB
4.8 KiB
Tasks: enterprise-react-translate
Change ID: enterprise-react-translate
Package: @suaveplan/react-translate
Target path: react/platform/react-translate
Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/logger
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold
- Create directory tree. Write
package.jsonat0.1.0,tsconfig.json,vitest.config.ts, scripts. - Dependencies:
@suaveplan/error workspace:^,@suaveplan/logger workspace:^,i18next catalog:i18n,react-i18next catalog:i18n,i18next-browser-languagedetector catalog:i18n,i18next-http-backend catalog:i18n,@opentelemetry/api catalog:observability,tslib catalog:build.
2. Error codes and types
- Define
TranslationError; codes:TRANSLATION_INIT_FAILED,TRANSLATION_LOAD_FAILED. - Define types:
I18nConfig,I18nNamespace,SupportedLanguage,LanguageBundle,TranslationProviderProps,UseTranslationReturn,UseErrorMessageReturn,UseDirectionReturn.
3. i18n config and lazy loader
createI18nConfig(options)— builds i18next config withmissingKeyHandlerthat forwards to@suaveplan/logger+ OTel counter. ThrowsTranslationError(TRANSLATION_INIT_FAILED)on invalid config.src/i18n/lazy/—createLazyLoader(namespaces)returns dynamic-import factory per language for Suspense-compatible lazy bundles.- Write
i18n-config.test.ts+lazy-loader.test.ts(≤500 lines total): config init, missing-key telemetry fires, lazy-load resolves.{ timeout: 10000 }. - Write
.mdfor each.
4. Translation bundles
- Write all 10 base bundles:
en.ts,en-gb.ts,cy.ts,cy-gb.ts,de.ts,es.ts,fr.ts,ar.ts,zh.ts,zh-cn.ts. - Write 8 auth-namespace bundles:
auth-en.ts,auth-cy.ts,auth-de.ts,auth-es.ts,auth-fr.ts,auth-ar.ts,auth-zh.ts,auth-en-gb.ts. - Export legacy aliases:
cy→cyGb,en→enGb,zh→zhCnwith JSDoc deprecation notes documenting the aliasing.
5. Provider
TranslationProvider
- Wraps app with i18next instance. Accepts
config,language,bundles. OTel span on init. - Write test + md.
6. Hooks
useTranslation
- Wraps
react-i18nextuseTranslation. ThrowsTranslationErrorinNODE_ENV !== 'production'when no provider is mounted; logs warning via@suaveplan/loggerin production. - Write
use-translation.test.ts(≤500 lines): happy path, missing-key stub-guard dev throw, prod soft-fail, namespace overrides.{ timeout: 5000 }. - Write md.
useErrorMessage
- Maps
SuaveplanErrorinstances to i18n strings via error code lookup. Falls back toerror.message. - Write test + md.
useDirection
- Returns
{ direction: 'ltr' | 'rtl', locale }based on current i18next language. RTL languages: ar, he, fa, ur. - Write test + md.
7. HOC
withTranslation
- Higher-order component wrapping a component with
tandi18nprops injected. - Write test + md.
8. Utils
utils.ts—formatDate(date, locale),formatCurrency(amount, currency, locale),negotiateLanguage(preferred, available).- Write
utils.test.ts(≤500 lines).{ timeout: 5000 }. - Write md.
9. Storybook
provider.stories.tsx— language switcher playground (dropdown to switch en/de/ar/fr).rtl.stories.tsx— Arabic layout with mirrored direction.plurals.stories.tsx— count-based plural form demo.formatting.stories.tsx— date + currency formatting bridge.
10. E2E
e2e/translate.spec.ts— Playwright:- Switch language from English to German; verify UI strings change.
- Switch to Arabic; verify
dir="rtl"applied to layout. - Test lazy-bundle load; verify Suspense fallback then content.
- Verify missing-key counter increments when a key is absent.
11. Verify and publish
bunx turbo lint typecheck test --filter=@suaveplan/react-translate— green.bunx turbo test:coverage --filter=@suaveplan/react-translate— 100%.bun scripts/publish.ts --package @suaveplan/react-translate.- Archive change folder.