278 lines
9.8 KiB
Markdown
278 lines
9.8 KiB
Markdown
# Spring Backend - Build Status
|
|
|
|
## ✅ **BUILD SUCCESSFUL**
|
|
|
|
The project now compiles and builds successfully!
|
|
|
|
---
|
|
|
|
## Completed Components
|
|
|
|
### 1. Project Infrastructure ✅
|
|
- [x] Gradle 8.5 wrapper configured
|
|
- [x] Spring Boot 3.2.0 application
|
|
- [x] All dependencies resolved
|
|
- [x] Build system functional (`./gradlew.bat build`)
|
|
|
|
### 2. Database Layer ✅
|
|
- [x] **Flyway Migration** (`V1__init_schema.sql`)
|
|
- MariaDB-compatible schema
|
|
- JSON columns for arrays
|
|
- All tables, indexes, and foreign keys
|
|
|
|
- [x] **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)
|
|
|
|
- [x] **Repositories**
|
|
- `GroupRepository.java` - Group data access
|
|
- `MemberRepository.java` - Member data access with complex queries
|
|
- Custom queries for authentication and delta updates
|
|
|
|
### 3. Security & Authentication ✅
|
|
- [x] **Blake2TokenHasher** - 100% compatible with Rust implementation
|
|
- [x] **TokenAuthenticationFilter** - JWT-style token validation
|
|
- [x] **SecurityConfig** - Public/protected endpoint configuration
|
|
- [x] **CorsConfig** - RuneLite plugin + frontend support
|
|
|
|
### 4. Configuration ✅
|
|
- [x] `application.yml` - MariaDB, security, CORS config
|
|
- [x] `application-test.yml` - Test profile
|
|
- [x] Environment variable support
|
|
|
|
---
|
|
|
|
## How to Build & Run
|
|
|
|
### Prerequisites
|
|
- Java 17+ installed
|
|
- MariaDB running (for bootRun)
|
|
|
|
### Build Commands
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
# 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)**:
|
|
```sql
|
|
skills INTEGER[24]
|
|
```
|
|
|
|
**Java (MariaDB)**:
|
|
```java
|
|
@JdbcTypeCode(SqlTypes.JSON)
|
|
@Column(name = "skills", columnDefinition = "json")
|
|
private List<Integer> skills;
|
|
```
|
|
|
|
**JSON in Database**:
|
|
```json
|
|
[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
|