test(sql): align contracts with clean initialization

This commit is contained in:
2026-09-17 15:10:27 +08:00
parent 1fe99eb6d0
commit 9dc344bdef
68 changed files with 851 additions and 1448 deletions
@@ -43,12 +43,11 @@ class FinanceContractTest {
assertFalse(operations.contains("bl.source_id=f.source_fee_id"));
String unified = Files.readString(Path.of("../deploy/sql/头程数据库统一增量-MySQL8.sql"));
assertTrue(unified.contains("CREATE DATABASE IF NOT EXISTS baiyue_finance"));
assertTrue(unified.contains("assert_finance_permissions"));
assertTrue(unified.contains("merchant:finance:statement:view"));
int walletEventSchema = unified.indexOf("CREATE TABLE IF NOT EXISTS fin_wallet_event_outbox");
int finalPass = unified.lastIndexOf("SELECT 'PASS' AS migration_status");
int walletEventSchema = unified.indexOf("CREATE TABLE fin_wallet_event_outbox");
int finalPass = unified.lastIndexOf("SELECT 'PASS' AS initialization_status");
assertTrue(walletEventSchema >= 0);
assertTrue(finalPass > walletEventSchema);
assertTrue(unified.contains("CREATE PROCEDURE assert_wallet_event_schema()"));
assertFalse(unified.contains("CREATE PROCEDURE assert_wallet_event_schema()"));
}
}
@@ -22,12 +22,13 @@ class FinanceSettlementSchemaContractTest {
.contains("idx_fin_settlement_customer_direction_status (tenant_id, direction, status)")
.contains("total_amount DECIMAL(20,6)", "paid_amount DECIMAL(20,6)", "outstanding_amount DECIMAL(20,6)")
.contains("updated_at DATETIME(3)");
assertThat(unified)
.contains("CREATE TABLE IF NOT EXISTS fin_settlement (")
.contains("CREATE TABLE IF NOT EXISTS fin_settlement_line (")
.contains("CREATE TABLE IF NOT EXISTS fin_settlement_payment (")
.contains("idx_fin_settlement_customer_direction_status (tenant_id, direction, status)")
.contains("'fin_settlement', 'fin_settlement_line', 'fin_settlement_payment')) <> 16");
String normalized = unified.toLowerCase().replaceAll("\\s+", "");
assertThat(normalized)
.contains("createtablefin_settlement(")
.contains("createtablefin_settlement_line(")
.contains("createtablefin_settlement_payment(")
.contains("idx_fin_settlement_customer_direction_status(tenant_id,direction,status)");
assertThat(unified).doesNotContain("ALTER TABLE fin_settlement", "assert_finance");
}
private static Path resolveUnifiedSql() {
@@ -62,16 +62,14 @@ class FinanceSqlCommentContractTest {
}
@Test
void unifiedMigrationAddsBillLineAdjustmentReasonForNewAndExistingSchemas() throws Exception {
void unifiedInitializationDefinesBillLineAdjustmentReasonDirectly() throws Exception {
Path direct = Path.of("deploy", "sql", "头程数据库统一增量-MySQL8.sql");
Path unified = Files.exists(direct) ? direct : Path.of("..", "deploy", "sql", "头程数据库统一增量-MySQL8.sql");
String sql = Files.readString(unified, StandardCharsets.UTF_8);
assertThat(sql)
.contains("adjustment_reason VARCHAR(500) NULL COMMENT '最近一次账单调整行原因;完整历史保存在修订与审计记录'")
.contains("table_schema='baiyue_finance' AND table_name='fin_bill_line' AND column_name='adjustment_reason'")
.contains("ALTER TABLE baiyue_finance.fin_bill_line ADD COLUMN adjustment_reason")
.contains("queue_column_comment('baiyue_finance', 'fin_bill_line', 'adjustment_reason'");
.contains("adjustment_reason varchar(500) DEFAULT NULL COMMENT '最近一次账单调整行原因;完整历史保存在修订与审计记录'")
.doesNotContain("ALTER TABLE baiyue_finance.fin_bill_line", "queue_column_comment");
}
@Test
@@ -97,12 +95,17 @@ class FinanceSqlCommentContractTest {
assertThat(baseline)
.contains("updated_by_name VARCHAR(128) NULL COMMENT '最后修改操作人名称快照'")
.contains("created_by_name VARCHAR(128) NULL COMMENT '登记操作人名称快照'");
assertThat(unified)
.contains("CALL finance_add_operator_snapshot_column('fin_bill', 'created_by_name', 'created_by')")
.contains("CALL finance_add_operator_snapshot_column('fin_bill', 'updated_by_name', 'updated_by')")
.contains("CALL finance_add_operator_snapshot_column('fin_receipt', 'created_by_name', 'created_by')")
.contains("CALL finance_add_operator_snapshot_column('fin_cost', 'created_by_name', 'created_by')")
.contains("CALL finance_add_operator_snapshot_column('fin_settlement_payment', 'created_by_name', 'created_by')")
.contains("CALL finance_add_operator_snapshot_column('fin_bill_revision', 'created_by_name', 'created_by')");
assertThat(tableBlock(unified, "fin_bill")).contains("created_by_name", "updated_by_name");
assertThat(tableBlock(unified, "fin_receipt")).contains("created_by_name");
assertThat(tableBlock(unified, "fin_cost")).contains("created_by_name");
assertThat(tableBlock(unified, "fin_settlement_payment")).contains("created_by_name");
assertThat(tableBlock(unified, "fin_bill_revision")).contains("created_by_name");
assertThat(unified).doesNotContain("finance_add_operator_snapshot_column");
}
private static String tableBlock(String sql, String table) {
int start = sql.indexOf("CREATE TABLE " + table + " (");
int end = sql.indexOf(';', start);
return start < 0 || end < 0 ? "" : sql.substring(start, end);
}
}
@@ -14,12 +14,14 @@ class FinanceSubjectSeedContractTest {
String module = Files.readString(Path.of("src/main/resources/db/finance.sql"), StandardCharsets.UTF_8);
String unified = Files.readString(Path.of("../deploy/sql/头程数据库统一增量-MySQL8.sql"), StandardCharsets.UTF_8);
for (String sql : new String[] {module, unified}) {
assertThat(sql)
.contains("INSERT INTO fin_subject")
.contains("('PLATFORM_DEFAULT', '平台', 'ACTIVE', 0, 0, 0)")
.contains("ON DUPLICATE KEY UPDATE")
.contains("status = 'ACTIVE'");
}
assertThat(module)
.contains("INSERT INTO fin_subject")
.contains("('PLATFORM_DEFAULT', '平台', 'ACTIVE', 0, 0, 0)")
.contains("ON DUPLICATE KEY UPDATE")
.contains("status = 'ACTIVE'");
assertThat(unified)
.contains("INSERT INTO fin_subject (id, subject_code, subject_name, status")
.contains("VALUES (1,'PLATFORM_DEFAULT','平台','ACTIVE',0,0,0")
.doesNotContain("ON DUPLICATE KEY UPDATE");
}
}
@@ -10,18 +10,16 @@ import static org.assertj.core.api.Assertions.assertThat;
class FinanceWalletContractTest {
@Test
void unifiedMigrationDropsTheLegacyBalanceConstraintBeforeRewritingBalances() throws Exception {
void unifiedInitializationDefinesTheFinalWalletBalanceConstraintWithoutRewritingData() throws Exception {
Path migration = Path.of("deploy/sql/头程数据库统一增量-MySQL8.sql");
if (!Files.exists(migration)) migration = Path.of("..").resolve(migration);
String sql = Files.readString(migration, StandardCharsets.UTF_8);
int procedure = sql.indexOf("CREATE PROCEDURE migrate_fin_wallet_credit()");
int dropConstraint = sql.indexOf("ALTER TABLE fin_wallet_account DROP CHECK chk_fin_wallet_account_balance", procedure);
int rewriteBalance = sql.indexOf("SET actual_balance=actual_balance-credit_used", procedure);
assertThat(procedure).isGreaterThanOrEqualTo(0);
assertThat(sql.substring(procedure, rewriteBalance))
.contains("CHECK_CLAUSE LIKE '%actual_balance%'", "v_legacy_wallet_constraint OR v_credit_expiry_missing");
assertThat(dropConstraint).isBetween(procedure, rewriteBalance - 1);
String account = tableBlock(sql, "fin_wallet_account");
assertThat(account).contains(
"credit_expires_on date DEFAULT NULL",
"CONSTRAINT chk_fin_wallet_account_balance CHECK",
"frozen_balance >= credit_frozen");
assertThat(sql).doesNotContain("migrate_fin_wallet_credit", "SET actual_balance=actual_balance-credit_used");
}
@Test
@@ -68,4 +66,10 @@ class FinanceWalletContractTest {
.contains("/holds/{businessType}/{businessNo}/release")
.contains("Idempotency-Key");
}
private static String tableBlock(String sql, String table) {
int start = sql.indexOf("CREATE TABLE " + table + " (");
int end = sql.indexOf(';', start);
return start < 0 || end < 0 ? "" : sql.substring(start, end);
}
}