PRD -- MSP i18n: Invoicing Sub-batch
- Slug:
2026-04-09-msp-i18n-invoicing
- Date:
2026-04-09
- Status: Draft (ready to start — verified unchanged on 2026-04-17; see SCRATCHPAD "Status Recheck (2026-04-17)" for corrected file paths and upstream deltas)
- Parent plan:
/.ai/translation/MSP_i18n_plan.md
Summary
Extract all hardcoded English strings from 22 invoicing components in
packages/billing/src/components/, create the msp/invoicing namespace, wire
useTranslation('msp/invoicing'), and generate translations for 7 languages plus
pseudo-locales. PaperInvoice.tsx (44 LOC) has zero user-facing strings and is excluded.
Problem
MSP billing pages are one of the highest-value surfaces in the application (invoicing,
templates, tax management, recurring billing). All 22 invoicing components are hardcoded
English -- zero currently use useTranslation. Non-English MSP users encounter a
fully translated sidebar, dashboard, and settings chrome, but switch to raw English when
they enter any invoicing workflow (drafts, finalized, automatic generation, manual
creation, templates, tax reconciliation, etc.).
Goals
- Create
server/public/locales/en/msp/invoicing.json with all keys extracted from
22 invoicing components
- Wire
useTranslation('msp/invoicing') into every component with user-visible strings
- Use
useFormatters from @alga-psa/ui/lib/i18n/client for currency and date formatting
where hardcoded Intl.NumberFormat / toLocaleString is currently used
- Generate translations for 6 non-English locales (fr, es, de, nl, it, pl) + 2
pseudo-locales (xx, yy)
- Run
node scripts/generate-pseudo-locales.cjs && node scripts/validate-translations.cjs
green (exit 0) before shipping
- Measurable: invoicing coverage goes from 0% to 100% of production components wired
Non-goals
- Translating template content (user-designed invoice layouts, template AST field names)
- Translating invoice data (invoice numbers, client names, descriptions) -- those are
tenant data, not UI chrome
- Moving existing non-invoicing billing keys from other namespaces
- Wiring EE-only invoicing components not exported through
@alga-psa/billing/components
- Changing layout or visual design of any component
- Translating
console.error / console.log / console.warn developer-only messages
File Inventory
Large (600+ LOC) -- 2-3 features each
| Component |
LOC |
Est. strings |
Key content |
| AutomaticInvoices.tsx |
1,983 |
~120 |
Ready-to-invoice table, parent group labels, cadence badges, incompatibility reasons, materialization gap panel, recurring history table, reverse/delete dialogs, preview dialog, PO overage dialogs, error messages |
| ManualInvoices.tsx |
859 |
~50 |
Form labels, automated items table, line item headers, prepayment checkbox, error messages, validation, submit button states |
Medium (200-600 LOC) -- 1-2 features each
| Component |
LOC |
Est. strings |
Key content |
| DraftsTab.tsx |
550 |
~30 |
Table column headers, search placeholder, bulk actions, empty state, reverse confirmation dialog |
| FinalizedTab.tsx |
506 |
~30 |
Table column headers, search placeholder, bulk actions (download/email/unfinalize), empty state |
| RecurringServicePeriodsTab.tsx |
458 |
~40 |
Page title, schedule selector, form labels, summary stats, table headers, repair panel, regeneration preview |
| BillingCycles.tsx |
397 |
~25 |
Page title, tooltip, column headers, anchor labels, month names, search, loading text |
| InvoicePreviewPanel.tsx |
386 |
~20 |
Preview title, template selector, action buttons, loading/error/empty states |
| InvoiceTemplateEditor.tsx |
345 |
~20 |
Back nav, heading, template name label, visual/code tabs, save/cancel buttons, timestamps, validation errors |
| InvoiceTemplates.tsx |
344 |
~20 |
Section heading, column headers, action menu items (edit/clone/set default/delete), create button, loading text |
| ExternalTaxBatchImportDashboard.tsx |
320 |
~25 |
Card title/description, column headers, batch import button, progress bar labels, results summary, help text, empty state |
| ExternalTaxImportPanel.tsx |
297 |
~25 |
Panel title, pending/imported alerts, import button, history section, reconciliation labels, help text |
| SendInvoiceEmailDialog.tsx |
278 |
~25 |
Dialog title, summary counts, recipients heading, recipient source labels, custom message label, email preview, send/cancel buttons |
| TaxReconciliationView.tsx |
222 |
~20 |
Card title, comparison labels (Internal/External), table headers, warning alert, help text |
| GenerateTab.tsx |
207 |
~15 |
Invoice type selector labels, type descriptions, success dialog message |
Small (< 200 LOC) -- 1 feature each
| Component |
LOC |
Est. strings |
Key content |
| PrepaymentInvoices.tsx |
165 |
~15 |
Form heading, field labels, type options, placeholders, validation errors, submit button states |
| ContractInvoiceItems.tsx |
133 |
~10 |
Table headers (Description/Quantity/Rate/Amount), subtotal labels, product badge |
| InvoicingHub.tsx |
94 |
~5 |
Section heading, tab labels (Generate/Drafts/Finalized) |
| InvoiceTemplateManager.tsx |
92 |
~5 |
Headings (Invoice Template Manager, Sample Invoices, Template Preview) |
| InvoiceTaxSourceBadge.tsx |
81 |
~10 |
Badge labels (Tax: Internal/External/Pending), tooltip strings, adapter names |
| InvoiceAnnotations.tsx |
60 |
~5 |
Heading, internal/external labels, placeholder, add button |
| PurchaseOrderSummaryBanner.tsx |
45 |
~5 |
Field labels (PO Number, PO Authorized, PO Consumed, PO Remaining) |
Excluded (zero user-facing strings)
| Component |
LOC |
Reason |
| PaperInvoice.tsx |
44 |
Pure layout wrapper, no text content |
Namespace Structure
msp/invoicing.json
automaticInvoices.* -- Ready-to-invoice, parent groups, history, dialogs
manualInvoices.* -- Manual invoice form, line items, prepayment
draftsTab.* -- Drafts list, bulk actions, reverse dialog
finalizedTab.* -- Finalized list, bulk actions
recurringServicePeriods.* -- Schedule management, repair, regeneration
billingCycles.* -- Billing cycle table, anchor labels
invoicePreview.* -- Preview panel, action buttons
templateEditor.* -- Template editor form, tabs
templates.* -- Template list, actions
externalTax.* -- Batch import, single import, reconciliation
sendEmail.* -- Email dialog, recipient info
generateTab.* -- Type selector, descriptions
prepayment.* -- Prepayment form
contractItems.* -- Contract invoice items table
hub.* -- Invoicing hub, tab labels
templateManager.* -- Template manager, sample invoices
taxBadge.* -- Tax source badge labels, tooltips
annotations.* -- Annotations section
purchaseOrder.* -- PO summary banner
common.* -- Shared strings (Search, Cancel, Actions, Loading, etc.)
Acceptance Criteria