# ๐Ÿš€ 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`](../infrastructure/README.md) 2. Follow the setup instructions 3. Come back here once infrastructure is running **Verify infrastructure is healthy:** ```bash cd cloud/infrastructure/development task dev:status # All services should show (healthy) ``` ## ๐Ÿ Getting Started ### Installation ```bash # 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): ```bash 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 ```bash # 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 ```bash # 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 ```bash # Run all tests task test # Code quality checks task format # Format code task lint # Run linters ``` ### Database Operations **View database:** ```bash # 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):** ```bash task db:clear ``` ## ๐Ÿ”ง Usage ### Testing the API Create a test user and site to verify the backend works: **1. Register a user:** ```bash 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](https://haveibeenpwned.com/) database. If your password has been found in data breaches, registration will fail. Use a strong, unique password that hasn't been compromised. **Response:** ```json { "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: ```bash export TOKEN="eyJhbGci...your-access-token-here" ``` **2. Get your profile:** ```bash curl http://localhost:8000/api/v1/me \ -H "Authorization: JWT $TOKEN" ``` **3. Create a WordPress site:** ```bash 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): ```bash export API_KEY="your-api-key-here" ``` **4. Test plugin authentication:** ```bash curl http://localhost:8000/api/v1/plugin/status \ -H "Authorization: Bearer $API_KEY" ``` ### WordPress Plugin Integration **Access WordPress:** - URL: http://localhost:8081/wp-admin - Credentials: admin / admin **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:** - WordPress plugin setup: [`../../native/wordpress/README.md`](../../native/wordpress/README.md) - Complete API documentation: [`docs/API/README.md`](docs/API/README.md) ### Error Handling MaplePress uses **RFC 9457 (Problem Details for HTTP APIs)** for standardized error responses. All errors return a consistent, machine-readable format: ```json { "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](https://datatracker.ietf.org/doc/html/rfc9457)) - ๐Ÿ” Field-level validation errors See [`docs/API/README.md#error-handling`](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:** ```bash cd cloud/maplepress-backend rm .env cp .env.sample .env task dev ``` ### Infrastructure not running **Error:** Cassandra or Redis not available **Fix:** ```bash cd cloud/infrastructure/development task dev:start task dev:status # Wait until all show (healthy) ``` ### Port 8000 already in use **Fix:** ```bash 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](#testing-the-api) 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:** ```bash 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`):** ```bash # 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`](docs/API.md#test-mode-vs-live-mode) for details. ## ๐Ÿ”— Links - **API Documentation:** [`docs/API.md`](docs/API.md) - **Developer Guide:** [`docs/DEVELOPER_GUIDE.md`](docs/DEVELOPER_GUIDE.md) - **Getting Started Guide:** [`docs/GETTING-STARTED.md`](docs/GETTING-STARTED.md) - **WordPress Plugin:** [`../../native/wordpress/README.md`](../../native/wordpress/README.md) - **Architecture Details:** [`../../CLAUDE.md`](../../CLAUDE.md) - **Repository:** [Codeberg - mapleopentech/monorepo](https://codeberg.org/mapleopentech/monorepo) ## ๐Ÿค Contributing Found a bug? Want a feature to improve MaplePress? Please create an [issue](https://codeberg.org/mapleopentech/monorepo/issues/new). ## ๐Ÿ“ License This application is licensed under the [**GNU Affero General Public License v3.0**](https://opensource.org/license/agpl-v3). See [LICENSE](../../LICENSE) for more information.