A community-driven accessibility reporting platform for Calgary, Alberta. StreetWise enables residents to report accessibility issues throughout the city via an interactive web map or SMS messaging, helping make Calgary more accessible for everyone.
StreetWise is a full-stack web application that allows community members to report accessibility issues such as broken sidewalks, missing ramps, problematic crossings, parking issues, and entrance barriers. The platform features an interactive map visualization, SMS reporting for offline access, a staff dashboard for city employees, and comprehensive accessibility features to ensure the platform itself is inclusive.
- Interactive map with report markers and intelligent clustering
- SMS reporting via Twilio for users without internet connectivity
- Staff dashboard with advanced filtering, analytics, and report management
- Accessibility features including color blind modes and adjustable font sizes
- User authentication and profile management via Supabase
- Report voting system (upvote/downvote)
- Real-time updates via Supabase subscriptions
- Heatmap visualization by community showing report density
- Report categorization (sidewalk, ramp, crossing, parking, entrance)
- Community-based filtering and search
- React 18: Modern UI library for building interactive, component-based user interfaces
- Vite: Fast build tool and development server providing instant hot module replacement
- React Router: Client-side routing enabling single-page application navigation without page reloads
- Mapbox GL / react-map-gl: Interactive map visualization library for displaying reports geographically with 3D buildings and terrain
- Supabase JS: Real-time database client providing authentication, data management, and real-time subscriptions
- Supercluster: Efficient point clustering algorithm for grouping map markers at different zoom levels
- React Hot Toast: Non-intrusive toast notification library for user feedback
- date-fns: Modern date formatting and manipulation utilities
- Recharts: Data visualization library for dashboard metrics and analytics charts
- React Icons: Comprehensive icon library for consistent UI elements
- Flask: Lightweight Python web framework for building RESTful API endpoints
- Flask-CORS: Middleware enabling cross-origin requests between frontend and backend
- Supabase: PostgreSQL database with built-in real-time subscriptions, authentication, and Row-Level Security policies
- Twilio: SMS messaging service for receiving and sending text messages, enabling offline reporting capabilities
- OpenAI GPT-4o-mini: Natural language processing API for intelligently parsing SMS messages and extracting structured data (title, address, category)
- Google Maps Geocoding API: Converts text addresses to latitude/longitude coordinates with Calgary-specific bias for accurate location mapping
- ngrok: Local development tool that exposes Flask backend to the internet for Twilio webhook testing without deploying to production
- Python 3.8+: Programming language for backend services
OpenAI's GPT-4o-mini was chosen to intelligently parse natural language SMS messages. Instead of relying solely on regex patterns, the AI extracts structured data (title, address, category) from free-form text messages. This provides more accurate parsing of user-submitted reports, handling variations in language and format. The system falls back to regex-based extraction if OpenAI is unavailable, ensuring reliability.
Twilio enables SMS reporting, making the platform accessible to users without internet connectivity. This is crucial for inclusivity, as not all community members have reliable internet access. Users can text a description and location to a Twilio phone number, and the system processes the message to create a report. Twilio's webhook system allows real-time processing of incoming messages.
Google's Geocoding API provides reliable conversion of text addresses to precise latitude/longitude coordinates. The API is configured with Calgary-specific bias (components for country: CA, administrative_area: AB, locality: Calgary) to ensure accurate results for local addresses. This is essential for accurately mapping reports on the interactive map.
Supabase provides a PostgreSQL database with several key advantages: real-time subscriptions for live updates, built-in authentication, and Row-Level Security (RLS) policies for secure data access. The service role key is used in backend operations to bypass RLS when necessary (e.g., for SMS report creation), while the anon key is used in the frontend for user-facing operations.
Mapbox GL provides high-quality map rendering with 3D buildings and terrain visualization. The library supports custom styling, marker clustering, and interactive features essential for displaying accessibility reports geographically. The map is restricted to Calgary bounds to keep the focus on local issues.
ngrok is essential for local development when testing SMS webhooks. Twilio requires a publicly accessible URL to send webhook requests, and ngrok creates a secure tunnel from a public URL to the local Flask server. This allows developers to test SMS functionality without deploying to production.
HTC-25/
├── backend/ # Flask backend
│ ├── app.py # Main Flask application with API endpoints
│ ├── sms_handler.py # SMS processing, OpenAI parsing, geocoding
│ ├── requirements.txt # Python dependencies
│ └── README.md # Backend documentation
├── frontend/ # React frontend
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── Map.jsx # Interactive map with markers and clustering
│ │ │ ├── StaffDashboard.jsx # Staff dashboard with analytics
│ │ │ ├── AccessibilitySettings.jsx # Accessibility controls
│ │ │ ├── SMSSettings.jsx # SMS reporting configuration
│ │ │ └── ... # Other UI components
│ │ ├── pages/ # Page components
│ │ │ ├── Home.jsx # Main map view
│ │ │ └── MyReports.jsx # User's reports page
│ │ ├── context/ # React context providers
│ │ │ ├── AuthContext.jsx
│ │ │ └── AccessibilityContext.jsx
│ │ ├── lib/ # API and utility libraries
│ │ │ ├── supabaseClient.js
│ │ │ ├── staffApi.js
│ │ │ ├── votingApi.js
│ │ │ └── userProfileApi.js
│ │ ├── data/ # Static data files
│ │ │ └── calgaryCommunitiesData.js
│ │ ├── styles/ # Global styles
│ │ │ └── accessibility.css
│ │ ├── App.jsx # Main app component
│ │ └── main.jsx # Entry point
│ ├── package.json # Node dependencies
│ ├── vite.config.js # Vite configuration
│ └── README.md # Frontend documentation
└── README.md # This file
- Node.js 18+ and npm
- Python 3.8+
- Supabase account and project
- Mapbox account and access token
- Twilio account (for SMS features)
- Google Maps API key (for geocoding)
- OpenAI API key (for SMS parsing)
- Navigate to the backend directory:
cd backend- Create and activate a virtual environment:
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate- Install dependencies:
pip install -r requirements.txt- Create a
.envfile in the backend directory with the following variables:
TWILIO_ACCOUNT_SID=your_twilio_account_sid
TWILIO_AUTH_TOKEN=your_twilio_auth_token
TWILIO_PHONE_NUMBER=your_twilio_phone_number
GOOGLE_MAPS_API_KEY=your_google_maps_api_key
SUPABASE_URL=your_supabase_project_url
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
OPENAI_API_KEY=your_openai_api_key
PORT=5001- Run the Flask server:
python app.pyThe backend API will be running at http://localhost:5001
- Navigate to the frontend directory:
cd frontend- Install dependencies:
npm install- Create a
.envfile in the frontend directory with the following variables:
VITE_MAPBOX_TOKEN=your_mapbox_access_token
VITE_SUPABASE_URL=your_supabase_project_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key- Run the development server:
npm run devThe frontend will be running at http://localhost:5173 (Vite default port)
For testing SMS functionality locally, you'll need to expose your Flask backend to the internet:
-
Install ngrok: https://ngrok.com/download
-
Start your Flask backend (running on port 5001)
-
In a separate terminal, run ngrok:
ngrok http 5001-
Copy the HTTPS URL provided by ngrok (e.g.,
https://abc123.ngrok.io) -
In Twilio Console, configure your phone number's webhook URL:
- Go to Phone Numbers > Manage > Active Numbers
- Select your Twilio number
- Under "Messaging", set the webhook URL to:
https://abc123.ngrok.io/api/sms-webhook - Set HTTP method to POST
-
Test by sending an SMS to your Twilio number
StreetWise supports reporting accessibility issues via SMS, making the platform accessible to users without internet connectivity.
- Sign in to your StreetWise account
- Click on your profile dropdown in the navbar
- Select "SMS Settings"
- Enter your phone number (include country code, e.g., +1234567890)
- Save your phone number
Text your report to the Twilio phone number configured for your StreetWise instance. Include:
- A description of the accessibility issue
- The location (address, intersection, or landmark in Calgary)
Example messages:
- "Broken sidewalk at 123 Main St SW"
- "Missing ramp near Brentwood Station"
- "Broken crosswalk at 17th Ave and 4th St"
When an SMS is received:
-
OpenAI Parsing (Primary): The message is sent to OpenAI GPT-4o-mini to extract:
- A short title (max 40 characters)
- The address/location text
- The category (sidewalk, ramp, crossing, parking, or entrance)
-
Fallback Parsing: If OpenAI is unavailable or fails, the system uses regex patterns and keyword matching to extract the address and infer the category.
-
Geocoding: The extracted address is sent to Google Maps Geocoding API to get latitude/longitude coordinates, with Calgary-specific bias.
-
Report Creation: A report is created in Supabase with the extracted information.
-
Confirmation: The user receives an SMS confirmation with their report number.
GET /api/hello- Test backend connectionGET /api/status- Health check endpointGET /api/data- Get example dataPOST /api/data- Post data to backendPOST /api/sms-webhook- Twilio SMS webhook endpointGET /api/test-sms-webhook- Test SMS webhook configurationPOST /api/test-geocode- Test geocoding functionalityPOST /- Root endpoint (also handles Twilio webhooks for convenience)
You'll need two terminal windows:
Terminal 1 (Backend):
cd backend
source venv/bin/activate
python app.pyTerminal 2 (Frontend):
cd frontend
npm run devFrontend:
cd frontend
npm run buildThe production build will be in the frontend/dist directory.
VITE_MAPBOX_TOKEN: Mapbox access token for map renderingVITE_SUPABASE_URL: Supabase project URLVITE_SUPABASE_ANON_KEY: Supabase anonymous key for client-side operations
TWILIO_ACCOUNT_SID: Twilio account SIDTWILIO_AUTH_TOKEN: Twilio authentication tokenTWILIO_PHONE_NUMBER: Twilio phone number for receiving SMSGOOGLE_MAPS_API_KEY: Google Maps Geocoding API keySUPABASE_URL: Supabase project URLSUPABASE_SERVICE_ROLE_KEY: Supabase service role key (bypasses RLS)OPENAI_API_KEY: OpenAI API key for GPT-4o-miniPORT: Backend server port (default: 5001)
See LICENSE file for details.