fix(education): align capability and catalog boundaries
This commit is contained in:
@@ -41,7 +41,8 @@ public class EducationCapabilityController {
|
||||
"answer-save", "session-submit", "practice-report", "vocabulary-review",
|
||||
"exam-reminder", "learning-award", "student-feedback", "learning-summary",
|
||||
"tenant-leaderboard", "content-import-assets", "content-import-jobs",
|
||||
"content-export-policy"))
|
||||
"content-export-policy", "class-management", "class-invitations",
|
||||
"education-entitlements", "resource-product-bindings"))
|
||||
.themes(describeThemes())
|
||||
.catalogReadEnabled(educationProperties.isCatalogReadEnabled())
|
||||
.practiceWriteEnabled(educationProperties.isPracticeWriteEnabled())
|
||||
@@ -58,14 +59,16 @@ public class EducationCapabilityController {
|
||||
List.of("education", "infra"),
|
||||
List.of("production-scanner-adapter", "production-import-parser", "export-artifact-generation"),
|
||||
List.of(), "FEATURE_FLAG", "POSTGRESQL_INTEGRATION_TESTED"),
|
||||
theme("EDU-012", "classes-relationships", "BLOCKED",
|
||||
theme("EDU-012", "classes-relationships", "BOUNDED_IMPLEMENTED",
|
||||
List.of("education", "member", "system"),
|
||||
List.of("relationship-role-model", "class-data-scope", "invitation-contract"),
|
||||
List.of(), "FEATURE_FLAG", "CONTRACT_ONLY"),
|
||||
List.of("teacher-role-expansion", "platform-admin-cross-tenant-operations"),
|
||||
List.of(), "FEATURE_FLAG", "POSTGRESQL_INTEGRATION_TESTED",
|
||||
List.of("/admin-api/education/classes", "/app-api/education/class-invitations")),
|
||||
theme("EDU-013", "commercialization", "BOUNDED_IMPLEMENTED",
|
||||
List.of("education", "mall", "pay"),
|
||||
List.of("education", "mall", "pay", "member", "crm"),
|
||||
List.of("mall-order-item-public-event", "pay-refund-public-event", "crm-referral-contract"),
|
||||
List.of(), "ACCESS_FAIL_CLOSED", "POSTGRESQL_INTEGRATION_TESTED"),
|
||||
List.of(), "ACCESS_FAIL_CLOSED", "POSTGRESQL_INTEGRATION_TESTED",
|
||||
List.of("/admin-api/education/commercialization", "EducationEntitlementApi")),
|
||||
theme("EDU-014", "extended-learning", "PARTIAL",
|
||||
List.of("education", "member", "system"),
|
||||
List.of("video-entitlement-contract", "ai-recommendation-contract", "legacy-data-import"),
|
||||
|
||||
@@ -57,6 +57,9 @@ public class QuestionCatalogServiceImpl implements QuestionCatalogService {
|
||||
int pageNo = reqVO.getPageNo() != null ? reqVO.getPageNo() : 1;
|
||||
int pageSize = reqVO.getPageSize() != null ? reqVO.getPageSize() : 20;
|
||||
|
||||
if (reqVO.getCollectionId() != null && !reqVO.getCollectionId().isBlank()) {
|
||||
assertCollectionAccess(reqVO.getCollectionId());
|
||||
}
|
||||
CatalogQuestionPageResult pageResult = provider.listQuestions(
|
||||
reqVO.getCollectionId(), reqVO.getNodeId(),
|
||||
reqVO.getType(), reqVO.getDifficulty(),
|
||||
@@ -127,6 +130,9 @@ public class QuestionCatalogServiceImpl implements QuestionCatalogService {
|
||||
}
|
||||
int requestedCount = reqVO.getQuestionCount() != null ? reqVO.getQuestionCount() : 10;
|
||||
|
||||
if (reqVO.getCollectionId() != null && !reqVO.getCollectionId().isBlank()) {
|
||||
assertCollectionAccess(reqVO.getCollectionId());
|
||||
}
|
||||
CatalogPracticeBlueprintDTO blueprint = provider.getPracticeBlueprint(
|
||||
reqVO.getCollectionId(), reqVO.getNodeId(),
|
||||
reqVO.getType(), reqVO.getDifficulty());
|
||||
|
||||
@@ -52,12 +52,21 @@ public class EducationCapabilityControllerTest {
|
||||
assertEquals("1.0.0-test", data.getVersion(), "版本应匹配");
|
||||
assertNotNull(data.getCapabilities(), "能力列表不应为空");
|
||||
assertTrue(data.getCapabilities().contains("shell"), "应包含 shell 能力");
|
||||
assertTrue(data.getCapabilities().containsAll(List.of("class-management", "class-invitations",
|
||||
"education-entitlements", "resource-product-bindings")), "能力清单应包含已交付的 EDU-012/013 接口");
|
||||
assertNotNull(data.getThemes(), "迁移主题不应为空");
|
||||
assertEquals(5, data.getThemes().size(), "应完整列出 EDU-011 至 EDU-015");
|
||||
assertEquals(5, data.getThemes().stream().map(EducationThemeRespVO::getKey).distinct().count(),
|
||||
"迁移主题不应重复");
|
||||
assertTrue(data.getThemes().stream().noneMatch(theme -> "AVAILABLE".equals(theme.getStatus())),
|
||||
"未交付主题不得声明为可用");
|
||||
EducationThemeRespVO classes = data.getThemes().stream()
|
||||
.filter(theme -> "EDU-012".equals(theme.getKey())).findFirst().orElseThrow();
|
||||
assertEquals("BOUNDED_IMPLEMENTED", classes.getStatus(), "EDU-012 已交付的有界能力不得继续标为阻塞");
|
||||
assertTrue(classes.getExecutableInterfaces().contains("/admin-api/education/classes"));
|
||||
EducationThemeRespVO commercialization = data.getThemes().stream()
|
||||
.filter(theme -> "EDU-013".equals(theme.getKey())).findFirst().orElseThrow();
|
||||
assertTrue(commercialization.getExecutableInterfaces().contains("EducationEntitlementApi"));
|
||||
EducationThemeRespVO operations = data.getThemes().stream()
|
||||
.filter(theme -> "EDU-015".equals(theme.getKey())).findFirst().orElseThrow();
|
||||
assertEquals("LEGACY_DEPENDENT", operations.getStatus(), "默认 Scalar 模式必须披露遗留依赖");
|
||||
|
||||
Reference in New Issue
Block a user