build / build-push (push) Successful in 1m26s
含10-22精修六类修复: 续租renewRunning/结果INCOMPLETE_RESULT门/终态TASK_TERMINAL/liveGrant复用ACL/hosted幂等重放绑定/错误明细整条重序列化。 合规审计与证据: 工作区docs/tasks/REFINEMENT_AUDIT.md + evidence/refinement-20261022/(patch+指纹)。SQL未执行、测试未运行(仅-skipTests编译)。
65 lines
5.4 KiB
SQL
65 lines
5.4 KiB
SQL
-- ============================================================
|
||
-- 表单中心 v3 · 消费应用授权 DDL(MySQL 5.7 兼容复核版,TASK_1)
|
||
-- 范围:《consumer-access-v3.md》§2/§3 = 建两张表 form_ownership / form_consumer_grant
|
||
-- 依据:VERIFICATION V03/V04/V07;owner 绑定与 grant 分权(读/订阅)、默认拒绝、撤销留痕
|
||
-- 用途:生产 ddl-auto=none 时的升级脚本;开发期(本机 bsch_formcenter,ddl-auto=update)由 Hibernate
|
||
-- 自动追加,本脚本同时是"实表应当长什么样"的评审权威(沿 t2/t3/t10/t16 先例)。
|
||
-- 5.7 复核要点:①无 CTE/WITH、无函数索引、无生成列、无 CHECK 约束;②utf8mb4 显式写 CHARSET/COLLATE;
|
||
-- ③<b>不建物理外键</b>——form_uuid 对 form 是逻辑引用(同 t16 对 app_code 的处理:
|
||
-- 表单软删是唯一切除形态且无物理删除,绑定/授权行必须能在表单软删后继续存在以支撑溯源,
|
||
-- 建 FK 等于把"级联删"写进库侧规则);④无可空业务列(判权路径不写"未知=怎样"的分支)。
|
||
-- 身份口径:owner_app_key / consumer_app_key 存的是<b>平台 appKey</b>(UserBase 应用注册分配,
|
||
-- 验签三件套里那个 X-App-Key),<b>不是</b> form.app_code 那种人读 slug。
|
||
-- app_registry 仍是快应用目录,本批一行不加(v3 §1 红线:不把业务授权塞回注册表)。
|
||
-- 租户口径:consumer_school_id 既是授权生效域,也是读答卷时的行集限定域;0 不是合法消费域
|
||
-- (平台级是资源域,不是一个能答卷的租户),服务侧直接拒。
|
||
-- 默认拒绝:两把 *_allowed 开关默认 0,enabled 默认 1(建行即生效,但建之前服务侧必须显式给开关);
|
||
-- 撤销是 enabled=0 + grant_version 进位,<b>不删行</b>(判权 SQL 必须带 enabled 条件)。
|
||
-- 非幂等:MySQL 5.7 无 ADD/CREATE IF NOT EXISTS 的评审友好写法(写了反而掩盖"表已存在但列不对"的漂移)。
|
||
-- 执行前先 `SHOW TABLES LIKE 'form_ownership'` / `'form_consumer_grant'` 确认不存在;
|
||
-- 存量:系统未上线,两张表零存量、无需回填(与 t16 同一论证)。
|
||
-- ============================================================
|
||
|
||
CREATE TABLE `form_ownership` (
|
||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||
`form_uuid` VARCHAR(32) NOT NULL COMMENT '资源坐标:表单全局 uuid(契约 §1,不可枚举、跨版本不变)',
|
||
`form_school_id` BIGINT NOT NULL COMMENT '绑定时表单自己的 sch_id;0=平台级表单',
|
||
`owner_app_key` VARCHAR(64) NOT NULL COMMENT '资源拥有者应用的平台 appKey(写入前已核验 UserBase 注册身份)',
|
||
`create_by` VARCHAR(255) DEFAULT NULL,
|
||
`create_time` DATETIME DEFAULT NULL,
|
||
`update_by` VARCHAR(255) DEFAULT NULL,
|
||
`update_time` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_ownership_form` (`form_uuid`),
|
||
KEY `idx_ownership_owner` (`owner_app_key`, `form_school_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
||
COMMENT='表单资源拥有者绑定(v3 §2:一张表一个 owner,只能由管理面写;form_uuid 为逻辑引用不建 FK)';
|
||
|
||
CREATE TABLE `form_consumer_grant` (
|
||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||
`form_uuid` VARCHAR(32) NOT NULL COMMENT '被授权的表单 uuid',
|
||
`consumer_school_id` BIGINT NOT NULL COMMENT '消费租户(授权生效域 = 读答卷的行集限定域,≥1)',
|
||
`consumer_app_key` VARCHAR(64) NOT NULL COMMENT '消费应用的平台 appKey',
|
||
`read_allowed` TINYINT NOT NULL DEFAULT 0 COMMENT '读授权:目录/schema/answer/answers;默认拒绝',
|
||
`subscribe_allowed` TINYINT NOT NULL DEFAULT 0 COMMENT '订阅授权:答卷变更事件投递(owner 不天然持有)',
|
||
`enabled` TINYINT NOT NULL DEFAULT 1 COMMENT '生效开关;0=已撤销(保留行供审计与 grant_version 判新旧)',
|
||
`grant_version` INT NOT NULL DEFAULT 1 COMMENT '授权版本号:撤销与重申都进位,投递侧必须带它下发',
|
||
`create_by` VARCHAR(255) DEFAULT NULL,
|
||
`create_time` DATETIME DEFAULT NULL,
|
||
`update_by` VARCHAR(255) DEFAULT NULL,
|
||
`update_time` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_grant` (`form_uuid`, `consumer_school_id`, `consumer_app_key`),
|
||
KEY `idx_grant_consumer` (`consumer_app_key`, `consumer_school_id`, `enabled`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
||
COMMENT='消费应用对某张表单的显式授权(v3 §2:三元唯一、读与订阅分权、默认拒绝、撤销不删行)';
|
||
|
||
-- 自验(执行后逐条核对):
|
||
-- SHOW CREATE TABLE form_ownership\G -- 应含 UNIQUE KEY `uk_ownership_form` (`form_uuid`)
|
||
-- SHOW CREATE TABLE form_consumer_grant\G -- 应含 UNIQUE KEY `uk_grant` (三元键) 与 idx_grant_consumer
|
||
-- SELECT COUNT(*) FROM information_schema.columns
|
||
-- WHERE table_schema=DATABASE() AND table_name IN ('form_ownership','form_consumer_grant')
|
||
-- AND column_name REGEXP 'secret|app_code|role|perm'; -- 必须 0 行(密钥与 app_code 都不进授权表)
|
||
-- SELECT COUNT(*) FROM information_schema.referential_constraints
|
||
-- WHERE table_name IN ('form_ownership','form_consumer_grant'); -- 必须 0 行(无物理外键)
|