chore(deploy): synchronize phase3 unified database migration

This commit is contained in:
2026-08-10 13:31:42 +08:00
parent 88390f9401
commit ac085e0f53
6 changed files with 618 additions and 296 deletions
@@ -50,4 +50,74 @@ class Phase3FinalUnifiedSqlContractTest {
.contains("role.role_code IN ('PLATFORM_ADMIN','ORDER_OPERATOR')")
.contains("角色授权未完整写入");
}
@Test
void phase3ModuleSqlBlocksAreContiguousAndSynchronised() throws Exception {
String unified = normalise(Files.readString(resolveUnified()));
assertBlock(unified, "-- 来源:order/src/main/resources/db/phase3-order-parent-child-schema.sql",
"-- 来源:firstleg/src/main/resources/db/phase3-inbound-parent-child-schema.sql",
"order/src/main/resources/db/phase3-order-parent-child-schema.sql");
assertBlock(unified, "-- 来源:firstleg/src/main/resources/db/phase3-inbound-parent-child-schema.sql",
"-- 来源:firstleg/src/main/resources/db/phase3-ocean-booking-schema.sql",
"firstleg/src/main/resources/db/phase3-inbound-parent-child-schema.sql");
assertBlock(unified, "-- 来源:firstleg/src/main/resources/db/phase3-carrier-schedule-query-schema.sql",
"-- 来源:iam/src/main/resources/db/phase3-warehouse-roles.sql",
"firstleg/src/main/resources/db/phase3-carrier-schedule-query-schema.sql");
assertBlock(unified, "-- 来源:iam/src/main/resources/db/phase3-warehouse-roles.sql",
"-- 二、三期对外统一使用 INBOUNDED;历史 WAIT_SPLIT 仅由查询适配为 INBOUNDED,统一迁移不改写主表或历史状态。",
"iam/src/main/resources/db/phase3-warehouse-roles.sql");
}
@Test
void passIsUniqueAndOnlyTheFinalExecutableStatement() throws Exception {
String sql = normalise(Files.readString(resolveUnified()));
String pass = "SELECT 'PASS' AS migration_status";
assertThat(count(sql, pass)).isEqualTo(1);
int passIndex = sql.lastIndexOf(pass);
assertThat(passIndex).isGreaterThan(sql.lastIndexOf("USE "))
.isGreaterThan(sql.lastIndexOf("ALTER TABLE "))
.isGreaterThan(sql.lastIndexOf("CREATE TABLE "))
.isGreaterThan(sql.lastIndexOf("CALL "));
}
@Test
void legacySplitIndexesAreOnlyDroppedAndNeverRecreated() throws Exception {
String sql = normalise(Files.readString(resolveUnified()));
assertThat(sql)
.contains("DROP INDEX uk_inbound_one_child")
.contains("DROP INDEX uk_inbound_one_secondary")
.doesNotContain("UNIQUE KEY `uk_inbound_one_child`")
.doesNotContain("UNIQUE KEY `uk_inbound_one_secondary`")
.doesNotContain("UNIQUE KEY `uk_inbound_split_batch_source_item`");
}
private static void assertBlock(String unified, String marker, String nextMarker, String modulePath)
throws Exception {
int start = unified.indexOf(marker);
int next = unified.indexOf(nextMarker, start + marker.length());
assertThat(start).as("missing marker %s", marker).isGreaterThanOrEqualTo(0);
assertThat(next).as("missing next marker %s", nextMarker).isGreaterThan(start);
String module = normalise(Files.readString(resolve(modulePath))).trim();
String block = unified.substring(start + marker.length(), next).trim();
assertThat(block).as("module block drift: %s", modulePath)
.startsWith(module);
}
private static Path resolveUnified() {
return resolve("deploy/sql/头程数据库统一增量-MySQL8.sql");
}
private static Path resolve(String path) {
Path direct = Path.of(path);
if (Files.exists(direct)) return direct;
return Path.of("..", path).normalize();
}
private static String normalise(String value) {
return value.replace("\r\n", "\n").replace("\uFEFF", "");
}
private static int count(String value, String token) {
return value.split(java.util.regex.Pattern.quote(token), -1).length - 1;
}
}