# MaplePress Backend API Documentation

This directory contains comprehensive API documentation for the MaplePress backend, organized by endpoint.

## Base URL

```
http://localhost:8000
```

## Quick Links

### General
- [Health Check](health-check.md) - `GET /health`

### Authentication & User Management
- [Register User & Tenant](register.md) - `POST /api/v1/register`
- [Login](login.md) - `POST /api/v1/login`
- [Refresh Token](refresh-token.md) - `POST /api/v1/refresh`
- [Hello (Authenticated)](hello.md) - `POST /api/v1/hello`
- [Get User Profile](get-user-profile.md) - `GET /api/v1/me`

### Tenant Management
- [Create Tenant](create-tenant.md) - `POST /api/v1/tenants`
- [Get Tenant by ID](get-tenant-by-id.md) - `GET /api/v1/tenants/{id}`
- [Get Tenant by Slug](get-tenant-by-slug.md) - `GET /api/v1/tenants/slug/{slug}`

### User Management
- [Create User](create-user.md) - `POST /api/v1/users`
- [Get User by ID](get-user-by-id.md) - `GET /api/v1/users/{id}`

### Site Management
- [Create WordPress Site](create-site.md) - `POST /api/v1/sites`
- [List WordPress Sites](list-sites.md) - `GET /api/v1/sites`
- [Get WordPress Site](get-site.md) - `GET /api/v1/sites/{id}`
- [Delete WordPress Site](delete-site.md) - `DELETE /api/v1/sites/{id}`
- [Rotate Site API Key](rotate-site-api-key.md) - `POST /api/v1/sites/{id}/rotate-api-key`

### WordPress Plugin API
- [Verify API Key](plugin-verify-api-key.md) - `GET /api/v1/plugin/status`

---

## Authentication Overview

MaplePress uses a **dual authentication system**:

### 1. JWT Authentication (for Dashboard Users)

Used for user-facing dashboard endpoints (managing sites, users, tenants).

**Format**: `Authorization: JWT {access_token}`

**Endpoints**:
- All `/api/v1/sites` endpoints
- All `/api/v1/users` endpoints
- All `/api/v1/tenants` endpoints

**How to get JWT**:
1. Register: `POST /api/v1/register`
2. Login: `POST /api/v1/login`
3. Use returned `access_token` in Authorization header

### 2. API Key Authentication (for WordPress Plugins)

Used for WordPress plugin communication with the backend.

**Format**: `Authorization: Bearer {api_key}`

**Endpoints**:
- All `/api/v1/plugin/*` endpoints (status, sync, search, etc.)

**How to get API Key**:
1. Create a site via dashboard: `POST /api/v1/sites`
2. Copy the `api_key` from response (shown only once!)
3. Configure WordPress plugin with the API key

**API Key Format**: `live_sk_{40_random_characters}` or `test_sk_{40_random_characters}`

**Security**:
- API keys are hashed using SHA-256 before storage
- Never logged or displayed after initial creation
- Can be rotated if compromised using the rotate-api-key endpoint
- API key middleware validates and populates site context in requests
- Only keys with `live_sk_` or `test_sk_` prefix are accepted

---

## Test Mode vs Live Mode

MaplePress automatically generates different API key types based on your backend environment configuration.

### Test Mode (`test_sk_` keys)

**Automatically enabled when:**
- `APP_ENVIRONMENT=development` in `.env`

**Use for:**
- Local development with `localhost` URLs
- Testing and experimentation
- CI/CD pipelines

**Features:**
- Test keys work identically to live keys
- Separate from production data
- Can be used for integration testing
- Generated automatically in development environment

**Example:**
```bash
# In your .env file:
APP_ENVIRONMENT=development

# Create a site (automatically gets test_sk_ key):
curl -X POST http://localhost:8000/api/v1/sites \
  -H "Content-Type: application/json" \
  -H "Authorization: JWT $TOKEN" \
  -d '{
    "domain": "localhost:8081",
    "site_url": "http://localhost:8081"
  }'
```

Response will include: `"api_key": "test_sk_abc123..."`

### Live Mode (`live_sk_` keys)

**Automatically enabled when:**
- `APP_ENVIRONMENT=production` in `.env`

**Use for:**
- Production WordPress sites
- Public-facing websites
- Real customer data

**Features:**
- Production-grade API keys
- Should be kept secure and never committed to version control
- Used for real traffic and billing
- Generated automatically in production environment

**Example:**
```bash
# In your .env file:
APP_ENVIRONMENT=production

# Create a site (automatically gets live_sk_ key):
curl -X POST http://localhost:8000/api/v1/sites \
  -H "Content-Type: application/json" \
  -H "Authorization: JWT $TOKEN" \
  -d '{
    "domain": "example.com",
    "site_url": "https://example.com"
  }'
```

Response will include: `"api_key": "live_sk_xyz789..."`

### Environment Configuration

The API key type is **automatically determined** by the `APP_ENVIRONMENT` variable in `.env`:

```bash
# Development - Generates test_sk_ keys
APP_ENVIRONMENT=development

# Production - Generates live_sk_ keys
APP_ENVIRONMENT=production
```

**Two simple options:**
- `development` = test keys (`test_sk_*`)
- `production` = live keys (`live_sk_*`)

**No manual configuration needed!** The backend automatically generates the appropriate key type based on your environment.

---

## Testing Workflow

Here's a complete workflow to test the API from registration to creating sites:

### 1. Register a new user and tenant

```bash
# Save the response to extract tokens
# Note: timezone is optional and defaults to UTC if not provided
RESPONSE=$(curl -X POST http://localhost:8000/api/v1/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@mycompany.com",
    "password": "SecurePass123!",
    "first_name": "Admin",
    "last_name": "User",
    "name": "Admin User",
    "tenant_name": "My Company",
    "tenant_slug": "my-company",
    "agree_terms_of_service": true,
    "agree_promotions": false,
    "agree_to_tracking_across_third_party_apps_and_services": false
  }')

echo $RESPONSE | jq .

# Extract tokens (requires jq)
ACCESS_TOKEN=$(echo $RESPONSE | jq -r '.access_token')
TENANT_ID=$(echo $RESPONSE | jq -r '.tenant_id')
```

### 2. Login with existing credentials

```bash
# Login to get fresh tokens
LOGIN_RESPONSE=$(curl -X POST http://localhost:8000/api/v1/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@mycompany.com",
    "password": "SecurePass123!",
    "tenant_id": "'$TENANT_ID'"
  }')

echo $LOGIN_RESPONSE | jq .

# Extract new access token
ACCESS_TOKEN=$(echo $LOGIN_RESPONSE | jq -r '.access_token')
```

### 3. Get tenant information

```bash
# By ID
curl -X GET http://localhost:8000/api/v1/tenants/$TENANT_ID \
  -H "Authorization: JWT $ACCESS_TOKEN" | jq .

# By slug
curl -X GET http://localhost:8000/api/v1/tenants/slug/my-company \
  -H "Authorization: JWT $ACCESS_TOKEN" | jq .
```

### 4. Create a new WordPress site

```bash
SITE_RESPONSE=$(curl -X POST http://localhost:8000/api/v1/sites \
  -H "Content-Type: application/json" \
  -H "Authorization: JWT $ACCESS_TOKEN" \
  -d '{
    "domain": "example.com",
    "site_url": "https://example.com"
  }')

echo $SITE_RESPONSE | jq .

# Extract site ID and API key
SITE_ID=$(echo $SITE_RESPONSE | jq -r '.id')
API_KEY=$(echo $SITE_RESPONSE | jq -r '.api_key')
```

### 5. Verify API key (as WordPress plugin)

```bash
curl -X GET http://localhost:8000/api/v1/plugin/status \
  -H "Authorization: Bearer $API_KEY" | jq .
```

---

## Multi-Tenancy

This API implements multi-tenancy where:
- Each tenant is isolated from other tenants
- Users belong to specific tenants
- The `X-Tenant-ID` header is required for tenant-scoped operations (in development mode)
- In production, the tenant context will be extracted from the JWT token

---

## Error Handling

MaplePress uses **RFC 9457 (Problem Details for HTTP APIs)** for standardized, machine-readable error responses.

**Standard**: [RFC 9457 - Problem Details for HTTP APIs](https://datatracker.ietf.org/doc/html/rfc9457)

**Content-Type**: `application/problem+json`

### Error Response Format

All error responses follow the RFC 9457 format:

```json
{
  "type": "about:blank",
  "title": "Error Type",
  "status": 400,
  "detail": "Human-readable explanation of the error"
}
```

### Validation Errors (400 Bad Request)

For validation errors, an additional `errors` field provides field-level details:

```json
{
  "type": "about:blank",
  "title": "Validation Error",
  "status": 400,
  "detail": "One or more validation errors occurred",
  "errors": {
    "email": ["Invalid email format", "Email is required"],
    "password": ["Password must be at least 8 characters"]
  }
}
```

### Common HTTP Status Codes

- `200 OK`: Successful GET request
- `201 Created`: Successful resource creation
- `400 Bad Request`: Invalid input or missing required fields (with validation errors)
- `401 Unauthorized`: Authentication required or invalid token
- `403 Forbidden`: Authenticated but not authorized
- `404 Not Found`: Resource not found
- `409 Conflict`: Resource already exists (duplicate)
- `429 Too Many Requests`: Rate limit exceeded
- `500 Internal Server Error`: Server-side error

### Example Error Responses

**401 Unauthorized:**
```json
{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication required"
}
```

**409 Conflict:**
```json
{
  "type": "about:blank",
  "title": "Conflict",
  "status": 409,
  "detail": "Email already exists"
}
```

**500 Internal Server Error:**
```json
{
  "type": "about:blank",
  "title": "Internal Server Error",
  "status": 500,
  "detail": "Failed to process request"
}
```

---

## Development vs Production

**Development Mode** (current):
- Tenant context via `X-Tenant-ID` header
- Less strict validation
- Debug logging enabled
- Test API keys (`test_sk_*`) generated

**Production Mode**:
- Tenant context extracted from JWT token claims
- Strict validation
- Info/Error logging only
- Live API keys (`live_sk_*`) generated
