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