diff --git a/deploy/sql/头程数据库统一增量-MySQL8.sql b/deploy/sql/头程数据库统一增量-MySQL8.sql index e44663631..2d3c8eff9 100644 --- a/deploy/sql/头程数据库统一增量-MySQL8.sql +++ b/deploy/sql/头程数据库统一增量-MySQL8.sql @@ -9913,24 +9913,181 @@ WHERE role.tenant_id=0 AND role.role_code IN ('PLATFORM_ADMIN','ORDER_OPERATOR') USE baiyue_firstleg; --- Latest container customs permissions; old case/review/receipt actions are removed. +-- 来源:firstleg/src/main/resources/db/phase3-container-customs-schema.sql +SET NAMES utf8mb4; +USE baiyue_firstleg; + +CREATE TABLE IF NOT EXISTS fl_customs_container ( + id BIGINT UNSIGNED NOT NULL, + loading_plan_id BIGINT UNSIGNED NOT NULL COMMENT '已完成装柜计划ID;报关柜级聚合唯一键', + container_booking_id BIGINT UNSIGNED NOT NULL COMMENT '物理货柜ID', + status VARCHAR(40) NOT NULL COMMENT 'WAITING_CUSTOMER_DOCUMENTS、READY_TO_START、DECLARING、COMPLETED', + started_by BIGINT UNSIGNED NULL, + started_by_name VARCHAR(64) NULL, + started_at DATETIME(3) NULL, + completed_by BIGINT UNSIGNED NULL, + completed_by_name VARCHAR(64) NULL, + completed_at DATETIME(3) NULL, + created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + version INT UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY(id), + UNIQUE KEY uk_customs_container_plan(loading_plan_id), + UNIQUE KEY uk_customs_container_booking(container_booking_id), + KEY idx_customs_container_status(status,updated_at), + CONSTRAINT chk_customs_container_status CHECK(status IN + ('WAITING_CUSTOMER_DOCUMENTS','READY_TO_START','DECLARING','COMPLETED')) +) ENGINE=InnoDB COMMENT='装柜完成后的整柜出口报关聚合'; + +CREATE TABLE IF NOT EXISTS fl_customs_customer_document ( + id BIGINT UNSIGNED NOT NULL, + customs_container_id BIGINT UNSIGNED NOT NULL, + tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户隔离键;只允许关联同客户退税票', + file_id BIGINT UNSIGNED NOT NULL, + file_name VARCHAR(255) NOT NULL, + file_hash CHAR(64) NOT NULL, + content_type VARCHAR(128) NULL, + size_bytes BIGINT UNSIGNED NOT NULL, + status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE', + uploaded_by BIGINT UNSIGNED NOT NULL, + uploaded_at DATETIME(3) NOT NULL, + frozen_version INT UNSIGNED NULL, + frozen_at DATETIME(3) NULL, + deleted_by BIGINT UNSIGNED NULL, + deleted_at DATETIME(3) NULL, + version INT UNSIGNED NOT NULL DEFAULT 1, + created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + PRIMARY KEY(id), + KEY idx_customs_customer_document_container(customs_container_id,status,tenant_id), + CONSTRAINT fk_customs_customer_document_container FOREIGN KEY(customs_container_id) REFERENCES fl_customs_container(id), + CONSTRAINT chk_customs_customer_document_status CHECK(status IN('ACTIVE','DELETED')), + CONSTRAINT chk_customs_customer_document_freeze CHECK((frozen_at IS NULL AND frozen_version IS NULL) OR + (frozen_at IS NOT NULL AND frozen_version IS NOT NULL)) +) ENGINE=InnoDB COMMENT='客户整份退税报送资料逻辑根'; + +CREATE TABLE IF NOT EXISTS fl_customs_customer_document_inbound ( + document_id BIGINT UNSIGNED NOT NULL, + inbound_id BIGINT UNSIGNED NOT NULL, + tenant_id BIGINT UNSIGNED NOT NULL, + order_id BIGINT UNSIGNED NOT NULL, + inbound_code VARCHAR(40) NOT NULL, + created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + PRIMARY KEY(document_id,inbound_id), + KEY idx_customs_document_inbound(inbound_id,tenant_id), + CONSTRAINT fk_customs_document_inbound_document FOREIGN KEY(document_id) REFERENCES fl_customs_customer_document(id) +) ENGINE=InnoDB COMMENT='客户报送资料与当前柜退税入仓码多对多关系'; + +CREATE TABLE IF NOT EXISTS fl_customs_customer_document_version ( + id BIGINT UNSIGNED NOT NULL, + document_id BIGINT UNSIGNED NOT NULL, + document_version INT UNSIGNED NOT NULL, + file_id BIGINT UNSIGNED NOT NULL, + file_name VARCHAR(255) NOT NULL, + file_hash CHAR(64) NOT NULL, + content_type VARCHAR(128) NULL, + size_bytes BIGINT UNSIGNED NOT NULL, + scope_snapshot_json JSON NOT NULL, + action VARCHAR(24) NOT NULL COMMENT 'UPLOAD、REPLACE、SCOPE_CHANGE、DELETE', + operator_id BIGINT UNSIGNED NOT NULL, + created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + PRIMARY KEY(id), + UNIQUE KEY uk_customs_customer_document_version(document_id,document_version), + CONSTRAINT fk_customs_customer_document_version FOREIGN KEY(document_id) REFERENCES fl_customs_customer_document(id), + CONSTRAINT chk_customs_customer_document_version_action CHECK(action IN('UPLOAD','REPLACE','SCOPE_CHANGE','DELETE')) +) ENGINE=InnoDB COMMENT='客户报送资料文件与覆盖范围不可变版本'; + +CREATE TABLE IF NOT EXISTS fl_customs_frozen_document_inbound ( + document_id BIGINT UNSIGNED NOT NULL, + inbound_id BIGINT UNSIGNED NOT NULL, + tenant_id BIGINT UNSIGNED NOT NULL, + order_id BIGINT UNSIGNED NOT NULL, + inbound_code VARCHAR(40) NOT NULL, + created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + PRIMARY KEY(document_id,inbound_id), + CONSTRAINT fk_customs_frozen_document FOREIGN KEY(document_id) REFERENCES fl_customs_customer_document(id) +) ENGINE=InnoDB COMMENT='开始报关时冻结的客户资料覆盖范围'; + +CREATE TABLE IF NOT EXISTS fl_customs_completion_document ( + id BIGINT UNSIGNED NOT NULL, + source_document_id BIGINT UNSIGNED NOT NULL COMMENT '一份冻结客户资料严格对应一份完成文件逻辑根', + file_id BIGINT UNSIGNED NOT NULL, + file_name VARCHAR(255) NOT NULL, + file_hash CHAR(64) NOT NULL, + content_type VARCHAR(128) NULL, + size_bytes BIGINT UNSIGNED NOT NULL, + uploaded_by BIGINT UNSIGNED NOT NULL, + uploaded_by_name VARCHAR(64) NULL, + uploaded_at DATETIME(3) NOT NULL, + version INT UNSIGNED NOT NULL DEFAULT 1, + created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + PRIMARY KEY(id), + UNIQUE KEY uk_customs_completion_source(source_document_id), + CONSTRAINT fk_customs_completion_source FOREIGN KEY(source_document_id) REFERENCES fl_customs_customer_document(id) +) ENGINE=InnoDB COMMENT='报关完成文件当前版本'; + +CREATE TABLE IF NOT EXISTS fl_customs_completion_document_version ( + id BIGINT UNSIGNED NOT NULL, + completion_document_id BIGINT UNSIGNED NOT NULL, + document_version INT UNSIGNED NOT NULL, + file_id BIGINT UNSIGNED NOT NULL, + file_name VARCHAR(255) NOT NULL, + file_hash CHAR(64) NOT NULL, + content_type VARCHAR(128) NULL, + size_bytes BIGINT UNSIGNED NOT NULL, + operator_id BIGINT UNSIGNED NOT NULL, + operator_name VARCHAR(64) NULL, + created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + PRIMARY KEY(id), + UNIQUE KEY uk_customs_completion_version(completion_document_id,document_version), + CONSTRAINT fk_customs_completion_version FOREIGN KEY(completion_document_id) REFERENCES fl_customs_completion_document(id) +) ENGINE=InnoDB COMMENT='报关完成文件不可变覆盖版本'; + +CREATE TABLE IF NOT EXISTS fl_customs_container_history ( + id BIGINT UNSIGNED NOT NULL, + customs_container_id BIGINT UNSIGNED NOT NULL, + action VARCHAR(40) NOT NULL, + from_status VARCHAR(40) NULL, + to_status VARCHAR(40) NULL, + remark VARCHAR(500) NULL, + operator_id BIGINT UNSIGNED NOT NULL, + operator_name VARCHAR(64) NULL, + created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + PRIMARY KEY(id), + KEY idx_customs_container_history(customs_container_id,created_at,id), + CONSTRAINT fk_customs_container_history FOREIGN KEY(customs_container_id) REFERENCES fl_customs_container(id) +) ENGINE=InnoDB COMMENT='整柜报关状态与系统触发历史'; + +CREATE TABLE IF NOT EXISTS fl_customs_command ( + id BIGINT UNSIGNED NOT NULL, + actor_id BIGINT UNSIGNED NOT NULL, + action VARCHAR(80) NOT NULL, + idempotency_key VARCHAR(128) NOT NULL, + request_hash CHAR(64) NOT NULL, + status VARCHAR(16) NOT NULL, + result_id BIGINT UNSIGNED NULL, + created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + completed_at DATETIME(3) NULL, + PRIMARY KEY(id), + UNIQUE KEY uk_customs_command(actor_id,action,idempotency_key), + CONSTRAINT chk_customs_command_status CHECK(status IN('PROCESSING','SUCCESS')) +) ENGINE=InnoDB COMMENT='整柜报关写命令幂等事实'; + USE baiyue_iam; -DELETE rp FROM iam_role_permission rp WHERE rp.permission_id IN (5102171,5102173,5102174,5102175); -DELETE FROM iam_permission WHERE id IN (5102171,5102173,5102174,5102175) - AND permission_code IN ('platform:firstleg:customs:view','platform:firstleg:customs:review','platform:firstleg:customs:submit','platform:firstleg:customs:receipt'); -INSERT INTO iam_permission - (id,tenant_id,app_code,permission_type,parent_id,permission_code,permission_name,route_path,http_method,sort_no,status,built_in,deleted) -VALUES - (5102170,0,'PLATFORM','MENU',5102000,'platform:firstleg:customs:list','整柜报关','/first-leg/customs','GET',100,'ACTIVE',1,0), - (5102172,0,'PLATFORM','BUTTON',5102170,'platform:firstleg:customs:manage','维护整柜报关',NULL,'POST',20,'ACTIVE',1,0) -ON DUPLICATE KEY UPDATE tenant_id=0,app_code='PLATFORM',permission_type=VALUES(permission_type), - permission_code=VALUES(permission_code),permission_name=VALUES(permission_name),parent_id=VALUES(parent_id), - route_path=VALUES(route_path),http_method=VALUES(http_method),sort_no=VALUES(sort_no),status='ACTIVE',built_in=1,deleted=0; +DELETE rp FROM iam_role_permission rp WHERE rp.permission_id IN(5102171,5102173,5102174,5102175); +DELETE FROM iam_permission WHERE id IN(5102171,5102173,5102174,5102175) + AND permission_code IN('platform:firstleg:customs:view','platform:firstleg:customs:review','platform:firstleg:customs:submit','platform:firstleg:customs:receipt'); +INSERT INTO iam_permission(id,tenant_id,app_code,permission_type,parent_id,permission_code,permission_name, + route_path,http_method,sort_no,status,built_in,deleted) VALUES + (5102170,0,'PLATFORM','MENU',5102000,'platform:firstleg:customs:list','整柜报关','/first-leg/customs','GET',100,'ACTIVE',1,0), + (5102172,0,'PLATFORM','BUTTON',5102170,'platform:firstleg:customs:manage','维护整柜报关',NULL,'POST',20,'ACTIVE',1,0) +ON DUPLICATE KEY UPDATE permission_code=VALUES(permission_code),permission_name=VALUES(permission_name), + parent_id=VALUES(parent_id),route_path=VALUES(route_path),http_method=VALUES(http_method),status='ACTIVE',deleted=0; INSERT IGNORE INTO iam_role_permission(role_id,permission_id,tenant_id) -SELECT role.id,permission.id,0 FROM iam_role role JOIN iam_permission permission - ON permission.tenant_id=0 AND permission.app_code='PLATFORM' - AND permission.permission_code IN ('platform:firstleg:customs:list','platform:firstleg:customs:manage') -WHERE role.tenant_id=0 AND role.role_code IN ('PLATFORM_ADMIN','ORDER_OPERATOR'); +SELECT r.id,p.id,0 FROM iam_role r JOIN iam_permission p ON p.tenant_id=0 AND p.app_code='PLATFORM' + AND p.permission_code IN('platform:firstleg:customs:list','platform:firstleg:customs:manage') +WHERE r.tenant_id=0 AND r.role_code IN('PLATFORM_ADMIN','ORDER_OPERATOR'); USE baiyue_firstleg; /* Phase 3: link inbound preload plans to one or more container loading plans. */ CREATE TABLE IF NOT EXISTS fl_preload_loading_plan_link ( @@ -16776,77 +16933,6 @@ BEGIN END$$ DELIMITER ; --- 最新整柜报关基线:装柜完成后收集退税资料,按柜冻结、回传并自动收敛离仓。 -USE baiyue_firstleg; -CREATE TABLE IF NOT EXISTS fl_customs_container( - id BIGINT UNSIGNED NOT NULL,loading_plan_id BIGINT UNSIGNED NOT NULL,container_booking_id BIGINT UNSIGNED NOT NULL, - status VARCHAR(40) NOT NULL,started_by BIGINT UNSIGNED NULL,started_by_name VARCHAR(64) NULL,started_at DATETIME(3) NULL, - completed_by BIGINT UNSIGNED NULL,completed_by_name VARCHAR(64) NULL,completed_at DATETIME(3) NULL, - created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), - version INT UNSIGNED NOT NULL DEFAULT 0,PRIMARY KEY(id),UNIQUE KEY uk_customs_container_plan(loading_plan_id), - UNIQUE KEY uk_customs_container_booking(container_booking_id),KEY idx_customs_container_status(status,updated_at), - CONSTRAINT chk_customs_container_status CHECK(status IN('WAITING_CUSTOMER_DOCUMENTS','READY_TO_START','DECLARING','COMPLETED')) -)ENGINE=InnoDB COMMENT='装柜完成后的整柜出口报关聚合'; -CREATE TABLE IF NOT EXISTS fl_customs_customer_document( - id BIGINT UNSIGNED NOT NULL,customs_container_id BIGINT UNSIGNED NOT NULL,tenant_id BIGINT UNSIGNED NOT NULL, - file_id BIGINT UNSIGNED NOT NULL,file_name VARCHAR(255) NOT NULL,file_hash CHAR(64) NOT NULL,content_type VARCHAR(128) NULL, - size_bytes BIGINT UNSIGNED NOT NULL,status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE',uploaded_by BIGINT UNSIGNED NOT NULL, - uploaded_at DATETIME(3) NOT NULL,frozen_version INT UNSIGNED NULL,frozen_at DATETIME(3) NULL,deleted_by BIGINT UNSIGNED NULL, - deleted_at DATETIME(3) NULL,version INT UNSIGNED NOT NULL DEFAULT 1,created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),PRIMARY KEY(id), - KEY idx_customs_customer_document_container(customs_container_id,status,tenant_id), - CONSTRAINT fk_customs_customer_document_container FOREIGN KEY(customs_container_id) REFERENCES fl_customs_container(id), - CONSTRAINT chk_customs_customer_document_status CHECK(status IN('ACTIVE','DELETED')), - CONSTRAINT chk_customs_customer_document_freeze CHECK((frozen_at IS NULL AND frozen_version IS NULL)OR(frozen_at IS NOT NULL AND frozen_version IS NOT NULL)) -)ENGINE=InnoDB COMMENT='客户整份退税报送资料逻辑根'; -CREATE TABLE IF NOT EXISTS fl_customs_customer_document_inbound( - document_id BIGINT UNSIGNED NOT NULL,inbound_id BIGINT UNSIGNED NOT NULL,tenant_id BIGINT UNSIGNED NOT NULL, - order_id BIGINT UNSIGNED NOT NULL,inbound_code VARCHAR(40) NOT NULL,created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - PRIMARY KEY(document_id,inbound_id),KEY idx_customs_document_inbound(inbound_id,tenant_id), - CONSTRAINT fk_customs_document_inbound_document FOREIGN KEY(document_id) REFERENCES fl_customs_customer_document(id) -)ENGINE=InnoDB COMMENT='客户报送资料与当前柜退税入仓码多对多关系'; -CREATE TABLE IF NOT EXISTS fl_customs_customer_document_version( - id BIGINT UNSIGNED NOT NULL,document_id BIGINT UNSIGNED NOT NULL,document_version INT UNSIGNED NOT NULL,file_id BIGINT UNSIGNED NOT NULL, - file_name VARCHAR(255) NOT NULL,file_hash CHAR(64) NOT NULL,content_type VARCHAR(128) NULL,size_bytes BIGINT UNSIGNED NOT NULL, - scope_snapshot_json JSON NOT NULL,action VARCHAR(24) NOT NULL,operator_id BIGINT UNSIGNED NOT NULL, - created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),PRIMARY KEY(id),UNIQUE KEY uk_customs_customer_document_version(document_id,document_version), - CONSTRAINT fk_customs_customer_document_version FOREIGN KEY(document_id) REFERENCES fl_customs_customer_document(id), - CONSTRAINT chk_customs_customer_document_version_action CHECK(action IN('UPLOAD','REPLACE','SCOPE_CHANGE','DELETE')) -)ENGINE=InnoDB COMMENT='客户报送资料文件与覆盖范围不可变版本'; -CREATE TABLE IF NOT EXISTS fl_customs_frozen_document_inbound( - document_id BIGINT UNSIGNED NOT NULL,inbound_id BIGINT UNSIGNED NOT NULL,tenant_id BIGINT UNSIGNED NOT NULL, - order_id BIGINT UNSIGNED NOT NULL,inbound_code VARCHAR(40) NOT NULL,created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - PRIMARY KEY(document_id,inbound_id),CONSTRAINT fk_customs_frozen_document FOREIGN KEY(document_id) REFERENCES fl_customs_customer_document(id) -)ENGINE=InnoDB COMMENT='开始报关时冻结的客户资料覆盖范围'; -CREATE TABLE IF NOT EXISTS fl_customs_completion_document( - id BIGINT UNSIGNED NOT NULL,source_document_id BIGINT UNSIGNED NOT NULL,file_id BIGINT UNSIGNED NOT NULL, - file_name VARCHAR(255) NOT NULL,file_hash CHAR(64) NOT NULL,content_type VARCHAR(128) NULL,size_bytes BIGINT UNSIGNED NOT NULL, - uploaded_by BIGINT UNSIGNED NOT NULL,uploaded_by_name VARCHAR(64) NULL,uploaded_at DATETIME(3) NOT NULL,version INT UNSIGNED NOT NULL DEFAULT 1, - created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), - PRIMARY KEY(id),UNIQUE KEY uk_customs_completion_source(source_document_id), - CONSTRAINT fk_customs_completion_source FOREIGN KEY(source_document_id) REFERENCES fl_customs_customer_document(id) -)ENGINE=InnoDB COMMENT='报关完成文件当前版本'; -CREATE TABLE IF NOT EXISTS fl_customs_completion_document_version( - id BIGINT UNSIGNED NOT NULL,completion_document_id BIGINT UNSIGNED NOT NULL,document_version INT UNSIGNED NOT NULL, - file_id BIGINT UNSIGNED NOT NULL,file_name VARCHAR(255) NOT NULL,file_hash CHAR(64) NOT NULL,content_type VARCHAR(128) NULL, - size_bytes BIGINT UNSIGNED NOT NULL,operator_id BIGINT UNSIGNED NOT NULL,operator_name VARCHAR(64) NULL, - created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),PRIMARY KEY(id), - UNIQUE KEY uk_customs_completion_version(completion_document_id,document_version), - CONSTRAINT fk_customs_completion_version FOREIGN KEY(completion_document_id) REFERENCES fl_customs_completion_document(id) -)ENGINE=InnoDB COMMENT='报关完成文件不可变覆盖版本'; -CREATE TABLE IF NOT EXISTS fl_customs_container_history( - id BIGINT UNSIGNED NOT NULL,customs_container_id BIGINT UNSIGNED NOT NULL,action VARCHAR(40) NOT NULL, - from_status VARCHAR(40) NULL,to_status VARCHAR(40) NULL,remark VARCHAR(500) NULL,operator_id BIGINT UNSIGNED NOT NULL, - operator_name VARCHAR(64) NULL,created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),PRIMARY KEY(id), - KEY idx_customs_container_history(customs_container_id,created_at,id), - CONSTRAINT fk_customs_container_history FOREIGN KEY(customs_container_id) REFERENCES fl_customs_container(id) -)ENGINE=InnoDB COMMENT='整柜报关状态与系统触发历史'; -CREATE TABLE IF NOT EXISTS fl_customs_command( - id BIGINT UNSIGNED NOT NULL,actor_id BIGINT UNSIGNED NOT NULL,action VARCHAR(80) NOT NULL,idempotency_key VARCHAR(128) NOT NULL, - request_hash CHAR(64) NOT NULL,status VARCHAR(16) NOT NULL,result_id BIGINT UNSIGNED NULL, - created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),completed_at DATETIME(3) NULL,PRIMARY KEY(id), - UNIQUE KEY uk_customs_command(actor_id,action,idempotency_key),CONSTRAINT chk_customs_command_status CHECK(status IN('PROCESSING','SUCCESS')) -)ENGINE=InnoDB COMMENT='整柜报关写命令幂等事实'; -- 同柜且不可拆组:跨客户但同国内仓、渠道和目的仓港,整组锁定/解锁/消费。 USE baiyue_firstleg; CREATE TABLE IF NOT EXISTS fl_coload_group ( diff --git a/firstleg/src/test/java/com/baiyue/firstleg/repository/Phase3FinalUnifiedSqlContractTest.java b/firstleg/src/test/java/com/baiyue/firstleg/repository/Phase3FinalUnifiedSqlContractTest.java index 97b020c93..cf016a6b8 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/repository/Phase3FinalUnifiedSqlContractTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/repository/Phase3FinalUnifiedSqlContractTest.java @@ -78,7 +78,7 @@ class Phase3FinalUnifiedSqlContractTest { for (int id = 5102160; id <= 5102164; id++) assertThat(sql).contains(Integer.toString(id)); for (int id : java.util.List.of(5102170,5102172)) assertThat(sql).contains(Integer.toString(id)); - assertThat(sql).contains("DELETE FROM iam_permission WHERE id IN (5102171,5102173,5102174,5102175)") + assertThat(sql).contains("DELETE FROM iam_permission WHERE id IN(5102171,5102173,5102174,5102175)") .doesNotContain("(5102171,0,'PLATFORM','BUTTON'","(5102173,0,'PLATFORM','BUTTON'", "(5102174,0,'PLATFORM','BUTTON'","(5102175,0,'PLATFORM','BUTTON'"); for (int id = 5102180; id <= 5102183; id++) assertThat(sql).contains(Integer.toString(id)); @@ -111,6 +111,35 @@ class Phase3FinalUnifiedSqlContractTest { "iam/src/main/resources/db/phase3-warehouse-roles.sql"); } + @Test + void customsBaselineIsUniqueSynchronisedAndRunsBeforeFinalSchemaAssertion() throws Exception { + String unified = normalise(Files.readString(resolveUnified())); + String marker = "-- 来源:firstleg/src/main/resources/db/phase3-container-customs-schema.sql"; + String finalAssertion = "CREATE PROCEDURE assert_phase3_final_schema()"; + List tables = List.of( + "fl_customs_container", + "fl_customs_customer_document", + "fl_customs_customer_document_inbound", + "fl_customs_customer_document_version", + "fl_customs_frozen_document_inbound", + "fl_customs_completion_document", + "fl_customs_completion_document_version", + "fl_customs_container_history", + "fl_customs_command" + ); + + assertBlock(unified, marker, "/* Phase 3: link inbound preload plans", + "firstleg/src/main/resources/db/phase3-container-customs-schema.sql"); + assertThat(count(unified, marker)).isEqualTo(1); + assertThat(unified.indexOf(marker)).isLessThan(unified.indexOf(finalAssertion)); + for (String table : tables) { + String create = "CREATE TABLE IF NOT EXISTS " + table + " ("; + assertThat(count(unified, create)).as(table).isEqualTo(1); + assertThat(unified.indexOf(create)).as(table + " before final assertion") + .isLessThan(unified.indexOf(finalAssertion)); + } + } + @Test void financeFeeSourceMigrationsAreContiguousAndSynchronised() throws Exception { String unified = normalise(Files.readString(resolveUnified()));