Imported from YunWanJia-dev/cloudpvp-biz (
AGENTS.md). Install upstream withnpx skills add YunWanJia-dev/cloudpvp-biz. Copyright stays with the author.
AGENTS.md
Project Overview
cloudpvp is a Gradle multi-module project. It currently uses Spring Boot / Spring Cloud as the main runtime framework. The codebase should keep a clear distinction between framework-independent business/shared code and framework-specific adaptation code.
Root structure:
cloudpvp
├── build.gradle # Root build script for plugins, repositories, Java/Kotlin versions, and output layout
├── settings.gradle # Gradle multi-module declarations
├── buildSrc/
│ └── shared.gradle # Shared Gradle configuration for business services
├── gradle/
│ └── libs.versions.toml # Dependency and plugin version catalog
├── common-config.properties # Shared configuration file
├── cloudpvp-core/ # Framework-independent shared core module, remember `never` add any framework into this module.
├── cloudpvp-beans/ # Spring-related shared configuration, beans, and components
├── cloudpvp-gateway/ # Gateway service
├── cloudpvp-auth/ # Authentication service
├── cloudpvp-lobby/ # Lobby service
├── cloudpvp-play/ # Game/play configuration service
├── cloudpvp-state/ # Player state service
└── cloudpvp-user-summary/ # User profile summary service
Module Responsibilities
| Module | Responsibility |
|---|---|
cloudpvp-core |
Framework-independent shared core module. It contains business-shared entities, value types, constants, exceptions, protocol models, and pure utilities. It must not introduce Spring, Redis, Servlet, WebSocket, Gateway, or other framework-specific types. |
cloudpvp-beans |
Current Spring support module. It contains reusable Spring beans, configuration properties, auto-configuration, exception handling, and other framework-specific shared code. It is not a framework-independent module. It may be renamed to cloudpvp-spring-support later. |
cloudpvp-gateway |
Spring Cloud Gateway service. It owns entry routing, CORS, gateway filters, and other gateway-side behavior. |
cloudpvp-auth |
Authentication service. It currently owns Steam OpenID login, login callbacks, token issuing, and login page templates. |
cloudpvp-lobby |
Lobby service. It owns lobby creation, joining, leaving, host switching, WebSocket message delivery, and Redis-backed temporary state. |
cloudpvp-play |
Game/play configuration service. It owns queries for games, types, modes, and other play metadata. |
cloudpvp-state |
Player state service. It owns player online state, current state storage, and state WebSocket connections. |
cloudpvp-user-summary |
User profile summary service. It owns player profile queries, profile summary aggregation, and future profile refresh entry points. |
Responsibility Boundaries
cloudpvp-core
- Contains only framework-independent code.
- May contain shared domain entities, value types, enums, constants, DTOs, base exceptions, and pure-function utilities.
- Must not depend on Spring, Redis, Servlet, WebSocket, Spring Cloud Gateway, Spring Data, or similar framework types.
- Must not contain concrete infrastructure implementations such as HTTP client details, Redis serializers, or framework bean wiring.
- If a capability must be shared across frameworks, prefer a plain interface or configuration model and implement it in the concrete adapter layer.
cloudpvp-beans
- This is the Spring adaptation/support layer, not a shared business layer.
- It may depend on Spring Boot, Spring Web, Spring ConfigurationProperties, Spring Advice, and related framework APIs.
- It owns reusable Spring bean wiring, configuration property binding, global exception handling, Jackson configuration, and similar support code.
- It must not contain concrete business rules. Business rules belong to the corresponding business service module.
Business Service Modules
controller/websocketown protocol entry points: HTTP parameters, WebSocket sessions, and request/response conversion.serviceowns application flows and business use-case orchestration.repositoryowns data access interfaces or Spring Data repositories.configurationsowns framework configuration.entityshould primarily express business state. Avoid adding WebSocket sessions, Redis listeners, serializers, or other infrastructure behavior to entities.constant,model, andexceptionsshould hold service-local content. Move content tocloudpvp-coreonly when it is truly shared across services.
Directory Naming Conventions
controller: HTTP API entry points.websocket: WebSocket handlers.service: Application services and business flows.repository: Data access or state storage abstractions.entity: Business entities or state objects.model: API models, message models, or third-party response models.constant: Constants and enums.configurations: Framework configuration.property: Configuration property binding.component: Framework-managed reusable components.interceptor: Request or WebSocket handshake interceptors.exceptions: Business exceptions or service-local exceptions.
Review Guidelines
- When reviewing, first verify whether a finding is truly a business-impacting problem. Existing architecture may already provide validation, fallback behavior, idempotency, or recovery paths that make the suspected issue harmless in practice.
- Before fixing a confirmed issue, evaluate whether the change can introduce new problems, broaden the behavior unnecessarily, or over-design around an unlikely scenario.
- Keep fixes proportional to the confirmed risk and consistent with the current module boundaries, data flow, and framework responsibilities.
- After applying a fix, inspect the surrounding call paths and related business code once more to confirm the change does not break existing flows or assumptions.
- After a review or fix, leave a concise comment near the relevant code explaining why the fix is needed, or why the reviewed issue intentionally does not need a fix, so future reviews do not repeatedly flag the same case.
Comment Guidelines
Code Comments
- First and foremost, all comments must serve to improve code readability and maintainability.
- Add inline or block comments when a logic block has non-obvious intent, constraints, tradeoffs, or external API quirks.
- Prefer explaining why the code is written this way over merely restating what the code does.
- For variables, constants, methods, and other declarations, use Javadoc/KDoc comments for declaration-level information such as purpose, units, constraints, and caller-visible contracts, so IDE hover can show it.
- Use ordinary inline or block comments for explanations that depend on nearby implementation context, such as why a branch, ordering, workaround, or tradeoff is needed.
- For longer methods, add short comments above major logic blocks to make the flow easier to scan.
- Avoid comments that only repeat obvious statements from the code.
- When conducting a review, follow the review-specific comment requirements in Review Guidelines.
New Classes
- Add a class-level Javadoc/KDoc comment for every new public or framework-managed class.
- The first line should state the class name or main responsibility in concise terms.
- Use Chinese for class description lines, method summaries,
@param,@return, and@throwsdescriptions. - Add one short Chinese description line when the class responsibility is not obvious from its name.
- Add
@authorfor new classes. Do not invent the author from memory; get it from Git before writing the comment:
git config user.name
- Add
@sincefor new classes. Do not invent the timestamp from memory; get it from the command line before writing the comment:
Get-Date -Format "yyyy/M/d HH:mm"
Example:
/**
* SteamApiConfiguration
* Steam API 配置模型。
*
* @author sheip9
* @since 2026/5/15 15:31
*/
New Methods
- Add method-level Javadoc/KDoc for new public methods and for package/private methods whose behavior is not immediately obvious.
- The summary should describe what the method does in Chinese, not repeat the method name mechanically.
- Document each non-obvious parameter with
@param. - Document the return value with
@returnwhen the return type is not self-explanatory. - Document checked exceptions and expected business exceptions with
@throws. - Keep implementation details out of method comments unless callers need to know them.
Example:
/**
* 从已校验的令牌中获取当前玩家 ID。
*
* @param token 请求头中的授权令牌
* @return 当前玩家的 Steam ID64
* @throws UserIdInvalidException 当令牌无效或不包含玩家 ID 时抛出
*/