Support zip-based service area configuration

Objective

  • Let teams define service coverage using ZIP codes (or a similarly low-friction method) instead of relying only on hand-drawn map polygons.
  • Reduce setup friction and boundary gaps that block valid addresses when polygon edges are drawn imprecisely.
  • Match how many inspection companies already think about coverage — by ZIP, city, and region — while keeping existing scheduling and in-area checks reliable.

Background

  • Product feedback indicates manual polygon drawing in Settings → Service Areas is error-prone; small gaps near boundaries can exclude addresses that should be in coverage.
  • Teams asked for a simpler flow: enter ZIP codes and have the system generate coverage more reliably, rather than drawing precise shapes with a mouse.
  • Current behavior: service areas are polygon-only. Admins draw boundaries on a Mapbox map; each area stores a coordinate ring in area. Scheduler, inspector assignment, and API checks determine coverage by testing whether a property lat/lng is inside those polygons (booleanPointInPolygon).
  • There is no ZIP-list, city-picker, or auto-generated boundary configuration path today.

Product Decisions

Locked

  1. Problem type — This is a feature gap (new configuration capability), not a bug in existing polygon logic.
  2. User outcome — Teams need a less manual way to define coverage that reduces missed addresses near polygon edges.
  3. ZIP-first intent — ZIP-based entry is the primary requested alternative to mouse-drawn polygons.
  4. Existing polygon areas — Current polygon-based service areas and their downstream behavior (in-area checks, expanded areas, fees) must be understood before changing or replacing them.

Open (Remaining product clarifying decisions)

  1. Configuration modes — Should ZIP-based setup replace polygon drawing, supplement it (both allowed per company/area), or become the default with polygons as advanced?
  2. Answer: allow both
  3. Geography scope — ZIP codes only, or also city, county, or multi-select region lists in v1?
  4. Storage model — Store a ZIP list on the service area and resolve at runtime, or generate and persist a polygon from ZIP boundaries at save time (or both)?
  5. Answer: both, there needs to be a list of any selected zip codes that can be viewed by users.
  6. Geodata source — Which boundary provider should back ZIP → geometry conversion (e.g. Mapbox, Census ZCTA, commercial dataset)? Licensing and update cadence need a product call.
  7. Expanded service areas — Should expanded areas and expandedFee work the same for ZIP-defined coverage, or are expanded zones polygon-only in v1?
  8. Answer: yes, should work the same for ZIP-defined coverage
  9. Partial / edge cases — How should the product handle ZIP+4, shared ZIPs across cities, or addresses geocoded just outside a ZIP boundary?
  10. Answer: include entire ZIP in polygon. If users only want part of the ZIP they can remove it and draw an overlapping polygon
  11. Migration — Do existing polygon areas stay as-is, or should teams get a one-time path to convert polygons to ZIP lists (if even possible)?
  12. Answer: existing polygons stay as is.
  13. Inspector assignment — Confirm inspector ↔ service area assignment UX stays unchanged; only how areas are authored changes.
  14. Answer: confirmed, assignments remain unchanged.

Scope

Frontend

  • Service area settings UI: attik-frontend/src/app/tools/settings/service-areas/ServiceAreaMap.tsx uses Mapbox DrawControl for polygon authoring; ServiceAreaList.tsx, NewServiceRow.tsx, and EditServiceRow.tsx manage area metadata including expanded and expandedFee.
  • Inspector map display: attik-frontend/src/app/tools/settings/inspectors/[id]/InspectorServiceAreas/InspectorSettingsMap.tsx renders combined polygon boundaries for assigned areas.
  • Client-side in-area helpers: attik-frontend/src/util/functions/mapbox/checkPointWithinServiceAreas.ts and combineServiceAreaBoundries.ts assume polygon geometry.

Backend

  • Service area model: attik-backend/src/models/serviceAreaSchema.tsarea is a required coordinate array; no ZIP or city fields today.
  • Service area API: attik-backend/src/routes/serviceArea.ts — CRUD plus /find-containing uses booleanPointInPolygon on stored area rings.
  • Scheduling / slots: attik-backend/src/util/functions/schedule/batchSlotOptimizingAlgo.ts and slotOptimizingAlgo.ts — property lat/lng tested against inspector service-area polygons; malformed polygons are treated as outside rather than crashing.
  • Boundary utilities: attik-backend/src/util/functions/maps/combineServiceAreaBoundries.ts — merges polygon GeoJSON for display.

Downstream consumers (must remain correct after ZIP support)

  • Online scheduler and internal scheduling (SchedulerContext.tsx, NewSchedulingForm.tsx, SchedulingSlideOutSheet.tsx) — serviceAreaCost / expanded-fee logic from containing areas.
  • Workorder charge edits (EditChargesModal.tsx) — expanded service-area fee lookup.

Out of scope (unless product expands)

  • Changing how travel modifiers or non–service-area pricing rules work.
  • Fixing individual bad polygons on existing accounts without a ZIP authoring path (support/data cleanup is separate).

References

  • Settings entry: Tools → Settings → Service Areas (attik-frontend/src/app/tools/settings/service-areas/page.tsx)
  • attik-backend/src/models/serviceAreaSchema.ts
  • attik-backend/src/routes/serviceArea.ts
  • attik-frontend/src/app/tools/settings/service-areas/ServiceAreaMap.tsx

Please authenticate to join the conversation.

Upvoters
Status

Triage

Board
🏠

Main App

Date

2 days ago

Author

Linear

Subscribe to post

Get notified by email when there are changes.