docs/deployment.md: - Complete deployment guide for both automated and manual setup - Step-by-step instructions for Debian 12 ARM64 - Custom Caddy build with rate limiting plugin - Service configuration and security setup - Troubleshooting and maintenance sections - Performance tuning recommendations docs/api.md: - Comprehensive API documentation with examples - All public and admin endpoints documented - Request/response schemas and validation rules - Authentication flows and error handling - Rate limiting and security feature documentation - Client library examples (JavaScript, curl) Fixes README.md reference to non-existent docs/deployment.md. Both files provide detailed technical documentation for: - Deployment procedures and requirements - API usage and integration - Security features and limitations - Troubleshooting and maintenance 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
5.7 KiB
Great Lakes Ice Report - API Documentation
This document provides an overview of the API endpoints. For interactive documentation with examples, visit /api-docs
when the server is running.
Base URL
- Development:
http://localhost:3000
- Production:
https://your-domain.com
Authentication
Admin endpoints require Bearer token authentication:
Authorization: Bearer YOUR_TOKEN_HERE
Get a token by authenticating with the admin password at POST /api/admin/login
.
Rate Limiting
- General API: 30 requests per minute per IP
- Location Submissions: 10 requests per 15 minutes per IP
Public Endpoints
Get Configuration
GET /api/config
Returns MapBox API configuration for frontend geocoding.
Response:
{
"mapboxAccessToken": "pk.your_token_here",
"hasMapbox": true
}
Get Active Locations
GET /api/locations
Returns all active location reports (less than 48 hours old or marked persistent).
Response:
[
{
"id": 123,
"address": "Main St & Oak Ave, Grand Rapids, MI",
"latitude": 42.9634,
"longitude": -85.6681,
"description": "Black ice present, multiple vehicles stuck",
"persistent": false,
"created_at": "2025-01-15T10:30:00.000Z"
}
]
Submit Location Report
POST /api/locations
Submit a new ice condition report with automatic profanity filtering.
Request Body:
{
"address": "Main St & Oak Ave, Grand Rapids, MI",
"latitude": 42.9634,
"longitude": -85.6681,
"description": "Black ice spotted, drive carefully"
}
Validation:
address
: Required, max 500 characterslatitude
: Optional, valid numberlongitude
: Optional, valid numberdescription
: Optional, max 1000 characters
Response (Success):
{
"id": 125,
"address": "Main St & Oak Ave, Grand Rapids, MI",
"latitude": 42.9634,
"longitude": -85.6681,
"description": "Black ice spotted, drive carefully",
"persistent": false,
"created_at": "2025-01-15T12:00:00.000Z"
}
Response (Profanity Detected):
{
"error": "Submission rejected",
"message": "Your description contains inappropriate language...",
"details": {
"severity": "medium",
"wordCount": 1,
"detectedCategories": ["general"]
}
}
Admin Endpoints
All admin endpoints require authentication via Authorization: Bearer <token>
.
Admin Login
POST /api/admin/login
Authenticate with admin password to receive access token.
Request Body:
{
"password": "your_admin_password"
}
Response:
{
"token": "your_bearer_token_here",
"message": "Login successful"
}
Get All Locations
GET /api/admin/locations
Returns all location reports including expired ones.
Update Location
PUT /api/admin/locations/:id
Update location details.
Request Body:
{
"address": "Updated Address",
"latitude": 42.9634,
"longitude": -85.6681,
"description": "Updated description"
}
Toggle Persistent Status
PATCH /api/admin/locations/:id/persistent
Mark location as persistent (won't auto-expire) or remove persistent status.
Request Body:
{
"persistent": true
}
Delete Location
DELETE /api/admin/locations/:id
Permanently delete a location report.
Profanity Word Management
Get All Profanity Words
GET /api/admin/profanity-words
Add Profanity Word
POST /api/admin/profanity-words
Request Body:
{
"word": "badword",
"severity": "medium",
"category": "custom"
}
Update Profanity Word
PUT /api/admin/profanity-words/:id
Delete Profanity Word
DELETE /api/admin/profanity-words/:id
Error Responses
Rate Limiting
{
"error": "Too many location reports submitted",
"message": "You can submit up to 10 location reports every 15 minutes. Please wait before submitting more.",
"retryAfter": "15 minutes"
}
Validation Errors
{
"error": "Address must be a string with maximum 500 characters"
}
Authentication Errors
{
"error": "Access denied"
}
Not Found
{
"error": "Location not found"
}
Server Errors
{
"error": "Internal server error"
}
Interactive Documentation
For complete interactive API documentation with live testing capabilities, visit /api-docs
when running the server. This provides:
- Complete endpoint specifications
- Request/response schemas
- Interactive testing interface
- Authentication flows
- Example requests and responses
Security Features
- Rate Limiting: Prevents abuse and DoS attacks
- Input Validation: Strict length and type checking
- Profanity Filtering: Automatic content moderation
- Authentication: Secure admin access with bearer tokens
- HTTPS: SSL/TLS encryption in production
- Audit Logging: Suspicious activity detection
Client Libraries
The API follows REST conventions and can be consumed by any HTTP client. Examples:
JavaScript/Node.js
// Submit location report
const response = await fetch('/api/locations', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
address: 'Main St & Oak Ave',
description: 'Icy conditions'
})
});
curl
# Get active locations
curl https://your-domain.com/api/locations
# Submit location report
curl -X POST https://your-domain.com/api/locations \
-H "Content-Type: application/json" \
-d '{"address":"Main St & Oak Ave","description":"Icy conditions"}'
# Admin login
curl -X POST https://your-domain.com/api/admin/login \
-H "Content-Type: application/json" \
-d '{"password":"your_password"}'