release: 合并最新 TEST 并发布阿里云灰度

按本轮授权合并经过验证的发布候选,保留 main 已有修复。
This commit was merged in pull request #42.
This commit is contained in:
2026-11-06 14:16:54 +08:00
4 changed files with 33 additions and 25 deletions
@@ -11,14 +11,15 @@ import static org.assertj.core.api.Assertions.assertThat;
class LoadingEvidenceSqlContractTest {
@Test
void schemaOwnsEvidenceByCabinetWithOneActiveFactPerType() throws Exception {
void schemaOwnsMultipleEvidencePhotosByCabinetAndKeepsOperationIdempotency() throws Exception {
String sql = new ClassPathResource("db/phase3-loading-delivery-schema.sql")
.getContentAsString(StandardCharsets.UTF_8);
assertThat(sql)
.contains("CREATE TABLE IF NOT EXISTS fl_loading_cabinet_evidence")
.contains("container_booking_id BIGINT UNSIGNED NOT NULL")
.contains("source_task_id BIGINT UNSIGNED NOT NULL")
.contains("UNIQUE KEY uk_cabinet_evidence_active (container_booking_id,evidence_type,active_flag)")
.contains("KEY idx_cabinet_evidence_active (container_booking_id,evidence_type,active_flag)")
.doesNotContain("UNIQUE KEY uk_cabinet_evidence_active")
.contains("UNIQUE KEY uk_cabinet_evidence_operation (source_task_id,operation_key)")
.contains("DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci")
.contains("FOREIGN KEY (container_booking_id) REFERENCES fl_container_booking(id)")
@@ -31,7 +32,8 @@ class LoadingEvidenceSqlContractTest {
Path unified = Files.exists(direct) ? direct : Path.of("..", "deploy", "sql", "头程数据库统一增量-MySQL8.sql");
String sql = Files.readString(unified, StandardCharsets.UTF_8);
assertThat(sql).contains("CREATE TABLE fl_loading_cabinet_evidence")
.contains("uk_cabinet_evidence_active")
.contains("idx_cabinet_evidence_active")
.doesNotContain("uk_cabinet_evidence_active")
.contains("uk_cabinet_evidence_operation")
.contains("FOREIGN KEY (container_booking_id) REFERENCES fl_container_booking (id)")
.doesNotContain("CREATE TABLE fl_loading_evidence")
@@ -11,7 +11,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class ContainerWorkbenchSqlContractTest {
@Test
void pagesDomesticAndOverseasScopesFromOwnedActualFactsWithoutCopyingShipNodeSql() throws Exception {
void pagesDomesticAndOverseasScopesFromDispatchAndEmptyReturnFacts() throws Exception {
String sql = String.join("\n", ContainerBookingMapper.class
.getMethod("selectBookingPage", com.baomidou.mybatisplus.extension.plugins.pagination.Page.class,
com.baiyue.firstleg.dto.ContainerDtos.Query.class, String.class)
@@ -19,9 +19,10 @@ class ContainerWorkbenchSqlContractTest {
assertThat(sql).contains("#{workbench}='DOMESTIC'", "#{workbench}='OVERSEAS'",
"#{query.scope}='ACTIVE'", "#{query.scope}='HISTORY'", "fl_outbound_dispatch",
"confirmed_at IS NOT NULL", "b.actual_empty_reported_at IS NULL",
"b.actual_empty_reported_at IS NOT NULL", "outbound_dispatch_status")
.doesNotContain("fl_carrier_schedule_query", "fl_carrier_schedule_node_fact");
"confirmed_at IS NOT NULL", "fl_terminal_drayage returned",
"returned.actual_empty_return_at IS NOT NULL", "returned_node.standard_node='EMPTY_RETURNED'",
"returned_node.actual_at IS NOT NULL", "outbound_dispatch_status")
.doesNotContain("fl_carrier_schedule_query", "b.actual_empty_reported_at");
}
@Test
@@ -32,9 +32,6 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -178,7 +175,7 @@ class FbaPricingRepositoryRuleListTest {
}
@Test
void feeSendFromLegacyFlowAdvancesToWaitingPallet() {
void feeSendPreservesFulfillmentAndRequiresApprovedMeasurement() {
when(pricing.update(org.mockito.ArgumentMatchers.isNull(), org.mockito.ArgumentMatchers.any()))
.thenReturn(1);
@@ -188,25 +185,32 @@ class FbaPricingRepositoryRuleListTest {
ArgumentCaptor<LambdaUpdateWrapper<InboundPricingEntity>> wrapper =
ArgumentCaptor.forClass(LambdaUpdateWrapper.class);
verify(pricing).update(org.mockito.ArgumentMatchers.isNull(), wrapper.capture());
assertThat(wrapper.getValue().getSqlSet()).contains("feeStatus").contains("processStatus");
assertThat(wrapper.getValue().getCustomSqlSegment()).contains("tenantId", "id", "processStatus", "feeStatus");
assertThat(wrapper.getValue().getSqlSet()).contains("feeStatus").doesNotContain("processStatus");
assertThat(wrapper.getValue().getCustomSqlSegment())
.contains("tenantId", "id", "processStatus", "measureReviewStatus", "feeStatus");
assertThat(params(wrapper.getValue()).values())
.contains(10001L, 88L, "FEE_CONFIRMING", "CONFIRMED", "SENT", "WAIT_PALLET");
.contains(10001L, 88L, "FEE_CONFIRMING", "APPROVED", "CONFIRMED", "SENT")
.doesNotContain("WAIT_PALLET");
}
/** 费用确认状态集覆盖待组托及后续履约阶段。 */
@Test
void feeConfirmationAllowsPalletizationAndPostLoadingInboundStatuses() {
String source;
try {
source = Files.readString(Path.of(
"src/main/java/com/baiyue/firstleg/repository/FbaPricingRepository.java"),
StandardCharsets.UTF_8);
} catch (java.io.IOException exception) {
throw new AssertionError(exception);
}
assertThat(source)
.contains("List.of(\"FEE_CONFIRMING\", \"WAIT_PALLET\", \"WAIT_PALLETIZE\", \"WAIT_SPLIT\", \"LOADING\", \"LOADED\", \"DELIVERED\")");
when(pricing.update(org.mockito.ArgumentMatchers.isNull(), org.mockito.ArgumentMatchers.any()))
.thenReturn(1);
assertThat(repository.markInboundConfirmed(10001L, 88L)).isEqualTo(1);
@SuppressWarnings("unchecked")
ArgumentCaptor<LambdaUpdateWrapper<InboundPricingEntity>> wrapper =
ArgumentCaptor.forClass(LambdaUpdateWrapper.class);
verify(pricing).update(org.mockito.ArgumentMatchers.isNull(), wrapper.capture());
assertThat(wrapper.getValue().getSqlSet()).contains("feeStatus").doesNotContain("processStatus");
assertThat(wrapper.getValue().getCustomSqlSegment())
.contains("processStatus", "measureReviewStatus", "feeStatus");
assertThat(params(wrapper.getValue()).values())
.contains("WAIT_PRICING", "FEE_CONFIRMING", "WAIT_PALLET", "WAIT_PALLETIZE", "WAIT_SPLIT",
"LOADING", "LOADED", "DELIVERED", "APPROVED", "CALCULATED", "CONFIRMED");
}
@Test
@@ -45,7 +45,8 @@ class Phase3FinalUnifiedSqlContractTest {
void unifiedEntryKeepsFinalConstraintsAndImmutableTriggers() throws Exception {
String sql = sql();
assertThat(sql)
.contains("UNIQUE KEY uk_cabinet_evidence_active (container_booking_id,evidence_type,active_flag)")
.contains("KEY idx_cabinet_evidence_active (container_booking_id,evidence_type,active_flag)")
.doesNotContain("UNIQUE KEY uk_cabinet_evidence_active")
.contains("UNIQUE KEY uk_cabinet_evidence_operation (source_task_id,operation_key)")
.contains("UNIQUE KEY uk_inbound_one_active_remainder")
.contains("UNIQUE KEY uk_inbound_split_source_once")