Contents

Documentation / Site View

Site View

Site View is the operations intelligence platform behind Open Site Intelligence: an internal, desktop-first web application for managed service providers operating large estates of sites. The map is the primary interface; the intelligence layer behind it is the product. This page is the developer documentation for running and understanding it.

Introduction

Operational data in a managed service business lives in fragments: sites in spreadsheets, engineer assignments in email threads and individual heads. Site View makes the estate visible, searchable, and spatially queryable through a map-first interface backed by PostGIS. The defining promise: any operational question about the estate can be answered in under ten seconds.

The platform started with UK school estates and is now sector-agnostic. Vocabulary presets (Generic, Education, FM, Maintenance) rename the domain objects without touching the schema.

Roles and access

Three roles gate what a user can do.

RoleCan do
AdminEverything: user management, system config, all data edits.
EditorAdd and remove sites, edit site and engineer data, use all tools. No user management.
ViewerRead-only. Browse, search, run analytical tools. No writes; contract values hidden.

Roles are enforced in the database, not the interface. The UI hides buttons and guards routes for usability, but row-level security rejects any unauthorised operation regardless of what the client sends.

Installation

Prerequisites: Node.js 20+, a Supabase project, a MapTiler key, and an OpenRouteService key.

# 1. Install
npm install

# 2. Configure
cp .env.local.example .env.local   # fill in the values below

# 3. Apply database migrations (Supabase CLI)
supabase link --project-ref <your-project-ref>
supabase db push

# 4. Deploy edge functions
supabase functions deploy geocode-queue
supabase functions deploy ors-proxy

# 5. Run
npm run dev                        # http://localhost:3000 redirects to /map
Note. Two migrations, service_business_generalisation andtender_impact_analysis, are additive and safe to apply to a populated estate. The Tender Impact Analysis RPCs do not exist server-side until they are run.

Environment variables

VariableExposureNotes
NEXT_PUBLIC_SUPABASE_URLClientProject URL.
NEXT_PUBLIC_SUPABASE_ANON_KEYClientPublic by design; row-level security enforces access.
SUPABASE_SERVICE_ROLE_KEYServerEdge functions and admin routes only. Never client-side.
NEXT_PUBLIC_MAPTILER_KEYClientDomain-restricted in the MapTiler dashboard.
ORS_API_KEYServerProxied through an edge function; never in the client bundle.

Architecture and state

Site View is a single-page Next.js app on Vercel, with Supabase providing PostgreSQL, PostGIS, auth, and edge compute. Two edge functions run server-side: an async, rate-limited geocoding queue (Nominatim with a Postcodes.io fallback) and a proxy that keeps the OpenRouteService key out of the client.

Two kinds of state are kept strictly separate. Server state belongs to TanStack Query: no component reads Supabase outside a query hook, keys are structured, and mutations invalidate. Client state belongs to Zustand: viewport, active layers, selection, panels — nothing that originates from the server.

All spatial logic runs server-side. Every spatial query is a Postgres function called through Supabase RPC (get_sites_within_radius, get_nearest_sites,get_engineers_within_radius, search_sites). No PostGIS SQL ships in client code, so the logic stays centralised, testable, and frontend-independent.

Security model

Row-level security is the authoritative access layer, on every table, with no anonymous access. Secrets stay server-side: the OpenRouteService key lives only in an edge function, the service-role key never reaches the client, and the only client-exposed keys are the RLS-guarded Supabase anon key and a domain-locked MapTiler key. Contract values are excluded from viewer-role queries at the query layer, and user invitations go through a server-side route that verifies the caller's role first.

Tender Impact Analysis

The headline capability: model the operational consequences of winning a contract before committing to the bid. Drop a postcode, address, or map pin, confirm the marker, and get a factual report in seconds — nearest available engineers and their distances, which relationship manager owns the nearest sites, how many existing sites fall within reach, and drive-time reachability from a real OpenRouteService isochrone rather than a straight-line guess.

The analysis is geography-only by design. Where the estate does not hold the data to answer honestly, the feature says so rather than inventing a number.