diff --git a/docs/17-backend-annotation-findings.md b/docs/17-backend-annotation-findings.md
new file mode 100644
index 00000000..b4f88640
--- /dev/null
+++ b/docs/17-backend-annotation-findings.md
@@ -0,0 +1,249 @@
+# Backend Structure Findings During Annotation Pass
+
+This document records architecture and structure issues that became consistently visible while enriching backend comments. The goal is to preserve concrete observations discovered during code reading, not to propose a full redesign.
+
+## 1. Admin user management is split across overlapping application services
+
+Observed files:
+
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminUserAppService.java`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminUserManagementService.java`
+
+Why this stands out:
+
+- Both services sit in the application layer and are named as if they own the same capability.
+- The naming does not make the responsibility boundary obvious to a reader.
+- This increases the chance that new admin-user use cases get placed inconsistently.
+
+Suggested direction:
+
+- Either consolidate them into one application service, or split them with an explicit boundary such as query vs. command, or account governance vs. account operations.
+
+## 2. Several controllers still perform orchestration that belongs in application services
+
+Observed files:
+
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/NamespaceController.java`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/ReviewController.java`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/PromotionController.java`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillLifecycleController.java`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubCompatController.java`
+
+Why this stands out:
+
+- Some controllers coordinate multiple repositories, domain services, request-derived identities, and response assembly in one place.
+- The controller layer is therefore carrying request translation and business workflow orchestration at the same time.
+- This makes endpoint behavior harder to reuse, test, and document consistently.
+
+Suggested direction:
+
+- Move multi-step orchestration into dedicated application services and keep controllers focused on transport concerns.
+
+## 3. Compatibility endpoints are tightly coupled to canonical domain and repository internals
+
+Observed files:
+
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubCompatController.java`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubRegistryFacade.java`
+
+Why this stands out:
+
+- The compatibility layer pulls from repositories, domain services, and DTO-mapping concerns at the same time.
+- The layer is useful, but it is not isolated enough to act as a clean anti-corruption boundary.
+- Changes in canonical read models or publish flows are more likely to leak into compatibility code.
+
+Suggested direction:
+
+- Treat compatibility support as a dedicated adapter layer with narrower upstream contracts and fewer direct repository dependencies.
+
+## 4. Security route policy is spread across configuration and implementation classes
+
+Observed files:
+
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java`
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenScopeService.java`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/AuthContextFilter.java`
+
+Why this stands out:
+
+- Route access rules, token-scope rules, and request-context projection are all related to request authorization, but they are not expressed from one central policy model.
+- A reader has to jump across modules to reconstruct how one API route is actually protected.
+
+Suggested direction:
+
+- Centralize route policy metadata or at least define one authoritative mapping between path patterns, authentication modes, and scope requirements.
+
+## 5. Governance behavior is distributed across multiple services without one clear workflow owner
+
+Observed files:
+
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceGovernanceService.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillGovernanceService.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewService.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/PromotionService.java`
+
+Why this stands out:
+
+- Governance rules are present in the right domain areas, but the end-to-end moderation and publishing workflow is distributed.
+- Readers need to reconstruct lifecycle rules by navigating several services and controllers.
+
+Suggested direction:
+
+- Keep the domain split, but introduce a clearer workflow owner or workflow-facing facade for governance use cases.
+
+## 6. Search-related read paths are split in a way that is hard to follow at first glance
+
+Observed files:
+
+- `server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresFullTextQueryService.java`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/service/SkillSearchAppService.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillQueryService.java`
+
+Why this stands out:
+
+- The codebase has a sensible separation between search, application assembly, and canonical detail reads, but the naming alone does not make their responsibilities obvious.
+- New contributors may need several passes to understand which service is the authoritative entry point for each read scenario.
+
+Suggested direction:
+
+- Clarify the boundary in naming or package-level docs, especially around "search result assembly" vs. "authoritative skill detail query."
+
+## 7. Event-driven counter maintenance is useful but not yet modeled as a distinct projection concern
+
+Observed files:
+
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/SkillStarEventListener.java`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/SkillRatingEventListener.java`
+
+Why this stands out:
+
+- Listeners are maintaining derived counters, which is a legitimate pattern.
+- The projection/update responsibility is implicit rather than explicitly named as a read-model maintenance concern.
+
+Suggested direction:
+
+- Consider naming this area more explicitly as projection maintenance or read-model synchronization if the pattern continues to grow.
+
+## 8. Exception modeling is duplicated across application, domain, and auth layers
+
+Observed files:
+
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/LocalizedException.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/LocalizedDomainException.java`
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/exception/AuthFlowException.java`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/GlobalExceptionHandler.java`
+
+Why this stands out:
+
+- The codebase uses localized error codes consistently, which is good, but several layers define parallel exception abstractions with overlapping semantics.
+- The global exception handler then has to understand each branch separately.
+- This makes it harder to tell whether a new business error belongs to the app layer, the auth layer, or the shared domain exception model.
+
+Suggested direction:
+
+- Keep layer-specific exception types only where they represent a real boundary, and consider converging on a smaller shared contract for localized API-facing errors.
+
+## 9. Repository and read-model access patterns are mixed across layers
+
+Observed files:
+
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/repository/AdminUserSearchRepository.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/*/*Repository.java`
+- `server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/*`
+- `server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubCompatController.java`
+
+Why this stands out:
+
+- Some flows use domain repository ports, some use infra JPA repositories, and some app-layer read logic uses `EntityManager` directly.
+- This is not wrong in itself, but the conventions are not explicit, so contributors have to infer when bypassing the domain port layer is acceptable.
+- The mixed style increases the chance that query behavior and write behavior evolve under different architectural rules.
+
+Suggested direction:
+
+- Define explicit rules for when a use case should depend on domain repository ports, dedicated query repositories, or direct persistence adapters.
+
+## 10. OAuth login behavior is decomposed into many small classes without one visible flow owner
+
+Observed files:
+
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/SkillHubOAuth2AuthorizationRequestResolver.java`
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/CustomOAuth2UserService.java`
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/GitHubClaimsExtractor.java`
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuth2LoginSuccessHandler.java`
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuth2LoginFailureHandler.java`
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessPolicyFactory.java`
+
+Why this stands out:
+
+- The current decomposition is modular, but understanding one OAuth login request still requires following state across request resolution, provider-specific claim extraction, access-policy evaluation, account provisioning, and redirect handling.
+- The extension points are good, yet the absence of one flow-oriented facade or documented orchestration path increases onboarding cost.
+
+Suggested direction:
+
+- Keep the provider-specific strategy types, but consider a clearer flow owner or a compact architecture note that names the stages of the OAuth pipeline.
+
+## 11. Some domain repository ports leak Spring Data pagination types
+
+Observed files:
+
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillRepository.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewTaskRepository.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogQueryService.java`
+
+Why this stands out:
+
+- Several domain-facing repository contracts use `Page` and `Pageable` directly.
+- This makes the domain boundary more dependent on Spring Data semantics than on a framework-neutral query model.
+- It is workable, but it weakens the separation between domain contracts and persistence tooling.
+
+Suggested direction:
+
+- Either accept Spring Data as an intentional part of the domain boundary and document that choice, or introduce domain-oriented page/query abstractions where long-term isolation matters.
+
+## 12. The auth module follows a more direct JPA style than the business-domain modules
+
+Observed files:
+
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/ApiTokenRepository.java`
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/IdentityBindingRepository.java`
+- `server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/RoleRepository.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillRepository.java`
+- `server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRepositoryAdapter.java`
+
+Why this stands out:
+
+- The auth area usually talks directly to Spring Data JPA repositories over auth entities.
+- The business-domain area more often exposes domain repository ports and implements them through infra adapters.
+- Both styles are valid, but using them side by side without an explicit rationale makes the overall architecture feel uneven.
+
+Suggested direction:
+
+- Decide whether auth is intentionally allowed to stay as a more direct persistence-oriented module, and document that distinction so contributors know which style to apply in new code.
+
+## 13. Many domain objects double as persistence entities instead of being isolated from JPA concerns
+
+Observed files:
+
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/Skill.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/Namespace.java`
+- `server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewTask.java`
+- `server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillJpaRepository.java`
+- `server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/NamespaceMemberJpaRepository.java`
+
+Why this stands out:
+
+- The codebase often uses the same classes as both domain models and JPA persistence entities.
+- This keeps implementation compact, but it also means persistence annotations, lazy-loading behavior, and storage-driven shape decisions can leak into domain modeling concerns.
+- Combined with the repository-style differences already noted above, the codebase can feel partly domain-driven and partly persistence-driven depending on the module.
+
+Suggested direction:
+
+- If this is an intentional tradeoff, document it clearly as the project's default. Otherwise, consider introducing stronger separation only in areas where persistence concerns are starting to distort domain logic.
+
+## Priority Recommendation
+
+If only a small amount of structural cleanup is feasible, the highest-value items are:
+
+1. Reduce controller orchestration by introducing a few focused application services.
+2. Clarify the admin-user service boundary.
+3. Centralize security route policy so access behavior is easier to reason about.
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/SkillhubApplication.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/SkillhubApplication.java
index 38f33ec6..adb56bca 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/SkillhubApplication.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/SkillhubApplication.java
@@ -5,6 +5,9 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+/**
+ * Main Spring Boot entry point for the SkillHub backend application.
+ */
@SpringBootApplication
@EnableConfigurationProperties(ProfileModerationProperties.class)
public class SkillhubApplication {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/BootstrapAdminProperties.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/BootstrapAdminProperties.java
index 11aadcdf..d3de35df 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/BootstrapAdminProperties.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/BootstrapAdminProperties.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.bootstrap;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
+/**
+ * Configuration properties for bootstrapping a default admin account in controlled environments.
+ */
@Component
@ConfigurationProperties(prefix = "skillhub.bootstrap.admin")
public class BootstrapAdminProperties {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/LocalDevDataInitializer.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/LocalDevDataInitializer.java
index b78a871c..6755beed 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/LocalDevDataInitializer.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/LocalDevDataInitializer.java
@@ -20,6 +20,9 @@ import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * Seeds predictable users, memberships, and admin roles for the local development profile.
+ */
@Component
@Profile("local")
public class LocalDevDataInitializer implements ApplicationRunner {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/package-info.java
new file mode 100644
index 00000000..7a1e2f4b
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/bootstrap/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Startup initializers that prepare local development data and required system
+ * accounts before the application begins serving traffic.
+ */
+package com.iflytek.skillhub.bootstrap;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubCompatController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubCompatController.java
index dbd179f4..e689c0c8 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubCompatController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubCompatController.java
@@ -43,6 +43,10 @@ import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
+/**
+ * Compatibility controller that exposes SkillHub content using ClawHub-style routes and payload
+ * shapes expected by legacy clients.
+ */
@RestController
@RequestMapping("/api/v1")
public class ClawHubCompatController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubRegistryFacade.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubRegistryFacade.java
index 1a697f18..b7fac835 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubRegistryFacade.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubRegistryFacade.java
@@ -22,6 +22,10 @@ import java.util.Map;
import java.util.Optional;
import org.springframework.stereotype.Component;
+/**
+ * Facade that assembles registry-style compatibility responses from the platform's canonical search
+ * and skill services.
+ */
@Component
public class ClawHubRegistryFacade {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubRegistrySecurityConfig.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubRegistrySecurityConfig.java
index 66a632e9..bbc43dd1 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubRegistrySecurityConfig.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/ClawHubRegistrySecurityConfig.java
@@ -7,6 +7,10 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
+/**
+ * Declares a dedicated stateless security chain for public compatibility endpoints used by
+ * registry-style clients.
+ */
@Configuration
public class ClawHubRegistrySecurityConfig {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/SkillCoordinate.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/SkillCoordinate.java
index f1077287..b5b462c2 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/SkillCoordinate.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/SkillCoordinate.java
@@ -1,3 +1,6 @@
package com.iflytek.skillhub.compat;
+/**
+ * Canonical namespace-and-slug pair used by compatibility adapters to address one skill.
+ */
public record SkillCoordinate(String namespace, String slug) {}
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/WellKnownController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/WellKnownController.java
index 4ddfb79d..bc505f49 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/WellKnownController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/WellKnownController.java
@@ -5,6 +5,9 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
+/**
+ * Serves well-known compatibility metadata used by external clients to discover the API base.
+ */
@RestController
public class WellKnownController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/dto/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/dto/package-info.java
new file mode 100644
index 00000000..6b9d1a59
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/dto/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * DTOs dedicated to compatibility controllers so legacy response contracts do
+ * not leak into the primary application API surface.
+ */
+package com.iflytek.skillhub.compat.dto;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/package-info.java
new file mode 100644
index 00000000..3b2ae1cb
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/compat/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Compatibility endpoints and helpers that expose SkillHub data using
+ * conventions expected by external or legacy clients.
+ */
+package com.iflytek.skillhub.compat;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/AsyncConfig.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/AsyncConfig.java
index b7b9086e..8e921cd4 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/AsyncConfig.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/AsyncConfig.java
@@ -8,6 +8,10 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
+/**
+ * Enables asynchronous event handling and other background execution features used by the
+ * application module.
+ */
@Configuration
@EnableAsync
public class AsyncConfig {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/DomainBeanConfig.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/DomainBeanConfig.java
index 78fa6199..7b36265f 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/DomainBeanConfig.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/DomainBeanConfig.java
@@ -8,6 +8,10 @@ import org.springframework.context.annotation.Configuration;
import java.time.Clock;
+/**
+ * Wires application-level Spring beans that adapt configurable infrastructure into domain-facing
+ * ports.
+ */
@Configuration
public class DomainBeanConfig {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/OpenApiConfig.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/OpenApiConfig.java
index 214f7322..c285b676 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/OpenApiConfig.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/OpenApiConfig.java
@@ -8,6 +8,9 @@ import org.springframework.context.annotation.Configuration;
import java.util.List;
+/**
+ * OpenAPI metadata configuration for generated API documentation.
+ */
@Configuration
public class OpenApiConfig {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/WebMvcRateLimitConfig.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/WebMvcRateLimitConfig.java
index ca84cebd..0a7bfd93 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/WebMvcRateLimitConfig.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/WebMvcRateLimitConfig.java
@@ -5,6 +5,9 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+/**
+ * Registers MVC interceptors related to request rate limiting.
+ */
@Configuration
public class WebMvcRateLimitConfig implements WebMvcConfigurer {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/package-info.java
new file mode 100644
index 00000000..2a70c248
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/config/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Spring configuration properties and lightweight application wiring for the
+ * web layer.
+ */
+package com.iflytek.skillhub.config;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/AccountMergeController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/AccountMergeController.java
index 7e812f96..b7e1386e 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/AccountMergeController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/AccountMergeController.java
@@ -16,6 +16,10 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * Endpoints for initiating, verifying, and confirming account merge flows
+ * across multiple identities owned by the same user.
+ */
@RestController
@RequestMapping("/api/v1/account/merge")
public class AccountMergeController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/AuthController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/AuthController.java
index 76b62a92..1552f6f2 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/AuthController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/AuthController.java
@@ -38,6 +38,13 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+/**
+ * Authentication-facing HTTP endpoints.
+ *
+ *
This controller keeps transport concerns at the boundary and delegates the
+ * actual authentication, session bootstrap, and direct-login workflows to
+ * dedicated application or auth services.
+ */
@RestController
@RequestMapping("/api/v1/auth")
public class AuthController extends BaseApiController {
@@ -68,6 +75,10 @@ public class AuthController extends BaseApiController {
this.userAccountRepository = userAccountRepository;
}
+ /**
+ * Returns the current authenticated principal and refreshes the session if
+ * the persisted user state has diverged from the in-session snapshot.
+ */
@GetMapping("/me")
public ApiResponse me(@AuthenticationPrincipal PlatformPrincipal principal,
Authentication authentication,
@@ -103,18 +114,32 @@ public class AuthController extends BaseApiController {
return ok("response.success.read", AuthMeResponse.from(principal));
}
+ /**
+ * Lists browser-based authentication providers that can initiate an OAuth
+ * login flow for the current client.
+ */
@GetMapping("/providers")
public ApiResponse> providers(
@RequestParam(name = "returnTo", required = false) String returnTo) {
return ok("response.success.read", authMethodCatalog.listOAuthProviders(returnTo));
}
+ /**
+ * Lists all authentication methods exposed to the UI, including direct and
+ * OAuth-based flows.
+ */
@GetMapping("/methods")
public ApiResponse> methods(
@RequestParam(name = "returnTo", required = false) String returnTo) {
return ok("response.success.read", authMethodCatalog.listMethods(returnTo));
}
+ /**
+ * Rebuilds an authenticated session from an upstream identity assertion.
+ *
+ * This endpoint is used by trusted frontends or gateway flows that have
+ * already authenticated the user elsewhere.
+ */
@PostMapping("/session/bootstrap")
@RateLimit(category = "auth-session-bootstrap", authenticated = 30, anonymous = 15, windowSeconds = 60)
public ApiResponse bootstrapSession(@Valid @RequestBody SessionBootstrapRequest request,
@@ -125,6 +150,10 @@ public class AuthController extends BaseApiController {
);
}
+ /**
+ * Executes a direct-login flow and establishes a first-party web session on
+ * success.
+ */
@PostMapping("/direct/login")
@RateLimit(category = "auth-direct-login", authenticated = 20, anonymous = 10, windowSeconds = 60)
public ApiResponse directLogin(@Valid @RequestBody DirectLoginRequest request,
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/BaseApiController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/BaseApiController.java
index 51a49de7..62adb567 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/BaseApiController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/BaseApiController.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.controller;
import com.iflytek.skillhub.dto.ApiResponse;
import com.iflytek.skillhub.dto.ApiResponseFactory;
+/**
+ * Minimal controller base class that centralizes access to the standard API response factory.
+ */
public abstract class BaseApiController {
private final ApiResponseFactory responseFactory;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/DeviceAuthController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/DeviceAuthController.java
index 02f7d311..1913723c 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/DeviceAuthController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/DeviceAuthController.java
@@ -10,6 +10,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * API endpoints for the CLI-style device authorization flow.
+ */
@RestController
@RequestMapping("/api/v1/auth/device")
public class DeviceAuthController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/DeviceAuthWebController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/DeviceAuthWebController.java
index aec99cf1..c2f47d4c 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/DeviceAuthWebController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/DeviceAuthWebController.java
@@ -14,6 +14,10 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * Browser-side endpoint that lets an authenticated user authorize a pending
+ * device code and records the operation in the audit log.
+ */
@RestController
@RequestMapping("/api/v1/device")
public class DeviceAuthWebController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/HealthController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/HealthController.java
index 5d3bf3a1..f1d0d7c0 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/HealthController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/HealthController.java
@@ -7,6 +7,9 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * Minimal liveness endpoint used by tests, probes, and basic uptime checks.
+ */
@RestController
@RequestMapping("/api/v1")
public class HealthController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/LocalAuthController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/LocalAuthController.java
index daea30e0..8d6f5e4f 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/LocalAuthController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/LocalAuthController.java
@@ -23,6 +23,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * HTTP endpoints for local account registration, login, and password changes.
+ */
@RestController
@RequestMapping("/api/v1/auth/local")
public class LocalAuthController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/TokenController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/TokenController.java
index 673f3544..19115087 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/TokenController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/TokenController.java
@@ -19,6 +19,9 @@ import org.springframework.web.bind.annotation.*;
import java.time.Instant;
import java.util.List;
+/**
+ * Self-service API token management endpoints for authenticated users.
+ */
@RestController
@RequestMapping("/api/v1/tokens")
public class TokenController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AdminSkillController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AdminSkillController.java
index 708cfdb8..077538a9 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AdminSkillController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AdminSkillController.java
@@ -16,6 +16,10 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * Administrative skill-governance endpoints reserved for platform-level
+ * moderation actions such as hide and unhide.
+ */
@RestController
@RequestMapping("/api/v1/admin/skills")
public class AdminSkillController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AdminSkillReportController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AdminSkillReportController.java
index 232ed8c0..e779615d 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AdminSkillReportController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AdminSkillReportController.java
@@ -23,6 +23,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * Administrative endpoints for reviewing and resolving user-submitted skill
+ * reports.
+ */
@RestController
@RequestMapping("/api/v1/admin/skill-reports")
public class AdminSkillReportController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AuditLogController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AuditLogController.java
index 2616ea7e..ed8dc624 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AuditLogController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/AuditLogController.java
@@ -11,6 +11,9 @@ import org.springframework.web.bind.annotation.*;
import java.time.Instant;
+/**
+ * Read-only audit log endpoints for auditors and super administrators.
+ */
@RestController
@RequestMapping("/api/v1/admin/audit-logs")
public class AuditLogController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/UserManagementController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/UserManagementController.java
index 850ecc26..efaf7647 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/UserManagementController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/UserManagementController.java
@@ -15,6 +15,10 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
+/**
+ * Administrative endpoints for listing users and mutating user roles or
+ * account status.
+ */
@RestController
@RequestMapping("/api/v1/admin/users")
public class UserManagementController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/package-info.java
new file mode 100644
index 00000000..9b9ca139
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/admin/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Administrative controllers that expose platform-level management operations
+ * such as audit access, moderation, and user governance.
+ */
+package com.iflytek.skillhub.controller.admin;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/package-info.java
new file mode 100644
index 00000000..3662e031
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * HTTP controllers for authentication, profile management, and public API
+ * endpoints that do not belong to a more specialized sub-area.
+ */
+package com.iflytek.skillhub.controller;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/GovernanceController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/GovernanceController.java
index e14e4ea7..591371e5 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/GovernanceController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/GovernanceController.java
@@ -23,6 +23,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * Portal endpoints that expose governance dashboards, inbox items, activity,
+ * and user-facing governance notifications.
+ */
@RestController
@RequestMapping({"/api/v1/governance", "/api/web/governance"})
public class GovernanceController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/MeController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/MeController.java
index dd94be4b..a9d7926f 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/MeController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/MeController.java
@@ -14,6 +14,10 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * Portal endpoints scoped to the current authenticated user, such as owned and
+ * starred skill listings.
+ */
@RestController
@RequestMapping({"/api/v1/me", "/api/web/me"})
public class MeController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/NamespaceController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/NamespaceController.java
index 52f14913..84e2d297 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/NamespaceController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/NamespaceController.java
@@ -18,6 +18,10 @@ import java.util.Comparator;
import java.util.List;
import java.util.Map;
+/**
+ * Namespace portal endpoints for discovery, membership management, and
+ * namespace governance operations.
+ */
@RestController
@RequestMapping({"/api/v1", "/api/web"})
public class NamespaceController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/PromotionController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/PromotionController.java
index 5617f21c..e86f7dbf 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/PromotionController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/PromotionController.java
@@ -40,6 +40,10 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import java.util.Set;
+/**
+ * Promotion workflow endpoints that expose submission, review, and query
+ * operations for cross-namespace promotion requests.
+ */
@RestController
@RequestMapping({"/api/v1/promotions", "/api/web/promotions"})
public class PromotionController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/ReviewController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/ReviewController.java
index 54a9ca7d..9eaf1dc8 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/ReviewController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/ReviewController.java
@@ -41,6 +41,10 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import java.util.Set;
+/**
+ * Endpoints for submitting, browsing, approving, rejecting, and withdrawing
+ * review tasks.
+ */
@RestController
@RequestMapping({"/api/v1/reviews", "/api/web/reviews"})
public class ReviewController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillController.java
index 217804f3..3c0f87b8 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillController.java
@@ -34,6 +34,10 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
+/**
+ * Read-oriented skill endpoints for detail pages, lifecycle inspection, file
+ * browsing, version resolution, and download delivery.
+ */
@RestController
@RequestMapping({"/api/v1/skills", "/api/web/skills"})
public class SkillController extends BaseApiController {
@@ -53,6 +57,10 @@ public class SkillController extends BaseApiController {
this.metrics = metrics;
}
+ /**
+ * Returns the viewer-specific projection of a skill, including lifecycle
+ * pointers and interaction permissions derived from the caller context.
+ */
@GetMapping("/{namespace}/{slug}")
public ApiResponse getSkillDetail(
@PathVariable String namespace,
@@ -90,6 +98,10 @@ public class SkillController extends BaseApiController {
return ok("response.success.read", response);
}
+ /**
+ * Lists versions visible to the caller rather than every persisted version
+ * of the skill.
+ */
@GetMapping("/{namespace}/{slug}/versions")
public ApiResponse> listVersions(
@PathVariable String namespace,
@@ -120,6 +132,10 @@ public class SkillController extends BaseApiController {
return ok("response.success.read", response);
}
+ /**
+ * Returns metadata for a concrete version that the current caller is
+ * allowed to inspect.
+ */
@GetMapping("/{namespace}/{slug}/versions/{version}")
public ApiResponse getVersionDetail(
@PathVariable String namespace,
@@ -150,6 +166,10 @@ public class SkillController extends BaseApiController {
return ok("response.success.read", response);
}
+ /**
+ * Lists packaged files for a concrete version after visibility checks have
+ * been applied.
+ */
@GetMapping("/{namespace}/{slug}/versions/{version}/files")
public ApiResponse> listFiles(
@PathVariable String namespace,
@@ -208,6 +228,10 @@ public class SkillController extends BaseApiController {
return ok("response.success.read", response);
}
+ /**
+ * Streams a single packaged file directly from object storage through the
+ * application API.
+ */
@GetMapping("/{namespace}/{slug}/versions/{version}/file")
public ResponseEntity getFileContent(
@PathVariable String namespace,
@@ -254,6 +278,10 @@ public class SkillController extends BaseApiController {
.body(new InputStreamResource(content));
}
+ /**
+ * Resolves a human-facing version selector to the exact version that would
+ * be downloaded by the caller.
+ */
@GetMapping("/{namespace}/{slug}/resolve")
public ApiResponse resolveVersion(
@PathVariable String namespace,
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillLifecycleController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillLifecycleController.java
index adcc8224..5bee8282 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillLifecycleController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillLifecycleController.java
@@ -29,6 +29,10 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * Endpoints that mutate skill lifecycle state, including archive, unarchive,
+ * withdraw-review, delete-version, and rerelease operations.
+ */
@RestController
@RequestMapping({"/api/v1/skills", "/api/web/skills"})
public class SkillLifecycleController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillPublishController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillPublishController.java
index ced3ec4d..c853ca32 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillPublishController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillPublishController.java
@@ -19,6 +19,12 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
+/**
+ * Upload endpoints for skill packages.
+ *
+ * The controller is responsible for archive extraction and request shaping,
+ * while the domain service owns all publication validation and state changes.
+ */
@RestController
@RequestMapping({"/api/v1/skills", "/api/web/skills"})
public class SkillPublishController extends BaseApiController {
@@ -37,6 +43,10 @@ public class SkillPublishController extends BaseApiController {
this.skillHubMetrics = skillHubMetrics;
}
+ /**
+ * Publishes an uploaded package into the target namespace after archive
+ * extraction and visibility parsing.
+ */
@PostMapping("/{namespace}/publish")
@RateLimit(category = "publish", authenticated = 10, anonymous = 0)
public ApiResponse publish(
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillRatingController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillRatingController.java
index 88a48ca6..8ad74f97 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillRatingController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillRatingController.java
@@ -12,6 +12,9 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
+/**
+ * Endpoints for reading and mutating the current user's rating on a skill.
+ */
@RestController
@RequestMapping({"/api/v1/skills", "/api/web/skills"})
public class SkillRatingController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillReportController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillReportController.java
index c6180ef6..740bb890 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillReportController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillReportController.java
@@ -19,6 +19,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * Endpoints that let authenticated users report a skill for moderation.
+ */
@RestController
@RequestMapping({"/api/v1/skills", "/api/web/skills"})
public class SkillReportController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillSearchController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillSearchController.java
index a3786170..4f99473a 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillSearchController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillSearchController.java
@@ -11,6 +11,10 @@ import org.springframework.web.bind.annotation.*;
import java.util.Map;
+/**
+ * Portal search endpoint that adapts HTTP query parameters to the search
+ * application service and visibility scope.
+ */
@RestController
@RequestMapping({"/api/web/skills"})
public class SkillSearchController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillStarController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillStarController.java
index 8ffb88a9..5d95837e 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillStarController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillStarController.java
@@ -8,6 +8,9 @@ import com.iflytek.skillhub.domain.social.SkillStarService;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
+/**
+ * Endpoints for starring, unstarring, and checking star state on a skill.
+ */
@RestController
@RequestMapping({"/api/v1/skills", "/api/web/skills"})
public class SkillStarController extends BaseApiController {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillTagController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillTagController.java
index 1edd7036..6389ffa8 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillTagController.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/SkillTagController.java
@@ -16,6 +16,9 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
+/**
+ * Endpoints for reading and mutating named tags that point to skill versions.
+ */
@RestController
@RequestMapping({
"/api/v1/skills/{namespace}/{slug}/tags",
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/package-info.java
new file mode 100644
index 00000000..be4a56e5
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/portal/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Primary portal-facing API controllers for namespaces, skills, review flows,
+ * search, and other end-user operations.
+ */
+package com.iflytek.skillhub.controller.portal;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/MultipartPackageExtractor.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/MultipartPackageExtractor.java
index d7edec9b..6e3e6a1c 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/MultipartPackageExtractor.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/MultipartPackageExtractor.java
@@ -14,6 +14,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+/**
+ * Builds a publishable package model from multipart form uploads while enforcing package safety
+ * and size constraints.
+ */
@Component
public class MultipartPackageExtractor {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/ZipPackageExtractor.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/ZipPackageExtractor.java
index 5d3a7a80..2beaec70 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/ZipPackageExtractor.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/ZipPackageExtractor.java
@@ -17,6 +17,9 @@ import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
+/**
+ * Extracts zip uploads into validated package entries that can be consumed by the publish flow.
+ */
@Component
public class ZipPackageExtractor {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/package-info.java
new file mode 100644
index 00000000..72a03d65
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/support/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Controller support utilities for multipart parsing, archive extraction, and
+ * other transport-specific request preparation concerns.
+ */
+package com.iflytek.skillhub.controller.support;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/dto/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/dto/package-info.java
new file mode 100644
index 00000000..c7ef261f
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/dto/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Application DTOs used to keep HTTP request and response contracts separate
+ * from domain entities.
+ */
+package com.iflytek.skillhub.dto;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/BadRequestException.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/BadRequestException.java
index eef266bc..63f0c0aa 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/BadRequestException.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/BadRequestException.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.exception;
import org.springframework.http.HttpStatus;
+/**
+ * Application-layer exception mapped to HTTP 400 with a localized error code.
+ */
public class BadRequestException extends LocalizedException {
public BadRequestException(String messageCode, Object... messageArgs) {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/ForbiddenException.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/ForbiddenException.java
index 6c60cb10..77a97b45 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/ForbiddenException.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/ForbiddenException.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.exception;
import org.springframework.http.HttpStatus;
+/**
+ * Application-layer exception mapped to HTTP 403 with a localized error code.
+ */
public class ForbiddenException extends LocalizedException {
public ForbiddenException(String messageCode, Object... messageArgs) {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/GlobalExceptionHandler.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/GlobalExceptionHandler.java
index ebf0f43c..9e40abfd 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/GlobalExceptionHandler.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/GlobalExceptionHandler.java
@@ -23,6 +23,10 @@ import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
+/**
+ * Translates application, domain, auth, and infrastructure exceptions into the platform's JSON API
+ * error envelope.
+ */
@RestControllerAdvice
public class GlobalExceptionHandler {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/LocalizedError.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/LocalizedError.java
index 54622ed3..da494d0b 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/LocalizedError.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/LocalizedError.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.exception;
import org.springframework.http.HttpStatus;
+/**
+ * Common contract for errors that can be rendered as localized API responses.
+ */
public interface LocalizedError {
String messageCode();
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/LocalizedException.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/LocalizedException.java
index 5d41abe5..fe852f82 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/LocalizedException.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/LocalizedException.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.exception;
import org.springframework.http.HttpStatus;
+/**
+ * Base class for application-layer exceptions that carry a localized message code and HTTP status.
+ */
public abstract class LocalizedException extends RuntimeException implements LocalizedError {
private final String messageCode;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/UnauthorizedException.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/UnauthorizedException.java
index 7be50e3b..2efade6b 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/UnauthorizedException.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/UnauthorizedException.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.exception;
import org.springframework.http.HttpStatus;
+/**
+ * Application-layer exception mapped to HTTP 401 with a localized error code.
+ */
public class UnauthorizedException extends LocalizedException {
public UnauthorizedException(String messageCode, Object... messageArgs) {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/package-info.java
new file mode 100644
index 00000000..0ba38d23
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/exception/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Application-level exception translation and localized error payload support
+ * for the HTTP boundary.
+ */
+package com.iflytek.skillhub.exception;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/AuthContextFilter.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/AuthContextFilter.java
index 0338be30..8c776c77 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/AuthContextFilter.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/AuthContextFilter.java
@@ -23,6 +23,9 @@ import org.springframework.security.web.context.HttpSessionSecurityContextReposi
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
+/**
+ * Projects the authenticated principal into request attributes consumed by the controller layer.
+ */
@Component
public class AuthContextFilter extends OncePerRequestFilter {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/IdempotencyInterceptor.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/IdempotencyInterceptor.java
index e9780f46..9a950d60 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/IdempotencyInterceptor.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/IdempotencyInterceptor.java
@@ -16,6 +16,13 @@ import java.time.Instant;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
+/**
+ * Prevents duplicate execution of mutating HTTP requests identified by
+ * {@code X-Request-Id}.
+ *
+ * Redis is treated as the fast-path cache, while PostgreSQL remains the
+ * durable source of truth when cache access fails.
+ */
@Component
public class IdempotencyInterceptor implements HandlerInterceptor {
@@ -38,6 +45,10 @@ public class IdempotencyInterceptor implements HandlerInterceptor {
this.clock = clock;
}
+ /**
+ * Rejects duplicate mutating requests before controller execution and
+ * creates a processing marker for first-seen request identifiers.
+ */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String method = request.getMethod();
@@ -94,6 +105,10 @@ public class IdempotencyInterceptor implements HandlerInterceptor {
return true;
}
+ /**
+ * Finalizes the idempotency record with the observed response status once
+ * request processing has completed.
+ */
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
String method = request.getMethod();
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/RequestIdFilter.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/RequestIdFilter.java
index e9dc6422..cc5c0932 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/RequestIdFilter.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/RequestIdFilter.java
@@ -13,6 +13,10 @@ import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.UUID;
+/**
+ * Ensures every request has a request identifier for logs, responses, and downstream audit
+ * correlation.
+ */
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestIdFilter extends OncePerRequestFilter {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/RequestLoggingFilter.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/RequestLoggingFilter.java
index 7783f3c3..7ea50453 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/RequestLoggingFilter.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/RequestLoggingFilter.java
@@ -19,6 +19,9 @@ import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
+/**
+ * Logs inbound HTTP requests and responses with truncation suitable for operational debugging.
+ */
@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
public class RequestLoggingFilter extends OncePerRequestFilter {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/package-info.java
new file mode 100644
index 00000000..4fec52ef
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/filter/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Servlet filters and MVC interceptors that enrich requests with cross-cutting
+ * concerns such as logging, idempotency, and caller context.
+ */
+package com.iflytek.skillhub.filter;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/SkillRatingEventListener.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/SkillRatingEventListener.java
index eeef6e7e..2c536c74 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/SkillRatingEventListener.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/SkillRatingEventListener.java
@@ -7,6 +7,10 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;
+/**
+ * Updates denormalized skill rating counters when rating events are emitted by
+ * the social domain.
+ */
@Component
public class SkillRatingEventListener {
private final JdbcTemplate jdbcTemplate;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/SkillStarEventListener.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/SkillStarEventListener.java
index 903041f2..d0e13477 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/SkillStarEventListener.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/SkillStarEventListener.java
@@ -8,6 +8,9 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;
+/**
+ * Keeps the stored star count in sync with the star/unstar event stream.
+ */
@Component
public class SkillStarEventListener {
private final JdbcTemplate jdbcTemplate;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/package-info.java
new file mode 100644
index 00000000..911675c6
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Application event listeners that react to domain events to update read-side
+ * counters and other eventually consistent projections.
+ */
+package com.iflytek.skillhub.listener;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/metrics/SkillHubMetrics.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/metrics/SkillHubMetrics.java
index ab9714fc..abbd05dd 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/metrics/SkillHubMetrics.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/metrics/SkillHubMetrics.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.metrics;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Component;
+/**
+ * Small facade over Micrometer that centralizes metric names and tags used by backend flows.
+ */
@Component
public class SkillHubMetrics {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/metrics/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/metrics/package-info.java
new file mode 100644
index 00000000..a9c95b62
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/metrics/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Metrics helpers used to publish application and product telemetry from the
+ * web layer.
+ */
+package com.iflytek.skillhub.metrics;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/package-info.java
new file mode 100644
index 00000000..682c3f9e
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Application-layer orchestration for the SkillHub backend.
+ *
+ *
This module adapts HTTP requests, security context, and DTO mapping to the
+ * domain-layer services exposed by the other backend modules.
+ */
+package com.iflytek.skillhub;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/AnonymousDownloadIdentityService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/AnonymousDownloadIdentityService.java
index dee29900..f6ff6dff 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/AnonymousDownloadIdentityService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/AnonymousDownloadIdentityService.java
@@ -16,6 +16,10 @@ import javax.crypto.spec.SecretKeySpec;
import org.springframework.http.ResponseCookie;
import org.springframework.stereotype.Component;
+/**
+ * Assigns stable anonymous identities for download rate limiting by combining client IP data with
+ * a signed cookie.
+ */
@Component
public class AnonymousDownloadIdentityService {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/ClientIpResolver.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/ClientIpResolver.java
index 816b6e3c..c37ade23 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/ClientIpResolver.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/ClientIpResolver.java
@@ -5,6 +5,9 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.stereotype.Component;
+/**
+ * Resolves the best-effort client IP address from proxy-aware request headers.
+ */
@Component
public class ClientIpResolver {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/InMemorySlidingWindowRateLimiter.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/InMemorySlidingWindowRateLimiter.java
index 89f8be79..27dc4be8 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/InMemorySlidingWindowRateLimiter.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/InMemorySlidingWindowRateLimiter.java
@@ -7,6 +7,9 @@ import java.util.Deque;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
+/**
+ * Test-profile rate limiter that keeps sliding-window counters in memory.
+ */
@Component
@Profile("test")
public class InMemorySlidingWindowRateLimiter implements RateLimiter {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimit.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimit.java
index 1800ab83..5a187fd4 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimit.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimit.java
@@ -5,6 +5,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+/**
+ * Declares per-endpoint rate-limit settings for authenticated and anonymous callers.
+ */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimitInterceptor.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimitInterceptor.java
index 8aa5be3d..da421b5d 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimitInterceptor.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimitInterceptor.java
@@ -15,6 +15,10 @@ import org.springframework.web.servlet.HandlerMapping;
import java.util.Map;
+/**
+ * Enforces the {@link RateLimit} annotation by resolving caller identity and delegating quota
+ * checks to the configured rate limiter implementation.
+ */
@Component
public class RateLimitInterceptor implements HandlerInterceptor {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimiter.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimiter.java
index 0d003ab3..7471dc2f 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimiter.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RateLimiter.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.ratelimit;
+/**
+ * Contract for key-based rate limiter implementations used by API interceptors.
+ */
public interface RateLimiter {
boolean tryAcquire(String key, int limit, int windowSeconds);
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RedisSlidingWindowRateLimiter.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RedisSlidingWindowRateLimiter.java
index 7117b9bc..fe33dbfe 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RedisSlidingWindowRateLimiter.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/RedisSlidingWindowRateLimiter.java
@@ -10,6 +10,9 @@ import org.springframework.stereotype.Component;
import java.util.Collections;
+/**
+ * Production rate limiter backed by Redis and a Lua script for atomic sliding-window checks.
+ */
@Component
@Profile("!test")
public class RedisSlidingWindowRateLimiter implements RateLimiter {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/package-info.java
new file mode 100644
index 00000000..48bcbc09
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/ratelimit/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Rate-limiting annotations, interceptors, and implementations used to
+ * protect public APIs from abuse.
+ */
+package com.iflytek.skillhub.ratelimit;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/repository/AdminUserSearchRepository.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/repository/AdminUserSearchRepository.java
index c68bb7ed..fa5a0b16 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/repository/AdminUserSearchRepository.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/repository/AdminUserSearchRepository.java
@@ -18,6 +18,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+/**
+ * Custom query repository that builds pageable admin-user search results with optional filters.
+ */
@Repository
public class AdminUserSearchRepository {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/repository/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/repository/package-info.java
new file mode 100644
index 00000000..eba218ab
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/repository/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Application-specific query repositories that package read models tailored to
+ * web and administration use cases.
+ */
+package com.iflytek.skillhub.repository;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/ApiAccessDeniedHandler.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/ApiAccessDeniedHandler.java
index 44a7c626..81cebbde 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/ApiAccessDeniedHandler.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/ApiAccessDeniedHandler.java
@@ -15,6 +15,9 @@ import org.springframework.stereotype.Component;
import java.io.IOException;
+/**
+ * Converts authorization failures on API routes into the platform's standard JSON error envelope.
+ */
@Component
public class ApiAccessDeniedHandler implements AccessDeniedHandler {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/ApiAuthenticationEntryPoint.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/ApiAuthenticationEntryPoint.java
index 2611d3bf..8f5de8d2 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/ApiAuthenticationEntryPoint.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/ApiAuthenticationEntryPoint.java
@@ -15,6 +15,9 @@ import org.springframework.stereotype.Component;
import java.io.IOException;
+/**
+ * Converts unauthenticated API access attempts into a consistent JSON 401 response.
+ */
@Component
public class ApiAuthenticationEntryPoint implements AuthenticationEntryPoint {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/AuthFailureThrottleService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/AuthFailureThrottleService.java
index 19997a4b..7b76875c 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/AuthFailureThrottleService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/AuthFailureThrottleService.java
@@ -8,6 +8,9 @@ import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
+/**
+ * Tracks repeated authentication failures and throttles abusive identifiers or client addresses.
+ */
@Service
public class AuthFailureThrottleService {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/SensitiveLogSanitizer.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/SensitiveLogSanitizer.java
index 9b7efe73..ce38aea7 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/SensitiveLogSanitizer.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/SensitiveLogSanitizer.java
@@ -8,6 +8,9 @@ import java.util.stream.Collectors;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
+/**
+ * Applies lightweight redaction rules before sensitive strings are written to logs.
+ */
@Component
public class SensitiveLogSanitizer {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/package-info.java
new file mode 100644
index 00000000..5acb71e1
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/security/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Web security helpers that translate authorization failures, sanitize logs,
+ * and coordinate security-specific application behavior.
+ */
+package com.iflytek.skillhub.security;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminAuditLogAppService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminAuditLogAppService.java
index b811e9d7..f6dd7865 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminAuditLogAppService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminAuditLogAppService.java
@@ -13,6 +13,10 @@ import java.time.Instant;
import java.util.Collection;
import java.util.List;
+/**
+ * Read-only application service that queries audit logs with dynamic filtering
+ * tailored to administration screens.
+ */
@Service
public class AdminAuditLogAppService {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminSkillReportAppService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminSkillReportAppService.java
index fe807e4f..8670af6b 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminSkillReportAppService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminSkillReportAppService.java
@@ -17,6 +17,10 @@ import java.util.stream.Collectors;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
+/**
+ * Application service that enriches raw skill report records with skill and
+ * namespace context required by admin UIs.
+ */
@Service
public class AdminSkillReportAppService {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminUserAppService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminUserAppService.java
index 7b649576..656cefa0 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminUserAppService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminUserAppService.java
@@ -29,6 +29,10 @@ import java.util.TreeSet;
import java.util.Set;
import java.util.stream.Collectors;
+/**
+ * Administrative user-management application service built around the main
+ * search and mutation use cases exposed by the admin API.
+ */
@Service
public class AdminUserAppService {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminUserManagementService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminUserManagementService.java
index fe7133f7..6109efeb 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminUserManagementService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AdminUserManagementService.java
@@ -24,6 +24,10 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * Alternative user-management aggregation service that combines user records
+ * with role bindings for management-oriented views.
+ */
@Service
public class AdminUserManagementService {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AuthMethodCatalog.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AuthMethodCatalog.java
index 3e1f53c8..84324f18 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AuthMethodCatalog.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AuthMethodCatalog.java
@@ -15,6 +15,10 @@ import java.util.List;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
import org.springframework.stereotype.Service;
+/**
+ * Builds the catalog of authentication methods and OAuth providers that the UI
+ * can render dynamically.
+ */
@Service
public class AuthMethodCatalog {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/DirectAuthService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/DirectAuthService.java
index 3eb85795..caf62901 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/DirectAuthService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/DirectAuthService.java
@@ -12,6 +12,10 @@ import java.util.Map;
import java.util.function.Function;
import org.springframework.stereotype.Service;
+/**
+ * Dispatches direct-login requests to a configured provider and then binds the
+ * resulting principal to the current HTTP session.
+ */
@Service
public class DirectAuthService {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/GovernanceWorkbenchAppService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/GovernanceWorkbenchAppService.java
index f11983dc..08a5e5a6 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/GovernanceWorkbenchAppService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/GovernanceWorkbenchAppService.java
@@ -30,6 +30,12 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
+/**
+ * Application-facing aggregation service for the governance workbench.
+ *
+ *
It joins review, promotion, report, namespace, and audit sources into the
+ * composite read models consumed by governance screens.
+ */
@Service
public class GovernanceWorkbenchAppService {
@@ -75,6 +81,10 @@ public class GovernanceWorkbenchAppService {
this.adminAuditLogAppService = adminAuditLogAppService;
}
+ /**
+ * Returns top-level counts for the governance dashboard, scoped by the
+ * caller's namespace and platform roles.
+ */
public GovernanceSummaryResponse getSummary(String userId,
Map namespaceRoles,
Set platformRoles) {
@@ -89,6 +99,10 @@ public class GovernanceWorkbenchAppService {
);
}
+ /**
+ * Builds the governance inbox by combining pending reviews, promotions, and
+ * reports that the caller is allowed to see.
+ */
public PageResponse listInbox(String userId,
Map namespaceRoles,
Set platformRoles,
@@ -121,6 +135,10 @@ public class GovernanceWorkbenchAppService {
return new PageResponse<>(items.subList(fromIndex, toIndex), items.size(), page, size);
}
+ /**
+ * Returns audit-derived governance activity entries for callers with
+ * platform-wide visibility.
+ */
public PageResponse listActivity(Set platformRoles, int page, int size) {
if (!canReadActivity(platformRoles)) {
return new PageResponse<>(List.of(), 0, page, size);
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/MySkillAppService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/MySkillAppService.java
index 00183e97..98407e53 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/MySkillAppService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/MySkillAppService.java
@@ -25,6 +25,10 @@ import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
+/**
+ * Application service that assembles the current user's owned and starred
+ * skill lists with lifecycle context.
+ */
@Service
public class MySkillAppService {
private final SkillRepository skillRepository;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/NamespaceMemberCandidateService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/NamespaceMemberCandidateService.java
index 0401a7c8..34eb60f7 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/NamespaceMemberCandidateService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/NamespaceMemberCandidateService.java
@@ -19,6 +19,10 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+/**
+ * Finds candidate users that can be invited into a namespace while excluding
+ * existing members and immutable namespaces.
+ */
@Service
public class NamespaceMemberCandidateService {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/SessionBootstrapService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/SessionBootstrapService.java
index f24606fa..5a90e820 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/SessionBootstrapService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/SessionBootstrapService.java
@@ -13,6 +13,10 @@ import java.util.Map;
import java.util.function.Function;
import org.springframework.stereotype.Service;
+/**
+ * Restores a platform session from a passive authenticator and persists the
+ * resulting principal into Spring Security's session context.
+ */
@Service
public class SessionBootstrapService {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/SkillSearchAppService.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/SkillSearchAppService.java
index 13a01261..05d3cab3 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/SkillSearchAppService.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/SkillSearchAppService.java
@@ -23,6 +23,10 @@ import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
+/**
+ * Application service that adapts search queries to the search backend and
+ * enriches results with authoritative skill metadata and viewer permissions.
+ */
@Service
public class SkillSearchAppService {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/package-info.java
new file mode 100644
index 00000000..6dd561ce
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Application services that aggregate multiple domain services or repositories
+ * for controller-friendly use cases.
+ */
+package com.iflytek.skillhub.service;
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/task/IdempotencyCleanupTask.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/task/IdempotencyCleanupTask.java
index 935ad253..ea40dfee 100644
--- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/task/IdempotencyCleanupTask.java
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/task/IdempotencyCleanupTask.java
@@ -10,6 +10,10 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.Clock;
import java.time.Instant;
+/**
+ * Periodic maintenance task that expires old idempotency records and marks stale processing
+ * entries as failed.
+ */
@Component
public class IdempotencyCleanupTask {
diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/task/package-info.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/task/package-info.java
new file mode 100644
index 00000000..dc5670e6
--- /dev/null
+++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/task/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Scheduled background tasks that maintain read models and operational data.
+ */
+package com.iflytek.skillhub.task;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/bootstrap/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/bootstrap/package-info.java
new file mode 100644
index 00000000..85f528ac
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/bootstrap/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Authentication bootstrap helpers that restore session state from existing
+ * request context without forcing an explicit login step.
+ */
+package com.iflytek.skillhub.auth.bootstrap;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/RedisTemplateConfig.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/RedisTemplateConfig.java
index 74ea5215..aa36954f 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/RedisTemplateConfig.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/RedisTemplateConfig.java
@@ -9,6 +9,9 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
+/**
+ * Provides the shared Redis template used by authentication and other cross-cutting services.
+ */
@Configuration
public class RedisTemplateConfig {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java
index 664e9ba4..6958b6db 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java
@@ -29,6 +29,10 @@ import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWrite
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
+/**
+ * Central Spring Security configuration for browser sessions, API tokens, and
+ * public versus protected endpoints.
+ */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@@ -75,6 +79,13 @@ public class SecurityConfig {
this.mockAuthFilterProvider = mockAuthFilterProvider;
}
+ /**
+ * Builds the ordered security filter chain used by both browser and API
+ * clients.
+ *
+ * The chain mixes session-based authentication, bearer token support,
+ * CSRF rules for browser traffic, and method-level authorization.
+ */
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
var csrfHandler = new CsrfTokenRequestAttributeHandler();
@@ -210,6 +221,10 @@ public class SecurityConfig {
return http.build();
}
+ /**
+ * Provides the password encoder shared by local credentials and bootstrap
+ * flows.
+ */
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/package-info.java
new file mode 100644
index 00000000..acde246f
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Spring Security and infrastructure configuration for authentication and
+ * authorization concerns.
+ */
+package com.iflytek.skillhub.auth.config;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/DeviceAuthService.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/DeviceAuthService.java
index e9ac19a5..e838c9a8 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/DeviceAuthService.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/DeviceAuthService.java
@@ -11,6 +11,12 @@ import java.security.SecureRandom;
import java.util.Base64;
import java.util.concurrent.TimeUnit;
+/**
+ * Implements the device authorization flow used by CLI-style clients.
+ *
+ *
State is stored in Redis so the browser authorization step and token
+ * polling step can rendezvous without holding server-side session state.
+ */
@Service
public class DeviceAuthService {
@@ -38,6 +44,10 @@ public class DeviceAuthService {
this.verificationUri = verificationUri;
}
+ /**
+ * Starts a new device flow and returns both the polling token and the
+ * user-facing verification code.
+ */
public DeviceCodeResponse generateDeviceCode() {
String deviceCode = generateRandomDeviceCode();
String userCode = generateUserCode();
@@ -52,6 +62,9 @@ public class DeviceAuthService {
return new DeviceCodeResponse(deviceCode, userCode, verificationUri, EXPIRES_IN_SECONDS, POLL_INTERVAL_SECONDS);
}
+ /**
+ * Marks a user code as authorized by a concrete authenticated user.
+ */
public void authorizeDeviceCode(String userCode, String userId) {
String deviceCode = (String) redisTemplate.opsForValue().get(USER_CODE_PREFIX + userCode);
if (deviceCode == null) {
@@ -79,6 +92,10 @@ public class DeviceAuthService {
}
}
+ /**
+ * Polls the device code and either returns a pending response or redeems it
+ * into an API token exactly once.
+ */
public DeviceTokenResponse pollToken(String deviceCode) {
DeviceCodeData data = (DeviceCodeData) redisTemplate.opsForValue().get(DEVICE_CODE_PREFIX + deviceCode);
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/package-info.java
new file mode 100644
index 00000000..ca9aba63
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Device authorization flow support used by CLI and headless clients.
+ */
+package com.iflytek.skillhub.auth.device;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/direct/LocalDirectAuthProvider.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/direct/LocalDirectAuthProvider.java
index 181b85a3..f0406c99 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/direct/LocalDirectAuthProvider.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/direct/LocalDirectAuthProvider.java
@@ -4,6 +4,9 @@ import com.iflytek.skillhub.auth.local.LocalAuthService;
import com.iflytek.skillhub.auth.rbac.PlatformPrincipal;
import org.springframework.stereotype.Component;
+/**
+ * Direct-auth provider that delegates username and password verification to the local auth flow.
+ */
@Component
public class LocalDirectAuthProvider implements DirectAuthProvider {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/direct/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/direct/package-info.java
new file mode 100644
index 00000000..9905d8cb
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/direct/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Pluggable direct-login abstractions used by local or enterprise login
+ * experiences that bypass OAuth browser redirects.
+ */
+package com.iflytek.skillhub.auth.direct;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/entity/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/entity/package-info.java
new file mode 100644
index 00000000..3c85a796
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/entity/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Authentication and authorization persistence entities such as tokens,
+ * identity bindings, roles, and grants.
+ */
+package com.iflytek.skillhub.auth.entity;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/exception/AuthFlowException.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/exception/AuthFlowException.java
index b2127c80..4190ae7e 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/exception/AuthFlowException.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/exception/AuthFlowException.java
@@ -2,6 +2,10 @@ package com.iflytek.skillhub.auth.exception;
import org.springframework.http.HttpStatus;
+/**
+ * Auth-layer exception that carries both an HTTP status and a localized message code for API
+ * rendering.
+ */
public class AuthFlowException extends RuntimeException {
private final HttpStatus status;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/exception/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/exception/package-info.java
new file mode 100644
index 00000000..37aa599f
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/exception/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Exceptions that model expected authentication flow failures and map cleanly
+ * to HTTP responses.
+ */
+package com.iflytek.skillhub.auth.exception;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/IdentityBindingService.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/IdentityBindingService.java
index d716d4f3..2a4fae8b 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/IdentityBindingService.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/IdentityBindingService.java
@@ -16,6 +16,10 @@ import java.util.UUID;
import java.util.Set;
import java.util.stream.Collectors;
+/**
+ * Resolves external OAuth identities to platform users, creating or updating
+ * bindings and user records as needed.
+ */
@Service
public class IdentityBindingService {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/package-info.java
new file mode 100644
index 00000000..f9e7b72f
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/identity/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Services that manage the relationship between platform users and external
+ * identity-provider subjects.
+ */
+package com.iflytek.skillhub.auth.identity;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/LocalAuthService.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/LocalAuthService.java
index 4fd3fd99..9d378e25 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/LocalAuthService.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/LocalAuthService.java
@@ -21,6 +21,10 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * Handles username-and-password registration and login for first-party local
+ * accounts.
+ */
@Service
public class LocalAuthService {
@@ -57,6 +61,10 @@ public class LocalAuthService {
this.clock = clock;
}
+ /**
+ * Registers a new local user, creates the credential record, and ensures
+ * the user is enrolled in the global namespace.
+ */
@Transactional
public PlatformPrincipal register(String username, String password, String email) {
String normalizedUsername = normalizeUsername(username);
@@ -96,6 +104,10 @@ public class LocalAuthService {
return buildPrincipal(user);
}
+ /**
+ * Authenticates a local account and returns the principal snapshot used to
+ * establish a web session.
+ */
@Transactional
public PlatformPrincipal login(String username, String password) {
String normalizedUsername = normalizeUsername(username);
@@ -124,6 +136,9 @@ public class LocalAuthService {
return buildPrincipal(user);
}
+ /**
+ * Changes the stored password for an already authenticated local account.
+ */
@Transactional
public void changePassword(String userId, String currentPassword, String newPassword) {
LocalCredential credential = credentialRepository.findByUserId(userId)
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/LocalCredentialRepository.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/LocalCredentialRepository.java
index ffb65668..8346b9c2 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/LocalCredentialRepository.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/LocalCredentialRepository.java
@@ -4,6 +4,9 @@ import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
+/**
+ * JPA repository for username-password credentials linked to platform user accounts.
+ */
@Repository
public interface LocalCredentialRepository extends JpaRepository {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/PasswordPolicyValidator.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/PasswordPolicyValidator.java
index 1afcb86f..aca8baf3 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/PasswordPolicyValidator.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/PasswordPolicyValidator.java
@@ -4,6 +4,9 @@ import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
+/**
+ * Validates local-account passwords against the platform's length and character diversity rules.
+ */
@Component
public class PasswordPolicyValidator {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/package-info.java
new file mode 100644
index 00000000..7aa1200b
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/local/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Username-and-password authentication support, including registration,
+ * password changes, and local credential validation.
+ */
+package com.iflytek.skillhub.auth.local;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/AccountMergeRequestRepository.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/AccountMergeRequestRepository.java
index 8c98fb3c..8638cad5 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/AccountMergeRequestRepository.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/AccountMergeRequestRepository.java
@@ -4,6 +4,9 @@ import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
+/**
+ * JPA repository for pending account-merge requests between two platform identities.
+ */
@Repository
public interface AccountMergeRequestRepository extends JpaRepository {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/AccountMergeService.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/AccountMergeService.java
index 92368699..20fc4080 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/AccountMergeService.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/AccountMergeService.java
@@ -32,6 +32,10 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * Coordinates account merge requests and consolidates credentials, bindings,
+ * roles, memberships, and tokens into a single primary user.
+ */
@Service
public class AccountMergeService {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/package-info.java
new file mode 100644
index 00000000..61aea59e
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/merge/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Account-merge workflows for consolidating multiple authentication identities
+ * into a single platform user.
+ */
+package com.iflytek.skillhub.auth.merge;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/mock/MockAuthFilter.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/mock/MockAuthFilter.java
index a0ab03ae..8d42ed5a 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/mock/MockAuthFilter.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/mock/MockAuthFilter.java
@@ -21,6 +21,9 @@ import java.io.IOException;
import java.util.Set;
import java.util.stream.Collectors;
+/**
+ * Local-development filter that can establish a session for a requested mock user header.
+ */
@Component
@Profile("local")
@ConditionalOnProperty(name = "skillhub.auth.mock.enabled", havingValue = "true")
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/mock/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/mock/package-info.java
new file mode 100644
index 00000000..a2c9e502
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/mock/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Development-only authentication helpers that simulate authenticated callers
+ * in local environments.
+ */
+package com.iflytek.skillhub.auth.mock;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/AccountDisabledException.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/AccountDisabledException.java
index a2dd1b19..962165ec 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/AccountDisabledException.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/AccountDisabledException.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.auth.oauth;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
+/**
+ * OAuth authentication exception raised when the mapped platform account is disabled.
+ */
public class AccountDisabledException extends OAuth2AuthenticationException {
public AccountDisabledException() {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/AccountPendingException.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/AccountPendingException.java
index a5cbaac6..9a7ccef9 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/AccountPendingException.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/AccountPendingException.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.auth.oauth;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
+/**
+ * OAuth authentication exception raised when the mapped platform account is pending approval.
+ */
public class AccountPendingException extends OAuth2AuthenticationException {
public AccountPendingException() {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/CustomOAuth2UserService.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/CustomOAuth2UserService.java
index 774d4bef..2b013f47 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/CustomOAuth2UserService.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/CustomOAuth2UserService.java
@@ -22,6 +22,10 @@ import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
+/**
+ * Spring Security OAuth user-service bridge that extracts provider claims,
+ * evaluates access policy, and maps the result to a {@link PlatformPrincipal}.
+ */
@Service
public class CustomOAuth2UserService implements OAuth2UserService {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/GitHubClaimsExtractor.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/GitHubClaimsExtractor.java
index f7e807b9..51b802da 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/GitHubClaimsExtractor.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/GitHubClaimsExtractor.java
@@ -12,6 +12,10 @@ import java.util.List;
import org.springframework.stereotype.Component;
import java.util.Map;
+/**
+ * Provider-specific claims extractor that enriches GitHub OAuth users with their primary verified
+ * email when necessary.
+ */
@Component
public class GitHubClaimsExtractor implements OAuthClaimsExtractor {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuth2LoginFailureHandler.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuth2LoginFailureHandler.java
index 4f18a23a..4813e13c 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuth2LoginFailureHandler.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuth2LoginFailureHandler.java
@@ -12,6 +12,10 @@ import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
+/**
+ * Failure handler for OAuth logins that normalizes policy and account-state
+ * failures into predictable user-facing redirects.
+ */
@Component
public class OAuth2LoginFailureHandler extends SimpleUrlAuthenticationFailureHandler {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuth2LoginSuccessHandler.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuth2LoginSuccessHandler.java
index d0a1d1b2..3df9a237 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuth2LoginSuccessHandler.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuth2LoginSuccessHandler.java
@@ -13,6 +13,10 @@ import org.springframework.stereotype.Component;
import java.io.IOException;
+/**
+ * Login success handler that copies the resolved platform principal into the
+ * HTTP session and then redirects to the stored return target.
+ */
@Component
public class OAuth2LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthClaims.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthClaims.java
index 679d1a39..78dc9b80 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthClaims.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthClaims.java
@@ -2,6 +2,10 @@ package com.iflytek.skillhub.auth.oauth;
import java.util.Map;
+/**
+ * Normalized identity claims extracted from an OAuth provider before local account decisions are
+ * made.
+ */
public record OAuthClaims(
String provider,
String subject,
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthClaimsExtractor.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthClaimsExtractor.java
index 826b3c9b..64b75ec8 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthClaimsExtractor.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthClaimsExtractor.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.auth.oauth;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.user.OAuth2User;
+/**
+ * Strategy interface for converting provider-specific OAuth user payloads into normalized claims.
+ */
public interface OAuthClaimsExtractor {
String getProvider();
OAuthClaims extract(OAuth2UserRequest request, OAuth2User oAuth2User);
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthLoginRedirectSupport.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthLoginRedirectSupport.java
index 6d1fd77f..feb60816 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthLoginRedirectSupport.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/OAuthLoginRedirectSupport.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.auth.oauth;
+/**
+ * Utility methods and constants for safely handling post-login redirect targets in OAuth flows.
+ */
public final class OAuthLoginRedirectSupport {
public static final String SESSION_RETURN_TO_ATTRIBUTE = "skillhub.oauth.returnTo";
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/SkillHubOAuth2AuthorizationRequestResolver.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/SkillHubOAuth2AuthorizationRequestResolver.java
index 6b42f593..0e67b325 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/SkillHubOAuth2AuthorizationRequestResolver.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/SkillHubOAuth2AuthorizationRequestResolver.java
@@ -6,6 +6,10 @@ import org.springframework.security.oauth2.client.web.DefaultOAuth2Authorization
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.stereotype.Component;
+/**
+ * OAuth2 authorization request resolver that preserves a sanitized post-login redirect target in
+ * the HTTP session.
+ */
@Component
public class SkillHubOAuth2AuthorizationRequestResolver
implements org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/package-info.java
new file mode 100644
index 00000000..00ac05bc
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/oauth/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * OAuth login adapters, claims extraction, and redirect coordination for
+ * browser-based third-party authentication.
+ */
+package com.iflytek.skillhub.auth.oauth;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessDecision.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessDecision.java
index 1aea1213..2c33fcd3 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessDecision.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessDecision.java
@@ -1,5 +1,9 @@
package com.iflytek.skillhub.auth.policy;
+/**
+ * Possible outcomes when evaluating whether an externally authenticated user may access the
+ * platform.
+ */
public enum AccessDecision {
ALLOW, DENY, PENDING_APPROVAL
}
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessPolicy.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessPolicy.java
index f2049308..8ac38ea6 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessPolicy.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessPolicy.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.auth.policy;
import com.iflytek.skillhub.auth.oauth.OAuthClaims;
+/**
+ * Policy contract for deciding whether externally authenticated users may enter the platform.
+ */
public interface AccessPolicy {
AccessDecision evaluate(OAuthClaims claims);
}
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessPolicyFactory.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessPolicyFactory.java
index 79602966..b647c92b 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessPolicyFactory.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/AccessPolicyFactory.java
@@ -6,6 +6,9 @@ import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.Set;
+/**
+ * Builds the active external-access policy from configuration properties.
+ */
@Configuration
@ConfigurationProperties(prefix = "skillhub.access-policy")
public class AccessPolicyFactory {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/EmailDomainAccessPolicy.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/EmailDomainAccessPolicy.java
index fe9d442f..d688f2a2 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/EmailDomainAccessPolicy.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/EmailDomainAccessPolicy.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.auth.policy;
import com.iflytek.skillhub.auth.oauth.OAuthClaims;
import java.util.Set;
+/**
+ * Access policy that allows login only when the OAuth email belongs to an approved domain.
+ */
public class EmailDomainAccessPolicy implements AccessPolicy {
private final Set allowedDomains;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/OpenAccessPolicy.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/OpenAccessPolicy.java
index c0ef33ba..9febc325 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/OpenAccessPolicy.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/OpenAccessPolicy.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.auth.policy;
import com.iflytek.skillhub.auth.oauth.OAuthClaims;
+/**
+ * Access policy that accepts all OAuth-authenticated users.
+ */
public class OpenAccessPolicy implements AccessPolicy {
@Override
public AccessDecision evaluate(OAuthClaims claims) {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/ProviderAllowlistAccessPolicy.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/ProviderAllowlistAccessPolicy.java
index 2457f123..d44ec348 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/ProviderAllowlistAccessPolicy.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/ProviderAllowlistAccessPolicy.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.auth.policy;
import com.iflytek.skillhub.auth.oauth.OAuthClaims;
import java.util.Set;
+/**
+ * Access policy that limits login to explicitly allowed OAuth providers.
+ */
public class ProviderAllowlistAccessPolicy implements AccessPolicy {
private final Set allowedProviders;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/SubjectWhitelistAccessPolicy.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/SubjectWhitelistAccessPolicy.java
index daf6acaf..0b9546f5 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/SubjectWhitelistAccessPolicy.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/SubjectWhitelistAccessPolicy.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.auth.policy;
import com.iflytek.skillhub.auth.oauth.OAuthClaims;
import java.util.Set;
+/**
+ * Access policy that only permits a configured set of provider-subject pairs.
+ */
public class SubjectWhitelistAccessPolicy implements AccessPolicy {
private final Set whitelistedSubjects;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/package-info.java
new file mode 100644
index 00000000..7a4d3a21
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Access policies that decide whether an external identity is allowed to sign
+ * in to the platform.
+ */
+package com.iflytek.skillhub.auth.policy;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/PlatformPrincipal.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/PlatformPrincipal.java
index 0dfdf196..67f13102 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/PlatformPrincipal.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/PlatformPrincipal.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.auth.rbac;
import java.io.Serializable;
import java.util.Set;
+/**
+ * Serializable authenticated principal shared across session, OAuth, and API-token flows.
+ */
public record PlatformPrincipal(
String userId,
String displayName,
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/PlatformRoleDefaults.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/PlatformRoleDefaults.java
index 2ccfedee..eb34da07 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/PlatformRoleDefaults.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/PlatformRoleDefaults.java
@@ -4,6 +4,9 @@ import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;
+/**
+ * Utility methods for normalizing platform role sets and ensuring a baseline user role.
+ */
public final class PlatformRoleDefaults {
public static final String DEFAULT_USER_ROLE = "USER";
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/RbacService.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/RbacService.java
index 8c94e2ee..9aa4a185 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/RbacService.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/RbacService.java
@@ -11,6 +11,10 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+/**
+ * Resolves platform roles and permissions for a user from persisted RBAC
+ * bindings.
+ */
@Service
public class RbacService {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/package-info.java
new file mode 100644
index 00000000..a7b73f79
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Role-based access control primitives and services for platform-wide
+ * authorization checks.
+ */
+package com.iflytek.skillhub.auth.rbac;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/ApiTokenRepository.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/ApiTokenRepository.java
index 765c6946..b24c840c 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/ApiTokenRepository.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/ApiTokenRepository.java
@@ -8,6 +8,9 @@ import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
+/**
+ * JPA repository for personal API tokens and token listings scoped to one user.
+ */
@Repository
public interface ApiTokenRepository extends JpaRepository {
Optional findByTokenHash(String tokenHash);
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/IdentityBindingRepository.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/IdentityBindingRepository.java
index 12f48f8f..22499604 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/IdentityBindingRepository.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/IdentityBindingRepository.java
@@ -5,6 +5,9 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
+/**
+ * JPA repository for links between platform users and external identity-provider subjects.
+ */
@Repository
public interface IdentityBindingRepository extends JpaRepository {
Optional findByProviderCodeAndSubject(String providerCode, String subject);
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/RoleRepository.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/RoleRepository.java
index 2fcc3a46..e858f067 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/RoleRepository.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/RoleRepository.java
@@ -5,6 +5,9 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
+/**
+ * JPA repository for platform roles addressed by their stable code.
+ */
@Repository
public interface RoleRepository extends JpaRepository {
Optional findByCode(String code);
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/UserRoleBindingRepository.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/UserRoleBindingRepository.java
index 84e5bd37..162ed4fd 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/UserRoleBindingRepository.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/UserRoleBindingRepository.java
@@ -7,6 +7,9 @@ import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
+/**
+ * JPA repository for direct user-to-role assignments in the RBAC model.
+ */
@Repository
public interface UserRoleBindingRepository extends JpaRepository {
List findByUserId(String userId);
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/package-info.java
new file mode 100644
index 00000000..0225b70f
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/repository/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Repository ports for authentication persistence concerns.
+ */
+package com.iflytek.skillhub.auth.repository;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/session/PlatformSessionService.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/session/PlatformSessionService.java
index 01332a6d..3908ab71 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/session/PlatformSessionService.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/session/PlatformSessionService.java
@@ -10,13 +10,25 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.stereotype.Service;
+/**
+ * Synchronizes {@link PlatformPrincipal} snapshots with Spring Security's
+ * session-backed authentication context.
+ */
@Service
public class PlatformSessionService {
+ /**
+ * Establishes a new authenticated session and rotates the session id to
+ * reduce fixation risk.
+ */
public void establishSession(PlatformPrincipal principal, HttpServletRequest request) {
establishSession(principal, request, true);
}
+ /**
+ * Establishes a session for the supplied principal and optionally rotates
+ * the underlying servlet session id.
+ */
public void establishSession(PlatformPrincipal principal,
HttpServletRequest request,
boolean rotateSessionId) {
@@ -27,6 +39,10 @@ public class PlatformSessionService {
persist(principal, authentication, request, rotateSessionId);
}
+ /**
+ * Rebinds an updated principal to an already authenticated request without
+ * discarding the existing authentication object.
+ */
public void attachToAuthenticatedSession(PlatformPrincipal principal,
Authentication authentication,
HttpServletRequest request) {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/session/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/session/package-info.java
new file mode 100644
index 00000000..6afa5443
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/session/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Services that synchronize authenticated principals with the Spring Security
+ * session model.
+ */
+package com.iflytek.skillhub.auth.session;
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenAuthenticationFilter.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenAuthenticationFilter.java
index 3b227842..82c0f2c1 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenAuthenticationFilter.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenAuthenticationFilter.java
@@ -23,6 +23,10 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+/**
+ * Authenticates bearer tokens and projects them into a Spring Security
+ * principal with both roles and token scopes.
+ */
@Component
public class ApiTokenAuthenticationFilter extends OncePerRequestFilter {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenScopeFilter.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenScopeFilter.java
index aea4dfe0..8f69d5aa 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenScopeFilter.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenScopeFilter.java
@@ -17,6 +17,9 @@ import java.io.IOException;
import java.util.Set;
import java.util.stream.Collectors;
+/**
+ * Enforces fine-grained API token scopes after token authentication has established the principal.
+ */
@Component
public class ApiTokenScopeFilter extends OncePerRequestFilter {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenScopeService.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenScopeService.java
index 69c569c2..cb868267 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenScopeService.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenScopeService.java
@@ -9,6 +9,10 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
+/**
+ * Parses token scopes and evaluates whether a token may access a given HTTP
+ * method and path combination.
+ */
@Service
public class ApiTokenScopeService {
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenService.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenService.java
index 6ffcaa23..d750a860 100644
--- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenService.java
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/ApiTokenService.java
@@ -25,6 +25,9 @@ import java.util.HexFormat;
import java.util.List;
import java.util.Optional;
+/**
+ * Issues, rotates, validates, and revokes API tokens for non-browser clients.
+ */
@Service
public class ApiTokenService {
@@ -42,11 +45,18 @@ public class ApiTokenService {
public record TokenCreateResult(String rawToken, ApiToken entity) {}
+ /**
+ * Creates a token without an explicit expiration timestamp.
+ */
@Transactional
public TokenCreateResult createToken(String userId, String name, String scopeJson) {
return createToken(userId, name, scopeJson, null);
}
+ /**
+ * Creates a new token and returns the raw secret exactly once to the
+ * caller.
+ */
@Transactional
public TokenCreateResult createToken(String userId, String name, String scopeJson, String expiresAt) {
String normalizedName = normalizeName(name);
@@ -78,6 +88,10 @@ public class ApiTokenService {
return rotateToken(userId, name, scopeJson, null);
}
+ /**
+ * Rotates a token name by revoking the previous active token before issuing
+ * a replacement.
+ */
@Transactional
public TokenCreateResult rotateToken(String userId, String name, String scopeJson, String expiresAt) {
String normalizedName = normalizeName(name);
@@ -89,11 +103,18 @@ public class ApiTokenService {
return createToken(userId, name, scopeJson, expiresAt);
}
+ /**
+ * Validates a raw bearer token against its hash and lifecycle timestamps.
+ */
public Optional validateToken(String rawToken) {
String hash = sha256(rawToken);
return tokenRepo.findByTokenHash(hash).filter(token -> token.isValid(currentTime()));
}
+ /**
+ * Revokes a token owned by the current user. Missing or foreign tokens are
+ * ignored to keep revocation idempotent.
+ */
@Transactional
public void revokeToken(Long tokenId, String userId) {
tokenRepo.findById(tokenId)
@@ -104,6 +125,9 @@ public class ApiTokenService {
});
}
+ /**
+ * Updates the expiration timestamp of an active token owned by the caller.
+ */
@Transactional
public ApiToken updateExpiration(Long tokenId, String userId, String expiresAt) {
ApiToken token = tokenRepo.findById(tokenId)
diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/package-info.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/package-info.java
new file mode 100644
index 00000000..4fbcc815
--- /dev/null
+++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/token/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * API token issuance, authentication, and scope enforcement for non-browser
+ * clients.
+ */
+package com.iflytek.skillhub.auth.token;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogQueryService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogQueryService.java
index b2f74ef0..a94a1d27 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogQueryService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogQueryService.java
@@ -4,6 +4,9 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
+/**
+ * Read-side service for paginating audit log entries with simple filters.
+ */
@Service
public class AuditLogQueryService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogRepository.java
index bd967a41..b3b80541 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogRepository.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.domain.audit;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
+/**
+ * Domain repository contract for audit-log persistence and filtered pagination.
+ */
public interface AuditLogRepository {
AuditLog save(AuditLog auditLog);
Page search(String actorUserId, String action, Pageable pageable);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogService.java
index e477abe7..be9ef5f9 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/AuditLogService.java
@@ -6,6 +6,9 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.Clock;
import java.time.Instant;
+/**
+ * Records audit log entries for administrative and security-relevant actions.
+ */
@Service
public class AuditLogService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/package-info.java
new file mode 100644
index 00000000..dd3bfe73
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/audit/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Audit-domain abstractions for recording and querying security-sensitive or
+ * governance-relevant actions.
+ */
+package com.iflytek.skillhub.domain.audit;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/event/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/event/package-info.java
new file mode 100644
index 00000000..3107b825
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/event/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Cross-domain integration events published by the core business layer.
+ */
+package com.iflytek.skillhub.domain.event;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/GovernanceNotificationService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/GovernanceNotificationService.java
index 519c84a9..b6a7b8f6 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/GovernanceNotificationService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/GovernanceNotificationService.java
@@ -8,6 +8,9 @@ import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * Persists and manages governance notifications delivered to end users.
+ */
@Service
public class GovernanceNotificationService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/UserNotificationRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/UserNotificationRepository.java
index 85563adf..a6f159a8 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/UserNotificationRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/UserNotificationRepository.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.domain.governance;
import java.util.List;
import java.util.Optional;
+/**
+ * Domain repository contract for user-facing governance notifications.
+ */
public interface UserNotificationRepository {
UserNotification save(UserNotification notification);
Optional findById(Long id);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/package-info.java
new file mode 100644
index 00000000..60f14992
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/governance/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Governance notification models and ports used to inform users about review
+ * and moderation outcomes.
+ */
+package com.iflytek.skillhub.domain.governance;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/idempotency/IdempotencyRecordRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/idempotency/IdempotencyRecordRepository.java
index f4c298a3..4fee46c5 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/idempotency/IdempotencyRecordRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/idempotency/IdempotencyRecordRepository.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.domain.idempotency;
import java.time.Instant;
import java.util.Optional;
+/**
+ * Domain repository contract for tracking request idempotency state and cleanup operations.
+ */
public interface IdempotencyRecordRepository {
Optional findByRequestId(String requestId);
IdempotencyRecord save(IdempotencyRecord record);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/idempotency/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/idempotency/package-info.java
new file mode 100644
index 00000000..21c65499
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/idempotency/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Domain model for request idempotency tracking across retries of mutating
+ * operations.
+ */
+package com.iflytek.skillhub.domain.idempotency;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/GlobalNamespaceMembershipService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/GlobalNamespaceMembershipService.java
index 947d414f..1ef7d247 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/GlobalNamespaceMembershipService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/GlobalNamespaceMembershipService.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.domain.namespace;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * Ensures newly active users belong to the built-in global namespace.
+ */
@Service
public class GlobalNamespaceMembershipService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceAccessPolicy.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceAccessPolicy.java
index d798a7d5..5482628a 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceAccessPolicy.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceAccessPolicy.java
@@ -2,6 +2,10 @@ package com.iflytek.skillhub.domain.namespace;
import org.springframework.stereotype.Component;
+/**
+ * Encapsulates namespace lifecycle rules that determine which management actions are currently
+ * allowed.
+ */
@Component
public class NamespaceAccessPolicy {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceGovernanceService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceGovernanceService.java
index dda4574b..c9db527f 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceGovernanceService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceGovernanceService.java
@@ -6,6 +6,10 @@ import com.iflytek.skillhub.domain.shared.exception.DomainForbiddenException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * Applies namespace lifecycle transitions such as freeze, unfreeze, archive,
+ * and restore while recording audit history.
+ */
@Service
public class NamespaceGovernanceService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceMemberRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceMemberRepository.java
index 6387dab9..a07150f9 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceMemberRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceMemberRepository.java
@@ -6,6 +6,9 @@ import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Optional;
+/**
+ * Domain repository contract for namespace membership lookups and member administration.
+ */
public interface NamespaceMemberRepository {
Optional findByNamespaceIdAndUserId(Long namespaceId, String userId);
List findByUserId(String userId);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceMemberService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceMemberService.java
index 82c1c068..d8e8bc74 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceMemberService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceMemberService.java
@@ -8,6 +8,10 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
+/**
+ * Manages namespace membership additions, removals, and role changes under the
+ * namespace governance rules.
+ */
@Service
public class NamespaceMemberService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceRepository.java
index febf4ac0..775206e9 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceRepository.java
@@ -6,6 +6,9 @@ import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Optional;
+/**
+ * Domain repository contract for namespace aggregates and management-oriented reads.
+ */
public interface NamespaceRepository {
Optional findById(Long id);
List findByIdIn(List ids);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceService.java
index fef5ea3d..32f20fd1 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/NamespaceService.java
@@ -7,6 +7,9 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
+/**
+ * Domain service for namespace lifecycle and membership-gated mutations.
+ */
@Service
public class NamespaceService {
@@ -22,6 +25,10 @@ public class NamespaceService {
this.namespaceAccessPolicy = namespaceAccessPolicy;
}
+ /**
+ * Creates a team namespace and grants the creator the owner role in the
+ * same transaction.
+ */
@Transactional
public Namespace createNamespace(String slug, String displayName, String description, String creatorUserId) {
SlugValidator.validate(slug);
@@ -41,6 +48,9 @@ public class NamespaceService {
return namespace;
}
+ /**
+ * Updates mutable namespace profile fields after policy and role checks.
+ */
@Transactional
public Namespace updateNamespace(Long namespaceId, String displayName, String description, String avatarUrl,
String operatorUserId) {
@@ -63,11 +73,19 @@ public class NamespaceService {
return namespaceRepository.save(namespace);
}
+ /**
+ * Loads a namespace by slug and fails with a business exception when it is
+ * missing.
+ */
public Namespace getNamespaceBySlug(String slug) {
return namespaceRepository.findBySlug(slug)
.orElseThrow(() -> new DomainBadRequestException("error.namespace.slug.notFound", slug));
}
+ /**
+ * Returns archived namespaces only to callers that already belong to them;
+ * all other callers see archived namespaces as not found.
+ */
public Namespace getNamespaceBySlugForRead(String slug, String userId, Map userNsRoles) {
Namespace namespace = getNamespaceBySlug(slug);
if (namespace.getStatus() != NamespaceStatus.ARCHIVED) {
@@ -84,6 +102,9 @@ public class NamespaceService {
.orElseThrow(() -> new DomainBadRequestException("error.namespace.id.notFound", namespaceId));
}
+ /**
+ * Ensures the caller holds an owner or admin membership in the namespace.
+ */
public void assertAdminOrOwner(Long namespaceId, String userId) {
NamespaceRole role = namespaceMemberRepository.findByNamespaceIdAndUserId(namespaceId, userId)
.map(NamespaceMember::getRole)
@@ -93,6 +114,9 @@ public class NamespaceService {
}
}
+ /**
+ * Ensures the caller is at least a member of the namespace.
+ */
public void assertMember(Long namespaceId, String userId) {
namespaceMemberRepository.findByNamespaceIdAndUserId(namespaceId, userId)
.orElseThrow(() -> new DomainForbiddenException("error.namespace.membership.required"));
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/SlugValidator.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/SlugValidator.java
index dd3457e7..29c27677 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/SlugValidator.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/SlugValidator.java
@@ -5,6 +5,9 @@ import com.iflytek.skillhub.domain.shared.exception.DomainBadRequestException;
import java.util.Set;
import java.util.regex.Pattern;
+/**
+ * Validates and normalizes namespace-style slugs used across public identifiers.
+ */
public class SlugValidator {
private static final int MIN_LENGTH = 2;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/package-info.java
new file mode 100644
index 00000000..2700f3bc
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/namespace/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Namespace aggregate, membership rules, and governance policies that scope
+ * skills and collaboration permissions.
+ */
+package com.iflytek.skillhub.domain.namespace;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/SkillReportRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/SkillReportRepository.java
index 291e3503..62349668 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/SkillReportRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/SkillReportRepository.java
@@ -6,6 +6,9 @@ import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
+/**
+ * Domain repository contract for abuse reports filed against skills.
+ */
public interface SkillReportRepository {
SkillReport save(SkillReport report);
Optional findById(Long id);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/SkillReportService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/SkillReportService.java
index cb96f00d..52cbd871 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/SkillReportService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/SkillReportService.java
@@ -13,6 +13,10 @@ import java.time.Instant;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * Handles skill abuse reports from submission through moderation outcome
+ * handling.
+ */
@Service
public class SkillReportService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/package-info.java
new file mode 100644
index 00000000..869ab7e2
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/report/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Reporting domain objects and services for user-submitted skill abuse or
+ * quality issues.
+ */
+package com.iflytek.skillhub.domain.report;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/PromotionRequestRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/PromotionRequestRepository.java
index 4275959b..a6dc87c9 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/PromotionRequestRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/PromotionRequestRepository.java
@@ -4,6 +4,10 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.Optional;
+/**
+ * Domain repository contract for promotion requests that copy or elevate one skill version into a
+ * target catalog entry.
+ */
public interface PromotionRequestRepository {
PromotionRequest save(PromotionRequest request);
Optional findById(Long id);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/PromotionService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/PromotionService.java
index 7ee3c953..f627f749 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/PromotionService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/PromotionService.java
@@ -22,6 +22,13 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+/**
+ * Handles promotion requests that copy approved skills into the global
+ * namespace.
+ *
+ * Promotion is intentionally modeled separately from normal review because
+ * it creates or updates a distinct target skill lineage.
+ */
@Service
public class PromotionService {
@@ -55,6 +62,10 @@ public class PromotionService {
this.clock = clock;
}
+ /**
+ * Submits a promotion request for a published source version using both
+ * namespace and platform roles for authorization.
+ */
@Transactional
public PromotionRequest submitPromotion(Long sourceSkillId, Long sourceVersionId,
Long targetNamespaceId, String userId,
@@ -148,6 +159,10 @@ public class PromotionService {
return promotionRequestRepository.save(request);
}
+ /**
+ * Approves a promotion request and materializes a published copy of the
+ * source version in the target global namespace.
+ */
@Transactional
public PromotionRequest approvePromotion(Long promotionId, String reviewerId,
String comment, Set platformRoles) {
@@ -230,6 +245,9 @@ public class PromotionService {
return savedRequest;
}
+ /**
+ * Rejects a pending promotion request without changing the source skill.
+ */
@Transactional
public PromotionRequest rejectPromotion(Long promotionId, String reviewerId,
String comment, Set platformRoles) {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewPermissionChecker.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewPermissionChecker.java
index 21991214..bc5dae42 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewPermissionChecker.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewPermissionChecker.java
@@ -8,6 +8,9 @@ import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Set;
+/**
+ * Centralizes review and promotion permission checks derived from namespace and platform roles.
+ */
@Component
public class ReviewPermissionChecker {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewService.java
index 4802ac11..7133abb7 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewService.java
@@ -29,6 +29,13 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+/**
+ * Coordinates the review workflow for skill versions.
+ *
+ * This service owns transitions between draft, pending review, approved,
+ * and rejected states together with the review task record that tracks the
+ * moderation decision.
+ */
@Service
public class ReviewService {
@@ -65,6 +72,10 @@ public class ReviewService {
this.clock = clock;
}
+ /**
+ * Submits a draft version into the review queue using both namespace roles
+ * and platform roles to determine permission.
+ */
@Transactional
public ReviewTask submitReview(Long skillVersionId,
String userId,
@@ -98,6 +109,10 @@ public class ReviewService {
}
}
+ /**
+ * Legacy overload that evaluates submission rights only from namespace
+ * memberships.
+ */
@Transactional
public ReviewTask submitReview(Long skillVersionId,
String userId,
@@ -130,6 +145,10 @@ public class ReviewService {
}
}
+ /**
+ * Approves a pending review task, publishes the underlying version, and
+ * emits downstream notifications and publication events.
+ */
@Transactional
public ReviewTask approveReview(Long reviewTaskId, String reviewerId, String comment,
Map userNamespaceRoles,
@@ -202,6 +221,10 @@ public class ReviewService {
return reviewTaskRepository.findById(reviewTaskId).orElse(task);
}
+ /**
+ * Rejects a pending review task and returns the underlying version to a
+ * non-published state with reviewer metadata captured on the task.
+ */
@Transactional
public ReviewTask rejectReview(Long reviewTaskId, String reviewerId, String comment,
Map userNamespaceRoles,
@@ -244,6 +267,10 @@ public class ReviewService {
return reviewTaskRepository.findById(reviewTaskId).orElse(task);
}
+ /**
+ * Withdraws a previously submitted review request and puts the version back
+ * into draft so the owner can amend and resubmit it.
+ */
@Transactional
public SkillVersion withdrawReview(Long skillVersionId, String userId) {
ReviewTask task = reviewTaskRepository.findBySkillVersionIdAndStatus(
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewTaskRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewTaskRepository.java
index 9d3a3c49..5596f60a 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewTaskRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/ReviewTaskRepository.java
@@ -4,6 +4,9 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.Optional;
+/**
+ * Domain repository contract for moderation review tasks and their state transitions.
+ */
public interface ReviewTaskRepository {
ReviewTask save(ReviewTask reviewTask);
Optional findById(Long id);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/package-info.java
new file mode 100644
index 00000000..98386091
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/review/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Review and promotion workflows that move skill versions through moderation
+ * and cross-namespace publication.
+ */
+package com.iflytek.skillhub.domain.review;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainBadRequestException.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainBadRequestException.java
index 670489fe..aab80d58 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainBadRequestException.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainBadRequestException.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.domain.shared.exception;
+/**
+ * Domain exception used when caller input violates business validation rules.
+ */
public class DomainBadRequestException extends LocalizedDomainException {
public DomainBadRequestException(String messageCode, Object... messageArgs) {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainForbiddenException.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainForbiddenException.java
index 1d5c9525..14807d15 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainForbiddenException.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainForbiddenException.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.domain.shared.exception;
+/**
+ * Domain exception used when the caller lacks permission for the requested business action.
+ */
public class DomainForbiddenException extends LocalizedDomainException {
public DomainForbiddenException(String messageCode, Object... messageArgs) {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainNotFoundException.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainNotFoundException.java
index 36b64c55..df387c69 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainNotFoundException.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/DomainNotFoundException.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.domain.shared.exception;
+/**
+ * Domain exception used when a required business entity cannot be found.
+ */
public class DomainNotFoundException extends LocalizedDomainException {
public DomainNotFoundException(String messageCode, Object... messageArgs) {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/LocalizedDomainException.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/LocalizedDomainException.java
index c09d1919..35e55cd7 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/LocalizedDomainException.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/LocalizedDomainException.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.domain.shared.exception;
+/**
+ * Base class for domain-layer exceptions that carry a localized message code and arguments.
+ */
public abstract class LocalizedDomainException extends RuntimeException {
private final String messageCode;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/package-info.java
new file mode 100644
index 00000000..ee685b3d
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/shared/exception/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Reusable business exceptions raised by domain services and translated at the
+ * application boundary.
+ */
+package com.iflytek.skillhub.domain.shared.exception;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillFileRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillFileRepository.java
index 4cc0bd81..5a863645 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillFileRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillFileRepository.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.domain.skill;
import java.util.List;
+/**
+ * Domain repository contract for files belonging to one published or draft skill version.
+ */
public interface SkillFileRepository {
List findByVersionId(Long versionId);
SkillFile save(SkillFile file);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillRepository.java
index f3080f4f..d8ca3d44 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillRepository.java
@@ -6,6 +6,9 @@ import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Optional;
+/**
+ * Domain repository contract for loading and persisting skill aggregates and common read models.
+ */
public interface SkillRepository {
Optional findById(Long id);
List findByIdIn(List ids);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillTagRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillTagRepository.java
index f8cd1c1c..e45b09e6 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillTagRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillTagRepository.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.domain.skill;
import java.util.List;
import java.util.Optional;
+/**
+ * Domain repository contract for persisted skill tags and tag lookups.
+ */
public interface SkillTagRepository {
Optional findBySkillIdAndTagName(Long skillId, String tagName);
List findBySkillId(Long skillId);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillVersionRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillVersionRepository.java
index 6a5739c7..eaeacd13 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillVersionRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillVersionRepository.java
@@ -3,6 +3,9 @@ package com.iflytek.skillhub.domain.skill;
import java.util.List;
import java.util.Optional;
+/**
+ * Domain repository contract for skill version history and publication-state queries.
+ */
public interface SkillVersionRepository {
Optional findById(Long id);
List findByIdIn(List ids);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillVersionStatsRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillVersionStatsRepository.java
index 28685aa2..905621f9 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillVersionStatsRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/SkillVersionStatsRepository.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.domain.skill;
import java.util.Optional;
+/**
+ * Domain repository contract for per-version counters such as download statistics.
+ */
public interface SkillVersionStatsRepository {
Optional findBySkillVersionId(Long skillVersionId);
void incrementDownloadCount(Long skillVersionId, Long skillId);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/VisibilityChecker.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/VisibilityChecker.java
index 16980af1..f4632159 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/VisibilityChecker.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/VisibilityChecker.java
@@ -4,6 +4,10 @@ import com.iflytek.skillhub.domain.namespace.NamespaceRole;
import java.util.Map;
+/**
+ * Evaluates whether a caller may read a skill based on publication state, visibility, ownership,
+ * and namespace roles.
+ */
public class VisibilityChecker {
public boolean canAccess(Skill skill, String currentUserId, Map userNamespaceRoles) {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/metadata/SkillMetadataParser.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/metadata/SkillMetadataParser.java
index a461d2d2..36fc1ffc 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/metadata/SkillMetadataParser.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/metadata/SkillMetadataParser.java
@@ -6,6 +6,10 @@ import org.yaml.snakeyaml.Yaml;
import java.util.LinkedHashMap;
import java.util.Map;
+/**
+ * Parses `SKILL.md` frontmatter and body content into the normalized metadata model used by the
+ * publish pipeline.
+ */
public class SkillMetadataParser {
private static final String FRONTMATTER_DELIMITER = "---";
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/metadata/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/metadata/package-info.java
new file mode 100644
index 00000000..4fef333c
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/metadata/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Parsing and representation of metadata extracted from packaged skills.
+ */
+package com.iflytek.skillhub.domain.skill.metadata;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/package-info.java
new file mode 100644
index 00000000..6c438d5e
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Core skill aggregate model including versions, files, visibility, and
+ * repositories shared across publication and consumption flows.
+ */
+package com.iflytek.skillhub.domain.skill;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillDownloadService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillDownloadService.java
index bc9678b1..8e83ba1b 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillDownloadService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillDownloadService.java
@@ -26,6 +26,12 @@ import java.util.function.Supplier;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
+/**
+ * Domain service that delivers packaged skills to callers.
+ *
+ * It combines visibility checks, version resolution, object-storage access,
+ * and download tracking into a single download-oriented API.
+ */
@Service
public class SkillDownloadService {
private static final Logger log = LoggerFactory.getLogger(SkillDownloadService.class);
@@ -77,6 +83,9 @@ public class SkillDownloadService {
}
}
+ /**
+ * Downloads the latest published version available to the caller.
+ */
public DownloadResult downloadLatest(
String namespaceSlug,
String skillSlug,
@@ -97,6 +106,10 @@ public class SkillDownloadService {
return downloadVersion(skill, version);
}
+ /**
+ * Downloads an explicit version when the caller has permission to access
+ * the containing skill.
+ */
public DownloadResult downloadVersion(
String namespaceSlug,
String skillSlug,
@@ -114,6 +127,9 @@ public class SkillDownloadService {
return downloadVersion(skill, version);
}
+ /**
+ * Downloads the version pointed to by a mutable tag name.
+ */
public DownloadResult downloadByTag(
String namespaceSlug,
String skillSlug,
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillGovernanceService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillGovernanceService.java
index a96ccc67..51b21845 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillGovernanceService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillGovernanceService.java
@@ -23,6 +23,10 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * Handles governance-oriented mutations on skills and versions, including
+ * hiding, archiving, restoring, and destructive cleanup.
+ */
@Service
public class SkillGovernanceService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillLifecycleProjectionService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillLifecycleProjectionService.java
index 73b2d0e7..e374f3b9 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillLifecycleProjectionService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillLifecycleProjectionService.java
@@ -10,6 +10,10 @@ import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
+/**
+ * Builds lightweight lifecycle projections that describe which skill version should be surfaced to
+ * a given viewer.
+ */
@Service
public class SkillLifecycleProjectionService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillPublishService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillPublishService.java
index de5238b3..bd65eac3 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillPublishService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillPublishService.java
@@ -45,6 +45,12 @@ import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
+/**
+ * Publishes packaged skill artifacts into persisted skill and version records.
+ *
+ *
The service validates archive contents, parses metadata, stores files,
+ * creates review tasks when needed, and updates the skill's lifecycle pointer.
+ */
@Service
public class SkillPublishService {
@@ -100,6 +106,12 @@ public class SkillPublishService {
this.clock = clock;
}
+ /**
+ * Publishes an extracted package into the target namespace.
+ *
+ *
Super administrators may auto-publish, while regular publishers
+ * usually create a pending-review version.
+ */
@Transactional
public PublishResult publishFromEntries(
String namespaceSlug,
@@ -110,6 +122,10 @@ public class SkillPublishService {
return publishFromEntriesInternal(namespaceSlug, entries, publisherId, visibility, platformRoles, false, false);
}
+ /**
+ * Rebuilds a new version from an already published version by copying its
+ * stored files and rewriting the embedded metadata version field.
+ */
@Transactional
public PublishResult rereleasePublishedVersion(
Long skillId,
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillQueryService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillQueryService.java
index 55bf67c5..3a35e0a8 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillQueryService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillQueryService.java
@@ -31,6 +31,13 @@ import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
+/**
+ * Read-side domain service for skill detail, version browsing, and packaged
+ * file inspection.
+ *
+ *
Unlike search, this service works from the authoritative skill model and
+ * applies viewer-specific visibility rules before returning data.
+ */
@Service
public class SkillQueryService {
@@ -171,6 +178,10 @@ public class SkillQueryService {
);
}
+ /**
+ * Lists skills within a namespace after filtering out records the caller is
+ * not allowed to discover.
+ */
public Page listSkillsByNamespace(
String namespaceSlug,
String currentUserId,
@@ -193,6 +204,10 @@ public class SkillQueryService {
return new PageImpl<>(pageContent, pageable, accessibleSkills.size());
}
+ /**
+ * Returns metadata for a visible version, including the stored manifest and
+ * parsed metadata payload.
+ */
public SkillVersionDetailDTO getVersionDetail(
String namespaceSlug,
String skillSlug,
@@ -247,6 +262,10 @@ public class SkillQueryService {
return availableFiles(skillVersion.getId());
}
+ /**
+ * Opens a single file stream from object storage after verifying that the
+ * caller may inspect the requested version.
+ */
public InputStream getFileContent(
String namespaceSlug,
String skillSlug,
@@ -328,6 +347,10 @@ public class SkillQueryService {
return version.isDownloadReady();
}
+ /**
+ * Resolves a version selector such as an exact version, tag, or implicit
+ * latest reference into a concrete download target.
+ */
public ResolvedVersionDTO resolveVersion(
String namespaceSlug,
String skillSlug,
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillSlugResolutionService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillSlugResolutionService.java
index e4521da3..080172b1 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillSlugResolutionService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillSlugResolutionService.java
@@ -8,6 +8,9 @@ import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
+/**
+ * Resolves ambiguous namespace-slug pairs to the most appropriate skill record for the caller.
+ */
@Service
public class SkillSlugResolutionService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillTagService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillTagService.java
index 07c3fdc0..6d7a801b 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillTagService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillTagService.java
@@ -12,6 +12,10 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.List;
+/**
+ * Manages named tags that resolve to skill versions while enforcing
+ * visibility and membership constraints.
+ */
@Service
public class SkillTagService {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/package-info.java
new file mode 100644
index 00000000..6450f412
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Domain services that coordinate skill publication, lifecycle, query, and
+ * download use cases across multiple repositories and infrastructure ports.
+ */
+package com.iflytek.skillhub.domain.skill.service;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/BasicPrePublishValidator.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/BasicPrePublishValidator.java
index 86dca42c..c61e420b 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/BasicPrePublishValidator.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/BasicPrePublishValidator.java
@@ -9,6 +9,10 @@ import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+/**
+ * Default pre-publish validator that scans text-like package files for likely secrets and
+ * accidental real credentials.
+ */
@Component
public class BasicPrePublishValidator implements PrePublishValidator {
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/NoOpPrePublishValidator.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/NoOpPrePublishValidator.java
index cd8e1ef8..44ae1cc5 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/NoOpPrePublishValidator.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/NoOpPrePublishValidator.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.domain.skill.validation;
+/**
+ * Trivial validator used when no extra pre-publish checks are desired.
+ */
public class NoOpPrePublishValidator implements PrePublishValidator {
@Override
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/PrePublishValidator.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/PrePublishValidator.java
index 5f64f151..deb08471 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/PrePublishValidator.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/PrePublishValidator.java
@@ -4,6 +4,10 @@ import com.iflytek.skillhub.domain.skill.metadata.SkillMetadata;
import java.util.List;
+/**
+ * Extension point for content-aware validation that runs after package parsing but before a skill
+ * version is accepted for publishing.
+ */
public interface PrePublishValidator {
ValidationResult validate(SkillPackageContext context);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/SkillPackagePolicy.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/SkillPackagePolicy.java
index c4520a54..87a952b9 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/SkillPackagePolicy.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/SkillPackagePolicy.java
@@ -9,6 +9,10 @@ import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.Set;
+/**
+ * Shared package-policy rules for path normalization, extension allowlists, and lightweight file
+ * signature validation.
+ */
public final class SkillPackagePolicy {
public static final int MAX_FILE_COUNT = 100;
@@ -16,14 +20,14 @@ public final class SkillPackagePolicy {
public static final long MAX_TOTAL_PACKAGE_SIZE = 100 * 1024 * 1024; // 100MB
public static final String SKILL_MD_PATH = "SKILL.md";
public static final Set ALLOWED_EXTENSIONS = Set.of(
- // 文档
+ // Documentation
".md", ".txt", ".json", ".yaml", ".yml", ".html", ".css", ".csv", ".pdf",
- // 配置
+ // Configuration
".toml", ".xml", ".ini", ".cfg", ".env",
- // 脚本/语言
+ // Scripts and source code
".js", ".ts", ".py", ".sh", ".rb", ".go", ".rs", ".java", ".kt",
".lua", ".sql", ".r", ".bat", ".ps1", ".zsh", ".bash",
- // 图片
+ // Images
".png", ".jpg", ".jpeg", ".svg", ".gif", ".webp", ".ico"
);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/SkillPackageValidator.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/SkillPackageValidator.java
index a483612c..836a9eb5 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/SkillPackageValidator.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/SkillPackageValidator.java
@@ -10,6 +10,10 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+/**
+ * Validates uploaded skill packages against structural, metadata, and size constraints before
+ * publish-time domain processing continues.
+ */
public class SkillPackageValidator {
private static final Pattern YAML_LINE_COLUMN = Pattern.compile("line\\s+(\\d+),\\s+column\\s+(\\d+)");
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/package-info.java
new file mode 100644
index 00000000..fd6dc62e
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Validation policies for uploaded skill packages before they become persisted
+ * skill versions.
+ */
+package com.iflytek.skillhub.domain.skill.validation;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingRepository.java
index b29f5a4b..b628e598 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingRepository.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.domain.social;
import java.util.Optional;
+/**
+ * Domain repository contract for per-user ratings and rating aggregates on one skill.
+ */
public interface SkillRatingRepository {
SkillRating save(SkillRating rating);
Optional findBySkillIdAndUserId(Long skillId, String userId);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingService.java
index 7d8a6235..95e67b0c 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingService.java
@@ -10,6 +10,10 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
+/**
+ * Domain service for creating or updating user ratings on skills and emitting
+ * the corresponding social event.
+ */
@Service
public class SkillRatingService {
private final SkillRatingRepository ratingRepository;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarRepository.java
index 0cd9f1ab..2eabe344 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarRepository.java
@@ -4,6 +4,9 @@ import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
+/**
+ * Domain repository contract for skill star relationships and starred-skill pagination.
+ */
public interface SkillStarRepository {
SkillStar save(SkillStar star);
Optional findBySkillIdAndUserId(Long skillId, String userId);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarService.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarService.java
index b1dd49bc..e9a5485c 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarService.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarService.java
@@ -8,6 +8,9 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * Domain service for starring and unstarring skills in an idempotent manner.
+ */
@Service
public class SkillStarService {
private final SkillStarRepository starRepository;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/event/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/event/package-info.java
new file mode 100644
index 00000000..0a2ae09e
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/event/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Domain events emitted by social interactions so counters and projections can
+ * react asynchronously.
+ */
+package com.iflytek.skillhub.domain.social.event;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/package-info.java
new file mode 100644
index 00000000..f9631312
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Social interactions such as starring and rating that enrich the skill
+ * marketplace experience.
+ */
+package com.iflytek.skillhub.domain.social;
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/user/UserAccountRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/user/UserAccountRepository.java
index d2163c56..c0f4f295 100644
--- a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/user/UserAccountRepository.java
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/user/UserAccountRepository.java
@@ -6,6 +6,9 @@ import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Optional;
+/**
+ * Domain repository contract for user-account identity lookups and administrative searches.
+ */
public interface UserAccountRepository {
Optional findById(String id);
List findByIdIn(List ids);
diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/user/package-info.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/user/package-info.java
new file mode 100644
index 00000000..e9e49d57
--- /dev/null
+++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/user/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * User account and profile moderation domain objects that back identity and
+ * profile management flows.
+ */
+package com.iflytek.skillhub.domain.user;
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/AuditLogJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/AuditLogJpaRepository.java
index 8d6b4606..fa57defa 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/AuditLogJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/AuditLogJpaRepository.java
@@ -9,6 +9,9 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
+/**
+ * JPA-backed audit-log repository that adds specification-based filtering for admin queries.
+ */
@Repository
public interface AuditLogJpaRepository extends JpaRepository, JpaSpecificationExecutor, AuditLogRepository {
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaIdempotencyRecordRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaIdempotencyRecordRepository.java
index 8eafd1d7..300e7a56 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaIdempotencyRecordRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaIdempotencyRecordRepository.java
@@ -10,6 +10,10 @@ import org.springframework.stereotype.Repository;
import java.time.Instant;
+/**
+ * JPA repository that persists idempotency records and exposes cleanup operations used by
+ * background maintenance.
+ */
@Repository
public interface JpaIdempotencyRecordRepository extends JpaRepository, IdempotencyRecordRepository {
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRatingRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRatingRepository.java
index f60d8699..8996e226 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRatingRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRatingRepository.java
@@ -7,6 +7,9 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.Optional;
+/**
+ * JPA-backed repository for per-user skill ratings and their derived aggregates.
+ */
@Repository
public interface JpaSkillRatingRepository extends JpaRepository, SkillRatingRepository {
Optional findBySkillIdAndUserId(Long skillId, String userId);
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRepositoryAdapter.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRepositoryAdapter.java
index 6e9daecf..cf991282 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRepositoryAdapter.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRepositoryAdapter.java
@@ -12,6 +12,9 @@ import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
+/**
+ * Primary JPA-backed adapter that fulfills the domain-level {@link SkillRepository} contract.
+ */
@Repository
@Primary
public class JpaSkillRepositoryAdapter implements SkillRepository {
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillStarRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillStarRepository.java
index e75201e5..295273ac 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillStarRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillStarRepository.java
@@ -8,6 +8,9 @@ import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
+/**
+ * JPA-backed repository for skill star relationships and user star listings.
+ */
@Repository
public interface JpaSkillStarRepository extends JpaRepository, SkillStarRepository {
Optional findBySkillIdAndUserId(Long skillId, String userId);
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/NamespaceJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/NamespaceJpaRepository.java
index 1b21cc5d..7e7f3db0 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/NamespaceJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/NamespaceJpaRepository.java
@@ -11,6 +11,9 @@ import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
+/**
+ * JPA-backed namespace repository that also fulfills the domain namespace repository contract.
+ */
@Repository
public interface NamespaceJpaRepository
extends JpaRepository, NamespaceRepository {
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/NamespaceMemberJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/NamespaceMemberJpaRepository.java
index 7a745cc3..13094042 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/NamespaceMemberJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/NamespaceMemberJpaRepository.java
@@ -10,6 +10,9 @@ import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
+/**
+ * JPA-backed repository for namespace membership records and paged member listings.
+ */
@Repository
public interface NamespaceMemberJpaRepository
extends JpaRepository, NamespaceMemberRepository {
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/PromotionRequestJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/PromotionRequestJpaRepository.java
index 88cf99ea..d3ab5db9 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/PromotionRequestJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/PromotionRequestJpaRepository.java
@@ -12,6 +12,9 @@ import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.Optional;
+/**
+ * JPA-backed repository for promotion requests, including optimistic status updates.
+ */
@Repository
public interface PromotionRequestJpaRepository extends JpaRepository,
PromotionRequestRepository {
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/ReviewTaskJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/ReviewTaskJpaRepository.java
index 5ff37a7e..1fc4f7ea 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/ReviewTaskJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/ReviewTaskJpaRepository.java
@@ -12,6 +12,10 @@ import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.Optional;
+/**
+ * JPA-backed repository for review tasks, including optimistic update support for moderation
+ * decisions.
+ */
@Repository
public interface ReviewTaskJpaRepository extends JpaRepository, ReviewTaskRepository {
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillFileJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillFileJpaRepository.java
index db239fb4..21555436 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillFileJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillFileJpaRepository.java
@@ -7,6 +7,9 @@ import org.springframework.stereotype.Repository;
import java.util.List;
+/**
+ * JPA-backed repository for package files attached to one skill version.
+ */
@Repository
public interface SkillFileJpaRepository extends JpaRepository, SkillFileRepository {
List findByVersionId(Long versionId);
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillJpaRepository.java
index d784235a..cd98258e 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillJpaRepository.java
@@ -15,6 +15,9 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
+/**
+ * Base Spring Data JPA repository for persisted skill aggregates and common skill queries.
+ */
@Repository
public interface SkillJpaRepository extends JpaRepository, SkillRepository {
List findByIdIn(List ids);
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillReportJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillReportJpaRepository.java
index 1e352760..a88a0f47 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillReportJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillReportJpaRepository.java
@@ -9,6 +9,9 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
+/**
+ * JPA-backed repository for skill abuse reports and report queues ordered by creation time.
+ */
public interface SkillReportJpaRepository extends JpaRepository, SkillReportRepository {
boolean existsBySkillIdAndReporterIdAndStatus(Long skillId, String reporterId, SkillReportStatus status);
Page findByStatusOrderByCreatedAtDesc(SkillReportStatus status, Pageable pageable);
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillTagJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillTagJpaRepository.java
index 9a8aef3a..a232ebe6 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillTagJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillTagJpaRepository.java
@@ -8,6 +8,9 @@ import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
+/**
+ * JPA-backed repository for tags associated with a skill.
+ */
@Repository
public interface SkillTagJpaRepository extends JpaRepository, SkillTagRepository {
Optional findBySkillIdAndTagName(Long skillId, String tagName);
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillVersionJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillVersionJpaRepository.java
index e6095270..ca35771f 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillVersionJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillVersionJpaRepository.java
@@ -11,6 +11,9 @@ import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
+/**
+ * JPA-backed repository for skill version history and status-oriented version queries.
+ */
@Repository
public interface SkillVersionJpaRepository extends JpaRepository, SkillVersionRepository {
List findByIdIn(List ids);
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillVersionStatsJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillVersionStatsJpaRepository.java
index 3a926142..8dae9601 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillVersionStatsJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/SkillVersionStatsJpaRepository.java
@@ -10,6 +10,9 @@ import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
+/**
+ * JPA-backed repository for per-version statistics, including atomic download counter increments.
+ */
@Repository
public interface SkillVersionStatsJpaRepository extends JpaRepository, SkillVersionStatsRepository {
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/UserAccountJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/UserAccountJpaRepository.java
index 8fbb45cc..f2d4835c 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/UserAccountJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/UserAccountJpaRepository.java
@@ -11,6 +11,9 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
+/**
+ * JPA-backed user-account repository that provides filtered admin search over account records.
+ */
@Repository
public interface UserAccountJpaRepository
extends JpaRepository, JpaSpecificationExecutor, UserAccountRepository {
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/UserNotificationJpaRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/UserNotificationJpaRepository.java
index a4e461f6..5138ef62 100644
--- a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/UserNotificationJpaRepository.java
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/UserNotificationJpaRepository.java
@@ -5,6 +5,9 @@ import com.iflytek.skillhub.domain.governance.UserNotificationRepository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
+/**
+ * JPA-backed repository for notifications shown in the governance inbox.
+ */
public interface UserNotificationJpaRepository extends JpaRepository, UserNotificationRepository {
List findByUserIdOrderByCreatedAtDesc(String userId);
}
diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/package-info.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/package-info.java
new file mode 100644
index 00000000..fb0b3f50
--- /dev/null
+++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * JPA-backed adapters that implement domain repository contracts and other
+ * persistence-side projections.
+ */
+package com.iflytek.skillhub.infra.jpa;
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/HashingSearchEmbeddingService.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/HashingSearchEmbeddingService.java
index b92efe24..66fc338d 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/HashingSearchEmbeddingService.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/HashingSearchEmbeddingService.java
@@ -6,6 +6,10 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
+/**
+ * Lightweight embedding service that hashes lexical tokens into a fixed-size vector for approximate
+ * semantic ranking.
+ */
@Service
public class HashingSearchEmbeddingService implements SearchEmbeddingService {
private static final Pattern TOKEN_SPLITTER = Pattern.compile("[^\\p{L}\\p{N}_]+");
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchEmbeddingService.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchEmbeddingService.java
index 4eec4795..60273d88 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchEmbeddingService.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchEmbeddingService.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.search;
+/**
+ * Converts text into a serialized vector form and evaluates similarity against stored vectors.
+ */
public interface SearchEmbeddingService {
String embed(String text);
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchIndexService.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchIndexService.java
index 5b02ccbb..ccb33bd7 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchIndexService.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchIndexService.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.search;
import java.util.List;
+/**
+ * Writes and removes documents in the search index implementation.
+ */
public interface SearchIndexService {
void index(SkillSearchDocument document);
void batchIndex(List documents);
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchQuery.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchQuery.java
index 595ab6af..3941bc5c 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchQuery.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchQuery.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.search;
+/**
+ * Immutable search request model shared between application code and search implementations.
+ */
public record SearchQuery(
String keyword,
Long namespaceId,
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchQueryService.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchQueryService.java
index 28cfd5d8..66c74e9c 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchQueryService.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchQueryService.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.search;
+/**
+ * Read-side contract for executing skill searches against the configured search backend.
+ */
public interface SearchQueryService {
SearchResult search(SearchQuery query);
}
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchRebuildService.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchRebuildService.java
index 02ade3b4..ccd61e8e 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchRebuildService.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchRebuildService.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.search;
+/**
+ * Rebuilds search index state from authoritative domain data.
+ */
public interface SearchRebuildService {
void rebuildAll();
void rebuildByNamespace(Long namespaceId);
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchResult.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchResult.java
index 04ab826f..a0b6347d 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchResult.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchResult.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.search;
import java.util.List;
+/**
+ * Compact search response containing matching skill identifiers and pagination metadata.
+ */
public record SearchResult(
List skillIds,
long total,
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchVisibilityScope.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchVisibilityScope.java
index cb35d2c6..4f435e35 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchVisibilityScope.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SearchVisibilityScope.java
@@ -2,6 +2,9 @@ package com.iflytek.skillhub.search;
import java.util.Set;
+/**
+ * Caller visibility context used by search implementations to filter results consistently.
+ */
public record SearchVisibilityScope(
String userId,
Set memberNamespaceIds,
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SkillSearchDocument.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SkillSearchDocument.java
index d40fb09f..bf5e413a 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SkillSearchDocument.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/SkillSearchDocument.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.search;
+/**
+ * Denormalized search document model written to and read from the search subsystem.
+ */
public record SkillSearchDocument(
Long skillId,
Long namespaceId,
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/event/SearchIndexEventListener.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/event/SearchIndexEventListener.java
index 74cc7eca..b0fcee58 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/event/SearchIndexEventListener.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/event/SearchIndexEventListener.java
@@ -10,6 +10,9 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
+/**
+ * Reacts to committed skill lifecycle events and keeps the search index synchronized.
+ */
@Component
public class SearchIndexEventListener {
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/event/package-info.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/event/package-info.java
new file mode 100644
index 00000000..cf703287
--- /dev/null
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/event/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Search indexing listeners and event adapters that keep search documents in
+ * sync with domain changes.
+ */
+package com.iflytek.skillhub.search.event;
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/package-info.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/package-info.java
new file mode 100644
index 00000000..5ed7e6f5
--- /dev/null
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Search-facing ports and DTOs that provide skill discovery capabilities.
+ */
+package com.iflytek.skillhub.search;
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresFullTextIndexService.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresFullTextIndexService.java
index b856b82a..6025c7a2 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresFullTextIndexService.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresFullTextIndexService.java
@@ -11,6 +11,9 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
+/**
+ * PostgreSQL-backed search index writer that stores searchable documents and semantic vectors.
+ */
@Service
public class PostgresFullTextIndexService implements SearchIndexService {
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresFullTextQueryService.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresFullTextQueryService.java
index 158bcb25..d5eb7e43 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresFullTextQueryService.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresFullTextQueryService.java
@@ -19,6 +19,13 @@ import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
+/**
+ * PostgreSQL-backed implementation of {@link SearchQueryService}.
+ *
+ * The query pipeline combines structured visibility filters, full-text
+ * ranking, and an optional semantic re-ranking pass over a bounded candidate
+ * set.
+ */
@Service
public class PostgresFullTextQueryService implements SearchQueryService {
private static final Pattern QUERY_TERM_SPLITTER = Pattern.compile("[^\\p{L}\\p{N}_]+");
@@ -56,6 +63,10 @@ public class PostgresFullTextQueryService implements SearchQueryService {
this.maxCandidates = maxCandidates;
}
+ /**
+ * Executes a search query against the denormalized search document table
+ * and optionally re-ranks candidates using embeddings.
+ */
@Override
public SearchResult search(SearchQuery query) {
String normalizedKeyword = normalizeKeyword(query.keyword());
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresSearchRebuildService.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresSearchRebuildService.java
index 59bd51ef..1841a36a 100644
--- a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresSearchRebuildService.java
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/PostgresSearchRebuildService.java
@@ -13,6 +13,9 @@ import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
+/**
+ * Reconstructs PostgreSQL search documents from canonical skill and namespace records.
+ */
@Service
public class PostgresSearchRebuildService implements SearchRebuildService {
diff --git a/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/package-info.java b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/package-info.java
new file mode 100644
index 00000000..6526225b
--- /dev/null
+++ b/server/skillhub-search/src/main/java/com/iflytek/skillhub/search/postgres/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * PostgreSQL-specific search implementations and document models.
+ */
+package com.iflytek.skillhub.search.postgres;
diff --git a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/LocalFileStorageService.java b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/LocalFileStorageService.java
index ba87c7be..86b6b590 100644
--- a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/LocalFileStorageService.java
+++ b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/LocalFileStorageService.java
@@ -9,6 +9,12 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.time.Duration;
import java.util.List;
+/**
+ * Local-disk implementation of {@link ObjectStorageService}.
+ *
+ *
This adapter is intended for development or single-node deployments where
+ * storing objects on the application filesystem is acceptable.
+ */
@Service
@ConditionalOnProperty(name = "skillhub.storage.provider", havingValue = "local", matchIfMissing = true)
public class LocalFileStorageService implements ObjectStorageService {
@@ -18,6 +24,10 @@ public class LocalFileStorageService implements ObjectStorageService {
this.basePath = Paths.get(properties.getLocal().getBasePath()).toAbsolutePath().normalize();
}
+ /**
+ * Stores the incoming stream atomically by writing to a temporary sibling
+ * file before replacing the final path.
+ */
@Override
public void putObject(String key, InputStream data, long size, String contentType) {
try {
@@ -31,12 +41,18 @@ public class LocalFileStorageService implements ObjectStorageService {
} catch (IOException e) { throw new StorageAccessException("putObject", key, e); }
}
+ /**
+ * Opens the stored object as a streaming input.
+ */
@Override
public InputStream getObject(String key) {
try { return Files.newInputStream(resolve(key)); }
catch (IOException e) { throw new StorageAccessException("getObject", key, e); }
}
+ /**
+ * Resolves and deletes a single stored object if it exists.
+ */
@Override
public void deleteObject(String key) {
try { Files.deleteIfExists(resolve(key)); }
diff --git a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/ObjectMetadata.java b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/ObjectMetadata.java
index 8652dfba..f090e038 100644
--- a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/ObjectMetadata.java
+++ b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/ObjectMetadata.java
@@ -2,4 +2,7 @@ package com.iflytek.skillhub.storage;
import java.time.Instant;
+/**
+ * Minimal metadata returned by object-storage providers for one stored object.
+ */
public record ObjectMetadata(long size, String contentType, Instant lastModified) {}
diff --git a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/ObjectStorageService.java b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/ObjectStorageService.java
index 5873f36b..1ba1b45a 100644
--- a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/ObjectStorageService.java
+++ b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/ObjectStorageService.java
@@ -4,6 +4,9 @@ import java.io.InputStream;
import java.time.Duration;
import java.util.List;
+/**
+ * Storage abstraction for binary skill assets and bundles regardless of the backing provider.
+ */
public interface ObjectStorageService {
void putObject(String key, InputStream data, long size, String contentType);
InputStream getObject(String key);
diff --git a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/S3StorageService.java b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/S3StorageService.java
index ae50486c..50062e85 100644
--- a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/S3StorageService.java
+++ b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/S3StorageService.java
@@ -22,6 +22,10 @@ import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.List;
+/**
+ * S3-compatible object storage implementation used for persisted skill packages and generated
+ * download URLs.
+ */
@Service
@ConditionalOnProperty(name = "skillhub.storage.provider", havingValue = "s3")
public class S3StorageService implements ObjectStorageService {
diff --git a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/StorageAccessException.java b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/StorageAccessException.java
index 81f7db15..7f5790bc 100644
--- a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/StorageAccessException.java
+++ b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/StorageAccessException.java
@@ -1,5 +1,8 @@
package com.iflytek.skillhub.storage;
+/**
+ * Wraps provider-specific storage failures with normalized operation and object-key context.
+ */
public class StorageAccessException extends RuntimeException {
private final String operation;
diff --git a/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/package-info.java b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/package-info.java
new file mode 100644
index 00000000..ef098393
--- /dev/null
+++ b/server/skillhub-storage/src/main/java/com/iflytek/skillhub/storage/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Object storage abstraction and concrete storage implementations used for
+ * packaged skill assets.
+ */
+package com.iflytek.skillhub.storage;