Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
91 KiB
91 KiB
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/contractsnamespace rather than cramming keys intofeatures/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.tsexports pure string constants (CONTRACT_SUBTAB_LABELS,CONTRACT_TAB_LABELS). These cannot useuseTranslation()because the file is not a React component. Translate the consumed values at point-of-use inContracts.tsxandClientContractsTab.tsxinstead. - (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) createdpackages/billing/src/hooks/useBillingEnumOptions.tswithuseBillingFrequencyOptions,useFormatBillingFrequency,useContractLineTypeOptions,useFormatContractLineType, and addedenums.billingFrequency.*/enums.contractLineType.*tofeatures/billing.jsonin 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/*_OPTIONSexports inpackages/billing/src/constants/billing.tswere 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.tsmigration shape: keepCONTRACT_SUBTAB_LABELSas a value-to-value mapping only ifCONTRACT_LABEL_TO_SUBTABstill needs it as an identifier lookup. For display, add auseContractSubtabLabels()helper colocated with the consumers (Contracts.tsx/ClientContractsTab.tsx) that returns{ templates: t('...'), 'client-contracts': t('...'), drafts: t('...') }. Store/compare tab state byContractSubTabvalue, never by label. Keys go inmsp/contracts.jsonunder (suggested)common.tabs.*orenums.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 informatCurrencyFromMinorUnits()calls with locale fromuseFormatters(). Affects ContractDetail.tsx (invoice columns, PO amount display), ContractOverview.tsx, ReviewContractStep.tsx. TheformatCurrencyFromMinorUnitsutility accepts a locale parameter. - (2026-04-09) Do NOT translate
throw new Error(...)messages orconsole.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.tsxat 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) andContractPlanRateDialog.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 usingt()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.tsxhas a localformatFrequency()that maps frequency keys to display strings ('Weekly', 'Monthly', etc.). These should uset()rather than a local map. Same pattern inContractHeader.tsx. (2026-04-14 update): Formonthly/quarterly/annuallyspecifically, useuseFormatBillingFrequency()from@alga-psa/billing/hooks/useBillingEnumOptionsso these renderers share the samefeatures/billing.jsonkeys as the rest of the contract-lines UI.weeklyandbiweeklyare not in the shared enum — ifContractOverview.tsxneeds them, keep a localt()lookup for those two values only or extendBILLING_FREQUENCY_VALUES(check whether the backend can actually emit them first). - (2026-04-09)
ContractWizard.tsxdefinesSTEPSas aconsttuple:['Contract Basics', 'Fixed Fee Services', 'Products', 'Hourly Services', 'Usage-Based Services', 'Review & Create']. These are passed toWizardProgressandWizardNavigation. They need to be translated. Options: (a) convert to keys and translate in the component, (b) wrap witht()in a useMemo. Option (b) is simpler -- translate at point of use. - (2026-04-09) Same STEPS pattern in
TemplateWizard.tsxwithTEMPLATE_STEPS. - (2026-04-09)
BucketOverlayFields.tsxuses dynamic unit labels ('hours' vs custom unitLabel). The translation key should use interpolation:t('bucketOverlay.includedLabel', { units: resolvedUnitLabel }). - (2026-04-09)
TemplateServicePreviewSection.tsxuses 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 useuseFormatters().formatCurrency()or pass the active locale toformatCurrencyFromMinorUnits(). - (2026-04-09)
ContractDialog.tsxis 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_NAMESPACESfor/msp/billingcurrently loads:['common', 'msp/core', 'features/billing', 'msp/reports']. Adding'msp/contracts'is straightforward -- it just appends to the array. Check ifmsp/quoteswas also added recently (per the quotes sub-batch plan) to avoid merge conflicts. - (2026-04-09)
ServicePicker.tsx(56 LOC) andServiceCatalogPicker.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.tsxcontains substantial prose content (step descriptions, billing model explanations, best practices list). These are long strings but straightforward to extract. Use descriptive keys likequickStart.step1.description,quickStart.bestPractices.item1. - (2026-04-09)
contractsTabs.ts(27 LOC, no React) definesCONTRACT_SUBTAB_LABELSandCONTRACT_TAB_LABELS. These are consumed inContracts.tsxviaCustomTabsand inClientContractsTab.tsx. The tab component likely accepts string labels, so translate at the consumption point. Do NOT adduseTranslation()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.tsxhardcodes$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 informatCurrencyFromMinorUnitscalls 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)
F001completed: createdserver/public/locales/en/msp/contracts.jsonwith 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)
F002completed: generatedserver/public/locales/fr/msp/contracts.jsonfrom 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)
F003completed: generatedserver/public/locales/es/msp/contracts.jsonfrom English source with placeholder-safe machine translation. - (2026-04-14) Verification:
jq empty server/public/locales/es/msp/contracts.json. - (2026-04-14)
F004completed: generatedserver/public/locales/de/msp/contracts.jsonfrom 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)F005completed: generatedserver/public/locales/nl/msp/contracts.jsonfrom 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)F006completed: generatedserver/public/locales/it/msp/contracts.jsonfrom 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)
F007completed: generatedserver/public/locales/pl/msp/contracts.jsonfrom English source with placeholder-safe machine translation. - (2026-04-14) Verification:
jq empty server/public/locales/pl/msp/contracts.json. - (2026-04-14)
F008completed: rannode scripts/generate-pseudo-locales.cjs, which regenerated pseudo-locales includingxx/msp/contracts.jsonandyy/msp/contracts.json. - (2026-04-14) Verification:
jq empty server/public/locales/xx/msp/contracts.json && jq empty server/public/locales/yy/msp/contracts.jsonand spot-check confirmedxxvalues are11111patterns. - (2026-04-14)
F009completed: rannode scripts/validate-translations.cjsafter addingmsp/contractslocale files. - (2026-04-14) Validation result:
Errors: 0,Warnings: 0,PASSED. - (2026-04-14)
F010completed: updatedROUTE_NAMESPACES['/msp/billing']inpackages/core/src/lib/i18n/config.tsto preloadmsp/contractsalongside existing billing namespaces. - (2026-04-14)
F011completed inContractDetail.tsx: wireduseTranslation('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.*, andcontractDetail.validation.*keys inserver/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)
F012completed inContractDetail.tsx: translated Contract Details card title,Contract Name *andDescriptionlabels,No descriptionfallback, contract-name/description placeholders, and theSystem-managed defaultbadge. Added translated aria-label/title text for edit/save/cancel icon buttons in the details card. - (2026-04-14) Added
contractDetail.detailsCard.*keys inserver/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)
F013completed inContractDetail.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_OPTIONSconstant touseBillingFrequencyOptions()hook. - (2026-04-14) Added
contractDetail.headerCard.*keys inserver/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)
F014completed inContractDetail.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.*andcontractDetail.clientAssignment.*key groups andcommon.labels.yes|notoserver/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)
F015completed inContractDetail.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 inContractDetail.tsxwith locale-awareuseFormatters().formatCurrencyvia aformatMinorCurrencyhelper. - (2026-04-14) Added/expanded
contractDetail.quickActions.*,contractDetail.dialogs.*,contractDetail.documents.*, andcontractDetail.invoices.*keys inserver/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)
F016completed inContractDialog.tsx: wireduseTranslation('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.tsxbilling-frequency select from deprecatedBILLING_FREQUENCY_OPTIONStouseBillingFrequencyOptions(). - (2026-04-14) Added initial
contractDialog.title|actions|form|validationkeys toserver/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)
F017completed inContractDialog.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_DISPLAYoption-builder withuseContractLineTypeOptions()for the preset type filter. - (2026-04-14) Expanded
contractDialog.presets.*andcontractDialog.po.*keys inserver/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)
F018completed inContractDialog.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 tot(..., { defaultValue })usage. - (2026-04-14) Added
contractDialog.presetDetails.*keys toserver/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)
F019completed inContractTemplateDetail.tsx: wireduseTranslation('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_OPTIONScall sites withuseBillingFrequencyOptions(). - (2026-04-14) Added initial
templateDetail.*keys inserver/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)
F020completed inContractTemplateDetail.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 inserver/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)
F021completed inContractTemplateDetail.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.*andtemplateDetail.validation.*keys inserver/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)
F022completed inCreateCustomContractLineDialog.tsx: wireduseTranslation('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_OPTIONSwithuseBillingFrequencyOptions(). - (2026-04-14) Added
createCustomLine.*keys toserver/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)
F023completed inCreateCustomContractLineDialog.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 usest(). - (2026-04-14) Added
createCustomLine.validation.*plus additional bucket/hourly-label keys inserver/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)
F024completed inCreateCustomContractLineDialog.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 inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Repaired invalid
server/public/locales/en/msp/contracts.jsonstructure by reintegrating orphanedcontractDialog.documents|po|presets|presetDetailsandtemplateDetail.compositionblocks back into the main object (file now parses viajq). - (2026-04-14) Verification:
jq empty server/public/locales/en/msp/contracts.jsonandnpx eslint packages/billing/src/components/billing-dashboard/contracts/CreateCustomContractLineDialog.tsx(pass; warning-only lint). - (2026-04-14)
F025completed inContractLines.tsx: wireduseTranslation('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 inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractLines.tsx(pass; warnings only) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F026completed inContractLines.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.confirmwith 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.inlinekeys inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractLines.tsx(pass; warnings only) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F027completed inContractLines.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', ...)inContractLines.tsxwith locale-awareuseFormatters().formatCurrency(...)for all rate displays;formatRatenow 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) andnpx eslint packages/billing/src/components/billing-dashboard/contracts/ContractLines.tsx(pass; warnings only). - (2026-04-14)
F028completed inAddContractLinesDialog.tsx: wireduseTranslation('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_DISPLAYmap withuseContractLineTypeOptions()and useduseFormatContractLineType()for preset type badges. - (2026-04-14) Added initial
addLines.*namespace keys inserver/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), andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F029completed inAddContractLinesDialog.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 inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/AddContractLinesDialog.tsx(pass; warnings only) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F030completed inContracts.tsx: wireduseTranslation('msp/contracts'), localized sub-tab labels via point-of-use mapping (no hook usage incontractsTabs.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|emptykeys inserver/public/locales/en/msp/contracts.jsonand introduced a localcontractSubtabLabelsmapping helper inContracts.tsxto satisfycontractsTabs.tsconsumption-point translation requirement. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/Contracts.tsx(pass; warnings only) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F031completed inContracts.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|emptykeys inserver/public/locales/en/msp/contracts.jsonto 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) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F032completed inContracts.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|emptykeys inserver/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)
F033completed inClientContractsTab.tsx: wireduseTranslation('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 (
contractToTerminatestate +ConfirmationDialog) so terminate is explicitly confirmed before mutation. - (2026-04-14) Expanded
clientContracts.*keys inserver/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) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F034completed inClientContractsTab.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.noMatcheskey inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ClientContractsTab.tsx(pass; warnings only) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F035completed inContractWizard.tsx: wireduseTranslation('msp/contracts'), localized wizard step labels via memoizedstepLabels, 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.unsavedChangeskeys inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractWizard.tsx(pass) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F036completed inContractWizard.tsx: localized recurring authoring validation output by switching from raw helper English strings to translatedwizard.validation.unsupportedRecurringAuthoringCombinationwith interpolation for line type and billing frequencies. Added recurring frequency/line-type subkeys underwizard.validation.recurring.*. - (2026-04-14)
F036also 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(...)fromshared/billingClients/recurringAuthoringValidation.tsso UIs can localize without parsing English text; retainedgetUnsupportedRecurringAuthoringCombinationMessage(...)for existing consumers/tests and preserved prior wording semantics (annualin 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.tsfrompackages/billing(pass), andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F037completed inContractOverview.tsx: wireduseTranslation('msp/contracts')and localized overview header/title, stat card labels, variable-summary note, and theView detailslink; service type badges now use shared enum formatteruseFormatContractLineType()(Fixed/Hourly/Usage). - (2026-04-14) Currency-formatting cleanup in
ContractOverview.tsx: replaced hardcodednew Intl.NumberFormat('en-US', ...)path withuseFormatters().formatCurrencyviaformatCurrencyCents(...), keeping locale-aware output and translated money placeholder fallback. - (2026-04-14) Added
contractOverview.title+contractOverview.stats.*keys toserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractOverview.tsx(pass; warnings only) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F038completed inContractOverview.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 bothsemi-annuallyandsemi_annuallyinputs. - (2026-04-14) Added
contractOverview.lines.*,contractOverview.frequency.*, andcontractOverview.errors.failedToLoadOverviewkeys inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractOverview.tsx(pass; warning-onlyreact-hooks/exhaustive-deps),jq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F039completed inPricingScheduleDialog.tsx: wireduseTranslation('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) inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/PricingScheduleDialog.tsx(pass) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F040completed inPricingSchedules.tsx: wireduseTranslation('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 inserver/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-onlyreact-hooks/exhaustive-deps) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F041completed inTemplatesTab.tsx: wireduseTranslation('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 toserver/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-onlyreact-hooks/exhaustive-deps) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F042completed inServiceCatalogPicker.tsx: wireduseTranslation('msp/contracts')and localized picker placeholder, search placeholder, empty results text, product/service badges, and custom-item footer controls (Custombadge, add-as-custom text, type-name hint). - (2026-04-14) Added
servicePicker.catalog.*keys toserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ServiceCatalogPicker.tsx(pass) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F043completed inContractForm.tsx: wireduseTranslation('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 deprecatedBILLING_FREQUENCY_OPTIONSwithuseBillingFrequencyOptions()from@alga-psa/billing/hooks/useBillingEnumOptions. - (2026-04-14) Added
contractForm.*keys inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractForm.tsx(pass; existing warning-onlyno-non-null-assertion/no-explicit-any),rg -n "BILLING_FREQUENCY_OPTIONS" .../ContractForm.tsx(no matches), andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F044completed inQuickStartGuide.tsx: wireduseTranslation('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 inserver/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) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F045completed inBucketOverlayFields.tsx: wireduseTranslation('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 inserver/public/locales/en/msp/contracts.jsonincludingunits.hour|hours|unitsand placeholder strings. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/BucketOverlayFields.tsx(pass) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F046completed inContractLineEditDialog.tsx: wireduseTranslation('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 inserver/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) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F047completed inContractHeader.tsx: wireduseTranslation('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 inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractHeader.tsx(pass) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F048completed inContractDetailSwitcher.tsx: wireduseTranslation('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.contractkeys inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ContractDetailSwitcher.tsx(pass) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F049completed inContractLineRateDialog.tsxandContractPlanRateDialog.tsx: wireduseTranslation('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 inserver/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) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F050completed inBillingFrequencyOverrideSelect.tsx: wireduseTranslation('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 inserver/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), andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F051completed inServicePicker.tsx: wireduseTranslation('msp/contracts')and localized default placeholder, search placeholder, and empty-message copy. - (2026-04-14) Expanded
servicePicker.*keys inserver/public/locales/en/msp/contracts.jsonwith top-level picker strings while preservingservicePicker.catalog.*for async catalog picker. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/ServicePicker.tsx(pass) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F052completed inwizard-steps/ContractBasicsStep.tsx: wireduseTranslation('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 inserver/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) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F053completed inwizard-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_OPTIONSusage withuseBillingFrequencyOptions()anduseFormatBillingFrequency()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-awareuseFormatters().formatCurrency. - (2026-04-14) Expanded
wizardBasics.*key tree inserver/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), andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F054completed inwizard-steps/FixedFeeServicesStep.tsx: wireduseTranslation('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 inserver/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 unusedBucketOverlayFields/overlay helpers),jq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F055completed inwizard-steps/ProductsStep.tsx: wireduseTranslation('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 inserver/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), andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F056completed inwizard-steps/HourlyServicesStep.tsx: wireduseTranslation('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 inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/wizard-steps/HourlyServicesStep.tsx(pass) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F057completed inwizard-steps/UsageBasedServicesStep.tsx: wireduseTranslation('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 inserver/public/locales/en/msp/contracts.json. - (2026-04-14) Verification:
npx eslint packages/billing/src/components/billing-dashboard/contracts/wizard-steps/UsageBasedServicesStep.tsx(pass) andjq empty server/public/locales/en/msp/contracts.json(pass). - (2026-04-14)
F058completed inReviewContractStep.tsx: wireduseTranslation('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_OPTIONSlookup withuseBillingFrequencyOptions()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), andrg -n "BILLING_FREQUENCY_OPTIONS|BILLING_FREQUENCY_DISPLAY" .../ReviewContractStep.tsx(no matches). - (2026-04-14)
F059completed inReviewContractStep.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 withuseFormatBillingFrequency()for fixed/hourly/usage billing-frequency override labels. - (2026-04-14) Expanded
wizardReview.*keys inserver/public/locales/en/msp/contracts.jsonto 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 allwizardReview.*usages inReviewContractStep.tsx(missing 0). - (2026-04-14)
F060completed intemplate-wizard/TemplateWizard.tsx: wireduseTranslation('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 structuredgetUnsupportedRecurringAuthoringCombination()+ localized interpolation (templateWizard.validation.unsupportedRecurringAuthoringCombination) with translated line-type/frequency labels. - (2026-04-14) Added
templateWizard.*keys inserver/public/locales/en/msp/contracts.json(title,steps,actions,errors,validation, andvalidation.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), andrg -n "Create Contract Template|Template Basics|Publish Template|Template name is required" .../TemplateWizard.tsx(matches onlydefaultValuefallbacks). - (2026-04-14)
F061completed intemplate-wizard/steps/TemplateContractBasicsStep.tsx: wireduseTranslation('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_OPTIONSwithuseBillingFrequencyOptions()for the billing-frequency select. - (2026-04-14) Added
templateBasics.*keys inserver/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), andrg -n "BILLING_FREQUENCY_OPTIONS|BILLING_FREQUENCY_DISPLAY" .../TemplateContractBasicsStep.tsx(no matches). - (2026-04-14)
F062completed intemplate-wizard/steps/TemplateFixedFeeServicesStep.tsx: wireduseTranslation('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 undertemplateFixed.*. - (2026-04-14) Added
templateFixed.*keys inserver/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 fortemplateFixed.*usages (missing 0). - (2026-04-14)
F063completed intemplate-wizard/steps/TemplateProductsStep.tsx: wireduseTranslation('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 Productand ensured alltemplateProducts.*usages are backed by locale keys. - (2026-04-14) Added
templateProducts.*keys inserver/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 fortemplateProducts.*usages (missing 0). - (2026-04-14)
F064completed intemplate-wizard/steps/TemplateHourlyServicesStep.tsx: wireduseTranslation('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 Serviceand ensured alltemplateHourly.*usages are backed by locale keys. - (2026-04-14) Added
templateHourly.*keys inserver/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 fortemplateHourly.*usages (missing 0). - (2026-04-14)
F065completed intemplate-wizard/steps/TemplateUsageBasedServicesStep.tsx: wireduseTranslation('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 Serviceand ensured alltemplateUsage.*usages are backed by locale keys. - (2026-04-14) Added
templateUsage.*keys inserver/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 fortemplateUsage.*usages (missing 0). - (2026-04-14)
F066completed intemplate-wizard/steps/TemplateReviewContractStep.tsx: wireduseTranslation('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 inserver/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 fortemplateReview.*usages (missing 0). - (2026-04-14)
F067completed intemplate-wizard/TemplateServicePreviewSection.tsx: wireduseTranslation('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 inserver/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 fortemplatePreview.*usages (missing 0). - (2026-04-14)
T001completed: rannode scripts/generate-pseudo-locales.cjs && node scripts/validate-translations.cjsafter syncing missingmsp/contractskeys from English intode/es/fr/it/nl/pllocale files. - (2026-04-14) Validation result:
Errors: 0,Warnings: 0,PASSEDacrossde/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)
T002completed: addedpackages/billing/tests/billing-dashboard/ContractsSubbatch.i18n.test.tswith a ContractDetail tab-label wiring assertion (contractDetail.tabs.overview|lines|pricing|documents|invoices) validating both sourcet(...)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)
T003completed: extendedContractsSubbatch.i18n.test.tswith 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)
T004completed: extendedContractsSubbatch.i18n.test.tswith details-card wiring checks coveringcontractDetail.detailsCard.*labels and edit/save/cancel action keys pluscontractDetail.labels.noDescriptionlocale 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)
T005completed: extendedpackages/billing/tests/billing-dashboard/ContractsSubbatch.i18n.test.tswith 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)
T006completed: extendedpackages/billing/tests/billing-dashboard/ContractsSubbatch.i18n.test.tswith 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)
T007completed: added ContractDetail assertions for translated quick-action buttons, footer save/cancel/saving labels, and discard/unsaved/delete confirmation dialog copy inContractsSubbatch.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)
T008completed: added invoice-tab i18n coverage inContractsSubbatch.i18n.test.tsfor 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)
T009completed: added pseudo-locale guard inContractsSubbatch.i18n.test.tsthat extracts allContractDetail.tsxtranslation keys and asserts each resolves toxxpseudo values (11111pattern), covering all tabs. - (2026-04-15) Discovery/fix:
contractDetail.documents.loadingwas referenced inContractDetail.tsxbut missing from locale JSON. AddedcontractDetail.documents.loadingto all 9 locale files (en/de/es/fr/it/nl/pl/xx/yy) with pseudo values forxx/yy. - (2026-04-15) Verification:
cd packages/billing && npx vitest run tests/billing-dashboard/ContractsSubbatch.i18n.test.ts(pass; 1 file, 8 tests) andnode scripts/validate-translations.cjs(pass; Errors: 0, Warnings: 0). - (2026-04-15)
T010completed: addedpackages/billing/tests/billing-dashboard/ContractDialog.i18n.test.tswith coverage for ContractDialog title/form/renewal labels and validation keys, asserting both sourcet(...)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)
T011completed: extendedContractDialog.i18n.test.tswith 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)
T012completed: added pseudo-locale coverage inContractDialog.i18n.test.tsby extracting allt('...')keys fromContractDialog.tsxand asserting each resolves toxxpseudo-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)
T013completed: addedpackages/billing/tests/billing-dashboard/ContractTemplateDetail.i18n.test.tswith 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)
T014completed: extendedContractTemplateDetail.i18n.test.tswith 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)
T015completed: extendedContractTemplateDetail.i18n.test.tsto validate translated cadence labels inContractTemplateDetail.tsxand 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)
T016completed: added pseudo-locale coverage inContractTemplateDetail.i18n.test.tsby extracting allt('...')keys used inContractTemplateDetail.tsxand asserting each resolves toxxpseudo 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)
T017completed: addedpackages/billing/tests/billing-dashboard/CreateCustomContractLineDialog.i18n.test.tswith 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)
T018completed: extendedCreateCustomContractLineDialog.i18n.test.tswith coverage for bucket/proration copy and validation surfaces (allcreateCustomLine.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)
T019completed: added pseudo-locale coverage inCreateCustomContractLineDialog.i18n.test.tsby extracting all dialogt('...')keys and asserting they resolve toxxpseudo 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)
T020completed: addedpackages/billing/tests/billing-dashboard/ContractLines.i18n.test.tswith 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)
T021completed: extendedContractLines.i18n.test.tswith 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.cadenceOwnerwas referenced inContractLines.tsxbut missing from locale files. Added the key across all 9msp/contractslocale files (en/de/es/fr/it/nl/pl/xx/yy) with pseudo values forxx/yy. - (2026-04-15) Verification:
cd packages/billing && npx vitest run tests/billing-dashboard/ContractLines.i18n.test.ts(pass; 1 file, 2 tests) andnode scripts/validate-translations.cjs(pass; Errors: 0, Warnings: 0). - (2026-04-15)
T022completed: added pseudo-locale coverage inContractLines.i18n.test.tsby extracting allt('...')keys used inContractLines.tsxand asserting they resolve toxxpseudo 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)
T023completed: addedpackages/billing/tests/billing-dashboard/AddContractLinesDialog.i18n.test.tscovering 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)
T024completed: extendedAddContractLinesDialog.i18n.test.tswith 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)
T025completed: addedpackages/billing/tests/billing-dashboard/Contracts.i18n.test.tscovering 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)
T026completed: extendedContracts.i18n.test.tswith 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)
T027completed: extendedContracts.i18n.test.tswith 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)
T028completed: added pseudo-locale coverage inContracts.i18n.test.tsby extracting allt('...')keys fromContracts.tsxand asserting they resolve toxxpseudo 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)
T029completed: addedpackages/billing/tests/billing-dashboard/ClientContractsTab.i18n.test.tswith 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)
T030completed: extendedClientContractsTab.i18n.test.tswith 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)
T031completed: addedpackages/billing/tests/billing-dashboard/ContractWizard.i18n.test.tswith 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)
T032completed: extendedContractWizard.i18n.test.tswith 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)
T033completed: addedpackages/billing/tests/billing-dashboard/ContractOverview.i18n.test.tswith stat-card and overview-heading i18n assertions forContractOverview.tsx. - (2026-04-15) Discovery/fix:
common.moneyPlaceholderwas referenced inContractOverview.tsxbut missing frommsp/contractslocale files. Added it across all 9 locales (en/de/es/fr/it/nl/pl/xx/yy) with pseudo values forxx/yy. - (2026-04-15) Verification:
cd packages/billing && npx vitest run tests/billing-dashboard/ContractOverview.i18n.test.ts(pass; 1 file, 1 test) andnode scripts/validate-translations.cjs(pass; Errors: 0, Warnings: 0). - (2026-04-15)
T034completed: extendedContractOverview.i18n.test.tswith 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)
T035completed: addedpackages/billing/tests/billing-dashboard/PricingSchedules.i18n.test.tswith 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.openMenuandcommon.notAvailablewere referenced inPricingSchedules.tsxbut missing frommsp/contractslocales. Added both keys across all 9 locales (en/de/es/fr/it/nl/pl/xx/yy) with pseudo values forxx/yy. - (2026-04-15) Verification:
cd packages/billing && npx vitest run tests/billing-dashboard/PricingSchedules.i18n.test.ts(pass; 1 file, 1 test) andnode scripts/validate-translations.cjs(pass; Errors: 0, Warnings: 0). - (2026-04-15)
T036completed: addedpackages/billing/tests/billing-dashboard/TemplatesTab.i18n.test.tswith 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)
T037completed: addedpackages/billing/tests/billing-dashboard/ContractForm.i18n.test.tswith 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)
T038completed: addedpackages/billing/tests/billing-dashboard/QuickStartGuide.i18n.test.tswith 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)
T039completed: extendedQuickStartGuide.i18n.test.tswith pseudo-locale coverage by extracting allQuickStartGuide.tsxtranslation keys and assertingxxvalues 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)
T040completed: addedpackages/billing/tests/billing-dashboard/BucketOverlayFields.i18n.test.tswith 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)
T041completed: addedpackages/billing/tests/billing-dashboard/ContractLineEditDialog.i18n.test.tswith 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)
T042completed: addedpackages/billing/tests/billing-dashboard/ContractHeader.i18n.test.tswith 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)
T043completed: addedpackages/billing/tests/billing-dashboard/ContractDetailSwitcher.i18n.test.tsto assertContractDetailSwitcher.tsxwires all loading/error states throught('detailSwitcher.*')inmsp/contractsand 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)
T044completed: addedpackages/billing/tests/billing-dashboard/ContractLineRateDialog.i18n.test.tswith assertions that bothContractLineRateDialog.tsxandContractPlanRateDialog.tsxusecontractLineRate.*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)
T045completed: addedpackages/billing/tests/billing-dashboard/BillingFrequencyOverrideSelect.i18n.test.tsto verify label/description/placeholder/confirmation strings are wired tofrequencyOverride.*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)
T046completed: addedpackages/billing/tests/billing-dashboard/ServicePicker.i18n.test.tsverifying picker placeholder/search/empty states are sourced fromservicePicker.*translation keys and exist inen/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)
T047completed: addedpackages/billing/tests/billing-dashboard/ContractBasicsStep.i18n.test.tswith assertions covering translated heading/description, template picker labels/loading copy, client picker labels/hint, and contract-name field copy inContractBasicsStep.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)
T048completed: extendedpackages/billing/tests/billing-dashboard/ContractBasicsStep.i18n.test.tsto assert renewal-mode/cadence-owner/PO copy and summary labels are translated inContractBasicsStep.tsx, including pluralized locale coverage fornoticePeriodDays_*andrenewalTermMonths_*. - (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)
T049completed: addedpackages/billing/tests/billing-dashboard/FixedFeeServicesStep.i18n.test.tscovering translated heading/description, base-rate + proration labels, service picker labels, empty state, and alternate billing-frequency label inFixedFeeServicesStep.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)
T050completed: addedpackages/billing/tests/billing-dashboard/ProductsStep.i18n.test.tswith assertions for translated step heading/description, product picker labels, quantity/override-rate/default-price copy, validation messages, add action, and empty state inProductsStep.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)
T051completed: addedpackages/billing/tests/billing-dashboard/HourlyServicesStep.i18n.test.tsvalidating 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)
T052completed: addedpackages/billing/tests/billing-dashboard/UsageBasedServicesStep.i18n.test.tsvalidating 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)
T053completed: addedpackages/billing/tests/billing-dashboard/ReviewContractStep.i18n.test.tsasserting 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)
T054completed: extendedpackages/billing/tests/billing-dashboard/ReviewContractStep.i18n.test.tswith 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)
T055completed: addedpackages/billing/tests/billing-dashboard/TemplateWizard.i18n.test.tsverifying 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)
T056completed: addedpackages/billing/tests/billing-dashboard/TemplateContractBasicsStep.i18n.test.tswith 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)
T057completed: addedpackages/billing/tests/billing-dashboard/TemplateFixedFeeServicesStep.i18n.test.tsverifying 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)
T058completed: addedpackages/billing/tests/billing-dashboard/TemplateProductsStep.i18n.test.tsto 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)
T059completed: addedpackages/billing/tests/billing-dashboard/TemplateHourlyServicesStep.i18n.test.tswith 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)
T060completed: addedpackages/billing/tests/billing-dashboard/TemplateUsageBasedServicesStep.i18n.test.tsto 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)
T061completed: addedpackages/billing/tests/billing-dashboard/TemplateReviewContractStep.i18n.test.tswith 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)
T062completed: addedpackages/billing/tests/billing-dashboard/TemplateServicePreviewSection.i18n.test.tsto 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)
T063completed: addedpackages/billing/tests/billing-dashboard/ContractsIntegration.i18n.test.tsintegration-style coverage validating/msp/billingroute namespace preload includesmsp/contracts, Contracts/Templates/ClientContracts components useuseTranslation('msp/contracts'), sub-tab labels are translated at consumption (common.tabs.*), and all extractedt('...')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)
T064completed: extendedContractsIntegration.i18n.test.tswith 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 forcommon.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)
T065completed: extended integration coverage to validate contract-detail route translation wiring acrossContractDetail.tsx,ContractLines.tsx, andPricingSchedules.tsx; asserts all extracted translation keys resolve in bothenandde, 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)
T066completed: extended integration coverage for the contract creation wizard (ContractWizard+ all six wizard-step components). The test extracts all literalt('...')keys, verifies key-set breadth (>220), and asserts locale resolution in bothenandde(with plural-handling checks forwizardBasics.summary.values.noticePeriodDays_*andrenewalTermMonths_*). - (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)
T067completed: 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 bothenanddelocales. - (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)
T068completed: extended integration suite withQuickStartGuidecoverage asserting all extracted translation keys resolve indeand pseudo-localexx; 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)
T069completed: added locale-format integration assertions inContractsIntegration.i18n.test.tsensuring bothContractDetail.tsxandReviewContractStep.tsxavoid hardcoded'en-US'/formatCurrencyFromMinorUnits(...)and useuseFormatters().formatCurrencyvia 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).