A production-ready crowdsourced issue reporting platform built with Leaflet.js and Go. Report and track community issues like potholes, accessibility problems, broken streetlights, and more.
- πΊοΈ Interactive Map: Click-to-report issues with Leaflet.js integration
- πΈ Image Upload: Attach photos to issue reports (max 10MB)
- π·οΈ Categorization: Multiple issue categories (pothole, accessibility, streetlight, graffiti, trash, other)
- π Real-time Statistics: Track total, new, and resolved issues
- π Community Voting: Upvote important issues to increase visibility
- π Advanced Filtering: Filter by category, status, and location
- π Geolocation: Automatic user location detection
- π± Responsive Design: Works seamlessly on desktop and mobile
- β‘ RESTful API: Clean, well-documented API endpoints
- π PostgreSQL Database: Robust data persistence with proper indexing
- π³ Docker Ready: Full containerization with docker-compose
- π Production Security: CORS, rate limiting, input validation
- π Scalable Architecture: Clean architecture pattern with repository layer
- π CI/CD Pipeline: Automated testing and deployment with GitHub Actions
- π Comprehensive Logging: Request/response logging for debugging
- π₯ Health Checks: Built-in health and readiness endpoints
community-issue-mapper/
βββ backend/ # Go backend application
β βββ cmd/
β β βββ server/ # Application entry point
β βββ internal/
β β βββ api/ # API layer
β β β βββ handlers/ # HTTP handlers
β β β βββ middleware/ # Middleware (CORS, logging, rate limiting)
β β β βββ router.go # Route definitions
β β βββ config/ # Configuration management
β β βββ database/ # Database connection
β β βββ models/ # Data models
β β βββ repository/ # Data access layer
β β βββ service/ # Business logic layer
β βββ migrations/ # Database migrations
β βββ go.mod # Go dependencies
βββ frontend/ # Frontend application
β βββ css/ # Stylesheets
β βββ js/ # JavaScript modules
β β βββ api.js # API client
β β βββ map.js # Map management
β β βββ app.js # Main application logic
β βββ index.html # Main HTML file
βββ uploads/ # Uploaded images storage
βββ .github/workflows/ # GitHub Actions CI/CD
βββ docker-compose.yml # Docker composition
βββ Dockerfile # Docker image definition
βββ README.md # This file
- Docker and Docker Compose (recommended)
- OR Go 1.21+ and PostgreSQL 14+
-
Clone the repository
git clone https://github.com/codeforgood-org/community-issue-mapper.git cd community-issue-mapper -
Create environment file
cp .env.example .env # Edit .env with your preferred settings -
Start the application
docker-compose up -d
-
Run migrations
docker-compose run migrate
-
Access the application
- Web UI: http://localhost:8080
- API: http://localhost:8080/api/v1
- Health Check: http://localhost:8080/health
-
Install dependencies
cd backend go mod download -
Set up PostgreSQL
createdb community_issues
-
Run migrations
# Install migrate tool first brew install golang-migrate # macOS # or download from https://github.com/golang-migrate/migrate make migrate-up
-
Start the server
make run # or with auto-reload (requires air) make dev
http://localhost:8080/api/v1
GET /api/v1/issuesQuery Parameters:
category(optional): Filter by category (pothole, accessibility, streetlight, graffiti, trash, other)status(optional): Filter by status (new, in_progress, resolved, closed)min_lat,max_lat,min_lng,max_lng(optional): Bounding box filterlimit(optional): Maximum number of results (default: 100, max: 1000)offset(optional): Pagination offset
Response:
[
{
"id": 1,
"title": "Large pothole on Main Street",
"description": "Dangerous pothole near the intersection",
"category": "pothole",
"status": "new",
"latitude": 37.7749,
"longitude": -122.4194,
"address": "123 Main St",
"image_url": "/uploads/1.jpg",
"reporter_name": "John Doe",
"reporter_email": "john@example.com",
"votes": 5,
"created_at": "2025-01-01T10:00:00Z",
"updated_at": "2025-01-01T10:00:00Z"
}
]POST /api/v1/issues
Content-Type: application/jsonRequest Body:
{
"title": "Broken streetlight",
"description": "Streetlight not working for 2 weeks",
"category": "streetlight",
"latitude": 37.7749,
"longitude": -122.4194,
"address": "456 Oak Ave",
"reporter_name": "Jane Smith",
"reporter_email": "jane@example.com"
}GET /api/v1/issues/{id}PATCH /api/v1/issues/{id}
Content-Type: application/jsonRequest Body (all fields optional):
{
"title": "Updated title",
"description": "Updated description",
"status": "in_progress",
"category": "pothole"
}DELETE /api/v1/issues/{id}POST /api/v1/issues/{id}/upload
Content-Type: multipart/form-dataForm Data:
image: Image file (max 10MB)
POST /api/v1/issues/{id}/voteGET /api/v1/statsResponse:
{
"total_issues": 150,
"issues_by_status": {
"new": 45,
"in_progress": 30,
"resolved": 60,
"closed": 15
},
"issues_by_category": {
"pothole": 40,
"accessibility": 25,
"streetlight": 20,
"graffiti": 15,
"trash": 30,
"other": 20
}
}GET /healthGET /readymake help # Show all available commands
make build # Build the application
make run # Run the application
make test # Run tests
make test-coverage # Run tests with coverage report
make clean # Clean build artifacts
make docker-build # Build Docker image
make docker-up # Start Docker containers
make docker-down # Stop Docker containers
make docker-logs # View Docker logs
make migrate-up # Run database migrations up
make migrate-down # Run database migrations down
make migrate-create # Create a new migration
make deps # Download dependencies
make lint # Run linter
make dev # Run with auto-reloadcd backend
go test -v ./...
# With coverage
go test -v -race -coverprofile=coverage.out ./...
go tool cover -html=coverage.outmake migrate-create name=add_new_fieldThis creates two files in backend/migrations/:
{timestamp}_add_new_field.up.sql{timestamp}_add_new_field.down.sql
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 8080 |
ENV |
Environment (development/production) | development |
DB_HOST |
Database host | localhost |
DB_PORT |
Database port | 5432 |
DB_USER |
Database user | issueapp |
DB_PASSWORD |
Database password | issueapp_password |
DB_NAME |
Database name | community_issues |
DB_SSL_MODE |
Database SSL mode | disable |
CORS_ALLOWED_ORIGINS |
Allowed CORS origins | * |
MAX_UPLOAD_SIZE |
Max upload size in bytes | 10485760 (10MB) |
UPLOAD_DIR |
Upload directory | ./uploads |
RATE_LIMIT_REQUESTS |
Rate limit requests | 100 |
RATE_LIMIT_DURATION |
Rate limit duration | 1m |
-
Build and push Docker image
docker build -t your-registry/community-issue-mapper:latest . docker push your-registry/community-issue-mapper:latest -
Deploy with docker-compose
docker-compose up -d
The application can be easily deployed to:
- AWS ECS/Fargate: Use the included Dockerfile
- Google Cloud Run: Supports container deployment
- Azure Container Instances: Direct Docker deployment
- Heroku: Use container registry
- DigitalOcean App Platform: Docker-based deployment
- Set
ENV=productionfor production - Use proper database credentials
- Configure CORS origins appropriately
- Set up SSL/TLS termination at load balancer
- Use managed PostgreSQL service for production
- β CORS protection with configurable origins
- β Rate limiting to prevent abuse
- β Input validation and sanitization
- β SQL injection prevention (parameterized queries)
- β File upload validation
- β Secure headers
β οΈ TODO: Add authentication/authorizationβ οΈ TODO: Add HTTPS enforcementβ οΈ TODO: Add API key management
The project includes:
- Unit tests for repository layer
- Integration tests for API endpoints
- GitHub Actions CI/CD pipeline
- Code coverage reporting
/health: Database connectivity check/ready: Application readiness check
All requests are logged with:
- HTTP method
- Request URI
- Response status
- Response size
- Request duration
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Leaflet.js - Interactive map library
- OpenStreetMap - Map data
- Gorilla Mux - HTTP router
- PostgreSQL - Database
For support, please open an issue on GitHub or contact the maintainers.
- User authentication and authorization
- Email notifications for issue updates
- Admin dashboard for issue management
- Mobile applications (iOS/Android)
- SMS notifications
- Integration with city management systems
- Analytics and reporting dashboard
- Multi-language support
- Dark mode
- Offline support with PWA
Built with β€οΈ for communities everywhere