# Scratchpad -- MSP i18n: Contracts Sub-batch

- Plan slug: `2026-04-09-msp-i18n-contracts`
- Created: `2026-04-09`

## What This Is

A mechanical wiring pass: 37 unwired contract components (+ 1 pure-constants file) x `useTranslation('msp/contracts')`. This is the largest sub-batch in the MSP i18n effort at ~14,100 LOC across 38 files spanning 3 directory levels.

## Decisions

- **(2026-04-09)** Use a dedicated `msp/contracts` namespace rather than cramming keys into `features/billing`. Rationale: 38 files with ~800-1200 estimated keys would bloat the billing namespace beyond maintainability. Contracts are a self-contained feature area.
- **(2026-04-09)** `contractsTabs.ts` exports pure string constants (`CONTRACT_SUBTAB_LABELS`, `CONTRACT_TAB_LABELS`). These cannot use `useTranslation()` because the file is not a React component. Translate the consumed values at point-of-use in `Contracts.tsx` and `ClientContractsTab.tsx` instead.
- **(2026-04-14)** **Adopt the shared enum-labels option-hook pattern for all `BILLING_FREQUENCY_*` / `PLAN_TYPE_*` / `CONTRACT_LINE_TYPE_*` call sites owned by this batch.** The contract-lines sub-batch (shipped 2026-04-14) created `packages/billing/src/hooks/useBillingEnumOptions.ts` with `useBillingFrequencyOptions`, `useFormatBillingFrequency`, `useContractLineTypeOptions`, `useFormatContractLineType`, and added `enums.billingFrequency.*` / `enums.contractLineType.*` to `features/billing.json` in all 9 locales. This batch **must** migrate every call site in the PRD's "Shared enum label migration" table rather than translating surrounding labels and leaving the enum values in English. The deprecated `*_DISPLAY` / `*_OPTIONS` exports in `packages/billing/src/constants/billing.ts` were left in place **only** so this batch can flip the switch file-by-file; once all call sites are migrated, remove the deprecated aliases in the same PR as the last migration (or as a final clean-up commit). Pattern reference: `.ai/translation/enum-labels-pattern.md`. Audit command: `rg -n '_DISPLAY|_OPTIONS' packages/billing/src/components/billing-dashboard/contracts/`.
- **(2026-04-14)** **`contractsTabs.ts` migration shape:** keep `CONTRACT_SUBTAB_LABELS` as a value-to-value mapping only if `CONTRACT_LABEL_TO_SUBTAB` still needs it as an identifier lookup. For display, add a `useContractSubtabLabels()` helper colocated with the consumers (`Contracts.tsx` / `ClientContractsTab.tsx`) that returns `{ templates: t('...'), 'client-contracts': t('...'), drafts: t('...') }`. Store/compare tab state by `ContractSubTab` value, never by label. Keys go in `msp/contracts.json` under (suggested) `common.tabs.*` or `enums.contractSubtab.*`.
- **(2026-04-09)** Use `t('key', { defaultValue: 'English fallback' })` signature everywhere for fallback-safety. This matches the pattern established in existing msp/* namespaces.
- **(2026-04-09)** Replace hardcoded `'en-US'` locale in `formatCurrencyFromMinorUnits()` calls with locale from `useFormatters()`. Affects ContractDetail.tsx (invoice columns, PO amount display), ContractOverview.tsx, ReviewContractStep.tsx. The `formatCurrencyFromMinorUnits` utility accepts a locale parameter.
- **(2026-04-09)** Do NOT translate `throw new Error(...)` messages or `console.error()` strings. Only translate user-visible strings rendered in JSX.
- **(2026-04-09)** Use i18next `{{count}}` interpolation for pluralized strings (e.g., `'{{count}} service'` / `'{{count}} services'`; `'{{count}} day'` / `'{{count}} days'`).
- **(2026-04-09)** Use i18next named interpolation for dynamic values in dialog titles (e.g., `t('contractLineRate.title', { name: plan.contract_line_name, defaultValue: 'Set Custom Rate for {{name}}' })`).
- **(2026-04-09)** Ship in sub-batches due to size. Recommended split:
  - Sub-batch A: Namespace creation (F001), translations (F002-F009), route config (F010) -- foundational.
  - Sub-batch B: Large components -- ContractDetail (F011-F015), ContractDialog (F016-F018), ContractTemplateDetail (F019-F021).
  - Sub-batch C: Medium components -- CreateCustomContractLineDialog (F022-F024), ContractLines (F025-F027), AddContractLinesDialog (F028-F029), Contracts/ClientContracts (F030-F034).
  - Sub-batch D: Client wizard steps -- ContractWizard (F035-F036), ContractBasicsStep (F052-F053), service steps (F054-F057), ReviewContractStep (F058-F059).
  - Sub-batch E: Template wizard + small components -- TemplateWizard (F060), template steps (F061-F067), and remaining small components (F037-F051).

## Discoveries / Constraints

- **(2026-04-09)** `ContractDetail.tsx` at 2,330 LOC is the largest single component. It contains 5 tab views, 3 confirmation dialogs, assignment editing with 8+ field types, invoice column definitions, and status formatting. Estimated at 300-400 unique translatable strings. Split into 5 features (F011-F015).
- **(2026-04-09)** Two near-identical dialog files exist: `ContractLineRateDialog.tsx` (99 LOC) and `ContractPlanRateDialog.tsx` (95 LOC). They share the same structure and strings. Consolidate into one feature (F049) for translation efficiency.
- **(2026-04-09)** `formatRenewalModeLabel()` in ContractDetail.tsx returns hardcoded English strings ('Auto-renew', 'Non-renewing', 'Manual renewal'). These need to be translated using `t()` calls at the rendering site, not inside the formatting function (which has no hook access). Extract to translated labels in the component body.
- **(2026-04-09)** `ContractOverview.tsx` has a local `formatFrequency()` that maps frequency keys to display strings ('Weekly', 'Monthly', etc.). These should use `t()` rather than a local map. Same pattern in `ContractHeader.tsx`. **(2026-04-14 update):** For `monthly/quarterly/annually` specifically, use `useFormatBillingFrequency()` from `@alga-psa/billing/hooks/useBillingEnumOptions` so these renderers share the same `features/billing.json` keys as the rest of the contract-lines UI. `weekly` and `biweekly` are not in the shared enum — if `ContractOverview.tsx` needs them, keep a local `t()` lookup for those two values only or extend `BILLING_FREQUENCY_VALUES` (check whether the backend can actually emit them first).
- **(2026-04-09)** `ContractWizard.tsx` defines `STEPS` as a `const` tuple: `['Contract Basics', 'Fixed Fee Services', 'Products', 'Hourly Services', 'Usage-Based Services', 'Review & Create']`. These are passed to `WizardProgress` and `WizardNavigation`. They need to be translated. Options: (a) convert to keys and translate in the component, (b) wrap with `t()` in a useMemo. Option (b) is simpler -- translate at point of use.
- **(2026-04-09)** Same STEPS pattern in `TemplateWizard.tsx` with `TEMPLATE_STEPS`.
- **(2026-04-09)** `BucketOverlayFields.tsx` uses dynamic unit labels ('hours' vs custom unitLabel). The translation key should use interpolation: `t('bucketOverlay.includedLabel', { units: resolvedUnitLabel })`.
- **(2026-04-09)** `TemplateServicePreviewSection.tsx` uses a confirmation dialog with template literal message containing service and preset names. Convert to interpolation: `t('templatePreview.removeConfirmMessage', { serviceName, presetName })`.
- **(2026-04-09)** Several components format currency with hardcoded `'en-US'`: ContractDetail.tsx (lines 1093, 1644, 2126), ContractOverview.tsx (line 19 formatCurrency), ReviewContractStep.tsx (line 62-64). All should be migrated to use `useFormatters().formatCurrency()` or pass the active locale to `formatCurrencyFromMinorUnits()`.
- **(2026-04-09)** `ContractDialog.tsx` is a legacy create/edit dialog (1,386 LOC). It has its own preset picker with rate overrides and service overrides -- complex nested state. Translating it requires careful interpolation for dynamic preset names and rate displays.
- **(2026-04-09)** `ROUTE_NAMESPACES` for `/msp/billing` currently loads: `['common', 'msp/core', 'features/billing', 'msp/reports']`. Adding `'msp/contracts'` is straightforward -- it just appends to the array. Check if `msp/quotes` was also added recently (per the quotes sub-batch plan) to avoid merge conflicts.
- **(2026-04-09)** `ServicePicker.tsx` (56 LOC) and `ServiceCatalogPicker.tsx` (225 LOC) are thin wrappers. The former has 3 translatable strings (placeholder, search placeholder, empty message). The latter has more (~20-30) with search, filter, and selection UI.
- **(2026-04-09)** `QuickStartGuide.tsx` contains substantial prose content (step descriptions, billing model explanations, best practices list). These are long strings but straightforward to extract. Use descriptive keys like `quickStart.step1.description`, `quickStart.bestPractices.item1`.
- **(2026-04-09)** `contractsTabs.ts` (27 LOC, no React) defines `CONTRACT_SUBTAB_LABELS` and `CONTRACT_TAB_LABELS`. These are consumed in `Contracts.tsx` via `CustomTabs` and in `ClientContractsTab.tsx`. The tab component likely accepts string labels, so translate at the consumption point. Do NOT add `useTranslation()` to the .ts constant file.

## Gotchas

- **Shared status labels**: Status labels ('Active', 'Draft', 'Terminated', 'Expired') appear in ContractDetail.tsx, ContractHeader.tsx, ContractForm.tsx, TemplatesTab.tsx, ClientContractsTab.tsx, and Contracts.tsx. Use `common.status.*` keys in the namespace to avoid duplication.
- **Renewal mode labels**: 'Auto-renew', 'Manual renewal', 'Non-renewing' appear in ContractDetail.tsx and ContractBasicsStep.tsx. Use `common.renewal.*` keys.
- **Billing timing labels**: 'In Arrears' / 'In Advance' appear in ContractLineEditDialog.tsx, ContractLines.tsx, ContractTemplateDetail.tsx, and wizard steps. Use `common.billing.timing.*` keys.
- **Currency symbol hardcoding**: `BucketOverlayFields.tsx` hardcodes `$` as the currency symbol prefix (line 136). This should ideally use the contract's currency symbol, but that is a functional change beyond i18n scope. Note it but do not fix.
- **Date formatting**: Several components use `new Intl.DateTimeFormat(undefined, ...)` which already respects browser locale -- no change needed for these. Only the explicit `'en-US'` locale in `formatCurrencyFromMinorUnits` calls needs migration.
- **Large test surface**: 67 features x ~1.5 tests = ~100 test cases. For efficiency, group small-component tests into composite test files (e.g., one test file covering F045-F051 small components).

## Execution Log

- **(2026-04-14)** `F001` completed: created [`server/public/locales/en/msp/contracts.json`](../../../../server/public/locales/en/msp/contracts.json) with the full top-level namespace/group scaffold from the PRD (`common`, `status`, `renewal`, `billing`, `po`, and all component/wizard group buckets). Added initial key population for the first ContractDetail tranche (tabs/cards/dialogs/invoices/common actions/status/fallback labels) so follow-on features can wire to stable keys immediately.
- **(2026-04-14)** Runbook/verification: `jq empty server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Constraint: key count is intentionally incremental at this stage; groups are pre-created so subsequent feature commits can append keys without structural churn.
- **(2026-04-14)** `F002` completed: generated [`server/public/locales/fr/msp/contracts.json`](../../../../server/public/locales/fr/msp/contracts.json) from English source using placeholder-safe machine translation (`{{...}}` tokens protected/restored).
- **(2026-04-14)** Verification: `jq empty server/public/locales/fr/msp/contracts.json`.
- **(2026-04-14)** `F003` completed: generated [`server/public/locales/es/msp/contracts.json`](../../../../server/public/locales/es/msp/contracts.json) from English source with placeholder-safe machine translation.
- **(2026-04-14)** Verification: `jq empty server/public/locales/es/msp/contracts.json`.
- **(2026-04-14)** `F004` completed: generated [`server/public/locales/de/msp/contracts.json`](../../../../server/public/locales/de/msp/contracts.json) from English source with placeholder-safe machine translation.
- **(2026-04-14)** Verification: `jq empty server/public/locales/de/msp/contracts.json`.
MD && git add ee/docs/plans/2026-04-09-msp-i18n-contracts/features.json ee/docs/plans/2026-04-09-msp-i18n-contracts/SCRATCHPAD.md server/public/locales/de/msp/contracts.json && git commit -m "feat(F004): add german contracts locale namespace"- **(2026-04-14)** `F005` completed: generated [`server/public/locales/nl/msp/contracts.json`](../../../../server/public/locales/nl/msp/contracts.json) from English source with placeholder-safe machine translation.
- **(2026-04-14)** Verification: `jq empty server/public/locales/nl/msp/contracts.json`.
MD && git add ee/docs/plans/2026-04-09-msp-i18n-contracts/features.json ee/docs/plans/2026-04-09-msp-i18n-contracts/SCRATCHPAD.md server/public/locales/nl/msp/contracts.json && git commit -m "feat(F005): add dutch contracts locale namespace"- **(2026-04-14)** `F006` completed: generated [`server/public/locales/it/msp/contracts.json`](../../../../server/public/locales/it/msp/contracts.json) from English source with placeholder-safe machine translation.
- **(2026-04-14)** Italian accent audit note: machine output preserves accented graphemes where emitted by translator; full strict audit will be enforced again during `F009` (`validate-translations.cjs`).
- **(2026-04-14)** Verification: `jq empty server/public/locales/it/msp/contracts.json`.
- **(2026-04-14)** `F007` completed: generated [`server/public/locales/pl/msp/contracts.json`](../../../../server/public/locales/pl/msp/contracts.json) from English source with placeholder-safe machine translation.
- **(2026-04-14)** Verification: `jq empty server/public/locales/pl/msp/contracts.json`.
- **(2026-04-14)** `F008` completed: ran `node scripts/generate-pseudo-locales.cjs`, which regenerated pseudo-locales including `xx/msp/contracts.json` and `yy/msp/contracts.json`.
- **(2026-04-14)** Verification: `jq empty server/public/locales/xx/msp/contracts.json && jq empty server/public/locales/yy/msp/contracts.json` and spot-check confirmed `xx` values are `11111` patterns.
- **(2026-04-14)** `F009` completed: ran `node scripts/validate-translations.cjs` after adding `msp/contracts` locale files.
- **(2026-04-14)** Validation result: `Errors: 0`, `Warnings: 0`, `PASSED`.
- **(2026-04-14)** `F010` completed: updated `ROUTE_NAMESPACES['/msp/billing']` in `packages/core/src/lib/i18n/config.ts` to preload `msp/contracts` alongside existing billing namespaces.
- **(2026-04-14)** `F011` completed in `ContractDetail.tsx`: wired `useTranslation('msp/contracts')` and translated tab labels (`Overview`, `Contract Lines`, `Pricing Schedules`, `Documents`, `Invoices`), unsaved-changes warning copy, save-success toast/alert copy, system-managed-default informational alert copy, and validation alert heading/field labels.
- **(2026-04-14)** Added corresponding `contractDetail.alerts.*`, `contractDetail.systemManaged.*`, and `contractDetail.validation.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractDetail.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F012` completed in `ContractDetail.tsx`: translated Contract Details card title, `Contract Name *` and `Description` labels, `No description` fallback, contract-name/description placeholders, and the `System-managed default` badge. Added translated aria-label/title text for edit/save/cancel icon buttons in the details card.
- **(2026-04-14)** Added `contractDetail.detailsCard.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractDetail.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F013` completed in `ContractDetail.tsx`: localized the Contract Header card title/labels (`Status` / `Assignment Status`, billing frequency, currency, created, last updated), status badges/options (`Active`, `Draft`, `Terminated`, `Expired`), renewal summary labels (`Mode`, `Source`, `Notice`, `Decision Due`), renewal source values (`Tenant defaults`, `Custom settings`), and expired-status note.
- **(2026-04-14)** Migrated this file’s billing-frequency select from deprecated `BILLING_FREQUENCY_OPTIONS` constant to `useBillingFrequencyOptions()` hook.
- **(2026-04-14)** Added `contractDetail.headerCard.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractDetail.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F014` completed in `ContractDetail.tsx`: localized Client Ownership + Client Assignment sections (owner/client/status/start/end labels, empty states, `Ongoing`, PO labels + required/not-required text, and assignment action buttons). Localized renewal-handling editor labels (use-tenant-defaults toggle, renewal mode, notice period, renewal term, ticket board/status labels and placeholders) and read-only renewal summary text.
- **(2026-04-14)** Added `contractDetail.clientOwnership.*` and `contractDetail.clientAssignment.*` key groups and `common.labels.yes|no` to `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractDetail.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F015` completed in `ContractDetail.tsx`: localized Quick Actions card/button labels, footer Save/Cancel button text states (`Save Changes`, dirty-state variant, `Saving...`), discard/leave/delete confirmation dialogs, documents-tab loading text, invoice-tab title/help/refresh/loading/empty text, and invoice table column/preview labels.
- **(2026-04-14)** Currency formatting cleanup: replaced all hardcoded `formatCurrencyFromMinorUnits(..., 'en-US', ...)` usages in `ContractDetail.tsx` with locale-aware `useFormatters().formatCurrency` via a `formatMinorCurrency` helper.
- **(2026-04-14)** Added/expanded `contractDetail.quickActions.*`, `contractDetail.dialogs.*`, `contractDetail.documents.*`, and `contractDetail.invoices.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractDetail.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F016` completed in `ContractDialog.tsx`: wired `useTranslation('msp/contracts')` and localized dialog title, core form labels/placeholders (`Client`, `Contract Name`, `Billing Frequency`, `Currency`, `Start/End Date`, `Description`), renewal-settings labels/copy (`Renewal Mode`, `Use Tenant Renewal Defaults`, notice period, renewal term), and required-field validation messages.
- **(2026-04-14)** Migrated `ContractDialog.tsx` billing-frequency select from deprecated `BILLING_FREQUENCY_OPTIONS` to `useBillingFrequencyOptions()`.
- **(2026-04-14)** Added initial `contractDialog.title|actions|form|validation` keys to `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractDialog.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F017` completed in `ContractDialog.tsx`: localized PO section labels/copy (`Require Purchase Order`, PO number/amount labels/placeholders, note banner text) and preset-picker shell copy (section heading, loading/empty states, search placeholder, type filter labels, reset, no-match text, selected-count summary).
- **(2026-04-14)** Shared enum migration in this file: replaced deprecated `CONTRACT_LINE_TYPE_DISPLAY` option-builder with `useContractLineTypeOptions()` for the preset type filter.
- **(2026-04-14)** Expanded `contractDialog.presets.*` and `contractDialog.po.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractDialog.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F018` completed in `ContractDialog.tsx`: localized expanded preset detail content including fixed-rate configuration labels/help text, service summary copy, hourly-config labels, hourly/usage service field labels (`Quantity`, `Rate`, `Unit of Measure`), and default-rate helper text. Also translated all remaining tooltip/help copy in this file to `t(..., { defaultValue })` usage.
- **(2026-04-14)** Added `contractDialog.presetDetails.*` keys to `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractDialog.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F019` completed in `ContractTemplateDetail.tsx`: wired `useTranslation('msp/contracts')` and localized page-level header/back/error/loading copy, template badge/edit-toggle text, template basics edit-card labels/placeholders/actions, and template snapshot metadata labels (`Billing Frequency`, `Currency`, `Contract Lines`, `Created`, `Last Updated`).
- **(2026-04-14)** Shared enum migration in this file: replaced both `BILLING_FREQUENCY_OPTIONS` call sites with `useBillingFrequencyOptions()`.
- **(2026-04-14)** Added initial `templateDetail.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractTemplateDetail.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F020` completed in `ContractTemplateDetail.tsx`: localized the contract-lines composition area (section title, group headings, empty states, per-line service counts, service-detail labels, bucket summaries) and template-service manager labels/actions (manager title, empty hint, fixed-fee-rate label, edit-rate action).
- **(2026-04-14)** Added `templateDetail.composition.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractTemplateDetail.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F021` completed in `ContractTemplateDetail.tsx`: localized template guidance edit/review sections (`Usage Notes`, `Recommended Cadence`, `Tags`, placeholders/hints, save/cancel/saving labels) and translated template-level save/error feedback messages (`Template name is required`, billing-frequency required, failed-update basics/guidance, failed-load template).
- **(2026-04-14)** Added `templateDetail.guidance.*` and `templateDetail.validation.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractTemplateDetail.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F022` completed in `CreateCustomContractLineDialog.tsx`: wired `useTranslation('msp/contracts')`, localized dialog shell labels/actions, contract-line basics section, billing-frequency + billing-timing labels/options, billing-model selector copy (Fixed/Hourly/Usage cards), and top-level per-type section headers/descriptions.
- **(2026-04-14)** Shared enum migration in this file: replaced deprecated `BILLING_FREQUENCY_OPTIONS` with `useBillingFrequencyOptions()`.
- **(2026-04-14)** Added `createCustomLine.*` keys to `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/CreateCustomContractLineDialog.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F023` completed in `CreateCustomContractLineDialog.tsx`: localized form validation/error messages, bucket-overlay toggles (`Add bucket of hours/consumption`), and hourly minimum/round-up labels. Dialog create failure fallback message now uses `t()`.
- **(2026-04-14)** Added `createCustomLine.validation.*` plus additional bucket/hourly-label keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/CreateCustomContractLineDialog.tsx` (pass; warnings only, no errors).
- **(2026-04-14)** `F024` completed in `CreateCustomContractLineDialog.tsx`: localized fixed/hourly/usage service preview sections (section labels, item/service row labels, select placeholders, quantity/rate/unit labels, add buttons, empty states) and localized rate-helper displays with interpolation (`{{rate}}/hour`, `{{rate}}/{{unit}}`).
- **(2026-04-14)** Localized remaining help/tooltip-style explanatory alert copy in this dialog for Fixed/Hourly/Usage service configuration sections.
- **(2026-04-14)** Added `createCustomLine.*` keys for service preview and rate-display strings in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Repaired invalid `server/public/locales/en/msp/contracts.json` structure by reintegrating orphaned `contractDialog.documents|po|presets|presetDetails` and `templateDetail.composition` blocks back into the main object (file now parses via `jq`).
- **(2026-04-14)** Verification: `jq empty server/public/locales/en/msp/contracts.json` and `npx eslint packages/billing/src/components/billing-dashboard/contracts/CreateCustomContractLineDialog.tsx` (pass; warning-only lint).
- **(2026-04-14)** `F025` completed in `ContractLines.tsx`: wired `useTranslation('msp/contracts')` and localized section title/description, Add from Presets + Create Custom buttons, empty state copy, loading text, expand/collapse button labels, summary metadata labels (Name/Type/Frequency/Rate/Services), and action labels.
- **(2026-04-14)** Contract-line type/frequency summaries now use shared enum formatters via `useFormatContractLineType()` + `useFormatBillingFrequency()`.
- **(2026-04-14)** Added `contractLines.*` keys for top-level list UI in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractLines.tsx` (pass; warnings only) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F026` completed in `ContractLines.tsx`: localized inline edit/configuration UI (billing timing, cadence owner, minimum/round-up fields, fixed/usage guidance), service-detail labels, save/cancel/saving controls, inline loading text, and bucket section labels/value templates.
- **(2026-04-14)** Added translated delete confirmation before removing a contract line (`window.confirm` with interpolated line name).
- **(2026-04-14)** Localized error-state fallbacks for contract-lines load/refresh/remove/editability/update flows in this component.
- **(2026-04-14)** Expanded `contractLines.errors|dialogs|configuration|services|bucket|loading.inline` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractLines.tsx` (pass; warnings only) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F027` completed in `ContractLines.tsx`: localized expanded service-list labels (type label, quantity badge/field labels, hourly/unit/tax-allocation rate labels, unit-of-measure label/default, services section heading/count).
- **(2026-04-14)** Replaced `new Intl.NumberFormat('en-US', ...)` in `ContractLines.tsx` with locale-aware `useFormatters().formatCurrency(...)` for all rate displays; `formatRate` now uses active locale and tenant currency code.
- **(2026-04-14)** Removed unused `renderServiceDetails()` helper that still contained hardcoded English fragments and old locale formatting assumptions.
- **(2026-04-14)** Verification: `rg -n "new Intl.NumberFormat|en-US" packages/billing/src/components/billing-dashboard/contracts/ContractLines.tsx` (no matches) and `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractLines.tsx` (pass; warnings only).
- **(2026-04-14)** `F028` completed in `AddContractLinesDialog.tsx`: wired `useTranslation('msp/contracts')` and localized dialog title/header, search + type filter UI, reset action, loading/empty/no-match states, preset row metadata/service counts, select/deselect affordances, fixed-rate override labels, quantity/rate/unit field labels, and footer add/cancel actions.
- **(2026-04-14)** Shared enum migration in this file: replaced deprecated `CONTRACT_LINE_TYPE_DISPLAY` map with `useContractLineTypeOptions()` and used `useFormatContractLineType()` for preset type badges.
- **(2026-04-14)** Added initial `addLines.*` namespace keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/AddContractLinesDialog.tsx` (pass; warnings only), `rg -n "CONTRACT_LINE_TYPE_DISPLAY|_DISPLAY|_OPTIONS" .../AddContractLinesDialog.tsx` (no matches), and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F029` completed in `AddContractLinesDialog.tsx`: localized expanded preset detail sections (fixed-rate config, services reference/configuration, hourly overrides, usage quantity/rate/unit fields, default-rate helper text), plus empty-search and loading states.
- **(2026-04-14)** Added localized dialog-level validation/error feedback for preset load/details/add failures and rendered them via destructive `Alert`.
- **(2026-04-14)** Expanded `addLines.errors.*` and additional detail keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/AddContractLinesDialog.tsx` (pass; warnings only) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F030` completed in `Contracts.tsx`: wired `useTranslation('msp/contracts')`, localized sub-tab labels via point-of-use mapping (no hook usage in `contractsTabs.ts`), localized New/Create actions, search placeholders + aria labels, draft badge count aria text, loading copy, draft empty-state text, and fetch-error alert fallback.
- **(2026-04-14)** Added `contractsList.search|actions|drafts|loading|errors|empty` keys in `server/public/locales/en/msp/contracts.json` and introduced a local `contractSubtabLabels` mapping helper in `Contracts.tsx` to satisfy `contractsTabs.ts` consumption-point translation requirement.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/Contracts.tsx` (pass; warnings only) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F031` completed in `Contracts.tsx`: localized row action menus (edit/delete/resume/terminate/restore/set-active/discard + sr-only menu labels), status badges (active/draft/terminated/expired/published/archived), delete/discard confirmation dialogs (titles/messages/button labels with interpolation), and all related toast/error fallback messages.
- **(2026-04-14)** Expanded `contractsList.status|actions|dialogs|toasts|empty` keys in `server/public/locales/en/msp/contracts.json` to cover menu/dialog messaging and fallback record labels.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/Contracts.tsx` (pass; warnings only) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F032` completed in `Contracts.tsx`: localized all current column headers across templates/client/drafts tables, translated dash/description fallback cell values, and localized contracts loading indicator text.
- **(2026-04-14)** Added explicit translated empty states for template/client/draft filtered views (`noTemplates`, `noClientContracts`, `noDraftMatches`) so each sub-tab has user-visible empty-copy coverage.
- **(2026-04-14)** Expanded `contractsList.columns|heading|empty` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/Contracts.tsx` (pass; warnings only), `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F033` completed in `ClientContractsTab.tsx`: wired `useTranslation('msp/contracts')`, localized client-contract table headers (including added billing-frequency + PO indicator columns), status badges, search placeholder/aria labels, row action menu labels, and related fallback/toast copy.
- **(2026-04-14)** Added a localized terminate confirmation dialog flow (`contractToTerminate` state + `ConfirmationDialog`) so terminate is explicitly confirmed before mutation.
- **(2026-04-14)** Expanded `clientContracts.*` keys in `server/public/locales/en/msp/contracts.json` (columns, search, dialogs, toasts, PO labels, upcoming-renewals labels/statuses/actions/window options).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ClientContractsTab.tsx` (pass; warnings only) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F034` completed in `ClientContractsTab.tsx`: localized loading/error states, added translated empty-state rendering for filtered client contracts, and localized PO indicator column values (`Required` / `Not required`).
- **(2026-04-14)** Added `clientContracts.empty.noMatches` key in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ClientContractsTab.tsx` (pass; warnings only) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F035` completed in `ContractWizard.tsx`: wired `useTranslation('msp/contracts')`, localized wizard step labels via memoized `stepLabels`, localized step validation errors, translated create/edit wizard titles, and localized unsaved-changes confirmation dialog copy.
- **(2026-04-14)** Added `wizard.steps|wizard.validation|wizard.title|wizard.dialogs.unsavedChanges` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractWizard.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F036` completed in `ContractWizard.tsx`: localized recurring authoring validation output by switching from raw helper English strings to translated `wizard.validation.unsupportedRecurringAuthoringCombination` with interpolation for line type and billing frequencies. Added recurring frequency/line-type subkeys under `wizard.validation.recurring.*`.
- **(2026-04-14)** `F036` also standardized template-load and draft/create failure surfaces to namespace-backed fallback messages (`wizard.errors.failedToLoadTemplates|failedToLoadTemplateDetails|failedToCreateContract|failedToSaveDraft`) so user-visible wizard status copy stays translatable.
- **(2026-04-14)** Supporting shared-helper change: exported `getUnsupportedRecurringAuthoringCombination(...)` from `shared/billingClients/recurringAuthoringValidation.ts` so UIs can localize without parsing English text; retained `getUnsupportedRecurringAuthoringCombinationMessage(...)` for existing consumers/tests and preserved prior wording semantics (`annual` in the supported list fallback sentence).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractWizard.tsx shared/billingClients/recurringAuthoringValidation.ts packages/billing/tests/recurringAuthoringValidation.wiring.test.ts` (pass), `npx vitest run recurringAuthoringValidation.wiring.test.ts` from `packages/billing` (pass), and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F037` completed in `ContractOverview.tsx`: wired `useTranslation('msp/contracts')` and localized overview header/title, stat card labels, variable-summary note, and the `View details` link; service type badges now use shared enum formatter `useFormatContractLineType()` (Fixed/Hourly/Usage).
- **(2026-04-14)** Currency-formatting cleanup in `ContractOverview.tsx`: replaced hardcoded `new Intl.NumberFormat('en-US', ...)` path with `useFormatters().formatCurrency` via `formatCurrencyCents(...)`, keeping locale-aware output and translated money placeholder fallback.
- **(2026-04-14)** Added `contractOverview.title` + `contractOverview.stats.*` keys to `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractOverview.tsx` (pass; warnings only) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F038` completed in `ContractOverview.tsx`: localized line-card frequency and service-count copy, Included Services heading, no-services fallback, section-level Expand/Collapse all toggle, and no-lines empty-state/CTA text.
- **(2026-04-14)** Frequency labels now resolve through `useFormatBillingFrequency()` with localized fallbacks for values not covered by billing enums (`contractOverview.frequency.*`), preserving compatibility with both `semi-annually` and `semi_annually` inputs.
- **(2026-04-14)** Added `contractOverview.lines.*`, `contractOverview.frequency.*`, and `contractOverview.errors.failedToLoadOverview` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractOverview.tsx` (pass; warning-only `react-hooks/exhaustive-deps`), `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F039` completed in `PricingScheduleDialog.tsx`: wired `useTranslation('msp/contracts')` and localized dialog title/actions, all form labels/toggles/placeholders, duration-unit options, and validation/error fallback messages.
- **(2026-04-14)** Added `pricingSchedules.dialog.*` keys (actions, title, fields, duration units, validation, errors) in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/PricingScheduleDialog.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F040` completed in `PricingSchedules.tsx`: wired `useTranslation('msp/contracts')` and localized list header/title, table column headers, row action menu labels, delete confirmation text, read-only notice, empty-state copy, loading text, and timeline labels/value fallbacks (`Ongoing`, `Default rate`, `Use default rate`).
- **(2026-04-14)** Added `pricingSchedules.list.*` keys in `server/public/locales/en/msp/contracts.json` (actions, columns, dialogs, errors, loading, empty, timeline, values, read-only notice).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/PricingSchedules.tsx` (pass; warning-only `react-hooks/exhaustive-deps`) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F041` completed in `TemplatesTab.tsx`: wired `useTranslation('msp/contracts')`, localized template list column headers/status badges/search copy, create/edit/delete actions, loading and fetch/delete error fallbacks, and added explicit localized empty/no-match states for template searches.
- **(2026-04-14)** Added `templatesTab.*` keys to `server/public/locales/en/msp/contracts.json` (actions/columns/status/search/loading/errors/empty/values).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/TemplatesTab.tsx` (pass; warning-only `react-hooks/exhaustive-deps`) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F042` completed in `ServiceCatalogPicker.tsx`: wired `useTranslation('msp/contracts')` and localized picker placeholder, search placeholder, empty results text, product/service badges, and custom-item footer controls (`Custom` badge, add-as-custom text, type-name hint).
- **(2026-04-14)** Added `servicePicker.catalog.*` keys to `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ServiceCatalogPicker.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F043` completed in `ContractForm.tsx`: wired `useTranslation('msp/contracts')` and localized heading, field labels/placeholders, validation heading + required-field list labels, status option labels/expired helper note, and save button states.
- **(2026-04-14)** Shared enum migration in `ContractForm.tsx`: replaced deprecated `BILLING_FREQUENCY_OPTIONS` with `useBillingFrequencyOptions()` from `@alga-psa/billing/hooks/useBillingEnumOptions`.
- **(2026-04-14)** Added `contractForm.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractForm.tsx` (pass; existing warning-only `no-non-null-assertion`/`no-explicit-any`), `rg -n "BILLING_FREQUENCY_OPTIONS" .../ContractForm.tsx` (no matches), and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F044` completed in `QuickStartGuide.tsx`: wired `useTranslation('msp/contracts')` and localized collapsed/expanded guide titles, show/minimize/dismiss controls, all three step headings + descriptions + helper notes, billing model labels/descriptions, best-practices title/list items, and the create-first-contract CTA.
- **(2026-04-14)** Added `quickStart.*` key tree in `server/public/locales/en/msp/contracts.json` (actions, badge, subtitle, steps, billingModels, bestPractices).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/QuickStartGuide.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F045` completed in `BucketOverlayFields.tsx`: wired `useTranslation('msp/contracts')` and localized included-units label/tooltips, overage-rate label + tooltip with interpolated units, and rollover label/description with unit interpolation.
- **(2026-04-14)** Added `bucketOverlay.*` keys in `server/public/locales/en/msp/contracts.json` including `units.hour|hours|units` and placeholder strings.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/BucketOverlayFields.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F046` completed in `ContractLineEditDialog.tsx`: wired `useTranslation('msp/contracts')` and localized interpolated dialog title, pricing/timing section labels, timing options + contextual descriptions, validation fallback, and footer action states (`Save Changes` / `Saving...` / `Cancel`).
- **(2026-04-14)** Added `contractLineEdit.*` keys in `server/public/locales/en/msp/contracts.json` (title, sections, fields, timing options/descriptions, validation, actions, fallback values).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractLineEditDialog.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F047` completed in `ContractHeader.tsx`: wired `useTranslation('msp/contracts')`, localized stat labels, status badges, template/client-owned badges, ongoing value, and PO alert copy.
- **(2026-04-14)** Contract-header frequency display now uses shared enum formatter `useFormatBillingFrequency()` instead of local title-casing.
- **(2026-04-14)** Added `contractHeader.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractHeader.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F048` completed in `ContractDetailSwitcher.tsx`: wired `useTranslation('msp/contracts')` and localized all loading/error states (`missing contract id`, `contract not found`, `unable/failed to load details`, `no contract selected`, `Loading contract...`).
- **(2026-04-14)** Added `detailSwitcher.errors.*` + `detailSwitcher.loading.contract` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractDetailSwitcher.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F049` completed in `ContractLineRateDialog.tsx` and `ContractPlanRateDialog.tsx`: wired `useTranslation('msp/contracts')` in both dialogs and localized interpolated title, rate field label, validation fallback, and Save Rate/Cancel actions.
- **(2026-04-14)** Added shared `contractLineRate.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractLineRateDialog.tsx packages/billing/src/components/billing-dashboard/contracts/ContractPlanRateDialog.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F050` completed in `BillingFrequencyOverrideSelect.tsx`: wired `useTranslation('msp/contracts')` for label/description/placeholder/confirmation copy with interpolation and switched deprecated enum constants to hooks (`useBillingFrequencyOptions`, `useFormatBillingFrequency`).
- **(2026-04-14)** Added `frequencyOverride.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/BillingFrequencyOverrideSelect.tsx` (pass), `rg -n "BILLING_FREQUENCY_OPTIONS|BILLING_FREQUENCY_DISPLAY" .../BillingFrequencyOverrideSelect.tsx` (no matches), and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F051` completed in `ServicePicker.tsx`: wired `useTranslation('msp/contracts')` and localized default placeholder, search placeholder, and empty-message copy.
- **(2026-04-14)** Expanded `servicePicker.*` keys in `server/public/locales/en/msp/contracts.json` with top-level picker strings while preserving `servicePicker.catalog.*` for async catalog picker.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/ServicePicker.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F052` completed in `wizard-steps/ContractBasicsStep.tsx`: wired `useTranslation('msp/contracts')` for the step shell and first-section UX (heading/description, template picker labels + loading text + preview labels, client label/loading/select/hint, and contract-name label/placeholder/hint).
- **(2026-04-14)** Added `wizardBasics.heading|description|template.*|client.*|contractName.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.tsx` (pass; warnings only) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F053` completed in `wizard-steps/ContractBasicsStep.tsx`: localized remaining basics-step copy for billing frequency/cadence owner/currency/date fields, fixed-term + evergreen renewal blocks, optional description, PO configuration, and contract summary labels/values.
- **(2026-04-14)** Shared enum migration in this file: replaced deprecated `BILLING_FREQUENCY_OPTIONS` usage with `useBillingFrequencyOptions()` and `useFormatBillingFrequency()` for field options + summary display.
- **(2026-04-14)** Currency-formatting cleanup in summary PO amount: removed hardcoded `formatCurrencyFromMinorUnits(..., 'en-US', ...)` path in favor of locale-aware `useFormatters().formatCurrency`.
- **(2026-04-14)** Expanded `wizardBasics.*` key tree in `server/public/locales/en/msp/contracts.json` (billingFrequency, cadenceOwner, currency, dates, renewal, additionalDescription, po, summary with pluralized values).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.tsx` (pass; warning-only non-null assertions), `rg -n "BILLING_FREQUENCY_OPTIONS" .../ContractBasicsStep.tsx` (no matches), and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F054` completed in `wizard-steps/FixedFeeServicesStep.tsx`: wired `useTranslation('msp/contracts')` and localized step heading/description, fixed-fee explainer, base-rate section, proration copy, service picker labels/actions, empty-state text, recurring preview labels, and alternate billing-frequency override label.
- **(2026-04-14)** Added `wizardFixed.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/wizard-steps/FixedFeeServicesStep.tsx` (pass; warning-only pre-existing unused `BucketOverlayFields`/overlay helpers), `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F055` completed in `wizard-steps/ProductsStep.tsx`: wired `useTranslation('msp/contracts')` and localized step heading/description, product picker labels/placeholders, quantity + override-rate labels, default-price/helper/error copy, add-product action, and empty-state text.
- **(2026-04-14)** Added `wizardProducts.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ProductsStep.tsx` (pass; warning-only pre-existing unused `_` destructuring vars), and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F056` completed in `wizard-steps/HourlyServicesStep.tsx`: wired `useTranslation('msp/contracts')` and localized step heading/description, hourly explainer copy, minimum/round-up field labels+hints, service picker + hourly-rate labels, bucket toggle label, empty state, summary labels, and alternate billing-frequency override label.
- **(2026-04-14)** Added `wizardHourly.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/wizard-steps/HourlyServicesStep.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F057` completed in `wizard-steps/UsageBasedServicesStep.tsx`: wired `useTranslation('msp/contracts')` and localized step heading/description, usage explainer, service picker/unit-rate/unit-of-measure labels+helpers, bucket toggle label, empty-state copy, summary labels, and alternate billing-frequency override label.
- **(2026-04-14)** Added `wizardUsage.*` keys in `server/public/locales/en/msp/contracts.json`.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/wizard-steps/UsageBasedServicesStep.tsx` (pass) and `jq empty server/public/locales/en/msp/contracts.json` (pass).
- **(2026-04-14)** `F058` completed in `ReviewContractStep.tsx`: wired `useTranslation('msp/contracts')` and translated review heading/description plus Contract Basics labels (`Client`, `Contract Name`, `Billing Frequency`, `Currency`, `Start Date`, `End Date`, `Renewal Mode`, `Notice Period`, `Renewal Term`) and fallback values (`Not selected`, `Not specified`, `N/A`, `Ongoing`).
- **(2026-04-14)** Shared enum migration in this file (part 1): replaced `BILLING_FREQUENCY_OPTIONS` lookup with `useBillingFrequencyOptions()` for the Contract Basics billing-frequency display.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ReviewContractStep.tsx` (pass), `rg -n "formatCurrencyFromMinorUnits\\(|en-US" .../ReviewContractStep.tsx` (no matches), and `rg -n "BILLING_FREQUENCY_OPTIONS|BILLING_FREQUENCY_DISPLAY" .../ReviewContractStep.tsx` (no matches).
- **(2026-04-14)** `F059` completed in `ReviewContractStep.tsx`: localized all service summary sections (Fixed Fee, Products, Hourly, Usage-Based), including section headings/count badges, service rows, rate/unit displays, bucket summaries, PO requirements card, monthly total summary card, and final pre-submit checklist text.
- **(2026-04-14)** Shared enum migration in this file (part 2): replaced `BILLING_FREQUENCY_DISPLAY[...]` override renderers with `useFormatBillingFrequency()` for fixed/hourly/usage billing-frequency override labels.
- **(2026-04-14)** Expanded `wizardReview.*` keys in `server/public/locales/en/msp/contracts.json` to cover service summaries, recurring preview copy, PO labels, bucket interpolation strings, and checklist/total labels.
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ReviewContractStep.tsx` (pass), `jq empty server/public/locales/en/msp/contracts.json` (pass), and key coverage audit for all `wizardReview.*` usages in `ReviewContractStep.tsx` (`missing 0`).
- **(2026-04-14)** `F060` completed in `template-wizard/TemplateWizard.tsx`: wired `useTranslation('msp/contracts')` and localized template wizard step labels (`Template Basics`, `Fixed Fee Blocks`, `Products`, `Hourly Blocks`, `Usage-Based Blocks`, `Review & Publish`), dialog title, and navigation button labels (`Continue`, `Publish Template`).
- **(2026-04-14)** Localized template-wizard validation/errors for template name required, billing frequency required, duplicate name states, at-least-one-service requirement, failed-create fallback, and recurring-authoring unsupported-combination copy.
- **(2026-04-14)** Recurring validation migration: switched from raw `getUnsupportedRecurringAuthoringCombinationMessage()` string pass-through to structured `getUnsupportedRecurringAuthoringCombination()` + localized interpolation (`templateWizard.validation.unsupportedRecurringAuthoringCombination`) with translated line-type/frequency labels.
- **(2026-04-14)** Added `templateWizard.*` keys in `server/public/locales/en/msp/contracts.json` (`title`, `steps`, `actions`, `errors`, `validation`, and `validation.recurring.*`).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/template-wizard/TemplateWizard.tsx` (pass), `jq empty server/public/locales/en/msp/contracts.json` (pass), and `rg -n "Create Contract Template|Template Basics|Publish Template|Template name is required" .../TemplateWizard.tsx` (matches only `defaultValue` fallbacks).
- **(2026-04-14)** `F061` completed in `template-wizard/steps/TemplateContractBasicsStep.tsx`: wired `useTranslation('msp/contracts')` and localized step heading/description, Template Name label+placeholder+help text, Internal Notes label+placeholder+help text, and Recommended Billing Frequency label+placeholder+help text.
- **(2026-04-14)** Shared enum migration in this file: replaced deprecated `BILLING_FREQUENCY_OPTIONS` with `useBillingFrequencyOptions()` for the billing-frequency select.
- **(2026-04-14)** Added `templateBasics.*` keys in `server/public/locales/en/msp/contracts.json` (`heading`, `description`, `fields`, `placeholders`, `help`).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/template-wizard/steps/TemplateContractBasicsStep.tsx` (pass), `jq empty server/public/locales/en/msp/contracts.json` (pass), and `rg -n "BILLING_FREQUENCY_OPTIONS|BILLING_FREQUENCY_DISPLAY" .../TemplateContractBasicsStep.tsx` (no matches).
- **(2026-04-14)** `F062` completed in `template-wizard/steps/TemplateFixedFeeServicesStep.tsx`: wired `useTranslation('msp/contracts')` and localized step heading/description, fixed-fee explainer panel, cadence-owner labels/help/options, billing-timing label/options/placeholder, proration toggle label/help, service picker labels/placeholders, quantity helper text, and add-service action.
- **(2026-04-14)** Added translation wrappers for preview-specific fallback labels (`Unknown Service`, `Cadence Owner:`, `Billing Timing:`, `Service:`, `Invoice window:`) and ensured template-fixed keys are fully present under `templateFixed.*`.
- **(2026-04-14)** Added `templateFixed.*` keys in `server/public/locales/en/msp/contracts.json` (`heading`, `description`, `info`, `cadenceOwner`, `billingTiming`, `fields`, `placeholders`, `help`, `preview`, `actions`).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/template-wizard/steps/TemplateFixedFeeServicesStep.tsx` (pass), `jq empty server/public/locales/en/msp/contracts.json` (pass), and key coverage audit for `templateFixed.*` usages (`missing 0`).
- **(2026-04-14)** `F063` completed in `template-wizard/steps/TemplateProductsStep.tsx`: wired `useTranslation('msp/contracts')` and localized step heading/description, products section label, per-row product labels, select-product placeholder, quantity label/help text, and add-product action.
- **(2026-04-14)** Added translation wrapper for preview fallback `Unknown Product` and ensured all `templateProducts.*` usages are backed by locale keys.
- **(2026-04-14)** Added `templateProducts.*` keys in `server/public/locales/en/msp/contracts.json` (`heading`, `description`, `fields`, `placeholders`, `help`, `actions`, `preview`).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/template-wizard/steps/TemplateProductsStep.tsx` (pass), `jq empty server/public/locales/en/msp/contracts.json` (pass), and key coverage audit for `templateProducts.*` usages (`missing 0`).
- **(2026-04-14)** `F064` completed in `template-wizard/steps/TemplateHourlyServicesStep.tsx`: wired `useTranslation('msp/contracts')` and localized step heading/description, hourly explainer, time-rounding settings heading/labels/hints, service picker labels/placeholders, bucket toggle label, and add-service action.
- **(2026-04-14)** Added translation wrapper for preview fallback `Unknown Service` and ensured all `templateHourly.*` usages are backed by locale keys.
- **(2026-04-14)** Added `templateHourly.*` keys in `server/public/locales/en/msp/contracts.json` (`heading`, `description`, `info`, `rounding`, `fields`, `placeholders`, `preview`, `actions`).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/template-wizard/steps/TemplateHourlyServicesStep.tsx` (pass), `jq empty server/public/locales/en/msp/contracts.json` (pass), and key coverage audit for `templateHourly.*` usages (`missing 0`).
- **(2026-04-14)** `F065` completed in `template-wizard/steps/TemplateUsageBasedServicesStep.tsx`: wired `useTranslation('msp/contracts')` and localized step heading/description, usage explainer, services section labels, per-row service labels, unit-of-measure label/placeholder/help text, bucket-allocation toggle label, and add-service action.
- **(2026-04-14)** Added translation wrapper for preview fallback `Unknown Service` and ensured all `templateUsage.*` usages are backed by locale keys.
- **(2026-04-14)** Added `templateUsage.*` keys in `server/public/locales/en/msp/contracts.json` (`heading`, `description`, `info`, `fields`, `placeholders`, `help`, `preview`, `actions`).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/template-wizard/steps/TemplateUsageBasedServicesStep.tsx` (pass), `jq empty server/public/locales/en/msp/contracts.json` (pass), and key coverage audit for `templateUsage.*` usages (`missing 0`).
- **(2026-04-14)** `F066` completed in `template-wizard/steps/TemplateReviewContractStep.tsx`: wired `useTranslation('msp/contracts')` and localized review heading/description, Template Basics labels/fallbacks, service section titles, quantity/unit/bucket labels, cadence/billing summary labels, and bucket-summary interpolation strings.
- **(2026-04-14)** Added explicit empty-section indicators for each service group in review (`fixed`, `products`, `hourly`, `usage`) so the step always renders section-level feedback even with no selected services.
- **(2026-04-14)** Added `templateReview.*` keys in `server/public/locales/en/msp/contracts.json` (`sections`, `fields`, `fallback`, `empty`, `common`, `fixed`, `hourly`, `usage`, `bucket`).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/template-wizard/steps/TemplateReviewContractStep.tsx` (pass), `jq empty server/public/locales/en/msp/contracts.json` (pass), and key coverage audit for `templateReview.*` usages (`missing 0`).
- **(2026-04-14)** `F067` completed in `template-wizard/TemplateServicePreviewSection.tsx`: wired `useTranslation('msp/contracts')` and localized service type labels (`Fixed Fee`, `Products`, `Hourly`, `Usage-Based`), selected-services heading with interpolation (`{{type}}`, `{{count}}`), and the quantity label (`Qty:`).
- **(2026-04-14)** Localized preset-remove confirmation dialog title/message/confirm/cancel labels using interpolation (`{{serviceName}}`, `{{presetName}}`).
- **(2026-04-14)** Added `templatePreview.*` keys in `server/public/locales/en/msp/contracts.json` (`serviceType`, `selectedHeading`, `labels.qty`, `removeDialog.*`).
- **(2026-04-14)** Verification: `npx eslint packages/billing/src/components/billing-dashboard/contracts/template-wizard/TemplateServicePreviewSection.tsx` (pass), `jq empty server/public/locales/en/msp/contracts.json` (pass), and key coverage audit for `templatePreview.*` usages (`missing 0`).
- **(2026-04-14)** `T001` completed: ran `node scripts/generate-pseudo-locales.cjs && node scripts/validate-translations.cjs` after syncing missing `msp/contracts` keys from English into `de/es/fr/it/nl/pl` locale files.
- **(2026-04-14)** Validation result: `Errors: 0`, `Warnings: 0`, `PASSED` across `de/es/fr/it/nl/pl/xx/yy`.
- **(2026-04-14)** Locale maintenance note: this pass only backfilled missing keys for parity; existing translated values were preserved, and newly introduced keys currently default to English text until follow-up translation refresh.
- **(2026-04-14)** `T002` completed: added `packages/billing/tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` with a ContractDetail tab-label wiring assertion (`contractDetail.tabs.overview|lines|pricing|documents|invoices`) validating both source `t(...)` usage and English locale key presence.
- **(2026-04-14)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-14)** `T003` completed: extended `ContractsSubbatch.i18n.test.ts` with ContractDetail alert-key coverage (`contractDetail.alerts.unsavedChanges`, `contractDetail.alerts.saveSuccess`) and English-locale value assertions.
- **(2026-04-14)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-14)** `T004` completed: extended `ContractsSubbatch.i18n.test.ts` with details-card wiring checks covering `contractDetail.detailsCard.*` labels and edit/save/cancel action keys plus `contractDetail.labels.noDescription` locale presence.
- **(2026-04-14)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` (pass; 1 file, 3 tests).
- **(2026-04-15)** `T005` completed: extended `packages/billing/tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` with ContractDetail header-card i18n coverage for status/billing/currency/renewal labels (`contractDetail.headerCard.*`, `status.*`, `renewal.*`, `common.labels.*`) and English locale key-presence assertions.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` (pass; 1 file, 4 tests).
- **(2026-04-15)** `T006` completed: extended `packages/billing/tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` with Client Ownership + Client Assignment coverage asserting translated labels for cards, PO fields, yes/no + ongoing values, and the no-client-assigned empty state.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` (pass; 1 file, 5 tests).
- **(2026-04-15)** `T007` completed: added ContractDetail assertions for translated quick-action buttons, footer save/cancel/saving labels, and discard/unsaved/delete confirmation dialog copy in `ContractsSubbatch.i18n.test.ts`.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` (pass; 1 file, 6 tests).
- **(2026-04-15)** `T008` completed: added invoice-tab i18n coverage in `ContractsSubbatch.i18n.test.ts` for ContractDetail title/help text, refresh CTA, loading/empty/no-template states, invoice preview label, and table column headers.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` (pass; 1 file, 7 tests).
- **(2026-04-15)** `T009` completed: added pseudo-locale guard in `ContractsSubbatch.i18n.test.ts` that extracts all `ContractDetail.tsx` translation keys and asserts each resolves to `xx` pseudo values (`11111` pattern), covering all tabs.
- **(2026-04-15)** Discovery/fix: `contractDetail.documents.loading` was referenced in `ContractDetail.tsx` but missing from locale JSON. Added `contractDetail.documents.loading` to all 9 locale files (`en/de/es/fr/it/nl/pl/xx/yy`) with pseudo values for `xx`/`yy`.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsSubbatch.i18n.test.ts` (pass; 1 file, 8 tests) and `node scripts/validate-translations.cjs` (pass; Errors: 0, Warnings: 0).
- **(2026-04-15)** `T010` completed: added `packages/billing/tests/billing-dashboard/ContractDialog.i18n.test.ts` with coverage for ContractDialog title/form/renewal labels and validation keys, asserting both source `t(...)` usage and English locale-key presence.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractDialog.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T011` completed: extended `ContractDialog.i18n.test.ts` with PO section and preset-picker coverage (labels, helper copy, loading/empty/no-match states, selected-count copy, and preset detail headings), validating source key usage + English locale presence.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractDialog.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T012` completed: added pseudo-locale coverage in `ContractDialog.i18n.test.ts` by extracting all `t('...')` keys from `ContractDialog.tsx` and asserting each resolves to `xx` pseudo-locale values (`11111`), guarding against fallback English leakage.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractDialog.i18n.test.ts` (pass; 1 file, 3 tests).
- **(2026-04-15)** `T013` completed: added `packages/billing/tests/billing-dashboard/ContractTemplateDetail.i18n.test.ts` with page-level i18n assertions for loading/error header copy, back-to-templates actions, template badge/snapshot labels, and key section labels used by ContractTemplateDetail.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractTemplateDetail.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T014` completed: extended `ContractTemplateDetail.i18n.test.ts` with template composition + service-manager coverage for grouped line headings, empty states, service-count copy, inline service labels, bucket/minutes formatting labels, and service management action text.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractTemplateDetail.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T015` completed: extended `ContractTemplateDetail.i18n.test.ts` to validate translated cadence labels in `ContractTemplateDetail.tsx` and billing-timing option/description labels used in the template line edit flow (`ContractLineEditDialog.tsx`).
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractTemplateDetail.i18n.test.ts` (pass; 1 file, 3 tests).
- **(2026-04-15)** `T016` completed: added pseudo-locale coverage in `ContractTemplateDetail.i18n.test.ts` by extracting all `t('...')` keys used in `ContractTemplateDetail.tsx` and asserting each resolves to `xx` pseudo values (`11111`).
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractTemplateDetail.i18n.test.ts` (pass; 1 file, 4 tests).
- **(2026-04-15)** `T017` completed: added `packages/billing/tests/billing-dashboard/CreateCustomContractLineDialog.i18n.test.ts` with i18n wiring assertions for dialog shell labels, billing-frequency/timing controls, billing-model selector copy, and service-picker labels.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/CreateCustomContractLineDialog.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T018` completed: extended `CreateCustomContractLineDialog.i18n.test.ts` with coverage for bucket/proration copy and validation surfaces (all `createCustomLine.validation.*` keys + validation prefix), ensuring translated labels and errors are wired.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/CreateCustomContractLineDialog.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T019` completed: added pseudo-locale coverage in `CreateCustomContractLineDialog.i18n.test.ts` by extracting all dialog `t('...')` keys and asserting they resolve to `xx` pseudo values (`11111`).
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/CreateCustomContractLineDialog.i18n.test.ts` (pass; 1 file, 3 tests).
- **(2026-04-15)** `T020` completed: added `packages/billing/tests/billing-dashboard/ContractLines.i18n.test.ts` with coverage for ContractLines header/description, add/create actions, expand/collapse controls, summary column labels, service-count copy, loading copy, and empty-state text.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractLines.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T021` completed: extended `ContractLines.i18n.test.ts` with inline-edit and service-detail coverage (configuration labels, timing/cadence labels, service/bucket detail labels, delete confirmation, and editability error text).
- **(2026-04-15)** Discovery/fix: `billing.labels.cadenceOwner` was referenced in `ContractLines.tsx` but missing from locale files. Added the key across all 9 `msp/contracts` locale files (`en/de/es/fr/it/nl/pl/xx/yy`) with pseudo values for `xx`/`yy`.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractLines.i18n.test.ts` (pass; 1 file, 2 tests) and `node scripts/validate-translations.cjs` (pass; Errors: 0, Warnings: 0).
- **(2026-04-15)** `T022` completed: added pseudo-locale coverage in `ContractLines.i18n.test.ts` by extracting all `t('...')` keys used in `ContractLines.tsx` and asserting they resolve to `xx` pseudo values (`11111`).
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractLines.i18n.test.ts` (pass; 1 file, 3 tests).
- **(2026-04-15)** `T023` completed: added `packages/billing/tests/billing-dashboard/AddContractLinesDialog.i18n.test.ts` covering AddContractLinesDialog shell copy (title/search/filter/reset/loading/empty), add-action labels, and preset-selection count labels.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/AddContractLinesDialog.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T024` completed: extended `AddContractLinesDialog.i18n.test.ts` with expanded preset-detail coverage (fixed/hourly/usage configuration labels + helper copy) and dialog-level loading/empty/error states.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/AddContractLinesDialog.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T025` completed: added `packages/billing/tests/billing-dashboard/Contracts.i18n.test.ts` covering Contracts sub-tab labels (point-of-use translation), create actions, search placeholders/aria labels, drafts badge copy, and page heading/loading/error labels.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/Contracts.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T026` completed: extended `Contracts.i18n.test.ts` with row-action menu, confirmation dialog, and toast/operation-status i18n coverage for templates/client contracts/drafts workflows.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/Contracts.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T027` completed: extended `Contracts.i18n.test.ts` with all active table-column header key checks across template, client, and draft views, plus related per-subtab empty/loading labels.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/Contracts.i18n.test.ts` (pass; 1 file, 3 tests).
- **(2026-04-15)** `T028` completed: added pseudo-locale coverage in `Contracts.i18n.test.ts` by extracting all `t('...')` keys from `Contracts.tsx` and asserting they resolve to `xx` pseudo values (`11111`).
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/Contracts.i18n.test.ts` (pass; 1 file, 4 tests).
- **(2026-04-15)** `T029` completed: added `packages/billing/tests/billing-dashboard/ClientContractsTab.i18n.test.ts` with i18n assertions for client-contract table columns, PO indicator labels, status badge labels, top-level tab labels, and search placeholder/aria text.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ClientContractsTab.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T030` completed: extended `ClientContractsTab.i18n.test.ts` with loading/error/empty-state checks and terminate-confirmation dialog copy coverage, plus related operation failure toasts.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ClientContractsTab.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T031` completed: added `packages/billing/tests/billing-dashboard/ContractWizard.i18n.test.ts` with ContractWizard step-label i18n checks (`wizard.steps.*`) plus translated create/edit wizard title keys.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractWizard.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T032` completed: extended `ContractWizard.i18n.test.ts` with validation/error coverage for required wizard fields, recurring-authoring unsupported-combination copy (including dynamic recurring key usage checks), save-draft/create failure messages, and unsaved-changes confirmation dialog labels.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractWizard.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T033` completed: added `packages/billing/tests/billing-dashboard/ContractOverview.i18n.test.ts` with stat-card and overview-heading i18n assertions for `ContractOverview.tsx`.
- **(2026-04-15)** Discovery/fix: `common.moneyPlaceholder` was referenced in `ContractOverview.tsx` but missing from `msp/contracts` locale files. Added it across all 9 locales (`en/de/es/fr/it/nl/pl/xx/yy`) with pseudo values for `xx`/`yy`.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractOverview.i18n.test.ts` (pass; 1 file, 1 test) and `node scripts/validate-translations.cjs` (pass; Errors: 0, Warnings: 0).
- **(2026-04-15)** `T034` completed: extended `ContractOverview.i18n.test.ts` with line-card coverage for service-count interpolation keys, included-services/no-services labels, expand/collapse controls, and no-lines empty-state copy; also asserted dynamic frequency-key usage and fallback-frequency key presence.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractOverview.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T035` completed: added `packages/billing/tests/billing-dashboard/PricingSchedules.i18n.test.ts` with list + dialog coverage for pricing schedules (title/columns/actions/loading/empty/timeline copy and dialog fields/actions/validation/errors).
- **(2026-04-15)** Discovery/fix: `common.actions.openMenu` and `common.notAvailable` were referenced in `PricingSchedules.tsx` but missing from `msp/contracts` locales. Added both keys across all 9 locales (`en/de/es/fr/it/nl/pl/xx/yy`) with pseudo values for `xx`/`yy`.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/PricingSchedules.i18n.test.ts` (pass; 1 file, 1 test) and `node scripts/validate-translations.cjs` (pass; Errors: 0, Warnings: 0).
- **(2026-04-15)** `T036` completed: added `packages/billing/tests/billing-dashboard/TemplatesTab.i18n.test.ts` with coverage for TemplatesTab columns/status labels, search placeholders, row actions, loading/error/empty copy, and menu accessibility label.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/TemplatesTab.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T037` completed: added `packages/billing/tests/billing-dashboard/ContractForm.i18n.test.ts` with i18n coverage for ContractForm heading/fields, status options + expired helper, validation/error copy, and save button states.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractForm.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T038` completed: added `packages/billing/tests/billing-dashboard/QuickStartGuide.i18n.test.ts` with full QuickStart content-key coverage (actions, steps, billing-model labels/descriptions, and best-practice items).
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/QuickStartGuide.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T039` completed: extended `QuickStartGuide.i18n.test.ts` with pseudo-locale coverage by extracting all `QuickStartGuide.tsx` translation keys and asserting `xx` values use the pseudo pattern (`11111`).
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/QuickStartGuide.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T040` completed: added `packages/billing/tests/billing-dashboard/BucketOverlayFields.i18n.test.ts` with bucket-overlay i18n assertions for included/overage/rollover labels/tooltips/placeholders and unit strings.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/BucketOverlayFields.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T041` completed: added `packages/billing/tests/billing-dashboard/ContractLineEditDialog.i18n.test.ts` with translation-key assertions for dialog title interpolation, pricing/timing section labels, timing options/descriptions, validation/error copy, and save/cancel states.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractLineEditDialog.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T042` completed: added `packages/billing/tests/billing-dashboard/ContractHeader.i18n.test.ts` with translation-key checks for stat labels, status badges, template/client-owned badges, ongoing/not-available values, and PO-required alert copy.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractHeader.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T043` completed: added `packages/billing/tests/billing-dashboard/ContractDetailSwitcher.i18n.test.ts` to assert `ContractDetailSwitcher.tsx` wires all loading/error states through `t('detailSwitcher.*')` in `msp/contracts` and that matching English locale keys exist.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractDetailSwitcher.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T044` completed: added `packages/billing/tests/billing-dashboard/ContractLineRateDialog.i18n.test.ts` with assertions that both `ContractLineRateDialog.tsx` and `ContractPlanRateDialog.tsx` use `contractLineRate.*` translation keys for title interpolation, rate field label, validation copy, and action labels.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractLineRateDialog.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T045` completed: added `packages/billing/tests/billing-dashboard/BillingFrequencyOverrideSelect.i18n.test.ts` to verify label/description/placeholder/confirmation strings are wired to `frequencyOverride.*` keys with interpolation variables sourced from formatted billing-frequency labels.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/BillingFrequencyOverrideSelect.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T046` completed: added `packages/billing/tests/billing-dashboard/ServicePicker.i18n.test.ts` verifying picker placeholder/search/empty states are sourced from `servicePicker.*` translation keys and exist in `en/msp/contracts.json`.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ServicePicker.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T047` completed: added `packages/billing/tests/billing-dashboard/ContractBasicsStep.i18n.test.ts` with assertions covering translated heading/description, template picker labels/loading copy, client picker labels/hint, and contract-name field copy in `ContractBasicsStep.tsx`.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractBasicsStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T048` completed: extended `packages/billing/tests/billing-dashboard/ContractBasicsStep.i18n.test.ts` to assert renewal-mode/cadence-owner/PO copy and summary labels are translated in `ContractBasicsStep.tsx`, including pluralized locale coverage for `noticePeriodDays_*` and `renewalTermMonths_*`.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractBasicsStep.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T049` completed: added `packages/billing/tests/billing-dashboard/FixedFeeServicesStep.i18n.test.ts` covering translated heading/description, base-rate + proration labels, service picker labels, empty state, and alternate billing-frequency label in `FixedFeeServicesStep.tsx`.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/FixedFeeServicesStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T050` completed: added `packages/billing/tests/billing-dashboard/ProductsStep.i18n.test.ts` with assertions for translated step heading/description, product picker labels, quantity/override-rate/default-price copy, validation messages, add action, and empty state in `ProductsStep.tsx`.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ProductsStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T051` completed: added `packages/billing/tests/billing-dashboard/HourlyServicesStep.i18n.test.ts` validating translated step/explainer copy, minimum-time and round-up labels/hints, service picker/hourly-rate labels, add action, empty state, and alternate frequency label.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/HourlyServicesStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T052` completed: added `packages/billing/tests/billing-dashboard/UsageBasedServicesStep.i18n.test.ts` validating translated heading/description, service picker labels, unit-rate/unit-of-measure copy, bucket toggle label, add action, empty state, and alternate frequency label.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/UsageBasedServicesStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T053` completed: added `packages/billing/tests/billing-dashboard/ReviewContractStep.i18n.test.ts` asserting Contract Basics heading/field labels, renewal-mode labels, and fallback values (`Not selected`, `Not specified`, `N/A`, `Ongoing`) are translation-key backed.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ReviewContractStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T054` completed: extended `packages/billing/tests/billing-dashboard/ReviewContractStep.i18n.test.ts` with coverage for fixed/products/hourly/usage summary sections, rate and bucket interpolation keys, PO summary labels, monthly-total card, and final checklist copy.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ReviewContractStep.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T055` completed: added `packages/billing/tests/billing-dashboard/TemplateWizard.i18n.test.ts` verifying template-wizard step labels/actions/validation/errors are translation-key driven, including dynamic recurring line-type/frequency lookups and locale-key presence.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/TemplateWizard.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T056` completed: added `packages/billing/tests/billing-dashboard/TemplateContractBasicsStep.i18n.test.ts` with key assertions for step heading/description plus template-name, internal-notes, and recommended-billing-frequency labels/placeholders/help text.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/TemplateContractBasicsStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T057` completed: added `packages/billing/tests/billing-dashboard/TemplateFixedFeeServicesStep.i18n.test.ts` verifying translated step/explainer/cadence-owner/billing-timing labels, service picker fields, add action, and preview copy.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/TemplateFixedFeeServicesStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T058` completed: added `packages/billing/tests/billing-dashboard/TemplateProductsStep.i18n.test.ts` to validate translated heading/description, product picker labels/placeholders/help, add action, and unknown-product preview fallback.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/TemplateProductsStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T059` completed: added `packages/billing/tests/billing-dashboard/TemplateHourlyServicesStep.i18n.test.ts` with assertions for translated heading/explainer, rounding settings labels/help, service picker fields, bucket toggle label, add action, and preview fallback copy.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/TemplateHourlyServicesStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T060` completed: added `packages/billing/tests/billing-dashboard/TemplateUsageBasedServicesStep.i18n.test.ts` to verify translated heading/explainer copy, service picker + unit-of-measure labels/placeholders/help, bucket allocation label, add action, and preview fallback.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/TemplateUsageBasedServicesStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T061` completed: added `packages/billing/tests/billing-dashboard/TemplateReviewContractStep.i18n.test.ts` with key assertions for review sections, empty states, service summary labels, cadence/billing labels, and bucket interpolation strings.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/TemplateReviewContractStep.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T062` completed: added `packages/billing/tests/billing-dashboard/TemplateServicePreviewSection.i18n.test.ts` to assert service-type labels, selected-services heading interpolation, quantity label, and remove-confirmation dialog copy are translation-key backed.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/TemplateServicePreviewSection.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T063` completed: added `packages/billing/tests/billing-dashboard/ContractsIntegration.i18n.test.ts` integration-style coverage validating `/msp/billing` route namespace preload includes `msp/contracts`, Contracts/Templates/ClientContracts components use `useTranslation('msp/contracts')`, sub-tab labels are translated at consumption (`common.tabs.*`), and all extracted `t('...')` keys across these files resolve in English locale.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsIntegration.i18n.test.ts` (pass; 1 file, 1 test).
- **(2026-04-15)** `T064` completed: extended `ContractsIntegration.i18n.test.ts` with German-locale integration assertions covering contracts sub-tab labels, key presence for columns/actions, and source wiring for translated sub-tab/column/action-menu keys. Added explicit de-vs-en differentiation checks for `common.tabs.*` labels.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsIntegration.i18n.test.ts` (pass; 1 file, 2 tests).
- **(2026-04-15)** `T065` completed: extended integration coverage to validate contract-detail route translation wiring across `ContractDetail.tsx`, `ContractLines.tsx`, and `PricingSchedules.tsx`; asserts all extracted translation keys resolve in both `en` and `de`, plus explicit de-vs-en localization checks for detail tab labels (`overview/lines/pricing/documents/invoices`).
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsIntegration.i18n.test.ts` (pass; 1 file, 3 tests).
- **(2026-04-15)** `T066` completed: extended integration coverage for the contract creation wizard (`ContractWizard` + all six wizard-step components). The test extracts all literal `t('...')` keys, verifies key-set breadth (`>220`), and asserts locale resolution in both `en` and `de` (with plural-handling checks for `wizardBasics.summary.values.noticePeriodDays_*` and `renewalTermMonths_*`).
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsIntegration.i18n.test.ts` (pass; 1 file, 4 tests).
- **(2026-04-15)** `T067` completed: extended integration coverage for template creation flow (`TemplateWizard` + all template-step components + `TemplateServicePreviewSection`). The test extracts literal translation keys (`>120`) and verifies key resolution across both `en` and `de` locales.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsIntegration.i18n.test.ts` (pass; 1 file, 5 tests).
- **(2026-04-15)** `T068` completed: extended integration suite with `QuickStartGuide` coverage asserting all extracted translation keys resolve in `de` and pseudo-locale `xx`; pseudo assertions (`contains '11111'`) enforce that visible quick-start copy is translation-driven rather than hardcoded.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsIntegration.i18n.test.ts` (pass; 1 file, 6 tests).
- **(2026-04-15)** `T069` completed: added locale-format integration assertions in `ContractsIntegration.i18n.test.ts` ensuring both `ContractDetail.tsx` and `ReviewContractStep.tsx` avoid hardcoded `'en-US'`/`formatCurrencyFromMinorUnits(...)` and use `useFormatters().formatCurrency` via local minor-unit helpers.
- **(2026-04-15)** Verification: `cd packages/billing && npx vitest run tests/billing-dashboard/ContractsIntegration.i18n.test.ts` (pass; 1 file, 7 tests).
