Skip to content

refactor(address-search): consolidate address shapes into one internal type#45

Open
divazbozz wants to merge 1 commit intomainfrom
claude/funny-dubinsky-85c8a3
Open

refactor(address-search): consolidate address shapes into one internal type#45
divazbozz wants to merge 1 commit intomainfrom
claude/funny-dubinsky-85c8a3

Conversation

@divazbozz
Copy link
Copy Markdown
Contributor

@divazbozz divazbozz commented Apr 21, 2026

Summary

  • Drops ParsedGoogleAddressComponents and the second copy of parseAddress. One internal AddressResult now carries line1 (street) and optional line2 (unit) separately across the flow, modal, and app.
  • Adds toSubmittedAddress(selection) in utils.ts; fetchHydration calls it as the single submission boundary. Wire payload to /api/address-router is unchanged — selection.address.line1 is still the joined street + unit string.
  • Simplifies the modal: no more dual props, no more googleAddressComponents.X || selection.address.X fallback chains — fields pre-fill directly from selection.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 main after #42 and #43 landed. Only touches the address-search module. No component API surface changes for embedding consumers.

Test plan

  • npx tsc --noEmit — clean
  • npm run lint — clean
  • npm run build — clean
  • Smoke in staging:
    • Battery flow: enter a valid address → hydrate → correct redirect
    • Energy-only flow: enter an address that triggers confirm_subpremise → modal pre-fills line1/line2 independently → submit folds them into single line1 on the wire
    • Multi-address hydration response → select option → re-submit still works (line2 absent from backend payload, round-trips correctly)
    • Verify posthog events (address_search_single_result, address_validation_override, etc.) still carry formattedAddress and the expected address.* fields

🤖 Generated with Claude Code


Open in Devin Review

…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>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 21, 2026

Important

Review skipped

Auto reviews are disabled on this repository. To trigger a review, include rabbit in the PR description. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4609fd6c-bb09-41fd-b8bd-08d94f4bf729

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/funny-dubinsky-85c8a3

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant