# Google Places Address Lookup

## Objective

Turn a half-typed address into a structured location the app can rely on.

An address autocomplete that fills structured location fields from real places and stays editable by hand.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Replace free-text address entry on the forms that need a real location with a lookup returning structured components, and keep every component field editable after the lookup returns.
2. Group the keystrokes of one lookup into a single billable session and close it when a place is chosen or the field is abandoned. Debounce input and set a minimum query length, because every keystroke that reaches the provider costs money.
3. Store the provider's place identifier in its own field, separate from the human-readable address the user sees. The two serve different purposes, and the display text must never be parsed back into structure.
4. Route requests through the server, or restrict the client credential by referrer and to the single capability it needs. An unrestricted key in a public page will be scraped and spent by someone else.
5. Mapbox Geocoding covers coordinate conversion and reverse lookup. Where both exist, assign one provider per field and say which — do not send the same query to two providers and try to reconcile the answers.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Suggestions are frequently incomplete for apartments, units, floors, and rural addresses. Always allow manual correction, and never block a save because the provider did not recognise the address.
- Address structure differs by country: postcode position, the presence of a state or province, and street ordering are not universal. Map components generically rather than assuming one national format.
- A business result and an address result are different things. Decide which the field accepts and filter accordingly, or a user picking a shop name saves a location with no street.
- Address queries are personal data. Keep raw lookup queries out of general application logs and put a retention limit on anything that is kept.
- Place identifiers can be retired or replaced over time. Keep the resolved components as well, so a stale identifier does not leave a record with no usable address.
- The provider's terms restrict how long results may be cached and what may be stored. Cache only what is permitted and re-resolve rather than warehousing full responses.
- Quota exhaustion or an outage must leave the plain text field usable so the user can still finish the form.
- Keyboard users must be able to move through suggestions and choose one without a mouse, and the suggestion list must be announced to screen readers.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Structured address components are captured and every one remains editable by hand.
- [ ] Lookups are debounced, grouped into a session, and the session is closed when the field resolves.
- [ ] The provider identifier is stored separately from the displayed address text.
- [ ] No unrestricted credential is exposed to the browser.
- [ ] A user can save a valid address the provider never suggested.
- [ ] Raw location queries do not appear in general application logs.
- [ ] Provider unavailability leaves manual entry fully working.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
