The Problem

Organizations that need to monitor physical‑world infrastructure (e.g., telecom towers, power plants, airports) must manually scrape OpenStreetMap or write bespoke queries. The effort is repetitive, error‑prone, and hard to keep in sync with OSM’s evolving data model.

What This Does

sightline is a small Next.js web app that turns natural‑language or simple structured queries into Overpass API calls and presents the results on a Leaflet map.

  • The front‑end lives in components/ – e.g. SearchBar.tsx, Filters.tsx, ResultList.tsx, and the map UI in MapView.tsx.
  • The back‑end API routes are in app/api/:
  • search/route.ts receives a POST, validates the query (lib/parser.ts), resolves locations (lib/geo.ts), builds an Overpass query (lib/overpass.ts), and caches results (lib/cache.ts).
  • nominatim/route.ts provides a thin wrapper around the Nominatim geocoder.
  • Core data types are defined in lib/types.ts (e.g., ParsedQuery, GeoResult, SearchResult).

Together they let a user type “power plants near mumbai” and receive a plotted list of assets without writing any Overpass QL.

How It Is Wired

Execution starts when a browser loads app/page.tsx. The Home component renders the search UI (SearchBar, Filters) and the map (MapView).

When the user submits a query, the client issues a POST /api/search request handled by app/api/search/route.ts. The call chain is:

  1. POST handlerparseStructured (in lib/parser.ts) – parses natural or structured syntax.
  2. extractLocation (also in parser.ts) → waitForRateLimitfetchWithTimeout (both in lib/geo.ts) → calls the external Nominatim API.
  3. buildOverpassQuery (in lib/overpass.ts) assembles a QL string; it calls fetchWithTimeout again to invoke the Overpass API.
  4. Cache layergenerateKey (in lib/cache.ts) creates a deterministic cache key; getCached checks the in‑memory store, setCached writes the fresh result.
  5. The final SearchResult array is returned to the front‑end, where ResultList.tsx renders the list and MapView.tsx creates Leaflet pop‑ups using escapeHtml (defined in MapView.tsx).

The most widely used internal functions are generateKey (4 callers), waitForRateLimit (3 callers), and fetchWithTimeout (3 callers). Their instability scores are 0‑1, meaning they are leaf nodes or single‑direction dependencies, reducing the blast radius of changes. No circular imports were detected.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/sightline
cd sightline

# Install dependencies
npm install

# Run the development server (Next.js)
npm run dev   # starts http://localhost:3000

The app expects no additional configuration; it talks directly to the public Nominatim and Overpass endpoints. If you need to point to a private Overpass instance, modify the base URL in lib/overpass.ts.

Real‑World Use

A regional utilities provider could embed this UI in an internal dashboard. By feeding a daily “type:substation region:california” query, the dashboard automatically refreshes the map with any newly added substations, letting operators spot gaps without manual OSM queries.

Code Health & Issues

Measured findings (8 × Medium)

  • Oversized files: lib/types.ts, components/MapView.tsx (≈ 1 k lines each).
  • Duplicated 6‑line blocks across 5 files (Filters.tsx, ResultList.tsx, MapView.tsx, lib/geo.ts).
  • Deep nesting (max depth 7) in Filters.tsx, ResultList.tsx, SearchBar.tsx.
  • High branching density in lib/overpass.ts and lib/parser.ts.

Code‑health audit

  • High – No test suite (21 source files, 0 tests).
  • Medium – GitHub Actions workflow (.github/workflows/lint.yml) lacks least‑privilege permissions.
  • Medium – No Dependabot/Renovate configuration.
  • Medium – No dependency‑vulnerability scan in CI.
  • Medium – Checkout step keeps GITHUB_TOKEN; should set persist-credentials: false.
  • Low – Jobs have no timeout-minutes.
  • Low – Missing convention files (.editorconfig, .gitattributes, formatter config).

No Dockerfile, secret leakage, or license issues beyond the existing LICENSE.

The Bottom Line

sightline delivers a functional OSINT front‑end for OSM‑based infrastructure discovery with a clear separation between UI and API layers. Its biggest drawbacks are the lack of automated tests and several maintainability concerns (large files, duplicated logic, deep nesting). It is suitable for rapid prototyping or internal tooling, but would need a test suite and some refactoring before being trusted in a production‑critical environment.