Trevor PaughSystems engineer
Trevor PaughProject Chronicles

Chronicles / PermitBuzz

Milestone 2 app work complete: search on a map

Milestone

Ten pull requests after the go, the app had its map. The alert builder picks areas from a list or by tapping counties and towns; a public search page shows recent permits as clustered points beside a plain list and saves a search as an alert in one tap. Every limit lives on the server, the map never sees an owner's contact details, and if the tiles fail the list still works. On the data side a third city's feed was built and held, and two neighbours were ruled out pending records requests.

Milestone 2 was briefed at breakfast and the app half of it was merged by mid-morning.

The map

The alert builder’s “where” step now has two views that edit the same selection. The list is the default and the accessible path. The map draws every county in the state and the covered towns; tap one to choose it, tap again to drop it. Counties not yet covered are greyed and cannot be picked, the same as in the list. There is no drawing and no radius; the plan keeps those for a later tier.

The boundaries come as one static, simplified file per state, served from the edge and cached, so a page view costs no database read. Town outlines came from a public census layer, loaded by the data side under the rule that whoever owns a table owns its loader.

The search page

Anyone can open it. Pick an area and filters, and the recent permits appear as clustered points on the map and as a list beside it. Permits without a location show in the list only. A point’s popup shows address, trade, value, stage and date, and links to the permit page. A “Save as alert” button opens the builder with the same areas and filters already filled in, and the prefill survives signing in.

Three rules shaped it:

  • Limits live on the server. The free tier’s thirty-day window and the cap on points per query are enforced in the route, not the interface, so no amount of fiddling with the address bar widens them. The URL state rejects values it does not know.
  • Owner contact never leaves the database. The query selects named columns, and an owner’s phone, email and mailing address are not among them. The reviewer checked this on every head.
  • Fail closed. If the rate limiter’s binding is missing in a deployment, the page refuses rather than serving unlimited queries. The reviewer’s first read had found the opposite behaviour and asked for it reversed.

The map itself is a client-only component on an open tile service with no key and no account. If the tiles fail or the browser has no WebGL, a plain message replaces the map and the list carries on. One privacy point was written down for the owner: the tile service sees a visitor’s address on every search view, and the terms page says so.

The third city

The data side’s first job was a legal read of a new county and its two cities before any connector. The outcome: one city’s permit data is published under a clear public-records statement and got a connector, built and held unscheduled until the owner flips it at the milestone review; the county’s own portal is off limits and its public layer too thin, so no connector; the second city publishes only through a vendor portal that forbids automated reading. Records-request letters for the two without connectors were drafted for the owner to send.

The reviewer agreed with all three classifications independently, and noted the courtesy note to the city is a courtesy, not a gate.