diff --git a/muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAiRuntimeEndToEndLiveAcceptanceIT.java b/muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAiRuntimeEndToEndLiveAcceptanceIT.java index 76fcd8c1..13717f4d 100644 --- a/muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAiRuntimeEndToEndLiveAcceptanceIT.java +++ b/muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAiRuntimeEndToEndLiveAcceptanceIT.java @@ -10,7 +10,9 @@ import cn.iocoder.muse.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.muse.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.muse.framework.tenant.core.util.TenantUtils; import cn.iocoder.muse.module.ai.application.muse.MuseAiAuditServiceImpl; +import cn.iocoder.muse.module.ai.application.muse.MuseAiCandidateReviewService; import cn.iocoder.muse.module.ai.application.muse.MuseAiCommandServiceImpl; +import cn.iocoder.muse.module.ai.application.muse.MuseAiEventPublishOutboxService; import cn.iocoder.muse.module.ai.application.muse.MuseAiRuntimeCallRecorder; import cn.iocoder.muse.module.ai.application.muse.MuseAiRuntimeJobExecutor; import cn.iocoder.muse.module.ai.application.muse.MuseAiRuntimePayloadStore; @@ -19,6 +21,7 @@ import cn.iocoder.muse.module.ai.application.muse.MuseAiRuntimeProjectionService import cn.iocoder.muse.module.ai.application.muse.MuseAiRuntimeServiceImpl; import cn.iocoder.muse.module.ai.application.muse.MuseAiTaskService; import cn.iocoder.muse.module.ai.application.muse.MuseAiTaskServiceImpl; +import cn.iocoder.muse.module.ai.application.muse.facade.KnowledgeRetrievalFacade; import cn.iocoder.muse.module.ai.application.muse.facade.MuseAiRuntimeClient; import cn.iocoder.muse.module.ai.application.muse.facade.MuseContentWorkOwnerFacade; import cn.iocoder.muse.module.ai.application.muse.facade.RealNewApiMuseAiRuntimeClient; @@ -110,7 +113,9 @@ class P1rAiRuntimeEndToEndLiveAcceptanceIT { private static final String FLYWAY_LOCATION_PROPERTY = "p1r.flyway.locations"; private static final String POSTGRESQL_JDBC_PREFIX = "jdbc:postgresql://"; private static final String JDBC_URI_PREFIX = "jdbc:"; - private static final String TARGET_VERSION = "13"; + // 必须迁到当前最高版本 V31:V30 把 muse_ai_suggestion.authorization_snapshot_id 由 BIGINT 加宽为 VARCHAR(128) + // 以承载字符串 runtime permission envelope(ADR-020);若停在旧版本,投影写字符串授权快照会触发 bigint 类型不匹配。 + private static final String TARGET_VERSION = "31"; // 固定 test-only AES 密钥,供 EncryptTypeHandler 写入 live payload 时读取;不从用户环境变量取值。 private static final String TEST_ENCRYPTOR_PASSWORD = "p1rLiveEncrypt16"; private static final Long TENANT_ID = 100L; @@ -465,7 +470,7 @@ class P1rAiRuntimeEndToEndLiveAcceptanceIT { flyway.migrate(); MigrationInfo current = flyway.info().current(); assertEquals(TARGET_VERSION, Objects.requireNonNull(current, "必须存在当前 Flyway 版本") - .getVersion().getVersion(), "P1R-4 AI runtime live acceptance 至少需要 V13 schema"); + .getVersion().getVersion(), "P1R-4 AI runtime live acceptance 需迁到 V31 schema(含 V30 授权快照列 BIGINT→VARCHAR)"); return dbEngine; } @@ -957,6 +962,7 @@ class P1rAiRuntimeEndToEndLiveAcceptanceIT { MuseAiRuntimeJobExecutor.class, MuseAiRuntimeCallRecorder.class, MuseAiRuntimeProjectionService.class, + MuseAiCandidateReviewService.class, MuseAiRuntimeServiceImpl.class, MuseAiRuntimePolicyProvider.class, MuseAiRuntimePayloadStore.class, @@ -965,6 +971,29 @@ class P1rAiRuntimeEndToEndLiveAcceptanceIT { }) static class LiveAcceptanceConfiguration { + /** + * 运行时投影服务 {@link MuseAiRuntimeProjectionService} 通过 {@code @Resource} 强依赖事件投递 outbox 服务; + * 本 live-acceptance 仅断言 muse_ai_generation/job/runtime_call/task_event 等核心落库,不校验 outbox 行, + * 故提供空实现满足 bean 注入即可(与 {@code P1rContentMergeGeneratedSuggestionIT} 同源做法), + * 不引入真实 impl 以免把 outbox mapper 事务语义牵入本上下文。 + */ + @Bean + MuseAiEventPublishOutboxService museAiEventPublishOutboxService() { + return event -> { + }; + } + + /** + * 运行时 job executor 通过 {@code @Resource} 强依赖知识检索 facade(P-A/P-C 检索串联引入)。 + * 本 live-acceptance 只验证 AI 生成→runtime_call→落库主链,不校验知识检索上下文(那是 + * {@code P1rKnowledgeRuntimeEndToEndLiveAcceptanceIT} 的职责),故返回 facade 契约自带的 + * 「无命中/降级」空上下文({@link KnowledgeRetrievalFacade.ContextAssembly#empty}),executor 设计上对此幂等放行。 + */ + @Bean + KnowledgeRetrievalFacade knowledgeRetrievalFacade() { + return request -> KnowledgeRetrievalFacade.ContextAssembly.empty("p1r-live-ai-runtime-skip-retrieval"); + } + @Bean MuseAiProperties museAiProperties() { MuseAiProperties properties = new MuseAiProperties();