This commit is contained in:
2026-09-09 23:46:21 +08:00
parent 107374bec5
commit 3e4b9d0a9a
10 changed files with 2886 additions and 103 deletions
+1 -1
View File
@@ -93,7 +93,7 @@
- 内部接口先执行常量时间令牌校验;缺失或错误令牌不得进入消费事务。
- IAM 安全事件只能进入 `/internal/lastleg/security/v1/events`;通用 `/internal/lastleg/events` 只白名单接收装柜完成与实际船节点事件,禁止把 IAM 事件交给 `LoadingCompletedConsumer`。
- Lastleg 安全投影只接受 `ACTIVE`/`DISABLED` 两态安全语义;客户建档和审核的 `PROFILE_REQUIRED`/`PENDING`/`REJECTED`/`ARCHIVED` 由 IAM 在发布前统一折叠为 `DISABLED`,Lastleg 不兼容或解释国内工作流状态。
- 开发基线只为国内固定 `authUserId=1000001`、`tenantId=0` 的 `platform_admin` 写 USER/AUTHORIZATION version=0 投影;使用 `INSERT IGNORE`,后续 IAM version>=1 事件单调覆盖。不得扩大为历史账号运行时补齐或缺失投影默认放行。
- 开发/测试空库基线只为国内固定 `authUserId=1000001`、`tenantId=0` 的 `platform_admin` 写 USER/AUTHORIZATION version=0 投影;AUTHORIZATION 必须携带当前 `PLATFORM_ADMIN` 角色及按 IAM 跨区前缀筛选的完整权限快照,统一 SQL 重放只修正仍处于固定 baseline version=0 的该行,后续 IAM version>=1 事件单调覆盖。不得扩大为其他历史账号运行时补齐或缺失投影默认放行。
- PDA 入仓任务完成前必须先通过 `/unload-photos` 保存非空且不重复的卸柜照片文件 ID;照片上传时间由服务端记录,预计报空时间固定为照片上传时间加两天。完成入仓时,库存入账、计划/任务状态推进与 `OVERSEAS_CONTAINER_UNLOADED` V1 Outbox 必须处于同一事务;事件绑定来源头程货柜身份,不得从前端请求拼装或回查头程数据库。
- 海外 PDA 柜号签收只允许平台 `OVERSEAS_WAREHOUSE_PDA_OPERATOR` 使用 `lastleg:pda:operate`;国内头程 PDA 角色不得进入。PDA 不接收 `customerId`,候选按来源柜跨客户聚合,同柜允许多个客户;选柜会话、三类照片及整柜完成事实只绑定 `sourceContainerBookingId + containerNo`,文件与柜级跨区事件使用 `tenantId=0` 平台技术范围。签收后按每个入仓计划自身客户生成任务,扫码、SKU 实收、托盘和库存始终使用入仓码所属票的真实客户。未完成会话按平台操作账号和柜号分别全局唯一;平台管理员和客户账号不得进入该作业入口。
@@ -2058,16 +2058,137 @@ CREATE TABLE IF NOT EXISTS ll_security_projection (
KEY idx_security_projection_permission (aggregate_id,permission_version)
) ENGINE=InnoDB COMMENT='海外IAM安全状态与权限版本投影';
-- 开发基线固定管理员;后续真实 IAM 事件从 aggregate_version=1 单调覆盖该 version=0 投影。
-- 空库基线固定管理员必须携带当前海外授权快照;后续真实 IAM 事件从 aggregate_version=1 单调覆盖该 version=0 投影。
SET @platform_admin_overseas_roles = JSON_ARRAY('PLATFORM_ADMIN');
SET @platform_admin_overseas_authorities = JSON_ARRAY(
'platform:finance:bill:adjust',
'platform:finance:bill:update',
'platform:finance:bill:void',
'platform:finance:cost:create',
'platform:finance:cost:view',
'platform:finance:customer-account:adjust',
'platform:finance:customer-account:export',
'platform:finance:customer-account:list',
'platform:finance:customer-arap:export',
'platform:finance:customer-arap:list',
'platform:finance:customer-statement:export',
'platform:finance:customer-statement:list',
'platform:finance:customer-terms:update',
'platform:finance:customer-terms:view',
'platform:finance:fee-source:edit',
'platform:finance:fee-source:review',
'platform:finance:payment:create',
'platform:finance:receipt:create',
'platform:finance:receipt:view',
'platform:finance:receivable-statistics:export',
'platform:finance:receivable-statistics:list',
'platform:finance:recharge:review',
'platform:finance:reconciliation:adjust',
'platform:finance:reconciliation:create',
'platform:finance:reconciliation:issue',
'platform:finance:reconciliation:review',
'platform:finance:reconciliation:void',
'platform:finance:settlement-ap:create',
'platform:finance:settlement-ap:export',
'platform:finance:settlement-ap:list',
'platform:finance:settlement-ar:create',
'platform:finance:settlement-ar:export',
'platform:finance:settlement-ar:list',
'platform:finance:settlement:void',
'platform:overseas-business:looseboard:create',
'platform:overseas-business:looseboard:edit',
'platform:overseas-business:looseboard:list',
'platform:overseas-business:looseboard:status',
'platform:overseas-business:purchase:edit',
'platform:overseas-business:purchase:list',
'platform:overseas-business:purchase:review',
'platform:overseas-business:truck:create',
'platform:overseas-business:truck:edit',
'platform:overseas-business:truck:list',
'platform:overseas-business:truck:status',
'platform:overseas-master-data:exchange-rate:create',
'platform:overseas-master-data:exchange-rate:edit',
'platform:overseas-master-data:exchange-rate:export',
'platform:overseas-master-data:exchange-rate:list',
'platform:overseas-master-data:exchange-rate:status',
'platform:overseas-master-data:quote:create',
'platform:overseas-master-data:quote:edit',
'platform:overseas-master-data:quote:export',
'platform:overseas-master-data:quote:list',
'platform:overseas-master-data:quote:status',
'platform:overseas-master-data:vehicle:create',
'platform:overseas-master-data:vehicle:edit',
'platform:overseas-master-data:vehicle:export',
'platform:overseas-master-data:vehicle:list',
'platform:overseas-master-data:vehicle:status',
'platform:overseas-warehouse:carton:create',
'platform:overseas-warehouse:carton:edit',
'platform:overseas-warehouse:carton:list',
'platform:overseas-warehouse:customer-visit:edit',
'platform:overseas-warehouse:customer-visit:list',
'platform:overseas-warehouse:delivery:documents',
'platform:overseas-warehouse:delivery:list',
'platform:overseas-warehouse:delivery:return',
'platform:overseas-warehouse:delivery:status',
'platform:overseas-warehouse:dispatch:cancel',
'platform:overseas-warehouse:dispatch:edit',
'platform:overseas-warehouse:dispatch:list',
'platform:overseas-warehouse:dispatch:transfer-delivery',
'platform:overseas-warehouse:exception-order:create',
'platform:overseas-warehouse:exception-order:list',
'platform:overseas-warehouse:exception-order:process',
'platform:overseas-warehouse:inbound-order:create',
'platform:overseas-warehouse:inbound-order:edit',
'platform:overseas-warehouse:inbound-order:fba-appointment',
'platform:overseas-warehouse:inbound-order:list',
'platform:overseas-warehouse:inbound-order:smart-dispatch',
'platform:overseas-warehouse:inventory:adjust',
'platform:overseas-warehouse:inventory:edit',
'platform:overseas-warehouse:inventory:export',
'platform:overseas-warehouse:inventory:list',
'platform:overseas-warehouse:last-mile-order:edit',
'platform:overseas-warehouse:last-mile-order:export',
'platform:overseas-warehouse:last-mile-order:list',
'platform:overseas-warehouse:location:create',
'platform:overseas-warehouse:location:delete',
'platform:overseas-warehouse:location:edit',
'platform:overseas-warehouse:location:list',
'platform:overseas-warehouse:outbound:cancel',
'platform:overseas-warehouse:outbound:create',
'platform:overseas-warehouse:outbound:list',
'platform:overseas-warehouse:pallet:create',
'platform:overseas-warehouse:pallet:delete',
'platform:overseas-warehouse:pallet:edit',
'platform:overseas-warehouse:pallet:list',
'platform:overseas-warehouse:product:create',
'platform:overseas-warehouse:product:edit',
'platform:overseas-warehouse:product:list',
'platform:overseas-warehouse:relabel-order:create',
'platform:overseas-warehouse:relabel-order:list',
'platform:overseas-warehouse:relabel-order:status',
'platform:overseas-warehouse:warehouse:create',
'platform:overseas-warehouse:warehouse:edit',
'platform:overseas-warehouse:warehouse:list',
'platform:overseas-warehouse:warehouse:status'
);
INSERT IGNORE INTO ll_security_projection (
aggregate_type,aggregate_id,tenant_id,security_status,permission_version,roles_json,authorities_json,aggregate_version,
payload_hash,last_event_id,changed_at,updated_at
) VALUES
('USER','1000001',0,'ACTIVE',0,JSON_ARRAY(),JSON_ARRAY(),0,SHA2('lastleg-baseline:platform_admin:USER:0',256),
'baseline-platform-admin-user-v0','1970-01-01 00:00:00.000','1970-01-01 00:00:00.000'),
('AUTHORIZATION','1000001',0,NULL,0,JSON_ARRAY(),JSON_ARRAY(),0,SHA2('lastleg-baseline:platform_admin:AUTHORIZATION:0',256),
('AUTHORIZATION','1000001',0,NULL,0,@platform_admin_overseas_roles,@platform_admin_overseas_authorities,0,
SHA2('lastleg-baseline:platform_admin:AUTHORIZATION:0:current-authorities',256),
'baseline-platform-admin-authorization-v0','1970-01-01 00:00:00.000','1970-01-01 00:00:00.000');
UPDATE ll_security_projection
SET roles_json=@platform_admin_overseas_roles,
authorities_json=@platform_admin_overseas_authorities,
payload_hash=SHA2('lastleg-baseline:platform_admin:AUTHORIZATION:0:current-authorities',256),
updated_at=CURRENT_TIMESTAMP(3)
WHERE aggregate_type='AUTHORIZATION' AND aggregate_id='1000001' AND tenant_id=0
AND aggregate_version=0 AND last_event_id='baseline-platform-admin-authorization-v0';
CREATE TABLE IF NOT EXISTS ll_wallet_event_inbox (
event_id VARCHAR(64) NOT NULL COMMENT '国内Finance资金结果事件ID',
@@ -23,11 +23,21 @@ class LastlegSecurityContractTest {
"PRIMARY KEY (aggregate_type,aggregate_id)", "aggregate_version BIGINT",
"permission_version BIGINT", "roles_json JSON", "authorities_json JSON");
for (String sql : new String[]{baseline, migration}) {
assertThat(sql).contains("('USER','1000001',0,'ACTIVE',0,JSON_ARRAY(),JSON_ARRAY(),0",
"('AUTHORIZATION','1000001',0,NULL,0,JSON_ARRAY(),JSON_ARRAY(),0",
assertThat(sql).contains("SET @platform_admin_overseas_roles = JSON_ARRAY('PLATFORM_ADMIN')",
"SET @platform_admin_overseas_authorities = JSON_ARRAY(",
"('USER','1000001',0,'ACTIVE',0,JSON_ARRAY(),JSON_ARRAY(),0",
"('AUTHORIZATION','1000001',0,NULL,0,@platform_admin_overseas_roles,@platform_admin_overseas_authorities,0",
"baseline-platform-admin-user-v0",
"baseline-platform-admin-authorization-v0")
.doesNotContain("baseline-merchant-admin");
"baseline-platform-admin-authorization-v0",
"platform:overseas-warehouse:last-mile-order:list",
"platform:overseas-warehouse:inbound-order:list",
"platform:overseas-warehouse:dispatch:list",
"platform:overseas-business:purchase:list",
"platform:overseas-master-data:quote:list",
"platform:finance:fee-source:review",
"AND aggregate_version=0 AND last_event_id='baseline-platform-admin-authorization-v0'")
.doesNotContain("('AUTHORIZATION','1000001',0,NULL,0,JSON_ARRAY(),JSON_ARRAY(),0",
"baseline-merchant-admin");
}
assertThat(authSeed).contains("(1000001, 'platform_admin'", "default_tenant_id",
"default_app_code");