React Native + Expo
Cross-platform app, New Architecture enabled. Expo Router for navigation, EAS for builds and over-the-air updates.
Technical details
Tsamaya is a React Native app backed by a geospatial database and a Python data pipeline with a Claude-assisted review step. Here’s how the pieces fit.
The stack
Cross-platform app, New Architecture enabled. Expo Router for navigation, EAS for builds and over-the-air updates.
Map tiles, Directions API for routing, and Geocoding for search and reverse-geocoding the map.
Postgres with PostGIS geometry holds every zone and corridor. The app reads live; the editor writes via typed RPC functions.
Map-data fetch → proprietary crime-density scoring → zone/corridor classification → staging → promotion to live.
A second-opinion review pass flags questionable classifications for a human before anything reaches drivers.
Versioned SQL migrations keep the database reproducible; TestFlight distributes builds to testers.
Three repos, one system
Crime and map data flow through a pipeline, get reviewed, then go live for the app to read.
The routing model
The routing logic is a small set of deliberate rules, tuned over real South African routes, that decide when a detour is worth it and when it isn’t.
| What triggers a detour | Only higher-risk areas; caution-level zones are shown, never forced |
|---|---|
| Route check | The route is sampled and tested against every active zone for the current time |
| Corridor awareness | Recognises when a route already runs a known-safe corridor, and leaves it be |
| Detour limits | Bypasses are capped so they never wander unreasonably far from the direct line |
| Corridor selection | Only nearby safe corridors are used to steer around a risk area |
| Sanity check | Any detour that ends up excessively longer than direct is rejected. You get the direct route, clearly flagged |
| Time-aware | Separate risk weighting for daytime, evening and night |
Data model
Polygons with a name, city, three time-band risk levels, crime types, and a source. Soft-deleted (never hard-deleted) so history is recoverable.
red · orange · yellow
LineStrings with a buffer width that mark roads as safe (preferred when threading past risk) or danger (actively avoided). Identity is always (city, name), because road names repeat across metros.
safe · danger
Geometry is stored as PostGIS and written through ST_SetSRID(ST_GeomFromGeoJSON(…), 4326) RPCs, since PostgREST can’t auto-cast GeoJSON to geometry.
Coverage
Live across Gauteng (Johannesburg, Pretoria, Ekurhuleni and the West Rand), Cape Town, Stellenbosch and Secunda. Mapped metros: Johannesburg · Cape Town · Pretoria · Ekurhuleni · West Rand · Secunda · Stellenbosch. Adding a new city is a documented, repeatable runbook, not a rewrite.
We’re always glad to talk shop, or to find sponsors who want to fund the next metro.