A complete mono-repo project for reporting and managing public safety issues. Includes a web dashboard, mobile app, and backend API.
Citizen Safety is a platform that allows citizens to quickly report public issues (potholes, broken infrastructure, safety concerns, etc.) with photos, GPS location, and optional contact information. The web app provides an admin dashboard for managing and tracking these reports.
- Mobile App: User opens app β Takes photo β Adds description β Selects category β GPS location captured β Submits report
- Backend API: Receives report β Validates data β Stores in SQLite database β Returns issue ID
- Web Dashboard: Admin views all issues β Filters by category β Updates status β Exports data
- Node.js + Express + TypeScript
- SQLite (better-sqlite3) for persistence
- RESTful API with admin authentication
- React + Vite + TypeScript
- Chart.js for analytics
- Responsive design with muted color palette
- Expo + React Native + TypeScript
- Camera and location permissions
- Offline queue support with AsyncStorage
- Common TypeScript types and API client
- Workspace-based mono-repo structure
citizen-safety-ecosystem/
βββ backend/ # Express API server
β βββ src/
β β βββ controllers/
β β βββ routes/
β β βββ models/
β β βββ db/
β β βββ middleware/
β βββ migrations/
β βββ Dockerfile
βββ web/ # React web dashboard
β βββ src/
β β βββ pages/
β β βββ components/
β β βββ api/
β βββ vite.config.ts
βββ mobile/ # Expo mobile app
β βββ screens/
β βββ components/
β βββ utils/
β βββ app.json
βββ shared/ # Shared types and utilities
β βββ src/
β βββ types.ts
β βββ api-client.ts
βββ tests/ # Backend tests
βββ docs/ # Documentation and screenshots
- Node.js 18+ and npm 9+
- Expo CLI (for mobile):
npm install -g expo-cli - For mobile development: iOS Simulator (macOS) or Android Studio
- Clone and install dependencies:
cd citizen-safety-ecosystem
npm installThis will install dependencies for all workspaces (backend, web, mobile, shared).
- Set up environment variables:
Option A: Use setup script (recommended):
chmod +x scripts/setup.sh
./scripts/setup.shOption B: Manual setup:
Backend (backend/.env):
cp backend/env.example backend/.env
# Edit backend/.env with your valuesRequired variables:
PORT=3001(backend port)ADMIN_TOKEN=your-secret-admin-token(for admin endpoints)DATABASE_PATH=./data/citizen_safety.db(SQLite database path)CORS_ORIGIN=http://localhost:5173,exp://localhost:8081(allowed origins)
Web (web/.env):
cp web/env.example web/.env
# Edit web/.env with your valuesVariables:
VITE_API_BASE_URL=http://localhost:3001VITE_ADMIN_TOKEN=your-secret-admin-token(Optional, for admin features)
Mobile (mobile/app.json extra or environment):
Update app.json:
{
"extra": {
"apiBaseUrl": "http://localhost:3001"
}
}For physical devices, use your computer's IP address instead of localhost.
- Initialize database:
npm run migrate --workspace=backendOptionally seed with sample data:
npm run seed --workspace=backendYou'll need three terminal windows:
Terminal 1 - Backend:
npm run dev:backendBackend runs on http://localhost:3001
Terminal 2 - Web:
npm run dev:webWeb app runs on http://localhost:5173
Terminal 3 - Mobile:
npm run dev:mobileThen:
- Press
ifor iOS simulator - Press
afor Android emulator - Scan QR code with Expo Go app on physical device
Install concurrently globally and use:
npm run dev:all-
Install Expo Go app on your phone (iOS App Store or Google Play)
-
Start the mobile app:
cd mobile
npm start-
Choose connection method:
- Tunnel (recommended for testing): Works anywhere, slower
- LAN: Faster, requires same WiFi network
- Local: Only works on same machine
-
Scan QR code with Expo Go app
-
Update API URL in
mobile/app.jsonor.env:- For LAN: Use your computer's local IP (e.g.,
http://192.168.1.100:3001) - For tunnel: Use the tunnel URL provided by Expo
- For LAN: Use your computer's local IP (e.g.,
The app will request:
- Camera: For taking photos
- Photo Library: For selecting images
- Location: For GPS coordinates
Run backend tests:
npm test --workspace=backendTests use Jest + Supertest and cover:
- Health check endpoint
- Issue creation
- Input validation
npm run build:backend
npm start --workspace=backendnpm run build:web
npm run preview --workspace=webcd mobile
expo build:android # or expo build:iosOr use EAS Build:
eas build --platform android
eas build --platform iosdocker build -t citizen-safety-backend -f backend/Dockerfile .
docker run -p 3001:3001 \
-e PORT=3001 \
-e ADMIN_TOKEN=your-token \
-e DATABASE_PATH=/app/data/citizen_safety.db \
-v $(pwd)/data:/app/data \
citizen-safety-backenddocker-compose upSee docker-compose.yml for full setup.
-
Set environment variables:
PORT(usually auto-set)ADMIN_TOKEN(generate secure token)DATABASE_PATH(or use provided path)CORS_ORIGIN(your web app URL)
-
Deploy:
- Connect GitHub repo
- Set build command:
npm install && npm run build --workspace=shared && npm run build --workspace=backend - Set start command:
npm run migrate --workspace=backend && npm start --workspace=backend
-
Set environment variables:
VITE_API_BASE_URL(your backend URL)VITE_ADMIN_TOKEN(optional)
-
Deploy:
- Connect GitHub repo
- Build command:
npm install && npm run build --workspace=web - Output directory:
web/dist
- Update API URL in
app.json:
{
"extra": {
"apiBaseUrl": "https://your-backend-url.com"
}
}- Build and publish:
cd mobile
expo publish
# or
eas build --platform allSee api-spec.md for complete API documentation.
GET /api/ping- Health checkGET /api/issues- List issues (supports?limit,?category,?since)GET /api/issues/:id- Get single issuePOST /api/issues- Create issuePATCH /api/issues/:id- Update issue (admin)GET /api/issues/export.csv- Export CSV (admin)GET /api/issues/:id/image/:index- Get issue image
- Primary Text:
#0f172a(slate-900) - Secondary Text:
#64748b(slate-500) - Background:
#f8fafc(slate-50) - Primary Accent:
#2563eb(blue-600) or#0ea5a4(teal-600) - Success:
#16a34a(green-600) - Warning:
#ca8a04(yellow-600) - Error:
#dc2626(red-600)
No neon colors - muted, professional palette for readability and calm UX.
βββββββββββββββ
β Mobile β
β (Expo) β
ββββββββ¬βββββββ
β
β HTTP/REST
β
ββββββββΌβββββββ ββββββββββββ
β Backend ββββββββββΆβ SQLite β
β (Express) β β Database β
ββββββββ¬βββββββ ββββββββββββ
β
β HTTP/REST
β
ββββββββΌβββββββ
β Web App β
β (React) β
βββββββββββββββ
- Mobile: User submits report β Offline queue (if offline) β API β Database
- Web: Dashboard polls API β Displays issues β Admin updates status β API β Database
- Shared: Common types ensure consistency across all clients
- Admin endpoints protected with Bearer token authentication
- Input validation on all endpoints
- CORS configured for specific origins
- SQL injection protection via parameterized queries
- Image size limits (base64 in request body)
- TypeScript strict mode enabled
- ESLint for linting
- Prettier for formatting
- Consistent naming conventions
Run linting:
npm run lint # (if configured)- Create feature branch
- Make changes
- Run tests:
npm test - Submit pull request
MIT License - see LICENSE file
- Check if port 3001 is available
- Verify
.envfile exists and has correct values - Run
npm run migrateto initialize database
- Verify
VITE_API_BASE_URLinweb/.env - Check CORS settings in backend
- Ensure backend is running
- For physical device: Use computer's IP address, not
localhost - Check firewall settings
- Try tunnel mode in Expo
- Delete
data/citizen_safety.dband runnpm run migrateagain - Check file permissions on database directory
- Monorepo Structure - NPM Workspaces
- TypeScript - Type-safe development across all packages
- Node.js - Runtime environment (>=18.0.0)
- NPM - Package manager (>=9.0.0)
- Node.js - JavaScript runtime
- Express.js (v4.18.2) - Web framework
- TypeScript (v5.3.3) - Type-safe JavaScript
- TSX (v4.7.0) - TypeScript execution for development
- SQLite3 (better-sqlite3 v9.2.2) - Embedded database
- Database Migrations - Custom migration system
- CORS (v2.8.5) - Cross-Origin Resource Sharing
- dotenv (v16.3.1) - Environment variable management
- Jest (v29.7.0) - Testing framework
- Supertest (v6.3.3) - HTTP assertion library
- ts-jest (v29.1.1) - TypeScript preprocessor for Jest
- @types/cors, @types/express, @types/jest, @types/node, @types/supertest
- React Native (v0.81.5) - Mobile app framework
- React (v19.1.0) - UI library
- Expo (v54.0.25) - React Native development platform
- React Navigation (v6.1.18) - Navigation library
- @react-navigation/native (v6.1.18)
- @react-navigation/native-stack (v6.11.0)
- @react-navigation/bottom-tabs (v6.6.1)
- @expo/vector-icons (v15.0.3) - Icon library (MaterialCommunityIcons)
- expo-linear-gradient (v15.0.7) - Gradient components
- @react-native-async-storage/async-storage (v2.1.0) - Local storage
- React Context API - State management
- expo-location (v19.0.7) - GPS and location services
- expo-image-picker (v17.0.8) - Camera and photo library access
- expo-notifications (v0.32.13) - Push notifications
- expo-sms (v14.0.7) - SMS sending
- expo-clipboard (v8.0.7) - Clipboard operations
- expo-sharing (v14.0.7) - Share functionality
- expo-linking (v8.0.9) - Deep linking and URL handling
- expo-status-bar (v3.0.8) - Status bar control
- @react-native-community/netinfo (v11.3.1) - Network status detection
- Axios (via shared package) - HTTP client
- react-native-gesture-handler (v2.28.0) - Gesture recognition
- react-native-safe-area-context (v5.6.0) - Safe area handling
- react-native-screens (v4.16.0) - Native screen components
- Babel (@babel/core v7.20.0) - JavaScript compiler
- TypeScript (v5.3.3) - Type checking
- iOS - Native iOS support
- Android - Native Android support
- Web - Web platform support (via Expo Web)
- React (v18.2.0) - UI library
- React DOM (v18.2.0) - DOM rendering
- TypeScript (v5.3.3) - Type-safe development
- Vite (v5.0.8) - Fast build tool and dev server
- @vitejs/plugin-react (v4.2.1) - React plugin for Vite
- React Router DOM (v6.21.1) - Client-side routing
- Axios (v1.6.2) - HTTP client library
- Chart.js (v4.4.1) - Charting library
- react-chartjs-2 (v5.2.0) - React wrapper for Chart.js
- @types/react (v18.2.45)
- @types/react-dom (v18.2.18)
- TypeScript (v5.3.3) - Shared type definitions
- Axios (v1.6.2) - Shared API client
- @types/node (v20.10.5)
- TypeScript Compiler (tsc) - Type checking and compilation
- Vite - Web app bundler
- Babel - JavaScript/TypeScript transpilation
- TSX - TypeScript execution
- NPM Workspaces - Monorepo package management
- Concurrently (v8.2.2) - Run multiple commands simultaneously
- TypeScript - Static type checking
- ESLint (implicit via TypeScript strict mode)
- SQLite3 (better-sqlite3) - Embedded relational database
- Custom Migration System - Database schema versioning
- AsyncStorage (Mobile) - Local key-value storage
- File System - Image and file storage
- JWT (JSON Web Tokens) - Token-based authentication
- bcrypt (implicit) - Password hashing
- OTP (One-Time Password) - Email and phone verification
- CORS - Cross-origin resource sharing
- Environment Variables - Secure configuration management
- Express.js - RESTful API server
- Axios - HTTP client (shared across web and mobile)
- Expo Push Notifications - Push notification service
- Email Service (Mock/Development) - Email sending
- SMS Service (Mock/Development) - SMS sending
- CSS3 - Web styling
- CSS Animations - Smooth transitions and animations
- CSS Variables - Theme management
- React Native StyleSheet - Mobile styling
- Linear Gradients - Modern gradient effects
- Component-Based Architecture - React components
- Context API - State management
- Custom Hooks - Reusable logic
- GPS - Location tracking
- Geolocation API - Coordinate-based features
- Map Integration - Location visualization
- Image Picker - Camera and gallery access
- Image Processing - Base64 encoding/decoding
- Image Display - Responsive image rendering
- Offline Queue - Queue operations when offline
- Network Detection - Connectivity monitoring
- Data Synchronization - Sync when back online
- Docker (Dockerfile present) - Container support
- Docker Compose - Multi-container orchestration
- dotenv - Environment configuration
- env.example - Configuration templates
- Markdown - Documentation format
- API Specification - REST API documentation
- TypeScript Types - Self-documenting code
- TypeScript Strict Mode - Type safety
- ES Module System - Modern JavaScript modules
- CommonJS - Backend module system
- Git - Version control
- GitHub - Repository hosting
- TypeScript (Primary)
- JavaScript (Compiled)
- SQL (Database queries)
- CSS (Styling)
- JSON (Configuration)
- React (Web & Mobile)
- React Native (Mobile)
- Express.js (Backend)
- Expo (Mobile Platform)
- SQLite3
- Vite (Web)
- TypeScript Compiler
- Babel
- TSX
- Jest
- Supertest
- NPM
- NPM Workspaces
- TypeScript
- ESLint (implicit)
- Git
- Docker
- iOS - Native iOS app
- Android - Native Android app
- Web - Progressive Web App
- Backend - Node.js server
Built with β€οΈ for citizen safety and public service