# Group Ironmen Backend - Java/Spring Boot A complete rewrite of the Group Ironmen tracker backend from Rust to Java/Spring Boot, maintaining 100% API compatibility with the existing RuneLite plugin. --- ## ๐ŸŽฏ Project Status **โœ… COMPLETE - Ready for Deployment** All core functionality implemented and tested: - โœ… Database layer (JPA entities, repositories) - โœ… Security layer (Blake2 token authentication, CORS) - โœ… Business logic (services for groups, members, GE prices) - โœ… REST API (all endpoints matching Rust implementation) - โœ… Exception handling - โœ… Build successful --- ## ๐Ÿ“‹ Table of Contents - [Features](#features) - [Technology Stack](#technology-stack) - [Quick Start](#quick-start) - [API Endpoints](#api-endpoints) - [Configuration](#configuration) - [Deployment](#deployment) - [Development](#development) - [Testing](#testing) - [Documentation](#documentation) --- ## โœจ Features ### Core Features - **Group Management**: Create groups with up to 5 members - **Member Tracking**: Track player stats, skills, inventory, equipment, bank, etc. - **Delta Updates**: Efficient updates - only changed data is sent - **GE Prices**: Cached Grand Exchange prices updated every 4 hours - **Token Authentication**: Blake2-hashed tokens for secure access - **Per-Field Timestamps**: Track last update time for each member field ### API Compatibility - 100% compatible with existing RuneLite plugin - Identical JSON structure to Rust backend - Same authentication flow - Same endpoint paths and parameters --- ## ๐Ÿ› ๏ธ Technology Stack - **Java 17** - LTS version - **Spring Boot 3.2.0** - Application framework - **Spring Security** - Authentication & authorization - **Spring Data JPA** - Database access - **MariaDB** - Database (MySQL-compatible) - **Flyway** - Database migrations - **Lombok** - Reduce boilerplate code - **Gradle 8.5** - Build tool - **Bouncy Castle** - Blake2 cryptography --- ## ๐Ÿš€ Quick Start ### Prerequisites - Java 17 or higher - MariaDB 10.6+ (or MySQL 8.0+) - Gradle 8.5+ (wrapper included) ### 1. Clone Repository ```bash cd leagues-tools/spring-backend ``` ### 2. Setup Database ```sql CREATE DATABASE groupironman CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'groupironmen'@'localhost' IDENTIFIED BY 'your_password'; GRANT ALL PRIVILEGES ON groupironman.* TO 'groupironmen'@'localhost'; FLUSH PRIVILEGES; ``` ### 3. Configure Application Edit `src/main/resources/application.yml` or set environment variables: ```bash export DB_HOST=localhost export DB_PORT=3306 export DB_NAME=groupironman export DB_USER=groupironmen export DB_PASSWORD=your_password export BACKEND_SECRET=your_64_char_random_secret export CORS_ORIGINS=http://localhost:3000,http://localhost:4000 ``` ### 4. Build and Run ```bash # Build ./gradlew clean build # Run ./gradlew bootRun # Or run JAR directly java -jar build/libs/group-ironmen-backend-1.0.0.jar ``` ### 5. Test ```bash # Health check curl http://localhost:8080/api/ge-prices # Create group curl -X POST http://localhost:8080/api/create-group \ -H "Content-Type: application/json" \ -d '{"name": "Test Group", "member_names": ["Player1", "Player2"]}' ``` --- ## ๐Ÿ“ก API Endpoints ### Public Endpoints (No Authentication) | Method | Endpoint | Description | |--------|----------|-------------| | POST | `/api/create-group` | Create a new group | | GET | `/api/ge-prices` | Get cached GE prices | | GET | `/api/captcha-enabled` | Get captcha configuration | | GET | `/api/collection-log-info` | Get collection log metadata | ### Group Endpoints (Token Authentication Required) | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/group/{name}/get-group-data` | Get member data (supports delta updates) | | GET | `/api/group/{name}/am-i-logged-in` | Check authentication | | GET | `/api/group/{name}/am-i-in-group` | Check member membership | | GET | `/api/group/{name}/get-skill-data` | Get skill progression data | | GET | `/api/group/{name}/collection-log` | Get collection log data | ### Member Endpoints (Token Authentication Required) | Method | Endpoint | Description | |--------|----------|-------------| | POST | `/api/group/{name}/update-group-member` | Update member data (from plugin) | | POST | `/api/group/{name}/add-group-member` | Add new member to group | | DELETE | `/api/group/{name}/delete-group-member` | Remove member from group | | PUT | `/api/group/{name}/rename-group-member` | Rename a member | --- ## โš™๏ธ Configuration ### Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `DB_HOST` | localhost | MariaDB host | | `DB_PORT` | 3306 | MariaDB port | | `DB_NAME` | groupironman | Database name | | `DB_USER` | root | Database username | | `DB_PASSWORD` | password | Database password | | `SERVER_PORT` | 8080 | Application HTTP port | | `BACKEND_SECRET` | changeme | Token hashing secret (CHANGE IN PRODUCTION!) | | `CORS_ORIGINS` | * | Allowed CORS origins (comma-separated) | | `CAPTCHA_ENABLED` | false | Enable hCaptcha validation | | `CAPTCHA_SITEKEY` | | hCaptcha site key | | `CAPTCHA_SECRET` | | hCaptcha secret key | ### Application Properties See `src/main/resources/application.yml` for all configuration options. --- ## ๐Ÿšข Deployment ### For Debian/Proxmox VE See **[DEPLOYMENT.md](DEPLOYMENT.md)** for complete guide including: - LXC container setup - MariaDB installation & configuration - systemd service creation - Nginx reverse proxy setup - SSL certificate installation - Monitoring and maintenance ### Quick Deploy Script ```bash # Build JAR ./gradlew clean build -x test # Copy to server scp build/libs/group-ironmen-backend-1.0.0.jar user@server:/opt/group-ironmen-backend/ # Restart service (on server) ssh user@server "systemctl restart group-ironmen-backend" ``` --- ## ๐Ÿ’ป Development ### Project Structure ``` spring-backend/ โ”œโ”€โ”€ src/main/java/com/osleague/groupironmen/ โ”‚ โ”œโ”€โ”€ GroupIronmenApplication.java # Main application โ”‚ โ”œโ”€โ”€ config/ # Configuration classes โ”‚ โ”œโ”€โ”€ controller/ # REST controllers โ”‚ โ”œโ”€โ”€ dto/ # Data Transfer Objects โ”‚ โ”œโ”€โ”€ exception/ # Custom exceptions โ”‚ โ”œโ”€โ”€ model/ # JPA entities โ”‚ โ”œโ”€โ”€ repository/ # Spring Data repositories โ”‚ โ”œโ”€โ”€ security/ # Security components โ”‚ โ”œโ”€โ”€ service/ # Business logic โ”‚ โ””โ”€โ”€ util/ # Utilities โ”œโ”€โ”€ src/main/resources/ โ”‚ โ”œโ”€โ”€ application.yml # Main configuration โ”‚ โ””โ”€โ”€ db/migration/ # Flyway migrations โ”œโ”€โ”€ build.gradle # Build configuration โ””โ”€โ”€ README.md # This file ``` ### Building ```bash # Clean build ./gradlew clean build # Skip tests ./gradlew build -x test # Run tests only ./gradlew test # Generate JAR ./gradlew bootJar ``` ### Code Style - Java code formatted with standard conventions - Lombok used to reduce boilerplate - Comprehensive Javadoc comments - Follows Spring Boot best practices --- ## ๐Ÿงช Testing ### Unit Tests ```bash ./gradlew test ``` ### Integration Tests (Requires MariaDB) ```bash ./gradlew integrationTest ``` ### Manual Testing with curl **Create Group:** ```bash curl -X POST http://localhost:8080/api/create-group \ -H "Content-Type: application/json" \ -d '{ "name": "My Test Group", "member_names": ["Player1", "Player2", "Player3"] }' # Save the returned token! ``` **Update Member (as Plugin would):** ```bash curl -X POST http://localhost:8080/api/group/My%20Test%20Group/update-group-member \ -H "Content-Type: application/json" \ -H "Authorization: YOUR_TOKEN_HERE" \ -d '{ "name": "Player1", "stats": [99, 99, 100, 301], "skills": [13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431, 13034431] }' ``` **Get Group Data:** ```bash curl http://localhost:8080/api/group/My%20Test%20Group/get-group-data \ -H "Authorization: YOUR_TOKEN_HERE" ``` --- ## ๐Ÿ“š Documentation ### Available Documentation - **[IMPLEMENTATION_STATUS.md](IMPLEMENTATION_STATUS.md)** - Detailed implementation guide - **[BUILD_STATUS.md](BUILD_STATUS.md)** - Build instructions and status - **[STATUS_UPDATE.md](STATUS_UPDATE.md)** - Latest development progress - **[DEPLOYMENT.md](DEPLOYMENT.md)** - Production deployment guide (Debian/Proxmox) ### Key Design Decisions **1. MariaDB JSON Columns** - PostgreSQL arrays โ†’ MariaDB JSON columns - Uses `@JdbcTypeCode(SqlTypes.JSON)` annotation - Maintains compatibility with Rust schema **2. Blake2 Token Hashing** - 100% compatible with Rust implementation - 2 iterations of Blake2b-256 - Token + secret + group_name as salt **3. Delta Updates** - Per-field `last_update` timestamps - Only changed fields returned in responses - Reduces bandwidth for plugin updates **4. Stateless Authentication** - Token in Authorization header - No session storage - Group ID extracted from token validation --- ## ๐Ÿ” Security ### Authentication Flow 1. Client sends `Authorization: {token}` header 2. `TokenAuthenticationFilter` intercepts request 3. Token is hashed with Blake2 4. Database lookup: `SELECT group_id WHERE token_hash = ? AND group_name = ?` 5. If valid, `group_id` set in Spring Security context 6. Controller accesses `group_id` from `Authentication` principal ### Security Best Practices - โœ… Tokens are hashed (never stored in plain text) - โœ… CORS properly configured - โœ… SQL injection prevented (JPA parameterized queries) - โœ… Input validation on all endpoints - โœ… HTTPS recommended for production - โœ… Secrets via environment variables (not in code) --- ## ๐Ÿ› Troubleshooting ### Build Failures ```bash # Clean and rebuild ./gradlew clean build --refresh-dependencies # Check Java version java -version # Should be 17+ ``` ### Database Connection Issues ```bash # Test connection mysql -h localhost -u groupironmen -p groupironman # Check Flyway migrations ./gradlew flywayInfo ./gradlew flywayMigrate ``` ### Application Won't Start ```bash # Check logs ./gradlew bootRun --debug # Verify port 8080 is available netstat -an | grep 8080 ``` --- ## ๐Ÿค Contributing This is a migration project. Key compatibility requirements: - Maintain exact API compatibility with RuneLite plugin - Keep JSON structure identical to Rust implementation - Preserve authentication mechanism (Blake2 hashing) - Match database schema (via Flyway migrations) --- ## ๐Ÿ“„ License Same license as the original Rust project. --- ## ๐Ÿ”— Related Projects - **Rust Backend** (original): `group-ironmen-master/server/` - **Frontend** (Web Components): `group-ironmen-master/site/` - **RuneLite Plugin**: `group-ironmen-tracker-master/` - **League Tools Frontend**: `os-league-tools-master/` --- ## ๐Ÿ“ž Support For issues or questions: 1. Check existing documentation in this repository 2. Review Rust implementation for reference 3. Test with RuneLite plugin to verify compatibility --- **Status**: โœ… Complete and ready for deployment **Version**: 1.0.0 **Last Updated**: 2025-10-27