测试环境 SQL 执行说明
唯一数据库初始化与发布入口
- 国内区域固定入口:
头程数据库统一增量-MySQL8.sql。文件名保留历史兼容,内容维护为当前完整数据库基线和存量环境兼容升级,不再按日期拆分发布脚本。 - 海外区域固定增量入口:
海外区域统一增量-MySQL8.sql;空库先分别执行lastleg-service/src/main/resources/db/lastleg.sql与warehouse-overseas-service/src/main/resources/db/warehouse.sql基线,再执行该入口。固定入口会创建并校验独立的baiyue_event_bridge_overseas,再升级baiyue_lastleg与baiyue_lastlag_warehouse;IAM 安全事件 Inbox 和可恢复投影已并入baiyue_lastleg.ll_security_*,Redis 只作可重建镜像。 - Lastleg 基线和海外固定增量仅确定性初始化国内固定
platform_admin(authUserId=1000001、tenantId=0)的 USER/AUTHORIZATION version=0 安全投影;其他既有开发账号不建立兼容表或长期补投入口。 - 国内、海外 Compose 部署默认设置
SPRING_SQL_INIT_MODE=never,执行任一 SQL 均需用户单独授权。 - 该脚本汇总订单与客户、入库测量与计费及已实现国内货柜履约出仓能力的数据库基线、存量升级、IAM 权限资源和最终结构校验,适用于 MySQL 8.0。
- 正式上线前的数据库变更直接维护该文件中的当前基线、存量兼容处理和最终校验,不再创建按日期拆分的发布 SQL;正式上线后的迁移策略在生产发布规范中另行冻结。
- 当前测试环境尚未上线,船期价格表相关表、字段和索引只维护在现有初始化建表定义及本固定入口中,不向
phase1-order-extension.sql、phase2-fba-pricing-migration.sql或新的增量脚本追加同一结构。 - 模块
src/main/resources/db/下的 SQL 用于开发溯源;deploy/sql/下已有日期文件全部冻结为历史记录,不再单独部署,也不得与固定入口重复执行。 - 固定入口不包含
auth/phase1-admin-accounts.sql和warehouse/warehouse-seed.sql;仅在开发/测试基线账号缺失时创建平台管理员,重复执行不覆盖现有密码。脚本不创建固定客户、客户账号或演示订单;客户必须通过正式建档/注册流程创建。正式平台公共仓库主数据已内联到固定入口;义乌、东莞、洛杉矶、纽约四个固定作业仓均初始化RECEIVING,其中洛杉矶和纽约使用海外接柜入仓收货语义,FBA 目的地址不创建作业能力。 warehouse/phase2-pallet-location-schema-migration.sql的有效结构已被当前phase2-pallet-location-schema.sql和后续共享溢出位迁移完整覆盖,因此不重复内联,避免每次部署无条件删除并重建同名唯一索引。- 脚本会创建 9 个独立数据库:
baiyue_auth、baiyue_iam、baiyue_order、baiyue_warehouse、baiyue_firstleg、baiyue_file、baiyue_audit、baiyue_event_bridge、baiyue_finance。Gateway、Print、Integration Service 无数据库。 - IAM 消息中心基线已内联到固定入口,包括 5 张
iam_notification_*表、任务/事件幂等约束、平台消息管理权限、企业成员收件箱权限及默认角色授权;模块溯源脚本为iam/src/main/resources/db/notification-center.sql。 - IAM 跨区安全事件基线已内联到固定入口,包括主体权限版本、客户状态版本和可靠事件发送箱 3 张表;模块溯源脚本为
iam/src/main/resources/db/security-event-outbox.sql。IAM 新版本启动前必须先执行固定入口,避免安全事件 Relay 和授权快照查询因缺表失败。 - 完整执行所有增量区块并通过末段真实结构校验后,脚本最末才会返回唯一的
PASS;任一强校验失败会通过SIGNAL终止。
后续追加增量必须满足:
- 只新增或兼容升级,不清表、不删除业务数据。
- 新字段、索引、约束必须先查询
information_schema,允许整份脚本重复执行。 - 系统权限或字典配置使用唯一键和
ON DUPLICATE KEY UPDATE幂等写入。 - 每个增量区块末尾增加只读断言,并同步维护统一脚本末尾的总体验证。
- MySQL DDL 会隐式提交,执行前仍应在目标环境确认连接和授权;不能把跨库脚本视为可整体回滚事务。
Finance 首期人工财务基线
- Finance 数据库为
baiyue_finance,模块溯源脚本为finance/src/main/resources/db/finance.sql,测试和存量环境仍只执行统一入口。 - 首期只支持 CNY,包含平台主体、客户默认 30 天账期、账单及明细、人工收款及账单分配、单票/整柜人工成本、体积分摊结果、Firstleg 费用来源事件、幂等记录和不可变审计日志。
- 不包含钱包、发票、供应商在线应付、银行自动对账、复杂核销、汇率和月结。
- 统一脚本末尾会强校验 13 张 Finance 表、客户隔离/CNY/人工凭证关键字段,以及费用来源、Inbox、账单版本快照、收款、成本和写操作幂等唯一约束;任一缺失不会返回
PASS。
历史订单与客户回归脚本
- 历史文件:
2026-07-31订单与客户回归测试环境增量迁移.sql,仅供追溯,不再作为统一入口。 - 适用数据库:MySQL 8.0。
- 执行账号需要对
baiyue_iam、baiyue_warehouse、baiyue_order、baiyue_firstleg具备建表、改表、建索引、创建临时存储过程和数据写入权限。 - 脚本不会创建数据库,不会清理或删除业务数据,也不会写入演示租户、演示用户、演示仓库、演示往来单位或快递公司样本。
- 脚本可重复执行。MySQL 的 DDL 会隐式提交,因此不能把整份跨库脚本视为可整体回滚的事务。
- 该历史脚本曾内联 IAM 客户档案字段迁移和
platform:customer:view权限迁移,当前不得再单独执行。
IAM 来源与执行顺序
固定入口中的 IAM 段按以下模块迁移依赖顺序组织,并通过元数据判断或 ON DUPLICATE KEY UPDATE 保持可重复执行:
- IAM 基线表必须已存在(
iam.sql)。 - 权限父菜单和既有客户列表/审核权限基线(
phase1-admin-rbac.sql、rbac-role-management-v2.sql)。 phase1-platform-master-data-and-permission-management.sql中的platform:customer:view、既有角色继承及管理员授权。phase1-customer-profile.sql中的十个iam_tenant客户档案字段。phase1-onboarding.sql中的PROFILE_REQUIRED默认状态、审核结果字段、资质审核备注及成员审计字段。
固定入口同时幂等补齐审核自动开户所需的全局 MERCHANT_OWNER 角色模板、全局商户菜单/按钮权限和角色授权;执行后应使用 iam/src/test/resources/db/verify-phase1-admin-rbac.sql 确认模板存在且权限完整。
测试环境只执行当前固定入口;历史脚本和模块脚本不应在固定入口执行后再次串行执行。
执行方式
在 Navicat、DataGrip 或 MySQL 命令行中以“运行脚本”方式完整执行,确保客户端支持 DELIMITER。不要只选中局部语句执行。
执行前先重新连接目标数据库,开启客户端 keepalive,并关闭“遇错继续执行”;出现连接断开、语法错误或 SQLSTATE 45000 后不得从失败位置续跑。由于 DDL 会隐式提交,存量环境可能已经部分更新;修复失败原因后应使用同一固定入口从第一行完整重跑,依靠脚本的元数据判断和幂等写入收敛结构。若出现 MySQL 4031,先处理客户端连接保活或由数据库管理员调整 wait_timeout / interactive_timeout,再重新连接执行。
执行结束后必须看到 migration_status = PASS。如果中途出现 SQLSTATE 45000,必须按错误中给出的缺失表、字段或权限处理后重新完整执行。
国内货柜履约分柜、预装、拣货与装柜当前基线
- 模块表结构来源:
firstleg/src/main/resources/db/phase3-split-preload-schema.sql、firstleg/src/main/resources/db/phase3-loading-delivery-schema.sql。 - 国内货柜履约平台权限直接维护在统一初始化与发布入口中,避免额外增加独立权限脚本。
- 测试和生产环境仍只执行固定入口
头程数据库统一增量-MySQL8.sql,不得再串行执行上述模块脚本。 - 必须先执行统一增量并取得
PASS,再启动或重启 Firstleg Service;否则统一订单摘要查询会因缺少国内货柜履约操作表而失败。 - 统一脚本会创建智能装柜任务
fl_loading_pick_task,并把历史入库汇总任务按字段签名无损迁移到fl_inbound_loading_pick_task;未知混合结构会直接终止。WAIT_SPLIT是入库测量与计费有效终点,脚本不会改写主表或状态历史。 - 下载中心固定使用
5103040-5103041,库位权限迁移到5103060-5103064;入库装柜权限迁移到5102121-5102129,迁移会按permission_code保留角色授权,目标 ID 被其他语义占用时直接终止。
部署前可只读盘点:
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'baiyue_firstleg'
AND table_name IN (
'fl_preload_plan', 'fl_split_operation', 'fl_loading_evidence',
'fl_loading_operation', 'fl_loading_pick_task'
)
ORDER BY table_name;
SELECT permission_code
FROM baiyue_iam.iam_permission
WHERE tenant_id = 0 AND app_code = 'PLATFORM' AND status = 'ACTIVE' AND deleted = 0
AND permission_code IN (
'firstleg:inbound:split', 'firstleg:inbound:preload',
'firstleg:inbound:preload-view',
'platform:firstleg:inbound:loading:edit',
'platform:firstleg:inbound:loading:view',
'platform:firstleg:inbound:loading:complete',
'platform:firstleg:inbound:delivery:complete',
'platform:firstleg:inbound:picking:edit',
'platform:firstleg:inbound:picking:view'
)
ORDER BY permission_code;
公共导出中心存量升级
固定入口已包含 File 当前 6 张表,并通过 information_schema 为旧版 file_export_task 幂等补齐 8 个调度、重试和租约字段,不再允许通过 DROP TABLE 重建。执行完成后可额外核验:
SELECT COUNT(*) = 3 AS export_tables_ready
FROM information_schema.tables
WHERE table_schema = 'baiyue_file'
AND table_name IN ('file_export_task', 'file_export_outbox', 'file_export_task_guard');
SELECT COUNT(*) = 1 AS creation_guard_ready
FROM baiyue_file.file_export_task_guard
WHERE guard_key = 'GLOBAL_CREATE';
SELECT COUNT(*) = 8 AS scheduler_columns_ready
FROM information_schema.columns
WHERE table_schema = 'baiyue_file' AND table_name = 'file_export_task'
AND column_name IN ('dispatch_version', 'attempt_count', 'max_attempts', 'next_retry_at',
'lease_owner', 'lease_until', 'last_heartbeat_at', 'execution_deadline_at');
任一结果不是 1,禁止启动 File Service;只能继续追加兼容性增量修复,不得删除存量导出任务。
入库测量与计费第三方测量增量
- 模块脚本:
firstleg/src/main/resources/db/phase2-third-party-single-measurement-migration.sql。 - 历史入库测量与计费脚本:
2026-08-04-入库新增表字段-MySQL8一键执行.sql已冻结,仅供追溯。 - 当前固定入口
头程数据库统一增量-MySQL8.sql已内联该增量以及订单船司字段、入库测量与计费 28 项 IAM 权限和最新仓储资源租户字段。 - 新增
external_request_hash、inbound_detail_id、external_detail_no和第三方明细唯一索引,用于一条回传绑定一条订单货物明细及一张文件中心图片。 - 部署 Firstleg 新版本前必须完整执行固定入口,并确认末尾总体验证为
PASS。
稳定箱号与单箱当前测量
- 固定入口已包含
fl_inbound_carton_label,首次打印时按订单货物明细冻结每个实际箱的box_code和箱下标;重复打印、部分补打及设备测量均复用该映射。 fl_inbound_measurement_item已补齐box_code、machine_no、device_measured_at、updated_at,并通过uk_measure_box_code (tenant_id, box_code)保证同一客户下每个箱号只有一条当前测量记录。- 部署 Firstleg 新版本前必须完整执行固定入口。末尾会强校验映射表、四个测量字段及三个唯一约束,任一缺失均不会返回
PASS。
当前主体字段语义核验
- 业务单租户阶段,业务表中的
tenant_id > 0是客户 ID 和客户隔离键,不表示上级租户;费用项目是tenant_id = 0的平台公共主数据,入库费用明细仍以tenant_id > 0隔离客户并引用公共fee_item_id。 fl_third_party_call_log.tenant_id = 0仅表示第三方主体未知或尚未解析的哨兵值,不是平台客户记录或平台操作作用域,绝不能据此授权、查询或写入客户业务数据。上线后可只读统计:
SELECT COUNT(*) AS unresolved_third_party_calls
FROM baiyue_firstleg.fl_third_party_call_log
WHERE tenant_id = 0;
- 平台公共仓库、地址、服务能力、往来单位
wh_partner、快递公司、托盘、库位、预占和占用固定归平台作用域tenant_id=0;Firstleg 的warehouse_resource_tenant_id同步固定为0。 - 客户订单、客户文件和客户费用规则仍使用
tenant_id>0做客户隔离;往来单位不是客户私有数据,统一脚本会把wh_partner和wh_partner_type的作用域归零。
平台公共资源归零迁移与核验
测试环境仍只执行固定入口 头程数据库统一增量-MySQL8.sql,不要再串行执行模块脚本。执行前可只读盘点公共资源旧归属:
SELECT 'wh_warehouse' AS resource, COUNT(*) AS total, COALESCE(SUM(tenant_id <> 0), 0) AS non_platform
FROM baiyue_warehouse.wh_warehouse
UNION ALL SELECT 'wh_warehouse_address', COUNT(*), COALESCE(SUM(tenant_id <> 0), 0) FROM baiyue_warehouse.wh_warehouse_address
UNION ALL SELECT 'wh_service_capability', COUNT(*), COALESCE(SUM(tenant_id <> 0), 0) FROM baiyue_warehouse.wh_service_capability
UNION ALL SELECT 'wh_express_company', COUNT(*), COALESCE(SUM(tenant_id <> 0), 0) FROM baiyue_warehouse.wh_express_company
UNION ALL SELECT 'wh_pallet', COUNT(*), COALESCE(SUM(tenant_id <> 0), 0) FROM baiyue_warehouse.wh_pallet
UNION ALL SELECT 'wh_location', COUNT(*), COALESCE(SUM(tenant_id <> 0), 0) FROM baiyue_warehouse.wh_location
UNION ALL SELECT 'wh_location_reservation', COUNT(*), COALESCE(SUM(tenant_id <> 0), 0) FROM baiyue_warehouse.wh_location_reservation
UNION ALL SELECT 'wh_location_occupancy', COUNT(*), COALESCE(SUM(tenant_id <> 0), 0) FROM baiyue_warehouse.wh_location_occupancy
UNION ALL SELECT 'fl_inbound_pallet_allocation.resource_scope', COUNT(*),
COALESCE(SUM(warehouse_resource_tenant_id <> 0), 0)
FROM baiyue_firstleg.fl_inbound_pallet_allocation;
脚本会先把明确公共资源迁到 0,按父仓库回填地址和能力,再迁移平台往来单位、托盘、库位、预占、占用及 Firstleg 资源归属快照。末尾 PASS 前会强校验公共资源(含往来单位)全部归零、父子一致,以及客户费用规则不存在 tenant_id=0。执行后可再只读核验:
SELECT
(SELECT COUNT(*) FROM baiyue_warehouse.wh_warehouse WHERE tenant_id <> 0)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_warehouse_address WHERE tenant_id <> 0)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_service_capability WHERE tenant_id <> 0)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_partner
WHERE tenant_id <> 0 OR data_scope_id <> 0)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_partner_type
WHERE tenant_id <> 0 OR data_scope_id <> 0)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_express_company WHERE tenant_id <> 0)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_pallet WHERE tenant_id <> 0)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_location WHERE tenant_id <> 0)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_location_reservation WHERE tenant_id <> 0)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_location_occupancy WHERE tenant_id <> 0)
+ (SELECT COUNT(*) FROM baiyue_firstleg.fl_inbound_pallet_allocation
WHERE warehouse_resource_tenant_id <> 0) AS public_scope_violations,
(SELECT COUNT(*) FROM baiyue_warehouse.wh_overseas_storage_fee_rule WHERE tenant_id = 0)
AS customer_scope_violations;
SELECT
(SELECT COUNT(*) FROM baiyue_warehouse.wh_warehouse_address a
JOIN baiyue_warehouse.wh_warehouse w ON w.id = a.warehouse_id
WHERE a.tenant_id <> w.tenant_id)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_service_capability c
JOIN baiyue_warehouse.wh_warehouse w ON w.id = c.warehouse_id
WHERE c.tenant_id <> w.tenant_id)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_pallet p
JOIN baiyue_warehouse.wh_warehouse w ON w.id = p.warehouse_id
WHERE p.tenant_id <> w.tenant_id)
+ (SELECT COUNT(*) FROM baiyue_warehouse.wh_location l
JOIN baiyue_warehouse.wh_warehouse w ON w.id = l.warehouse_id
WHERE l.tenant_id <> w.tenant_id) AS parent_child_scope_mismatches;
上述三个结果 public_scope_violations、customer_scope_violations、parent_child_scope_mismatches 必须都为 0。
船司 FBA 价格公共作用域
- 当前测试环境
fl_carrier_fba_rate为空表,不执行存量价格迁移。 - 初始化表结构将船司 FBA 价格定义为平台公共价格,Firstleg 创建、查询和计费匹配固定使用
tenant_id = 0;客户计费规则仍按客户tenant_id > 0隔离。 - 初始化或重建测试库后,再启动或重启
firstleg-service。
海外仓阶梯费用增量
2026-08-05增量已追加到固定入口末尾,不创建新的日期部署脚本。- Warehouse 新增
wh_overseas_storage_fee_rule和wh_overseas_storage_fee_tier,包含客户唯一索引、分页索引、阶梯起始天唯一索引和规则明细查询索引。 - IAM 新增
platform:overseas-storage-fee:list/create/edit/delete四项权限,默认授予平台系统管理员。 - Warehouse Service 启动前必须先执行固定入口;末尾只有两张表、五个索引和四项权限均存在才返回
PASS。
海外仓权限目录
- 固定入口已同步
iam/src/main/resources/db/lastleg-permissions.sql的platform:overseas-*权限,并默认授予平台系统管理员。 - 旧
platform:lastleg:*权限会撤销角色关联并停用;不保留旧码兼容映射。 - 海外仓业务目录保留海外出库、派送列表入口;海外仓出库与派送写操作和客户派送权限由后续海外仓出库与派送区块直接收敛,不使用旧码兼容映射。
海外排车、出库与派送权限
- 国内固定入口已在海外仓业务
lastleg-permissions.sql权限段之后完整内联iam/src/main/resources/db/phase5-delivery-permissions.sql;测试和部署只执行固定入口,不再单独执行模块脚本。 - 平台端固定使用排车列表/编辑/取消/转派送、出库列表/创建/取消、派送列表/退回/状态/资料管理、异常订单列表/创建/处理和客户回访列表/编辑十六项权限;列表权限包含详情及只读辅助接口,写操作保持独立授权。
- 派送三类资料上传、替换、解绑和保存统一使用
platform:overseas-warehouse:delivery:documents,读取和下载仍使用platform:overseas-warehouse:delivery:list;默认授予PLATFORM_ADMIN、PLATFORM_CUSTOM_ADMIN、WAREHOUSE_OPERATOR。 - 客户端固定使用
merchant:warehouse:delivery:list和merchant:warehouse:delivery:create;客户默认管理员获得两项权限,其他客户角色不自动扩权。 WAREHOUSE_OPERATOR获得十六项后台作业权限,WAREHOUSE_TALLY只获得排车、出库、派送、异常订单和客户回访五项列表只读;国内、海外 PDA 岗位不得获得上述后台权限。
海外排车与出库结构升级
-
派送三类资料当前基线包含
ll_delivery_order.bol_no/documents_json与ll_delivery_document_revision;海外固定入口和 Lastleg 模块基线同步维护这些定义。仅保存装车照片、BOL文件(含签名)、签收文件(POD签收/快递签收)三个类别,摘要按类别计数。资料历史不可变,文件对象由 File 按真实客户与派送单绑定;不按 BOL 文本复用文件,不生成旧类别迁移或清理脚本。 -
海外仓出库与派送数据库部署仍只执行
海外区域统一增量-MySQL8.sql;空库先执行 Lastleg 与 Warehouse Overseas 当前基线,再完整执行固定入口并确认最末migration_status = PASS。 -
该海外固定入口会在任何海外仓出库与派送
ALTER与数据门禁前幂等创建排车 PDA、出库、派送、一件代发、异常订单和客户回访的完整当前结构,因此既有海外仓业务库不依赖模块基线或历史scripts/db/incremental.sql。国内固定入口只保留 IAM 海外仓出库与派送权限目录,不创建或修改baiyue_lastleg业务表。 -
固定入口只补目标字段并做 fail-fast 校验,不回填、改号、清理或从其他表推断开发旧行。
ll_dispatch_pda_task.warehouse_id存在NULL、空值或0,或任一待收敛全局业务号/任务号、完成幂等键发生冲突时,脚本立即SIGNAL;应重新造数,重置或清理仍需用户另行授权。 -
数据门禁通过后,脚本原位把
dispatch_no、outbound_no、排车 PDAtask_no、出库 PDAtask_no收敛为全局唯一,并建立(customer_id, completion_idempotency_key)完成命令唯一约束;旧客户复合索引不保留。 -
必须在启动或重启 Lastleg Service 前完成固定入口;不得单独执行模块基线补丁、日期脚本或手工兼容 SQL。
码头车队邮件
国内统一入口包含 fl_terminal_drayage_mail,用于冻结收件地址、两类邮件正文、投递状态和失败信息;创建后才可发布相关 Firstleg 功能。发信配置默认关闭,配置说明见 Firstleg 车队邮件。邮件功能涉及 Admin、Firstleg 和 Warehouse 内部联系资料接口,无新增权限码。