Assist_Design/docs/features/japan-post-address-lookup.md
barsa 78689da8fb feat(address): implement Japan address form with ZIP code lookup
- Add JapanAddressForm component for complete Japanese address input.
- Integrate ZipCodeInput for automatic address population via Japan Post API.
- Create hooks for ZIP code lookup and address service status.
- Define address-related types and constants in the domain package.
- Document the feature, including environment variables and API endpoints.
- Implement mapping functions for WHMCS and Salesforce address formats.
2026-01-13 18:41:17 +09:00

9.1 KiB

Japan Post ZIP Code Address Lookup

This feature provides Japanese address auto-completion using the Japan Post Digital Address API. When users enter a ZIP code, the system automatically looks up and populates prefecture, city, and town fields in both Japanese and romanized (English) formats.

Environment Variables

Add these to your .env file:

# Japan Post Digital Address API
JAPAN_POST_API_URL=https://api.da.posta.japanpost.jp
JAPAN_POST_CLIENT_ID=your_client_id
JAPAN_POST_CLIENT_SECRET=your_client_secret
JAPAN_POST_TIMEOUT=10000  # Optional, defaults to 10000ms

Contact Japan Post to obtain API credentials for the Digital Address service.

Architecture Overview

┌─────────────────────────────────────────────────────────────────────┐
│                           Portal (Next.js)                          │
├─────────────────────────────────────────────────────────────────────┤
│  ZipCodeInput ─► useZipCodeLookup ─► addressService.lookupByZipCode │
│       │                                         │                   │
│       ▼                                         ▼                   │
│  JapanAddressForm                    GET /api/address/lookup/zip/:zip│
└─────────────────────────────────────────────────────────────────────┘
                                                  │
                                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                            BFF (NestJS)                             │
├─────────────────────────────────────────────────────────────────────┤
│  AddressController ─► JapanPostAddressService                       │
│         │                       │                                   │
│         │                       ▼                                   │
│         │            JapanPostConnectionService                     │
│         │                  (OAuth token caching)                    │
│         │                       │                                   │
│         ▼                       ▼                                   │
│  PATCH /me/address/bilingual   Japan Post API                       │
│         │                                                           │
│         ▼                                                           │
│  UserProfileService.updateBilingualAddress()                        │
│         │                                                           │
│         ├──► WHMCS (English address - source of truth)              │
│         └──► Salesforce (Japanese address - secondary)              │
└─────────────────────────────────────────────────────────────────────┘

API Endpoints

Public Endpoints (No Auth Required)

Endpoint Method Description Rate Limit
/api/address/lookup/zip/:zipCode GET Look up address by ZIP code 30/min
/api/address/status GET Check service availability -

Authenticated Endpoints

Endpoint Method Description
/api/me/address/bilingual PATCH Update address with dual-write to WHMCS + Salesforce

Field Mappings

WHMCS (English/Romanized)

WHMCS Field Source
address1 {buildingName} {roomNumber} (for apartments) or {buildingName}
address2 town (romanized street/block)
city city (romanized)
state prefecture (romanized)
postcode ZIP code
country "JP"

Salesforce Contact (Japanese)

Salesforce Field Source
MailingStreet townJa (Japanese)
MailingCity cityJa (Japanese)
MailingState prefectureJa (Japanese)
MailingPostalCode ZIP code
MailingCountry "Japan"
BuildingName__c Building name (English)
RoomNumber__c Room number

Components

ZipCodeInput

Auto-lookup ZIP code input with visual feedback.

import { ZipCodeInput } from "@/features/address";

<ZipCodeInput
  value={zipCode}
  onChange={setZipCode}
  onAddressFound={address => {
    // address contains both Japanese and romanized fields
    console.log(address.prefecture, address.prefectureJa);
  }}
/>;

JapanAddressForm

Complete address form with residence type selection.

import { JapanAddressForm } from "@/features/address";

<JapanAddressForm
  onChange={(data, isComplete) => {
    // data is BilingualAddress type
    // isComplete is true when all required fields are filled
  }}
/>;

AddressStepJapan

Drop-in replacement for signup/registration flows.

import { AddressStepJapan } from "@/features/address";

<AddressStepJapan
  form={form}
  onJapaneseAddressChange={bilingualData => {
    // Capture Japanese fields for Salesforce sync
  }}
/>;

Dual-Write Behavior

When updating addresses via PATCH /me/address/bilingual:

  1. WHMCS Update (Blocking): English address is written to WHMCS as source of truth
  2. Salesforce Update (Non-Blocking): Japanese address is written to Salesforce
    • If Salesforce update fails, it's logged but doesn't fail the request
    • If no Salesforce mapping exists, update is skipped silently

Residence Type

Users select either:

  • House: Building name optional, no room number
  • Apartment/Mansion: Building name optional, room number required

The address1 field format changes based on residence type:

  • House: {buildingName} or empty
  • Apartment: {buildingName} {roomNumber}

Manual Address Entry

If users skip ZIP code lookup and enter addresses manually:

Scenario WHMCS Salesforce
ZIP lookup used English fields filled Japanese fields filled
Manual entry (no ZIP) English fields filled Japanese fields empty
Manual then ZIP lookup used English updated Japanese fields populated from lookup

Important: Manual address entry will work for WHMCS but Salesforce will receive empty Japanese address fields. The system does NOT perform reverse lookups on manually entered addresses.

Recommendation: Encourage users to enter ZIP code first to get proper Japanese address data for Salesforce.

Residence Type Selection

Users must explicitly choose their residence type:

  • House: Building name optional, no room number field shown
  • Apartment/Mansion: Building name optional, room number required

The form does not default to either option - users must select one to proceed.

Configuration Validation

On BFF startup, the service validates environment variables and logs errors:

# Missing configuration example log:
ERROR Japan Post API configuration is invalid. Address lookup will be unavailable.
  errors: [
    { envVar: "JAPAN_POST_API_URL", message: "Missing required environment variable" },
    { envVar: "JAPAN_POST_CLIENT_ID", message: "Missing required environment variable" }
  ]
  hint: "Add the required environment variables to your .env file"

The service will throw clear errors if called without proper configuration.

Error Handling

  • Invalid ZIP codes return empty results (no error)
  • Japan Post API timeouts return 500 error
  • Rate limiting returns 429 with retry-after header
  • Missing/invalid configuration throws descriptive error on API call