SportX is a Spring Boot backend for a sports challenge platform with an integrated AI assistant.
The project combines practical backend engineering and an AI RAG workflow:
- user authentication and profile management
- challenge registration and cancellation
- favorite spots and notifications
- Redis caching, distributed locking, and leaderboards
- RabbitMQ event delivery with retry, DLQ, and replay
- Qwen-based RAG assistant with knowledge retrieval and source citation
- Constructor injection with
finalfields and@RequiredArgsConstructor - Typed API responses with
Result<T> - Request validation with
@Validatedand@Valid - Global exception handling with business-friendly messages
- BCrypt password hashing
- Redis token session with automatic TTL refresh
- Login and verification-code rate limiting
- Redis + Lua distributed locking for challenge registration
- RabbitMQ retry, DLQ, failed-message persistence, and manual replay
- Swagger / OpenAPI documentation
- Unit and controller tests
- AI assistant with:
- knowledge ingestion from MySQL and markdown rules
- chunking via LangChain4j
- embedding-based retrieval
- generated answers with source snippets
- manual index rebuild endpoint
- Java 23
- Spring Boot 3.4.x
- MyBatis-Plus
- MySQL
- Redis
- RabbitMQ
- Spring Validation
- Spring Security Crypto (
BCryptPasswordEncoder) - Swagger / OpenAPI (
springdoc-openapi) - JUnit 5, Mockito, MockMvc
- LangChain4j
- Qwen-compatible OpenAI API mode
- Swagger UI:
http://localhost:8080/swagger-ui/index.html - OpenAPI JSON:
http://localhost:8080/v3/api-docs
POST /user/codePOST /user/loginPOST /user/regularLoginPOST /user/registerPOST /user/logoutGET /user/meGET /user/profilePUT /user/profile
Key behaviors:
- token-based login stored in Redis
- automatic token refresh on authenticated requests
- BCrypt password hashing
- login and verification-code throttling
- profile update support
GET /spots/{id}POST /spots/search
Key behaviors:
- spot detail cache
- search and filter support
GET /challenge/listGET /challenge/{id}GET /challenge/myPOST /challenge/addPOST /challenge/register/{id}POST /challenge/cancel/{id}
Key behaviors:
- challenge detail cache
- one-user-one-registration protection
- Redis + Lua distributed lock
- slot control with conditional database update
- MQ event publishing after registration and cancellation
POST /favorite/spots/{id}DELETE /favorite/spots/{id}GET /favorite/spots
Key behaviors:
- unique favorite relationship per user and spot
- paginated favorite list
GET /notification/listPUT /notification/read/{id}
Notification sources:
- registration success
- cancellation success
- challenge start reminder
- challenge end reminder
GET /leaderboard/spots/heatGET /leaderboard/users/score
Key behaviors:
- Redis ZSet-based hot spot leaderboard
- Redis ZSet-based user score leaderboard
GET /mq/failed/listPOST /mq/failed/retry/{id}
Key behaviors:
- RabbitMQ retry policy
- dead-letter queue routing
- failed-message persistence
- manual replay endpoint
- Redis-based idempotent consumption markers
POST /ai/askPOST /ai/reindex
Current AI scope:
- answers questions about platform rules, spots, and challenges
- retrieves relevant knowledge chunks before generation
- returns source citations with each answer
Current knowledge sources:
spotstablechallengetablesrc/main/resources/ai/platform-rules.md
Current AI flow:
- load knowledge from database and markdown
- split documents into chunks with LangChain4j
- generate embeddings
- store vectors in an in-memory embedding store
- retrieve relevant chunks for the question
- generate the final answer with cited sources
src/main/java/com/example/sportx/ControllerREST controllerssrc/main/java/com/example/sportx/Serviceservice interfacessrc/main/java/com/example/sportx/Service/Implservice implementationssrc/main/java/com/example/sportx/MapperMyBatis-Plus mapperssrc/main/java/com/example/sportx/Entitydomain entities and AI knowledge objectssrc/main/java/com/example/sportx/Entity/dtorequest DTOssrc/main/java/com/example/sportx/Entity/voresponse VOssrc/main/java/com/example/sportx/Configconfiguration classessrc/main/java/com/example/sportx/UtilsRedis, cache, MQ, and helper utilitiessrc/main/java/com/example/sportx/RabbitMQMQ config, listeners, and schedulersrc/main/resources/aiAI knowledge markdownsrc/main/resources/sqlSQL scripts
Main tables:
userspotschallengechallenge_participationnotificationsspot_favoritesfailed_messageleaderboard_snapshotleaderboard_entry
Important constraints:
- unique
(user_id, challenge_id)onchallenge_participation - unique
(user_id, spot_id)onspot_favorites
- MySQL on
127.0.0.1:3306 - Redis on
127.0.0.1:6379 - RabbitMQ on
127.0.0.1:5672
Main config:
src/main/resources/application.properties
Local private overrides:
src/main/resources/application-local.properties
application-local.properties is ignored by Git and should contain local secrets such as AI API keys.
Example AI configuration with Qwen:
ai.rag.embedding-api-key=your_qwen_key
ai.rag.embedding-base-url=https://dashscope.aliyuncs.com/compatible-mode/v1
ai.rag.embedding-model=text-embedding-v4
ai.rag.chat-api-key=your_qwen_key
ai.rag.chat-base-url=https://dashscope.aliyuncs.com/compatible-mode/v1
ai.rag.chat-model=qwen-turbo./mvnw spring-boot:run./mvnw package./mvnw test- failed-message table:
src/main/resources/sql/failed_message.sql
- unique indexes:
src/main/resources/sql/unique_indexes.sql
POST /ai/ask
Content-Type: application/json{
"question": "What are the current challenge rules on SportX?"
}POST /ai/reindexNo request body is required.
- The backend baseline is production-oriented in structure, not just CRUD-oriented.
- Reliability features are part of the main project design, not later add-ons.
- The AI module is intentionally isolated from the core transaction paths.
- Retrieval and generation are separated so providers can be changed independently.
Possible next improvements:
- stronger retrieval reranking for rule-specific questions
- persistent vector storage instead of in-memory index
- automatic reindexing after spot or challenge updates
- richer AI knowledge sources
- AI recommendation flow on top of user favorites and registrations