PAZATOR DOCS
LCTX
FEATURE — v0.May1526

LCTX
Globe Tracker.

Why it exists

Pazator ingests structured entity data, but location data is fundamentally different — it's continuous, time-bound, and comes from a completely separate pipeline (GPS pings, cell tower logs, etc.). The LCTX tracker keeps location data separate from entity profiles, linked only by a shared alias. This means you can have rich location history for a person without polluting the entity data model with hundreds of timestamped coordinates.

The globe visualisation gives you a "God's eye" view — satellite imagery, path lines, and automatic spin so you can watch movement patterns emerge without touching the keyboard.

Architecture

The tracker runs on a Supabase backend with a single locations table. Pazator connects via the Supabase JavaScript client with an anon key — no server-side middleware needed. Configuration is stored in localStorage.LCTXTrackerConfig and can be set through the "Configure tracker server" button in the tracker tab.

Supabase locations table schema

id          uuid / serial    (primary key)
name        text             (person alias, used for linking)
latitude    float8
longitude   float8
timestamp   timestamptz
ip          text
region      text
country     text
device      text
platform    text
user_agent  text
speed       float8
heading     float8

How It Works

1. Configuration

Click "Configure tracker server" to enter your Supabase project URL and anon key. The key is stored in localStorage and used to create a Supabase client via supabase.createClient(url, key). The tracker won't initialise until valid credentials are provided. On first visit, it prompts automatically.

2. Loading people

On map load, fetchTrackerPeople() queries the locations table with .select('name').order('timestamp', { ascending: false }), then groups by name with a point count. The result is rendered as a list in the sidebar — each item shows the name and number of data points.

3. Viewing a person's path

Click a person in the sidebar. showTrackerPersonLocations(name) fetches all rows for that name sorted ascending by timestamp, then:

  • Adds a LineString GeoJSON source (tracker-path) for the path trace
  • Adds a Point GeoJSON source (tracker-markers) for individual pings
  • flyTo() the latest coordinate at zoom 15, pitch 60
  • Reverse-geocodes the latest point via Nominatim and displays the address + available metadata (IP, device, platform, country, region)

4. Globe controls

  • Spin — continuous requestAnimationFrame rotation at configurable degrees/second (default 10°/s, max 60). Speed persisted across sessions.
  • Street labels — toggles an OSM raster overlay on top of the satellite imagery.
  • Angle / Top-down — sets pitch to 60° (isometric) or 0° (flat).
  • Reset view — flyTo [0,0] at zoom 2, pitch 60, bearing 0.
  • Filter toggle — visual CSS filter toggle on the map container (presentational, not a query filter).

5. Person linking

The tracker integrates with Pazator's entity model. You can connect a human entity to a tracker alias from the tracker tab itself (using the "Connect" dropdown), or from the entity detail slide panel. When linked, the human record gets trackerAlias and trackerLinkedAt fields. The detail panel then shows the latest known location for that alias, fetched live from Supabase.

Debug & Status

A #trackerDebug status line at the bottom of the sidebar shows what the tracker is doing: "Fetching tracker people...", "Found 1420 tracker points across 34 people.", or "Tracker disabled until you configure a Supabase connection." This is the main feedback channel since Supabase operations are async.

Danger Zone

The "Purge" button calls purgeTrackerData() which fires a DELETE FROM locations WHERE id != 0 on Supabase after a confirmation dialog. No undo.


What's Missing

No real-time subscriptions. The tracker polls Supabase on demand — it doesn't use Supabase's real-time features at all. Location history for linked entities is limited to the latest point; there's no timeline view showing all historical pings for a linked human. The tracker also doesn't push location updates to the entity graph or trigger alerts on proximity or geofence events.

Reverse geocoding is done client-side via Nominatim's free API, which has usage limits and no caching. If you click through many people in quick succession, you'll get HTTP 429 responses.