Files
leagues-tools/spring-backend/BUILD_STATUS.md

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 entity
    • Member.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 access
    • MemberRepository.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 config
  • application-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)

  1. Exception Handling (5 min)

    • Create custom exceptions
    • Add @ControllerAdvice global handler
  2. DTOs (15 min)

    • CreateGroupRequest/Response
    • UpdateMemberRequest
    • GroupMemberResponse
    • Must match Rust JSON structure exactly
  3. Service Layer (30 min)

    • GroupService - Create group, get group data
    • MemberService - Update/add/delete/rename members
    • Business logic and validation
  4. Controllers (30 min)

    • PublicController - /api/create-group, /api/ge-prices
    • GroupController - /api/group/{name}/get-group-data
    • MemberController - /api/group/{name}/update-group-member
  5. GE Prices Service (15 min)

    • HTTP client to RuneScape Wiki API
    • Caching with @Scheduled task
  6. 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:

  1. MariaDB running on localhost:3306
  2. Database named groupironman created
  3. 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

  1. Plugin sends Authorization header with raw token (no Bearer prefix)
  2. TokenAuthenticationFilter intercepts requests to /api/group/**
  3. Token is hashed with Blake2 (2 iterations)
  4. Database query: SELECT group_id WHERE token_hash = ? AND group_name = ?
  5. If found, groupId is set in Spring Security context
  6. 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:

  1. Exceptions & Handler - 5 minutes
  2. DTOs - 15 minutes
  3. Services - 30 minutes
  4. Controllers - 30 minutes
  5. 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