Backend Stability, Basically functional.
This commit is contained in:
420
spring-backend/README.md
Normal file
420
spring-backend/README.md
Normal file
@@ -0,0 +1,420 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user