9.8 KiB
Spring Backend - Build Status
✅ BUILD SUCCESSFUL
The project now compiles and builds successfully!
Completed Components
1. Project Infrastructure ✅
- Gradle 8.5 wrapper configured
- Spring Boot 3.2.0 application
- All dependencies resolved
- Build system functional (
./gradlew.bat build)
2. Database Layer ✅
-
Flyway Migration (
V1__init_schema.sql)- MariaDB-compatible schema
- JSON columns for arrays
- All tables, indexes, and foreign keys
-
JPA Entities
Group.java- Group ironman team entityMember.java- Player entity with all fields (stats, skills, inventory, etc.)- Uses
@JdbcTypeCode(SqlTypes.JSON)for array fields - Proper relationships (@ManyToOne, @OneToMany)
-
Repositories
GroupRepository.java- Group data accessMemberRepository.java- Member data access with complex queries- Custom queries for authentication and delta updates
3. Security & Authentication ✅
- Blake2TokenHasher - 100% compatible with Rust implementation
- TokenAuthenticationFilter - JWT-style token validation
- SecurityConfig - Public/protected endpoint configuration
- CorsConfig - RuneLite plugin + frontend support
4. Configuration ✅
application.yml- MariaDB, security, CORS configapplication-test.yml- Test profile- Environment variable support
How to Build & Run
Prerequisites
- Java 17+ installed
- MariaDB running (for bootRun)
Build Commands
# Navigate to spring-backend directory
cd spring-backend
# Clean build (skip tests)
./gradlew.bat clean build -x test
# Run the application (requires MariaDB)
./gradlew.bat bootRun
# Build Docker image (when Dockerfile is added)
./gradlew.bat bootBuildImage
Build Output
- JAR file:
build/libs/group-ironmen-backend-1.0.0.jar - Executable:
java -jar build/libs/group-ironmen-backend-1.0.0.jar
What's Next?
The foundation is complete and compilable. The next priority is implementing the business logic layer so the application can actually run and serve requests.
Immediate Next Steps (Priority Order)
-
Exception Handling (5 min)
- Create custom exceptions
- Add
@ControllerAdviceglobal handler
-
DTOs (15 min)
CreateGroupRequest/ResponseUpdateMemberRequestGroupMemberResponse- Must match Rust JSON structure exactly
-
Service Layer (30 min)
GroupService- Create group, get group dataMemberService- Update/add/delete/rename members- Business logic and validation
-
Controllers (30 min)
PublicController- /api/create-group, /api/ge-pricesGroupController- /api/group/{name}/get-group-dataMemberController- /api/group/{name}/update-group-member
-
GE Prices Service (15 min)
- HTTP client to RuneScape Wiki API
- Caching with @Scheduled task
-
Test the Application (30 min)
- Start with MariaDB connection
- Test create-group endpoint with Postman
- Test authentication filter
Testing Without MariaDB
If you want to test the build without a database:
# Build only (no runtime required)
./gradlew.bat clean build -x test
# This will succeed because:
# - All Java code compiles
# - Dependencies resolve correctly
# - Spring Boot JAR is created
To actually run the application (bootRun), you'll need:
- MariaDB running on localhost:3306
- Database named
groupironmancreated - Valid DB credentials in environment variables or application.yml
Architecture Summary
┌─────────────────────────────────────────┐
│ HTTP Requests (RuneLite Plugin) │
└───────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Security Layer │
│ - CorsConfig (allow plugin origin) │
│ - TokenAuthenticationFilter │
│ - Blake2TokenHasher │
└───────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Controllers (TODO) │
│ - PublicController │
│ - GroupController │
│ - MemberController │
└───────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Service Layer (TODO) │
│ - GroupService │
│ - MemberService │
│ - GrandExchangeService │
└───────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Repository Layer ✅ │
│ - GroupRepository │
│ - MemberRepository │
└───────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ JPA Entities ✅ │
│ - Group │
│ - Member │
└───────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ MariaDB (via Flyway) ✅ │
│ - groups table │
│ - members table │
│ - skills_* tables │
│ - collection_* tables │
└─────────────────────────────────────────┘
Current File Structure
spring-backend/
├── build.gradle ✅
├── settings.gradle ✅
├── gradlew / gradlew.bat ✅
├── gradle/wrapper/ ✅
├── IMPLEMENTATION_STATUS.md ✅
├── BUILD_STATUS.md ✅ (this file)
└── src/
└── main/
├── java/com/osleague/groupironmen/
│ ├── GroupIronmenApplication.java ✅
│ ├── model/
│ │ ├── Group.java ✅
│ │ └── Member.java ✅
│ ├── repository/
│ │ ├── GroupRepository.java ✅
│ │ └── MemberRepository.java ✅
│ ├── security/
│ │ ├── Blake2TokenHasher.java ✅
│ │ └── TokenAuthenticationFilter.java ✅
│ ├── config/
│ │ ├── SecurityConfig.java ✅
│ │ └── CorsConfig.java ✅
│ ├── service/ (TODO)
│ ├── controller/ (TODO)
│ ├── dto/ (TODO)
│ ├── exception/ (TODO)
│ └── util/ (TODO)
└── resources/
├── application.yml ✅
├── application-test.yml ✅
└── db/migration/
└── V1__init_schema.sql ✅
Key Technical Decisions
1. JSON Arrays (Not Native Arrays)
MariaDB doesn't support PostgreSQL's array types, so we're using JSON columns with Hibernate's @JdbcTypeCode(SqlTypes.JSON).
Rust (PostgreSQL):
skills INTEGER[24]
Java (MariaDB):
@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "skills", columnDefinition = "json")
private List<Integer> skills;
JSON in Database:
[13034431, 13034431, 13034431, ...]
2. Authentication Flow
- Plugin sends Authorization header with raw token (no Bearer prefix)
TokenAuthenticationFilterintercepts requests to/api/group/**- Token is hashed with Blake2 (2 iterations)
- Database query:
SELECT group_id WHERE token_hash = ? AND group_name = ? - If found,
groupIdis set in Spring Security context - Controllers access via
@AuthenticationPrincipal Long groupId
3. Delta Updates
The MemberRepository.findByGroupIdAndUpdatedAfter() query returns only members with changes since the from_time timestamp, matching Rust behavior.
Next Session Goals
When you return to development, aim to complete these in order:
- ✅ Exceptions & Handler - 5 minutes
- ✅ DTOs - 15 minutes
- ✅ Services - 30 minutes
- ✅ Controllers - 30 minutes
- ✅ Test with Postman - 30 minutes
Total: ~2 hours to MVP (Minimum Viable Product)
Once these are complete, you'll have a working backend that the RuneLite plugin can communicate with!
Status: ✅ Ready for Service Layer Implementation Last Updated: 2025-10-27 Build: SUCCESS