ice/docs/api.md
Claude Code 5176636f6d Add comprehensive documentation in docs/ directory
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>
2025-07-05 22:03:01 -04:00

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 characters
  • latitude: Optional, valid number
  • longitude: Optional, valid number
  • description: 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"}'