Initial commit: Open sourcing all of the Maple Open Technologies code.

This commit is contained in:
Bartlomiej Mika 2025-12-02 14:33:08 -05:00
commit 755d54a99d
2010 changed files with 448675 additions and 0 deletions

View file

@ -0,0 +1,373 @@
# 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