# ThrillWiki REST API Guide

## Phase 2B: REST API Development - Complete

This guide provides comprehensive documentation for the ThrillWiki REST API v1.

## Overview

The ThrillWiki API provides programmatic access to amusement park, ride, and company data. It uses django-ninja for fast, modern REST API implementation with automatic OpenAPI documentation.

## Base URL

- **Local Development**: `http://localhost:8000/api/v1/`
- **Production**: `https://your-domain.com/api/v1/`

## Documentation

- **Interactive API Docs**: `/api/v1/docs`
- **OpenAPI Schema**: `/api/v1/openapi.json`

## Features

### Implemented in Phase 2B

✅ **Full CRUD Operations** for all entities
✅ **Filtering & Search** on all list endpoints
✅ **Pagination** (50 items per page)
✅ **Geographic Search** for parks (dual-mode: SQLite + PostGIS)
✅ **Automatic OpenAPI/Swagger Documentation**
✅ **Pydantic Schema Validation**
✅ **Related Data** (automatic joins and annotations)
✅ **Error Handling** with detailed error responses

### Coming in Phase 2C

- JWT Token Authentication
- Role-based Permissions
- Rate Limiting
- Caching
- Webhooks

## Authentication

**Current Status**: Authentication placeholders are in place, but not yet enforced.

- **Read Operations (GET)**: Public access
- **Write Operations (POST, PUT, PATCH, DELETE)**: Will require authentication (JWT tokens)

## Endpoints

### System Endpoints

#### Health Check
```
GET /api/v1/health
```
Returns API health status.

#### API Information
```
GET /api/v1/info
```
Returns API metadata and statistics.

---

### Companies

Companies represent manufacturers, operators, designers, and other entities in the amusement industry.

#### List Companies
```
GET /api/v1/companies/
```

**Query Parameters:**
- `page` (int): Page number
- `search` (string): Search by name or description
- `company_type` (string): Filter by type (manufacturer, operator, designer, supplier, contractor)
- `location_id` (UUID): Filter by headquarters location
- `ordering` (string): Sort field (prefix with `-` for descending)

**Example:**
```bash
curl "http://localhost:8000/api/v1/companies/?search=B%26M&ordering=-park_count"
```

#### Get Company
```
GET /api/v1/companies/{company_id}
```

#### Create Company
```
POST /api/v1/companies/
```

**Request Body:**
```json
{
  "name": "Bolliger & Mabillard",
  "description": "Swiss roller coaster manufacturer",
  "company_types": ["manufacturer"],
  "founded_date": "1988-01-01",
  "website": "https://www.bolliger-mabillard.com"
}
```

#### Update Company
```
PUT /api/v1/companies/{company_id}
PATCH /api/v1/companies/{company_id}
```

#### Delete Company
```
DELETE /api/v1/companies/{company_id}
```

#### Get Company Parks
```
GET /api/v1/companies/{company_id}/parks
```
Returns all parks operated by the company.

#### Get Company Rides
```
GET /api/v1/companies/{company_id}/rides
```
Returns all rides manufactured by the company.

---

### Ride Models

Ride models represent specific ride types from manufacturers.

#### List Ride Models
```
GET /api/v1/ride-models/
```

**Query Parameters:**
- `page` (int): Page number
- `search` (string): Search by model name
- `manufacturer_id` (UUID): Filter by manufacturer
- `model_type` (string): Filter by model type
- `ordering` (string): Sort field

**Example:**
```bash
curl "http://localhost:8000/api/v1/ride-models/?manufacturer_id=<uuid>&model_type=coaster_model"
```

#### Get Ride Model
```
GET /api/v1/ride-models/{model_id}
```

#### Create Ride Model
```
POST /api/v1/ride-models/
```

**Request Body:**
```json
{
  "name": "Wing Coaster",
  "manufacturer_id": "uuid-here",
  "model_type": "coaster_model",
  "description": "Winged seating roller coaster",
  "typical_height": 164.0,
  "typical_speed": 55.0
}
```

#### Update Ride Model
```
PUT /api/v1/ride-models/{model_id}
PATCH /api/v1/ride-models/{model_id}
```

#### Delete Ride Model
```
DELETE /api/v1/ride-models/{model_id}
```

#### Get Model Installations
```
GET /api/v1/ride-models/{model_id}/installations
```
Returns all rides using this model.

---

### Parks

Parks represent theme parks, amusement parks, water parks, and FECs.

#### List Parks
```
GET /api/v1/parks/
```

**Query Parameters:**
- `page` (int): Page number
- `search` (string): Search by park name
- `park_type` (string): Filter by type (theme_park, amusement_park, water_park, family_entertainment_center, traveling_park, zoo, aquarium)
- `status` (string): Filter by status (operating, closed, sbno, under_construction, planned)
- `operator_id` (UUID): Filter by operator
- `ordering` (string): Sort field

**Example:**
```bash
curl "http://localhost:8000/api/v1/parks/?status=operating&park_type=theme_park"
```

#### Get Park
```
GET /api/v1/parks/{park_id}
```

#### Find Nearby Parks (Geographic Search)
```
GET /api/v1/parks/nearby/
```

**Query Parameters:**
- `latitude` (float, required): Center point latitude
- `longitude` (float, required): Center point longitude
- `radius` (float): Search radius in kilometers (default: 50)
- `limit` (int): Maximum results (default: 50)

**Geographic Modes:**
- **PostGIS (Production)**: Accurate distance-based search using `location_point`
- **SQLite (Local Dev)**: Bounding box approximation using `latitude`/`longitude`

**Example:**
```bash
curl "http://localhost:8000/api/v1/parks/nearby/?latitude=28.385233&longitude=-81.563874&radius=100"
```

#### Create Park
```
POST /api/v1/parks/
```

**Request Body:**
```json
{
  "name": "Six Flags Magic Mountain",
  "park_type": "theme_park",
  "status": "operating",
  "latitude": 34.4239,
  "longitude": -118.5971,
  "opening_date": "1971-05-29",
  "website": "https://www.sixflags.com/magicmountain"
}
```

#### Update Park
```
PUT /api/v1/parks/{park_id}
PATCH /api/v1/parks/{park_id}
```

#### Delete Park
```
DELETE /api/v1/parks/{park_id}
```

#### Get Park Rides
```
GET /api/v1/parks/{park_id}/rides
```
Returns all rides at the park.

---

### Rides

Rides represent individual rides and roller coasters.

#### List Rides
```
GET /api/v1/rides/
```

**Query Parameters:**
- `page` (int): Page number
- `search` (string): Search by ride name
- `park_id` (UUID): Filter by park
- `ride_category` (string): Filter by category (roller_coaster, flat_ride, water_ride, dark_ride, transport_ride, other)
- `status` (string): Filter by status
- `is_coaster` (bool): Filter for roller coasters only
- `manufacturer_id` (UUID): Filter by manufacturer
- `ordering` (string): Sort field

**Example:**
```bash
curl "http://localhost:8000/api/v1/rides/?is_coaster=true&status=operating"
```

#### List Roller Coasters Only
```
GET /api/v1/rides/coasters/
```

**Additional Query Parameters:**
- `min_height` (float): Minimum height in feet
- `min_speed` (float): Minimum speed in mph

**Example:**
```bash
curl "http://localhost:8000/api/v1/rides/coasters/?min_height=200&min_speed=70"
```

#### Get Ride
```
GET /api/v1/rides/{ride_id}
```

#### Create Ride
```
POST /api/v1/rides/
```

**Request Body:**
```json
{
  "name": "Steel Vengeance",
  "park_id": "uuid-here",
  "ride_category": "roller_coaster",
  "is_coaster": true,
  "status": "operating",
  "manufacturer_id": "uuid-here",
  "height": 205.0,
  "speed": 74.0,
  "length": 5740.0,
  "inversions": 4,
  "opening_date": "2018-05-05"
}
```

#### Update Ride
```
PUT /api/v1/rides/{ride_id}
PATCH /api/v1/rides/{ride_id}
```

#### Delete Ride
```
DELETE /api/v1/rides/{ride_id}
```

---

## Response Formats

### Success Responses

#### Single Entity
```json
{
  "id": "uuid",
  "name": "Entity Name",
  "created": "2025-01-01T00:00:00Z",
  "modified": "2025-01-01T00:00:00Z",
  ...
}
```

#### Paginated List
```json
{
  "items": [...],
  "count": 100,
  "next": "http://api/endpoint/?page=2",
  "previous": null
}
```

### Error Responses

#### 400 Bad Request
```json
{
  "detail": "Invalid input",
  "errors": [
    {
      "field": "name",
      "message": "This field is required"
    }
  ]
}
```

#### 404 Not Found
```json
{
  "detail": "Entity not found"
}
```

#### 500 Internal Server Error
```json
{
  "detail": "Internal server error",
  "code": "server_error"
}
```

---

## Data Types

### UUID
All entity IDs use UUID format:
```
"550e8400-e29b-41d4-a716-446655440000"
```

### Dates
ISO 8601 format (YYYY-MM-DD):
```
"2025-01-01"
```

### Timestamps
ISO 8601 format with timezone:
```
"2025-01-01T12:00:00Z"
```

### Coordinates
Latitude/Longitude as decimal degrees:
```json
{
  "latitude": 28.385233,
  "longitude": -81.563874
}
```

---

## Testing the API

### Using curl

```bash
# Get API info
curl http://localhost:8000/api/v1/info

# List companies
curl http://localhost:8000/api/v1/companies/

# Search parks
curl "http://localhost:8000/api/v1/parks/?search=Six+Flags"

# Find nearby parks
curl "http://localhost:8000/api/v1/parks/nearby/?latitude=28.385&longitude=-81.563&radius=50"
```

### Using the Interactive Docs

1. Start the development server:
   ```bash
   cd django
   python manage.py runserver
   ```

2. Open your browser to:
   ```
   http://localhost:8000/api/v1/docs
   ```

3. Explore and test all endpoints interactively!

---

## Geographic Features

### SQLite Mode (Local Development)

Uses simple latitude/longitude fields with bounding box approximation:
- Stores coordinates as `DecimalField`
- Geographic search uses bounding box calculation
- Less accurate but works without PostGIS

### PostGIS Mode (Production)

Uses advanced geographic features:
- Stores coordinates as `PointField` (geography type)
- Accurate distance-based queries
- Supports spatial indexing
- Full GIS capabilities

### Switching Between Modes

The API automatically detects the database backend and uses the appropriate method. No code changes needed!

---

## Next Steps

### Phase 2C: Admin Interface Enhancements
- Enhanced Django admin for all entities
- Bulk operations
- Advanced filtering
- Custom actions

### Phase 3: Frontend Integration
- React/Next.js frontend
- Real-time updates
- Interactive maps
- Rich search interface

### Phase 4: Advanced Features
- JWT authentication
- API rate limiting
- Caching strategies
- Webhooks
- WebSocket support

---

## Support

For issues or questions about the API:
1. Check the interactive documentation at `/api/v1/docs`
2. Review this guide
3. Check the POSTGIS_SETUP.md for geographic features
4. Refer to the main README.md for project setup

## Version History

- **v1.0.0** (Phase 2B): Initial REST API implementation
  - Full CRUD for all entities
  - Filtering and search
  - Geographic queries
  - Pagination
  - OpenAPI documentation
