Backend API for Rock Spotter - A platform where rock enthusiasts can share photos of rocks, participate in rock hunts, and earn achievements.
npm install
.env file in the backend directory (copy from .env.example):
cp .env.example .env
.env file with your configuration:
PORT=3000
MONGODB_URI=mongodb://localhost:27017/rock-spotter
JWT_SECRET=your-secret-key-here
Development mode:
npm run dev
Production mode:
npm start
The server will start on http://localhost:3000 (or the port specified in your .env file).
POST /api/users/register
Content-Type: application/json
{
"username": "rockfan123",
"email": "user@example.com",
"password": "password123"
}
POST /api/users/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "password123"
}
GET /api/rocks?page=1&limit=20&rockType=igneous
GET /api/rocks/nearby?longitude=-122.4194&latitude=37.7749&maxDistance=5000
POST /api/rocks
Authorization: Bearer <token>
Content-Type: application/json
{
"title": "Beautiful Granite Rock",
"description": "Found this amazing granite specimen!",
"photo": "https://example.com/photo.jpg",
"location": {
"type": "Point",
"coordinates": [-122.4194, 37.7749],
"address": "San Francisco, CA"
},
"rockType": "igneous",
"tags": ["granite", "pink", "sparkly"],
"isPublic": true
}
POST /api/rocks/:id/like
Authorization: Bearer <token>
POST /api/rocks/:id/comment
Authorization: Bearer <token>
Content-Type: application/json
{
"text": "Amazing find!"
}
GET /api/hunts?isActive=true&difficulty=medium&page=1&limit=20
POST /api/hunts
Authorization: Bearer <token>
Content-Type: application/json
{
"title": "Downtown Rock Hunt",
"description": "Find 5 rocks hidden downtown!",
"rocks": [
{
"rock": "rock_id_1",
"hint": "Look near the fountain",
"order": 1
}
],
"difficulty": "medium",
"startDate": "2025-10-20T00:00:00Z",
"endDate": "2025-10-27T23:59:59Z",
"maxParticipants": 100
}
POST /api/hunts/:id/join
Authorization: Bearer <token>
POST /api/hunts/:huntId/rocks/:rockId/found
Authorization: Bearer <token>
GET /api/hunts/my/progress
Authorization: Bearer <token>
GET /api/achievements?type=rocks&rarity=rare
POST /api/achievements
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "First Rock",
"description": "Share your first rock photo",
"icon": "πͺ¨",
"type": "rocks",
"criteria": {
"type": "count",
"target": 1
},
"rarity": "common"
}
GET /api/users/profile/me
Authorization: Bearer <token>
PUT /api/users/profile/me
Authorization: Bearer <token>
Content-Type: application/json
{
"username": "newusername",
"bio": "Rock enthusiast since 2025",
"profilePicture": "https://example.com/avatar.jpg"
}
All endpoints return appropriate HTTP status codes:
Error responses include a JSON object with an error field:
{
"error": "Error message here"
}
MIT