Files
form-center-service/sql/t2_definition_domain.sql
T
chenxing 03f6a971c3
build / build-push (push) Successful in 2m22s
feat(definition): T2 后端·定义域——版本模型、schema 校验器、选项字典与另存副本
定义与答卷物理分离的第一步:把"契约"落进可执行代码,让后续答卷域只需消费不必再解释。

- form/form_version 头表+版本行:已发布行零写路径(改版=v+1 新行,老行逐字节冻结),
  升版期间头表指针不动,使契约 §5 的钉版与 §3.2 的两层缓存声明天然成立;uuid 建草稿即生成
- FormSchemaValidator:19 项属性白名单、14/11 控件、options 只认 {label,value} 数组或
  dict:{code} 引用(字符串数组被拒)、searchable 只出显式声明字段、跨版本同 key 不得换 type
  (否则 answer_index 分类型落值的语义与"删字段后历史仍可筛"当场失效)
- 选项字典两级:管理面同层精确匹配(校级改不到平台级)、解析面 {会话校,0} 且本校遮蔽不回落;
  value 物理不可变而 label 可改;软删条目仍进提交放行集;引用是活引用、只在读路径内联展开
- 表单级配置(audience/fill_limit/deadline 补 23:59:59/报名号/状态定义)留在头表,不随版本快照
- 另存为副本:新 code+新 uuid+version 1、schema 深拷贝且字典引用随行,源表只读
- 出入参不出现库内 id;手写 DDL 落 sql/t2_definition_domain.sql 并按 MySQL 5.7 复核(无 native SQL)

自验:mvn -B -o clean package 绿(67 测试,含 27 条打真实 MySQL 的 IT),逐 V 证据与 9 条
实现期问题单见 docs/T2-report.md
2026-10-14 15:23:35 +08:00

92 lines
6.6 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================================
-- 表单中心 T2 · 定义域 DDL(MySQL 5.7 兼容复核版)
-- 范围:契约 §10 九表中的定义域四表 = form / form_version / form_dict / form_dict_item
-- (answer / answer_index / status_log / answer_op_log / fill_quota 属 T3)
-- 用途:本文件是**评审与生产脚本底稿**,不是应用启动依赖。
-- 开发期由 spring.jpa.hibernate.ddl-auto=update 自动建表(application.yml);
-- 生产建议 ddl-auto=none + 按本脚本升级(P10:160 生产 MySQL 版本待核,按 5.7 保守写)。
-- 5.7 复核要点:①无 CTE/WITH;②无函数索引/生成列;③utf8mb4(5.7 默认 utf8mb3 会截断 emoji/生僻字);
-- ④复合唯一键字节长 (8+64*4+64*4)=520 < 767,两个 uk 均不需要前缀长度;
-- ⑤TEXT/LONGTEXT 列不写 DEFAULT(5.7 不允许);⑥无物理外键(方案 §7.7 逻辑外键约定)。
-- P5 裁决:实体继承 BaseEntity,实际表=契约 §10 草案 + create_by/update_by 两列(不改 §10 文本)。
-- 审计两列在 BaseEntity 未标 nullable=false,故本脚本按建表实态写 DEFAULT NULL
-- (FormCenterAuditListener 恒写 now(),业务上不会为空)——差异记问题单 P15。
-- 本机取证:MySQL 8.0.45 / 库 bsch_formcenter 由 ddl-auto=update 建表后 SHOW CREATE TABLE 逐列比对一致。
-- ============================================================
CREATE TABLE `form` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`uuid` VARCHAR(32) NOT NULL COMMENT '数据面运行时身份:建草稿即生成、跨版本不变(契约 §1)',
`sch_id` BIGINT NOT NULL COMMENT '租户键;0=平台级表单(U5/U6,超管上下文建)',
`app_code` VARCHAR(64) NOT NULL DEFAULT 'form-center' COMMENT '归属应用:中心/平台级挂 form-center,快应用挂其 app_code',
`code` VARCHAR(64) NOT NULL COMMENT '入口寻址+配置期引用;同校同 app_code 内唯一;发布后不可改',
`name` VARCHAR(128) NOT NULL,
`current_version` INT DEFAULT NULL COMMENT '当前发布版本指针,NULL=从未发布(resolve 只认它)',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '0 草稿 / 1 已发布 / 2 停用(停用只断填报入口,数据可读可导)',
`status_defs` TEXT COMMENT '状态定义 JSON [{code,label,is_deleted}];NULL=默认待处理/已处理(V12)',
`audience` TINYINT NOT NULL DEFAULT 1 COMMENT '1 面向学生 / 2 面向教师(数据范围默认矩阵输入)',
`fill_limit` TINYINT NOT NULL DEFAULT 0 COMMENT '0 不限 / 1 限一次(去重维度按 subject→submitter 推导)',
`deadline` DATETIME DEFAULT NULL COMMENT '收集截止,datetime 粒度(只选日期时补当日 23:59:59)',
`answer_no_enabled` TINYINT NOT NULL DEFAULT 0 COMMENT '报名号开关,默认关',
`group_tag` VARCHAR(64) DEFAULT NULL COMMENT '多表单快应用的菜单分组标签',
`is_deleted` TINYINT NOT NULL DEFAULT 0 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_form_uuid` (`uuid`),
UNIQUE KEY `uk_form` (`sch_id`, `app_code`, `code`),
KEY `idx_form_app` (`sch_id`, `app_code`, `status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='表单头表(方案 §5.1)';
CREATE TABLE `form_version` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`form_id` BIGINT NOT NULL COMMENT '逻辑外键 → form.id(无物理 FK)',
`sch_id` BIGINT NOT NULL,
`app_code` VARCHAR(64) NOT NULL,
`code` VARCHAR(64) NOT NULL,
`version` INT NOT NULL COMMENT '只增不改(契约 §1)',
`schema_json` LONGTEXT NOT NULL COMMENT '结构快照:{"groups":[{key,label,fields:[…]}]},数组序即展示序、无 orderNum',
`change_log` VARCHAR(500) DEFAULT NULL COMMENT '升版改动说明',
`publish_time` DATETIME DEFAULT NULL COMMENT 'NULL=未发布草稿行;发布动作只补这一列,内容列从此冻结(V7)',
`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_form_ver` (`sch_id`, `app_code`, `code`, `version`),
KEY `idx_ver_form` (`form_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
COMMENT='版本行:行不可变(方案 §3.2)——已发布行禁止就地修改,改版=新增行';
CREATE TABLE `form_dict` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`sch_id` BIGINT NOT NULL DEFAULT 0 COMMENT '0=平台级(学校可见可用不可改);其余=校级(仅本校表单可引用)',
`code` VARCHAR(64) NOT NULL COMMENT 'schema 里 options.source="dict:{code}" 的引用键,建后不可改',
`name` VARCHAR(128) NOT NULL,
`is_deleted` TINYINT NOT NULL DEFAULT 0,
`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_dict` (`sch_id`, `code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='选项字典(契约 §2.1)';
CREATE TABLE `form_dict_item` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`dict_id` BIGINT NOT NULL COMMENT '逻辑外键 → form_dict.id',
`value` VARCHAR(64) NOT NULL COMMENT '答案存储值:建一次即不可变(实体 updatable=false + 本 uk)',
`label` VARCHAR(128) NOT NULL COMMENT '展示名,可随便改(改名不打穿历史答卷)',
`sort` INT NOT NULL DEFAULT 0 COMMENT '展示顺序(同值按 id 稳定排)',
`is_deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删:设计器不可新选,但 value 仍通过提交校验(V38)',
`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_dict_item` (`dict_id`, `value`),
KEY `idx_dict_item_sort` (`dict_id`, `sort`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='字典条目(契约 §2.1)';