monorepo/cloud/maplepress-backend/README.md
2025-12-02 22:48:40 -05:00

10 KiB

🚀 MaplePress Backend

Cloud-powered services platform for WordPress sites - Multi-tenant SaaS backend built with Go.

MaplePress offloads computationally intensive tasks from WordPress to improve site performance. Features include cloud-powered search (Meilisearch), JWT authentication for users, API key authentication for WordPress plugins, and multi-tenant architecture.

📋 Prerequisites

⚠️ Required: You must have the infrastructure running first.

If you haven't set up the infrastructure yet:

  1. Go to ../infrastructure/README.md
  2. Follow the setup instructions
  3. Come back here once infrastructure is running

Verify infrastructure is healthy:

cd cloud/infrastructure/development
task dev:status
# All services should show (healthy)

🏁 Getting Started

Installation

# From the monorepo root:
cd cloud/maplepress-backend

# Create environment file:
cp .env.sample .env

# Start the backend:
task dev

The backend runs at http://localhost:8000

Verify Installation

Open a new terminal (leave task dev running):

curl http://localhost:8000/health
# Should return: {"status":"healthy"}

Note: Your first terminal shows backend logs. Keep it running and use a second terminal for testing.

💻 Developing

Initial Configuration

Environment Files:

  • .env.sample - Template with defaults (committed to git)
  • .env - Your local configuration (git-ignored, created from .env.sample)
  • Use only .env for configuration (docker-compose loads this file)

The .env file defaults work for Docker development. Optional: Change APP_JWT_SECRET to a random string (use a password generator).

Running in Development Mode

# Start backend with hot-reload
task dev

# View logs (in another terminal)
docker logs -f maplepress-backend-dev

# Stop backend
task dev:down
# Or press Ctrl+C in the task dev terminal

What happens when you run task dev:

  • Docker starts the backend container
  • Auto-migrates database tables
  • Starts HTTP server on port 8000
  • Enables hot-reload (auto-restarts on code changes)

Wait for: Server started on :8000 in the logs

Daily Workflow

# Morning - check infrastructure (from monorepo root)
cd cloud/infrastructure/development && task dev:status

# Start backend (from monorepo root)
cd cloud/maplepress-backend && task dev

# Make code changes - backend auto-restarts

# Stop backend when done
# Press Ctrl+C

Testing

# Run all tests
task test

# Code quality checks
task format  # Format code
task lint    # Run linters

Database Operations

View database:

# From monorepo root
cd cloud/infrastructure/development
task cql

# Inside cqlsh:
USE maplepress;
DESCRIBE TABLES;
SELECT * FROM sites_by_id;

Reset database (⚠️ deletes all data):

task db:clear

🔧 Usage

Testing the API

Create a test user and site to verify the backend works:

1. Register a user:

curl -X POST http://localhost:8000/api/v1/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "MySecureP@ssw0rd2024!XyZ",
    "name": "Test User",
    "tenant_name": "Test Organization",
    "tenant_slug": "test-org",
    "agree_terms_of_service": true
  }'

Note: MaplePress checks passwords against the Have I Been Pwned database. If your password has been found in data breaches, registration will fail. Use a strong, unique password that hasn't been compromised.

Response:

{
  "user_id": "uuid-here",
  "user_email": "test@example.com",
  "user_name": "Test User",
  "tenant_id": "uuid-here",
  "tenant_name": "Test Organization",
  "access_token": "eyJhbGci...",
  "refresh_token": "eyJhbGci...",
  "access_expiry": "2025-10-29T12:00:00Z",
  "refresh_expiry": "2025-11-05T12:00:00Z"
}

Save the access_token from the response:

export TOKEN="eyJhbGci...your-access-token-here"

2. Get your profile:

curl http://localhost:8000/api/v1/me \
  -H "Authorization: JWT $TOKEN"

3. Create a WordPress site:

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"
  }'

Save the api_key from the response (shown only once):

export API_KEY="your-api-key-here"

4. Test plugin authentication:

curl http://localhost:8000/api/v1/plugin/status \
  -H "Authorization: Bearer $API_KEY"

WordPress Plugin Integration

Access WordPress:

Configure the plugin:

  1. Go to Settings → MaplePress
  2. Enter:
    • API URL: http://maplepress-backend-dev:8000
    • API Key: Your API key from step 3 above
  3. Click Save Settings & Verify Connection

⚠️ Important: Use the container name (maplepress-backend-dev), not localhost, because WordPress runs in Docker.

Next steps:

Error Handling

MaplePress uses RFC 9457 (Problem Details for HTTP APIs) for standardized error responses. All errors return a consistent, machine-readable format:

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

Benefits:

  • 📋 Structured, predictable error format
  • 🤖 Machine-readable for frontend parsing
  • 🌍 Industry standard (RFC 9457)
  • 🔍 Field-level validation errors

See docs/API/README.md#error-handling for complete error documentation.

⚙️ Configuration

Environment Variables

Key variables in .env:

Variable Default Description
APP_JWT_SECRET change-me-in-production-use-a-long-random-string Secret for JWT token signing
SERVER_PORT 8000 HTTP server port
DATABASE_HOSTS cassandra-1,cassandra-2,cassandra-3 Cassandra cluster nodes
CACHE_HOST redis Redis cache host
MEILISEARCH_HOST http://meilisearch:7700 Search engine URL

Docker vs Local:

  • Docker: Uses container names (cassandra-1, redis)
  • Local: Change to localhost

See .env.sample for complete documentation.

Task Commands

Command Description
task dev Start backend (auto-migrate + hot-reload)
task dev:down Stop backend
task test Run tests
task format Format code
task lint Run linters
task db:clear Reset database (⚠️ deletes data)
task migrate:up Manual migration

🔍 Troubleshooting

Backend won't start - "connection refused"

Error: dial tcp 127.0.0.1:9042: connect: connection refused

Cause: .env file has localhost instead of container names.

Fix:

cd cloud/maplepress-backend
rm .env
cp .env.sample .env
task dev

Infrastructure not running

Error: Cassandra or Redis not available

Fix:

cd cloud/infrastructure/development
task dev:start
task dev:status  # Wait until all show (healthy)

Port 8000 already in use

Fix:

lsof -i :8000  # Find what's using the port
# Stop the other service, or change SERVER_PORT in .env

Token expired (401 errors)

JWT tokens expire after 60 minutes. Re-run the registration step to get a new token.

WordPress can't connect

Problem: WordPress using localhost:8000 instead of container name

Fix: In WordPress settings, use http://maplepress-backend-dev:8000

Verify:

docker exec mapleopentech-wordpress-dev curl http://maplepress-backend-dev:8000/health

🛠️ Technology Stack

  • Go 1.23+ - Programming language
  • Clean Architecture - Code organization
  • Wire - Dependency injection
  • Cassandra - Multi-tenant database (3-node cluster)
  • Redis - Caching layer
  • Meilisearch - Full-text search
  • JWT - User authentication
  • API Keys - Plugin authentication

🌐 Services

When you run MaplePress, these services are available:

Service Port Purpose Access
MaplePress Backend 8000 HTTP API http://localhost:8000
Cassandra 9042 Database task cql (from infrastructure dir)
Redis 6379 Cache task redis (from infrastructure dir)
Meilisearch 7700 Search http://localhost:7700
WordPress 8081 Plugin testing http://localhost:8081

🧪 Test Mode vs Live Mode

MaplePress automatically generates the correct API key type based on your environment:

Automatic Behavior

Environment API Key Type When to Use
development test_sk_* Local development, testing
production live_sk_* Production sites

Configuration (.env):

# Development - automatically generates test_sk_ keys
APP_ENVIRONMENT=development

# Production - automatically generates live_sk_ keys
APP_ENVIRONMENT=production

No manual parameter needed! The backend determines the key type from APP_ENVIRONMENT.

See docs/API.md#test-mode-vs-live-mode for details.

🤝 Contributing

Found a bug? Want a feature to improve MaplePress? Please create an issue.

📝 License

This application is licensed under the GNU Affero General Public License v3.0. See LICENSE for more information.