AI-Powered Emergency Response Management Platform
A sophisticated platform for rapid disaster response that connects citizens, emergency agencies, and coordinators in a unified ecosystem. Features AI-driven incident verification, deepfake detection, intelligent resource allocation, and real-time coordination.
CodeAthon_Github.1.mp4
Demo shows: Incident reporting β AI verification β Dispatch β Real-time dashboards β Resolution
- Multi-Modal Incident Reporting - Voice (SOS) and image/text reporting
- AI-Powered Verification - Vision analysis, voice sentiment detection, and semantic alignment
- Deepfake Detection - EXIF analysis and AI generation detection with 95%+ accuracy
- Smart Trust Scoring - Synthesized 0-100 credibility score from multiple data sources
- Location-Based Consensus Scoring - β Increases score when more incidents detected nearby
- Intelligent Priority Coding - Auto-assign OMEGA to X-RAY priority codes based on verification
- Real-Time Resource Tracking - GPS-tracked resources with proximity matching and allocation
- Multi-Role Dashboards - Customized interfaces for citizens, agencies, and coordinators
- Crisis News Feed - AI-summarized, categorized news aggregation with sentiment analysis
- Interactive Heatmaps - Geographic incident density visualization with clustering
- Request Management - Formal resource request system with approval workflow
Frontend:
- React 19 + Vite
- Redux Toolkit, Tailwind CSS
- Leaflet + React-Leaflet (maps), Recharts (analytics)
- Firebase (auth), Axios (HTTP)
Backend:
- Node.js + Express.js
- MongoDB + Mongoose (with Geospatial Indexing)
- Google Generative AI (Gemini)
- Ollama Gemma3:4B (deepfake detection)
- Tesseract.js (OCR), Sharp (image processing)
APIs & Services:
- Cloudinary (media storage)
- Twilio (SMS notifications)
- Tavily (news aggregation)
- exif-parser, JWT, Bcrypt
β For Complete Project Documentation: See DETAILED_README.md
The detailed readme includes:
- β Complete system architecture & data flows
- β All 4 phases of incident processing pipeline
- β Forensics analysis & deepfake detection explained
- β AI analysis (Vision, Voice, Semantics)
- β Trust scoring formulas (A, B, C)
- β Priority coding system (OMEGA β X-RAY)
- β Resource management & allocation
- β Database schema with examples
- β Complete API documentation with requests/responses
- β Environment variables reference
- β Deployment guides
For detailed setup, configuration, and API documentation, see DETAILED_README.md
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β CITIZEN AGENCY COORDINATOR β
β (Reports) (Responds) (Allocates) β
β β β β β
βββββββΌβββββββββββββββββββββββΌββββββββββββββββββββββββΌβββββββββββ
β β β
v v v
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β React Frontend (Port 5173) β
β ββ Login/Auth β
β ββ SOS Trigger (Voice/Image) β
β ββ Real-time Map View β
β ββ Dashboard & Analytics β
β ββ Resource Requests β
ββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β HTTP/WebSocket
βββββββββββββββββββvββββββββββββββββββββββββββββββββββββββββ
β Node.js + Express Backend (Port 5000) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β 4-PHASE PROCESSING PIPELINE β β
β ββ Phase 1: Forensics (Deepfake Detection) β β
β ββ Phase 2: Vision/Voice Analysis (Parallel/Either-Or) β β
β ββ5-PHASE PROCESSING PIPELINE β β
β ββ Phase 1: Forensics (Deepfake Detection) β β
β ββ Phase 2: Vision/Voice Analysis β β
β ββ Phase 3: Semantic Alignment β β
β ββ Phase 4: Trust Scoring + Location Consensus β β
β ββ Phase 5: Priority Code Assignment
β β β
v v v
MongoDB Cloudinary External APIs
(Database) (Media CDN) (Google, Tavily, etc)
Detects AI-generated and deepfake images with 95%+ accuracy
Input: Image/Voice data
Analysis:
- EXIF Metadata Check: Scans for AI tool signatures (Midjourney, Stable Diffusion, DALL-E, Gemini, etc.)
- Pixel-Level Authentication: Analyzes noise patterns, compression artifacts
- Pocket Detection: Identifies if device was in pocket during recording
- Watermark Analysis: Detects stock photo/AI generation indicators
Output:
{
"isFake": false,
"confidenceScore": 92,
"realismFactor": 0.95,
"isPocket": false,
"verdict": "Authentic - Real device, valid metadata"
}Special Cases:
- β AI-generated images flagged but NOT automatically rejected
- β PNG files get harder scrutiny (max trust score capped at 30)
- β Pocket mode reduces visual scoring
Path A: Image Analysis (if image provided)
- Uses Google Gemini Vision API
- Detects: Fire, Smoke, Blood, Debris, People, Floods, etc.
- Returns:
detected_objects[],confidence,scene_description - Severity mapping: Critical β High β Medium β Low
Path B: Voice Analysis (if audio provided)
- Speech-to-Text conversion
- Keyword extraction (e.g., "Trapped", "Dying", "Fire", "Bleeding")
- Sentiment analysis: Panic (100%) β Neutral (50%) β Calm (30%)
- Urgency scoring: 1-10 scale
- Emotional state detection
Combined Processing:
- Both run in parallel if both inputs available
- Either/or if single input
- Output synchronized before Phase 3
Purpose: Cross-validates vision and voice data
Alignment Score (0-100):
- Perfect match: Vision=Fire + Voice="Fire" β 95%+ alignment β
- Good match: Vision=Smoke + Voice="Fire" β 75-85% alignment
- Partial match: Vision=Debris + Voice="Help" β 50-60% alignment
β οΈ - Mismatch: Vision=Car + Voice="Fire" β Below 50% alignment β (Fails cross-validation)
Impact:
- High alignment boosts final trust score (20% weight)
- Low alignment triggers manual review flag
- Severe mismatch can reduce score by 15-25 points
This is the key feature that increases score when more incidents are reported nearby:
// Algorithm: Geospatial Query within 1km radius, 15-minute window
const calculateLocationConsensus = async (latitude, longitude) => {
const radiusMeters = 1000; // 1km radius
const timeWindow = "15 minutes"; // Recent incidents
const nearbyIncidents = await Incident.find({
location: {
$geoWithin: {
$centerSphere: [[longitude, latitude], radiusInRadians],
},
},
createdAt: { $gte: fifteenMinutesAgo },
status: { $in: ["Pending", "Active"] },
}).count();
// Scoring based on cluster density
if (nearbyIncidents >= 3) return 100; // Strong consensus
if (nearbyIncidents >= 2) return 75; // Good consensus
if (nearbyIncidents >= 1) return 50; // Weak consensus
return 0; // Isolated incident
};How It Works:
- When incident is reported at coordinates (lat, lon)
- System searches for other incidents within 1km radius and 15 minutes
- Counts incidents with status "Pending" or "Active"
- Assigns consensus score:
- 3+ incidents β Score: 100 (Mass event confirmed)
- 2 incidents β Score: 75 (Multiple reports)
- 1 incident β Score: 50 (One other report)
- 0 incidents β Score: 0 (Isolated report)
Impact on Trust Score:
- Formula A (Image): 30% weight β +9-30 points possible
- Formula B (Voice): 30% weight β +10-30 points possible
- Formula C (Hybrid): 20-30% weight β +6-30 points possible
Real-World Example:
Area: Downtown District
Time: 14:32
Incident 1: Image report "Fire in building A"
β Location: [40.7128, -74.0060]
β Nearby incidents: 0
β Location Consensus Score: 0
β Base Score: 60 β Final: 60
Incident 2: Voice report "Fire! Help!" (14:33)
β Location: [40.7129, -74.0061] (50m away)
β Nearby incidents: 1 (Incident 1)
β Location Consensus Score: 50
β Base Score: 70 β Final: 84 β
(Boosted due to area consensus)
Incident 3: Image report "Fire spreading" (14:34)
β Location: [40.7130, -74.0062] (150m away)
β Nearby incidents: 2 (Incident 1, 2)
β Location Consensus Score: 75
β Base Score: 75 β Final: 95 β
β
(Strong confirmation)
Incident 4: Voice report "Fire at central station" (14:35)
β Location: [40.7131, -74.0063] (250m away)
β Nearby incidents: 3 (Incident 1, 2, 3)
β Location Consensus Score: 100
β Base Score: 80 β Final: 98 β
β
β
(Mass event confirmed)
Used when image is primary input
Trust Score = (Visual Score Γ 0.5 + Alignment Score Γ 0.2 + Location Consensus Γ 0.3)
Γ Realism Factor
Γ Format Factor (PNG: 0-30 cap, others: normal)
Components:
ββ Visual Score (0-90):
β ββ Fire/Collapse detected: 90
β ββ Blood/Flood detected: 80
β ββ General emergency: 70
ββ Alignment Score (0-100):
β ββ Vision vs Voice keyword matching
ββ Location Consensus (0-100): β NEW
β ββ Number of nearby incidents (1km, 15min)
ββ Realism Factor (0-1.0):
ββ Deepfake penalty if isFake
Final Score: 0-100
Examples:
-
Fire image, high alignment, 2 nearby incidents
- (90 Γ 0.5) + (85 Γ 0.2) + (75 Γ 0.3) = 45 + 17 + 22.5 = 84.5
-
Low-confidence image, poor alignment, isolated
- (45 Γ 0.5) + (30 Γ 0.2) + (0 Γ 0.3) = 22.5 + 6 + 0 = 28.5
Used when voice is primary input
Trust Score = (Keyword Score Γ 0.5 + Sentiment Score Γ 0.2 + Location Consensus Γ 0.3)
Components:
ββ Keyword Score (0-100):
β ββ "Dying/Trapped": 95
β ββ "Fire/Burning": 90
β ββ "Blood/Injury": 85
β ββ "Help/Emergency": 75
ββ Sentiment Score (0-100):
β ββ Panic: 85
β ββ Neutral: 50
β ββ Calm: 30
ββ Location Consensus (0-100): β NEW
ββ Number of nearby incidents
Final Score: 0-100
Examples:
-
Voice saying "Fire! Trapped! Help!", panic sentiment, 3 nearby incidents
- (95 Γ 0.5) + (85 Γ 0.2) + (100 Γ 0.3) = 47.5 + 17 + 30 = 94.5
-
Voice saying "Hello?", calm sentiment, isolated
- (30 Γ 0.5) + (30 Γ 0.2) + (0 Γ 0.3) = 15 + 6 + 0 = 21
Used when both voice and image/pocket data available
Trust Score (Normal Phone):
= (Visual Γ 0.4) + (Audio Γ 0.4) + (Location Consensus Γ 0.2)
Trust Score (Pocket Mode):
= (Visual Γ 0.1) + (Audio Γ 0.6) + (Location Consensus Γ 0.3)
Audio Score calculated using Formula B internally
Pocket Mode: Lower camera importance, higher voice importance
Assigns emergency response level (OMEGA to X-RAY)
- Trigger: 10+ incidents in 1km radius within 1 minute
- Response Level: 5 (Highest)
- Auto-Dispatch: YES
- Dispatch 50+ resources, activate emergency operation center
- Trigger: Trust Score β₯ 75 + (Trapped/Dying/Unconscious keywords OR Structural Collapse)
- Response Level: 5
- Auto-Dispatch: YES
- Dispatch ambulances, fire trucks, rescue teams
- Trigger: Trust Score β₯ 60 AND (Fire/Flood/Multiple Injuries/Accident detected)
- Response Level: 4
- Auto-Dispatch: YES
- Dispatch multiple resource types
- Trigger: Trust Score β₯ 45 AND (Emergency objects detected OR Location consensus β₯ 50)
- Response Level: 3
- Auto-Dispatch: NO
- Manual review before dispatch
- Trigger: Trust Score < 45 OR Low confidence
- Response Level: 2
- Auto-Dispatch: NO
- Requires operator review
- Trigger: AI-generated image detected OR Multiple false reports
- Response Level: 0
- Auto-Dispatch: NO
- Flagged for moderation
1. CITIZEN INITIATES
ββ Presses SOS button
ββ Records voice or selects image
2. DATA UPLOADED
ββ Audio/Image β Cloudinary CDN
ββ Location + Metadata captured
3. AI VERIFICATION (4 phases)
ββ Deepfake detection: 95%+ accuracy
ββ Vision/Voice analysis: Detects objects & extracts keywords
ββ Semantic alignment: Cross-validates
ββ Trust scoring: Final 0-100 score
4. AUTO-DISPATCH (if trust > 50)
ββ Finds nearest resources (geo-spatial query)
ββ Reserves ambulances/fire trucks
ββ Sends SMS alerts to agencies
ββ Updates real-time dashboard
ββ Tracks response times
5. AGENCY RESPONSE
ββ Agencies see incident on dashboard
ββ Dispatch teams to location
ββ Update status in real-time
ββ Upload response photos/notes
6. COORDINATOR OVERSIGHT
ββ Allocates resources between agencies
ββ Approves/rejects resource requests
ββ Views region-wide analytics
ββ Manages system-wide alerts
7. RESOLUTION
ββ Incident marked "Resolved"
ββ Analytics calculated
ββ Audit trail saved
ββ Performance metrics updated
- Voice SOS: Click button β Record voice β Auto-dispatch within 60s
- Image + Text: Take photo β Describe β Deepfake analysis
- Supported Languages: English, Bengali, Hindi, Gujarati, Italian, Russian, Arabic, Chinese, Marathi
- Deepfake detection via Ollama (local inference)
- EXIF metadata analysis
- Pixel-level authentication check
- GPS-tracked resources on map
- Proximity-based matching
- Status updates (Available β Deployed β Available)
- Geospatial indexing for <100ms queries
- Citizen: Report incidents, view nearby events, contact agencies
- Agency: Manage team, track resources, update status
- Coordinator: System overview, resource allocation, analytics
- Real-time news fetch via Tavily API
- AI summarization with Gemini
- Sentiment analysis & categorization
- Updated every 30 minutes
14:32:15 - Citizen 1 Reports
Input: Image of fire in building + voice "FIRE! HELP!"
Forensics: Real image, valid EXIF
Vision: Fire (95%), Smoke (90%)
Voice: Keywords ["FIRE", "HELP"], Sentiment: Panic
Location: [40.7128, -74.0060]
Location Consensus: 0 (first report)
Phase 4 Scoring:
Formula C (Hybrid):
Visual: 90
Audio: 95
Location: 0
Result: (90Γ0.4) + (95Γ0.4) + (0Γ0.2) = 74
Phase 5 Priority: BRAVO (Trust 74 + Emergency objects detected)
Action: β³ Waiting for manual review
14:33:20 - Citizen 2 Reports β (68 seconds later)
Input: Voice report only "FIRE! TRAPPED!"
Forensics: N/A (voice only)
Voice: Keywords ["FIRE", "TRAPPED"], Sentiment: Panic, Urgency: 9/10
Location: [40.7129, -74.0061] (50m from Citizen 1)
Location Consensus: 50 (1 other incident detected) β
Phase 4 Scoring:
Formula B (Voice):
Keywords: 95
Sentiment: 85
Location Consensus: 50 β BOOSTED by area consensus
Result: (95Γ0.5) + (85Γ0.2) + (50Γ0.3) = 80.5
Phase 5 Priority: DELTA (Trust 80.5 β₯ 75 + "TRAPPED" keyword)
Action: π¨ AUTO-DISPATCH TRIGGERED
β 2 Ambulances (2km away)
β 3 Fire Trucks (1.5km away)
β Rescue Team (3km away)
β SMS alerts to agencies
14:34:10 - Citizen 3 Reports β (50 seconds later)
Input: Image of fire spreading
Location: [40.7130, -74.0062] (100m from center)
Location Consensus: 75 (2 other incidents detected) ββ
Phase 4 Scoring:
Formula A (Image):
Visual: 95
Alignment: 85
Location Consensus: 75 β STRONGLY BOOSTED
Result: (95Γ0.5 + 85Γ0.2 + 75Γ0.3) = 80.5
Phase 5 Priority: DELTA
Action: π¨ COORDINATES RESOURCES, Updates status to "ACTIVE"
14:35:05 - Citizen 4 Reports β (55 seconds later)
Input: Image + voice report
Location: [40.7131, -74.0063] (150m away)
Location Consensus: 100 (3 other incidents! Mass event!) βββ
Phase 4 Scoring: 88.2
Phase 5 Priority: CRITICAL CASE
β Coordinator receives: "MASS FIRE EVENT NEAR DOWNTOWN CENTER"
β Escalates to EMERGENCY OPERATIONS CENTER
β Deploys: 10+ additional resources
β Notifies: Public alerts, evacuation orders
{
// Basic Info
type: "Fire" | "Flood" | "Medical" | "Accident" | etc,
severity: "Low" | "Medium" | "High" | "Critical",
mode: "VOICE" | "IMAGE_TEXT" | "SHAKE_HYBRID",
description: String,
// Location (Geospatial Indexing for fast queries)
location: {
type: "Point",
coordinates: [longitude, latitude] // GeoJSON format
},
// Phase 1: Forensics
forensics: {
isFake: Boolean,
confidenceScore: Number (0-100),
realismFactor: Number (0-1),
isPocket: Boolean,
deepfakeIndicators: [String],
analysis: { camera, aiDetected, pixelAnalysis, exifData }
},
// Phase 2-3: AI Analysis & Semantics
aiAnalysis: {
vision: {
detected: ["Fire", "Smoke", "People"],
confidence: Number,
severity: String
},
voice: {
keywords: ["Help", "Trapped", "Fire"],
sentiment: "panic" | "calm" | "neutral",
urgency: Number (1-10)
},
semantics: {
alignmentScore: Number (0-100),
description: String
}
},
// Phase 4: Trust Scoring β WITH LOCATION CONSENSUS
trustScore: {
totalScore: Number (0-100),
formula: "FORMULA_A" | "FORMULA_B" | "FORMULA_C",
breakdown: {
visual: Number,
audio: Number,
alignment: Number,
consensus: Number β Location consensus component
},
locationConsensus: {
nearbyIncidents: Number, β Count of incidents nearby
score: Number (0-100),
radius: 1000, // meters
timeWindow: "15 minutes"
}
},
// Phase 5: Priority Coding
priorityCode: {
code: "OMEGA" | "DELTA" | "CHARLIE" | "BRAVO" | "ALPHA" | "X-RAY",
description: String,
dispatchLevel: Number (0-5),
autoDispatch: Boolean
},
// Status & Tracking
status: "Pending" | "Active" | "Resolved" | "Spam",
reportedBy: ObjectId (User reference),
respondedBy: ObjectId (User reference),
dispatchedResources: [ObjectId], // Resource references
// Audit Log
verificationLog: [{
phase: String,
timestamp: Date,
result: Object
}],
createdAt: Date,
updatedAt: Date
}// 2dsphere index for geospatial queries (fastest)
db.incidents.createIndex({ location: "2dsphere" });
// Time-based queries (for 15-minute window)
db.incidents.createIndex({ createdAt: -1 });
// Trust score sorting/filtering
db.incidents.createIndex({ trustScore: -1 });
// Priority code filtering
db.incidents.createIndex({ "priorityCode.code": 1 });
// User-based queries
db.incidents.createIndex({ reportedBy: 1 });POST /api/incidents/create
Request:
{
"type": "Fire",
"description": "Apartment fire",
"latitude": 40.7128,
"longitude": -74.0060,
"audioFile": <File>, // OR
"imageFile": <File>, // OR
"text": "Fire in building"
}
Response:
{
"id": "incident_123",
"trustScore": 85.5,
"priorityCode": "DELTA",
"locationConsensus": {
"nearbyIncidents": 2,
"score": 75
},
"dispatchedResources": [
{ "type": "Ambulance", "eta": "3 mins" },
{ "type": "Fire Truck", "eta": "2 mins" }
]
}GET /api/incidents/nearby?latitude=40.7128&longitude=-74.0060&radius=1000
Response:
{
"incidents": [
{
"id": "incident_123",
"type": "Fire",
"trustScore": 85.5,
"distance": 150 // meters
},
...
],
"count": 3,
"locationConsensusScore": 75
}GET /api/incidents/analytics?region=downtown&timeframe=24h
Response:
{
"totalIncidents": 45,
"byType": {
"Fire": 8,
"Medical": 25,
"Accident": 12
},
"avgTrustScore": 72.3,
"dispatchedCount": 38,
"avgResponseTime": "4.2 mins",
"hotspots": [
{
"location": [40.7128, -74.0060],
"incidents": 12,
"severity": "High"
}
]
}- JWT Authentication: Token-based API access
- Bcrypt Hashing: Passwords hashed with salt rounds
- EXIF Stripping: Sensitive metadata removed from media
- XSS Protection: Input sanitization and output encoding
- Rate Limiting: Throttle requests to prevent abuse
- AI Detection: Catch and flag AI-generated false reports
- Location Privacy: Coordinates stored separately from user identity
English, Bengali, Hindi, Gujarati, Italian, Russian, Arabic, Chinese (Simplified & Traditional), Marathi
- Geospatial Query: <100ms (with 2dsphere index)
- AI Vision Analysis: ~2-3 seconds (Google Gemini)
- Voice Analysis: ~1-2 seconds (Speech-to-Text + keywords)
- Deepfake Detection: ~1-2 seconds (EXIF + pixel analysis)
- Trust Score Calculation: <500ms (including location consensus query)
- End-to-End Processing: 4-8 seconds typical
- Auto-Dispatch Time: <10 seconds from report to resources notified
# MongoDB
MONGO_URI=mongodb+srv://user:password@cluster.mongodb.net/crisisconnect
# APIs
GOOGLE_API_KEY=your_google_api_key
GEMINI_API_KEY=your_gemini_api_key
TAVILY_API_KEY=your_tavily_api_key
# Cloudinary
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
# Twilio
TWILIO_SID=your_twilio_sid
TWILIO_AUTH_TOKEN=your_auth_token
TWILIO_PHONE=+1234567890
# JWT
JWT_SECRET=your_jwt_secret
JWT_EXPIRE=7d
# Ports
PORT=5000
FRONTEND_PORT=5173
# Ollama (Local Deepfake Detection)
OLLAMA_BASE_URL=http://localhost:11434Input: Latitude, Longitude Output: Consensus Score (0-100), Nearby Incident Count
1. Define search parameters:
- Radius: 1000 meters (1 km)
- Time Window: 15 minutes
- Status Filter: "Pending" or "Active"
2. Query MongoDB with geospatial $geoWithin $centerSphere:
db.incidents.find({
location: { $geoWithin: { $centerSphere: [[lon, lat], radiusInRadians] } },
createdAt: { $gte: Date.now() - 15*60*1000 },
status: { $in: ["Pending", "Active"] }
})
3. Count results:
- if count >= 3: score = 100
- if count == 2: score = 75
- if count == 1: score = 50
- if count == 0: score = 0
4. Return { nearbyIncidents, score, radius, timeWindow }
Formula A (Image-Primary):
PreScore = (Visual Γ 0.5) + (Alignment Γ 0.2) + (LocationConsensus Γ 0.3)
FinalScore = min(100, PreScore Γ RealismFactor)
Formula B (Voice-Primary):
FinalScore = min(100, (Keyword Γ 0.5) + (Sentiment Γ 0.2) + (LocationConsensus Γ 0.3))
Formula C (Hybrid/Shake):
- Normal: (Visual Γ 0.4) + (Audio Γ 0.4) + (LocationConsensus Γ 0.2)
- Pocket: (Visual Γ 0.1) + (Audio Γ 0.6) + (LocationConsensus Γ 0.3)
cd backend
npm install
# Create .env file
cp .env.example .env
# Fill in your API keys
# Start MongoDB
mongod
# Create geospatial index
node fix_resources.js
# Run backend
npm startcd frontend
npm install
# Create .env file
VITE_API_URL=http://localhost:5000
VITE_FIREBASE_CONFIG=your_firebase_config
npm run dev# Terminal 1: Start backend
cd backend && npm start
# Terminal 2: Test incidents at same location
curl -X POST http://localhost:5000/api/incidents/create \
-F "type=Fire" \
-F "latitude=40.7128" \
-F "longitude=-74.0060" \
-F "description=Test incident 1" \
# Expected: locationConsensus.score = 0 (first incident)
# Wait 10 seconds, then:
curl -X POST http://localhost:5000/api/incidents/create \
-F "type=Fire" \
-F "latitude=40.71281" \
-F "longitude=-74.00601" \
-F "description=Test incident 2" \
# Expected: locationConsensus.score = 50 (1 nearby incident)
# Again:
curl -X POST http://localhost:5000/api/incidents/create \
-F "type=Fire" \
-F "latitude=40.71282" \
-F "longitude=-74.00602" \
-F "description=Test incident 3" \
# Expected: locationConsensus.score = 75 (2 nearby incidents)
# Again:
curl -X POST http://localhost:5000/api/incidents/create \
-F "type=Fire" \
-F "latitude=40.71283" \
-F "longitude=-74.00603" \
-F "description=Test incident 4" \
# Expected: locationConsensus.score = 100 (3+ nearby incidents) βSolution: Ensure MongoDB geospatial index exists:
db.incidents.createIndex({ location: "2dsphere" });Solution: Check incident coordinates are in [longitude, latitude] GeoJSON format:
// β
Correct
location: { type: "Point", coordinates: [-74.0060, 40.7128] }
// β Wrong
location: { type: "Point", coordinates: [40.7128, -74.0060] }Solution: Ensure these indexes exist:
db.incidents.createIndex({ location: "2dsphere" });
db.incidents.createIndex({ createdAt: -1 });
db.incidents.createIndex({ status: 1 });MIT License - See LICENSE file
Contributions welcome! Please follow code style guidelines and add tests for new features.
For issues or questions, please open a GitHub issue or contact the development team.