Skip to content
CaiserePublic

About

LasGrid is a real-time Lagos traffic incident map for reporting, tracking, and viewing road disruptions as they happen.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LaGRID

LaGRID is a live, community-powered traffic incident map for Lagos. It gives people a fast way to see road disruptions, report what they encounter, confirm reports from other drivers, and mark incidents as cleared.

The project pairs a Next.js/Leaflet map experience with an Express, WebSocket, and PostgreSQL backend designed to broadcast incident updates in real time.

What it does

  • Centers an interactive map on Lagos and displays active incident markers.
  • Supports traffic, accidents, road closures, flooding, construction, and other road issues.
  • Lets users select a location, add details, and drop a report pin.
  • Filters incidents by type and shows live per-category totals.
  • Lets users confirm reports (upvote) or mark them cleared.
  • Provides a real-time server protocol for incident reports, upvotes, resolutions, and viewer presence.
  • Limits server-submitted incident locations to a Lagos bounding box.

Current status

The web app is presently a polished front-end prototype: it starts with local seed data and simulates connection/report confirmation state. The server and its WebSocket event handlers are implemented separately, but the browser hook is not yet wired to that server. See Roadmap for the main integration work remaining.

Tech stack

Area Technology
Web client Next.js 16, React 19, TypeScript
Mapping Leaflet and React Leaflet; CARTO dark map tiles
API Express 5
Real time ws WebSocket server
Database PostgreSQL, Drizzle ORM
Tooling npm workspaces, TypeScript, tsx

Project structure

.
├── apps/
│   ├── web/                  # Next.js map interface
│   │   ├── app/              # App Router entry point and global styles
│   │   ├── components/       # Map, reporting UI, filters, summary, status UI
│   │   ├── hooks/            # Local incident state and connection-state hook
│   │   └── lib/              # Map constants, seed data, shared client types
│   └── server/               # Express + WebSocket service
│       ├── src/http/         # Health endpoint and incident REST routes
│       ├── src/ws/           # Rooms, presence, and incident event handlers
│       ├── src/db/           # Drizzle database client and schema
│       └── drizzle/          # PostgreSQL migration files
└── package.json              # Workspace commands

Getting started

Prerequisites

  • Node.js 20 or newer
  • npm 10 or newer
  • A PostgreSQL database (for the API/WebSocket server)

Install dependencies

npm install

Configure the server

Create apps/server/.env:

DATABASE_URL=postgresql://USER:PASSWORD@HOST:5432/DATABASE
MAP_ROOM=lagos-map
PORT=8080

DATABASE_URL is required when starting the server because the database client initializes at startup. MAP_ROOM is the shared WebSocket room used for the Lagos map.

Create the database schema

The initial SQL migration is at apps/server/drizzle/0000_powerful_husk.sql. Apply it to the database specified by DATABASE_URL using your preferred PostgreSQL migration workflow.

For example, from apps/server, you can use Drizzle Kit with the included configuration:

npx drizzle-kit push

Start development servers

npm run dev

This starts:

  • Web client: http://localhost:3000
  • API and WebSocket server: http://localhost:8080 and ws://localhost:8080

You can also run either workspace independently:

npm run dev:web
npm run dev:server

Available commands

Command Description
npm run dev Run the web client and server concurrently.
npm run dev:web Run only the Next.js development server.
npm run dev:server Run only the Express/WebSocket server in watch mode.
npm run build --workspace=apps/web Create a production web build.
npm run build --workspace=apps/server Compile the server to apps/server/dist.
npm run lint --workspace=apps/web Lint the web client.

Server API

The REST server mounts incident routes at /incidents.

Method Endpoint Current behavior
GET / Health response with status and timeStamp.
GET /incidents Returns all incidents in the database.
GET /incidents/:id Route placeholder; currently returns the requested ID.
POST /incidents Route placeholder for incident creation.
PATCH /incidents/:id/upvote Route placeholder for an upvote.
PATCH /incidents/:id/resolve Route placeholder for resolution.

Real-time incident writes currently happen over WebSockets rather than these placeholder REST mutations.

WebSocket protocol

Connect to ws://localhost:8080. On a successful connection the server sends:

{ "type": "CONNECTED", "message": "Websocket established" }

Clients should then join the shared map room:

{ "type": "JOIN_MAP" }

Client-to-server events

Event Payload
JOIN_MAP No payload. Adds the client to the map room and begins presence tracking.
INCIDENT_REPORT { "type", "description", "latitude", "longitude", "temId" }
INCIDENT_UPVOTE { "incidentId" }
INCIDENT_RESOLVE { "incidentId" }

INCIDENT_REPORT.type must be one of TRAFFIC_JAM, ACCIDENT, ROAD_CLOSURE, FLOODING, CONSTRUCTION, or OTHERS. Coordinates must fall within latitude 6.3–6.7 and longitude 3.1–3.6.

The temId field is echoed in the broadcast response so a client can replace an optimistic marker with the persisted incident. Its spelling reflects the current server contract.

Server-to-client events

Event Meaning
JOINED Confirms map-room membership and includes viewerCount.
VIEWER_COUNT Broadcasts the current viewer count.
INCIDENT_REPORTED Broadcasts a newly persisted incident and its originating temId.
INCIDENT_UPVOTED Broadcasts an incident ID and its new upvotes total.
INCIDENT_RESOLVED Broadcasts the resolved incident ID.
ERROR Indicates an unknown message type, invalid payload, invalid Lagos location, or JSON parsing error.
DB_ERROR Indicates a database operation failed.

Data model

Each database incident includes a UUID, category, description, latitude/longitude, reporter information, upvote count, resolved status, creation time, and expiry time. New WebSocket reports are set to expire 15 minutes after creation.

Roadmap

  • Connect useWebSocket in the web app to the server protocol.
  • Replace seeded incident data with an initial GET /incidents fetch.
  • Align client incident names (TRAFFIC, CLOSURE, OTHER) with server enum values (TRAFFIC_JAM, ROAD_CLOSURE, OTHERS).
  • Implement the REST route placeholders and fetch incidents by ID.
  • Add expiry processing to remove or hide expired incidents.
  • Add server-side validation, rate limiting, authentication/moderation, and automated tests before production use.

License

This project is licensed under the ISC License.

Built with 💚 by Omoshola

About

LasGrid is a real-time Lagos traffic incident map for reporting, tracking, and viewing road disruptions as they happen.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages