- Integrated AddressWriterService into GuestEligibilityWorkflowService and NewCustomerSignupWorkflowService for improved address writing to Salesforce. - Updated AddressModule to include SalesforceModule and export AddressWriterService. - Refactored address handling in various workflows to utilize the new address structure, ensuring consistency and reliability in address processing. - Removed deprecated address building logic from eligibility check store, streamlining address management across components.
8.2 KiB
Bilingual Address Handler for Registration
Date: 2026-03-03 Status: Design
Problem
Registration flows use addressFormSchema (simple English-only: address1, address2, city, state, postcode). The bilingual address infrastructure exists (bilingualAddressSchema, prepareWhmcsAddressFields, prepareSalesforceContactAddressFields, JapanAddressForm, Japan Post API integration) but isn't wired into signup workflows.
Salesforce receives English address data when it should receive Japanese. Address transformation logic is scattered inline across workflows.
Requirements
| Outcome | SF Write | WHMCS Write | Address Input |
|---|---|---|---|
| A (New Customer) | Japanese (at signup) | English (at signup) | JapanAddressForm |
| B (SF-Only) | Japanese (at eligibility check) | English (at account completion) | JapanAddressForm at eligibility |
| C (WHMCS Migration) | None | None | None |
| D (Portal Exists) | None | None | None |
Key Decisions
- Japan Post API postal code lookup auto-populates both JA and EN fields on the frontend.
- Always re-derive EN fields from postal code via Japan Post API on the backend when writing to WHMCS. One code path regardless of whether data is in Redis (fresh) or Salesforce (days later). Avoids Redis TTL dependency.
- Centralized
AddressWriterServicein BFF orchestrates all address writes. bilingualAddressSchemareplacesaddressFormSchemain all signup request/session/handoff schemas.JapanAddressFormreplaces simple address fields in all signup frontend forms.
Architecture
AddressWriterService (BFF)
Location: apps/bff/src/modules/address/address-writer.service.ts
AddressWriterService
Dependencies: JapanPostFacade, SalesforceAccountService
writeToSalesforce(sfAccountId, bilingualAddress)
→ prepareSalesforceContactAddressFields(address) → SF Contact update
→ Writes: MailingStreet (JA town+street), MailingCity (JA), MailingState (JA), BuildingName__c, RoomNumber__c
resolveAndPrepareWhmcsAddress(postalCode, townJa?, streetAddress, buildingInfo)
→ Japan Post API lookup by postal code
→ Match correct result using townJa (for multi-match postal codes)
→ prepareWhmcsAddressFields() with resolved EN fields
→ Returns: WhmcsAddressFields (address1, address2, city, state, postcode, country)
Schema Changes
Replace addressFormSchema with bilingualAddressSchema in:
| Schema | File | Change |
|---|---|---|
signupWithEligibilityRequestSchema |
domain/get-started/schema.ts |
address: addressFormSchema → address: bilingualAddressSchema |
completeAccountRequestSchema |
domain/get-started/schema.ts |
address: addressFormSchema.optional() → address: bilingualAddressSchema.optional() |
getStartedSessionSchema |
domain/get-started/schema.ts |
address: addressFormSchema.partial().optional() → address: bilingualAddressSchema.partial().optional() |
guestHandoffTokenSchema |
domain/get-started/schema.ts |
address: addressFormSchema.partial().optional() → address: bilingualAddressSchema.partial().optional() |
verifyCodeResponseSchema prefill |
domain/get-started/schema.ts |
address: addressFormSchema.partial().optional() → address: bilingualAddressSchema.partial().optional() |
guestEligibilityRequestSchema |
domain/get-started/schema.ts |
Remove bilingualEligibilityAddressSchema, use bilingualAddressSchema |
Workflow Changes
NewCustomerSignupWorkflowService (Outcome A):
- Accept
bilingualAddressSchemafrom request - After SF account creation:
addressWriter.writeToSalesforce(sfAccountId, address)→ JA to SF - For WHMCS client:
addressWriter.resolveAndPrepareWhmcsAddress(postcode, townJa, streetAddress, building)→ EN to WHMCS
GuestEligibilityWorkflowService (Outcome B - eligibility check):
- Refactor inline SF address write (lines 103-113) to use
addressWriter.writeToSalesforce() - Store bilingual address in handoff token (for B1 immediate flow)
SfCompletionWorkflowService (Outcome B - account completion):
- Resolve address from session (may have bilingual data if B1, or JA-only + postcode if B2)
addressWriter.resolveAndPrepareWhmcsAddress(postcode, townJa, streetAddress, building)→ EN to WHMCS
Frontend Changes
Replace simple address fields with JapanAddressForm component in:
- Signup with eligibility form (Outcome A)
- Guest eligibility form (Outcome B)
- Forms submit
bilingualAddressSchemashape
No address form needed for:
- Complete account (Outcome B) — address from session
- WHMCS migration (Outcome C) — no address needed
- Portal exists (Outcome D) — redirect to login
Data Flow Diagrams
Outcome A (New Customer):
User → JapanAddressForm → postal code lookup → auto-fill JA+EN
→ Submit (bilingualAddress) → BFF
→ addressWriter.writeToSalesforce(sfAccountId, address) → SF gets JA
→ addressWriter.resolveAndPrepareWhmcsAddress(postcode, townJa, ...) → Japan Post API → WHMCS gets EN
Outcome B1 (SF-Only, immediate):
User → JapanAddressForm (guest eligibility) → Submit (bilingualAddress) → BFF
→ addressWriter.writeToSalesforce(sfAccountId, address) → SF gets JA
→ Store bilingual in handoff token → Redis (30 min TTL)
→ User verifies email → complete account
→ addressWriter.resolveAndPrepareWhmcsAddress(postcode, townJa, ...) → Japan Post API → WHMCS gets EN
Outcome B2 (SF-Only, returns days later):
[Days ago] Guest eligibility → SF got JA address + postal code
[Now] User verifies email → system detects SF_UNMAPPED
→ Prefill from SF: postal code, JA address fields
→ addressWriter.resolveAndPrepareWhmcsAddress(postcode, townJa, ...) → Japan Post API → WHMCS gets EN
Files to Modify
Domain (packages/domain/)
get-started/schema.ts— Replace addressFormSchema references with bilingualAddressSchemaaddress/schema.ts— May need minor additions for the resolve flow
BFF (apps/bff/)
- New:
modules/address/address-writer.service.ts— Centralized address write service modules/address/address.module.ts— Export AddressWriterServicemodules/auth/infra/workflows/new-customer-signup-workflow.service.ts— Use AddressWriterServicemodules/auth/infra/workflows/guest-eligibility-workflow.service.ts— Use AddressWriterServicemodules/auth/infra/workflows/sf-completion-workflow.service.ts— Use AddressWriterServicemodules/auth/infra/workflows/steps/create-whmcs-client.step.ts— Accept WhmcsAddressFieldsmodules/auth/infra/workflows/verification-workflow.service.ts— Prefill bilingual address from SF
Portal (apps/portal/)
- Signup with eligibility form — Replace address fields with JapanAddressForm
- Guest eligibility form — Ensure JapanAddressForm is used, submits bilingualAddressSchema
- API layer — Update request types to match new schemas
Risks
- Japan Post API availability: If API is down during WHMCS write, registration fails. Mitigation: retry with backoff (existing retry.util), graceful error message.
- Multi-match postal codes: Some postal codes return multiple town entries. Mitigation: match using
townJafrom the stored/submitted address. - Schema migration: Changing session/handoff schemas could affect in-flight registrations. Mitigation: make new fields optional, handle old format gracefully during rollout.