refactor(address-search): consolidate address shapes into one internal type#45
refactor(address-search): consolidate address shapes into one internal type#45
Conversation
…l type
The address-search module had two overlapping shapes — `AddressResult` (line1
joined with subpremise) and `ParsedGoogleAddressComponents` (line1/line2
separate) — plus two near-identical parse functions. Keep a single internal
`AddressResult` with line1/line2 separate, serialize to the joined backend
shape at the HTTP boundary via a new `toSubmittedAddress` helper in
`fetchHydration`. The modal, flow, and app now thread one shape end-to-end.
- `types.ts`: drop `ParsedGoogleAddressComponents`; add optional `line2` to
`AddressResult.address` so backend hydration responses satisfy the type
without a separate wire type.
- `utils.ts`: rename `parseGoogleAddressComponents` to `parseAddress` and
delete the old joined-line1 `parseAddress`. Add `toSubmittedAddress`.
- `fetch.ts`: call `toSubmittedAddress` inside `fetchHydration` — the single
submission boundary. Wire payload is unchanged.
- `AddressConfirmModal`, `AddressSearchFlow`, `AddressSearchApp`: drop the
`googleAddressComponents` prop/state; the modal pre-fills directly from
`selection.address.{line1,line2,...}`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. To trigger a review, include ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🔴 External CustomEvent select and result emit line1 without the unit/subpremise — breaking change to the web component API
The parseAddress refactoring splits the old single line1 (street + unit) into line1 (street only) and a new line2 (unit). toSubmittedAddress folds them back together at the fetchHydration boundary, so the backend is fine. However, the onSelectEvent (AddressSearchApp.tsx:79) and onResultEvent (AddressSearchApp.tsx:139-142, AddressSearchApp.tsx:159-162) dispatch the internal AddressResult directly to the host page via CustomEvent (element.tsx:103-107) — without calling toSubmittedAddress. External consumers reading event.detail.selection.address.line1 will now receive only the street portion (e.g. "123 Main St") instead of the previous full street+unit (e.g. "123 Main St Apt 4"). The unit data is now in the new line2 field, but existing consumers have no knowledge of it.
Affected event dispatch sites
AddressSearchApp.tsx:79: onSelectEvent(detail) — detail.selection.address.line1 is street-only.
AddressSearchApp.tsx:139: onResultEvent({ result: result.data, selection: detail.selection }) — same.
AddressSearchApp.tsx:159: onResultEvent({ result: { redirectUrl }, selection }) — selection state has the split format.
All three surface as CustomEvent("select") and CustomEvent("result") at element.tsx:103-107.
(Refers to line 79)
Prompt for agents
The onSelectEvent and onResultEvent callbacks dispatch AddressResult objects with the new internal shape (line1 = street only, line2 = unit) to external consumers via CustomEvents. External consumers previously received line1 as the full street + unit string. There are two possible fixes:
1. Apply toSubmittedAddress at the event boundaries: Before dispatching onSelectEvent and onResultEvent, fold line1+line2 back into a single line1 so external consumers see the same shape as before. This preserves backward compatibility.
2. Document the change and coordinate with consumers: If the split format is intentionally exposed, update the README to document the new line2 field and the changed line1 semantics, and ensure all consuming pages are updated to handle the new shape.
Option 1 is safer and can be done locally in AddressSearchApp.tsx by wrapping the selection in toSubmittedAddress before passing it to onSelectEvent and onResultEvent.
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
ParsedGoogleAddressComponentsand the second copy ofparseAddress. One internalAddressResultnow carriesline1(street) and optionalline2(unit) separately across the flow, modal, and app.toSubmittedAddress(selection)inutils.ts;fetchHydrationcalls it as the single submission boundary. Wire payload to/api/address-routeris unchanged —selection.address.line1is still the joined street + unit string.googleAddressComponents.X || selection.address.Xfallback chains — fields pre-fill directly fromselection.address.{line1,line2,...}.Net: +97 / −119 lines, with the bulk of the additions being doc comments on the consolidated type and the new helper.
Scope
Branched off
mainafter #42 and #43 landed. Only touches the address-search module. No component API surface changes for embedding consumers.Test plan
npx tsc --noEmit— cleannpm run lint— cleannpm run build— cleanconfirm_subpremise→ modal pre-fills line1/line2 independently → submit folds them into singleline1on the wireaddress_search_single_result,address_validation_override, etc.) still carryformattedAddressand the expectedaddress.*fields🤖 Generated with Claude Code