- sql/t16_app_registry.sql:§17.2 建表(uk_app_code 全库唯一、form.app_code 逻辑引用不建 FK)。
本机核对:dev 库 ddl-auto 建的表与脚本列型逐列一致,且 Hibernate 尊重显式索引名(无漂移);
脚本另在临时库实跑一遍校验语法后已清理。
- 实体 AppRegistry:app_code/sch_id 均 updatable=false——code 是入口链接与 routing key 的组成段,发布即冻结。
- AppRegistryService 四条写侧规则:C10 格式 + 保留字 form-center(大小写变体也算撞名);
撞 uk 前先按 code 点名(在用=已存在 / 只剩软删行=编码不复用,都是可诊断 CUSTOM(5) 而不是库内 500,P125);
删除保护按 countLiveByAppCode 全库统计(code 全库唯一,他校还在用同样算在用,取窄的一边);
删除=实体 save 改标记(软删全仓保持实体写,bulk UPDATE 会绕过审计监听器)。
- 域规则:清单=本校∪平台级;改/删只动 sch_id==本次域的行,他校行按"app 不存在"回答。
超管建平台级需显式 schId=0,与两表端点同一条代查口径,零新增判据。守卫复用 requirePlatformAdmin(C4③)。
- 入口链接由后端生成:{context-path}/front/#/app/{code}/,本地无 context 段时回落 /#/app/{code}/
(同 host.config.ts 的推导),前端只补 origin。
- 新增 GET/POST/PUT/DELETE /api/form/admin/apps。
测试 AppRegistryIT(V59/V65/V69,8 例):反射断言持久字段恰好 appCode/name/schId/isDeleted 且无
role|perm|admin|user|auth 形态列名;保留字与 6 种非法 slug + 2/64 位边界;重复注册不撞库;
本校∪平台级清单与链接后缀;普通教师 FORBIDDEN、他校"app 不存在";改名只改 name;
草稿态即算在用(msg 带张数),表单软删后才让删;软删后 code 不复用。
门禁 mvn -B -o clean test → Tests run: 273, Failures: 0, Errors: 0。
40 lines
3.4 KiB
SQL
40 lines
3.4 KiB
SQL
-- ============================================================
|
||
-- 表单中心 T16 · app 注册表 DDL(MySQL 5.7 兼容复核版)
|
||
-- 范围:《表单中心契约v2》§5.2/§17.2 一笔 = 建表 app_registry
|
||
-- 验收:V59(零角色字段)/ V65(uk(app_code) 全库唯一 + 保留字)/ V69(CRUD 与在用禁删)
|
||
-- 用途:生产 ddl-auto=none 时的升级脚本;开发期(本机 bsch_formcenter,ddl-auto=update)由 Hibernate
|
||
-- 自动追加,本脚本同时是"实表应当长什么样"的评审权威(沿 t2/t3/t10 先例)。
|
||
-- 5.7 复核要点:①无 CTE/WITH、无函数索引、无生成列、无 CHECK 约束;②utf8mb4 显式写 CHARSET/COLLATE;
|
||
-- ③InnoDB、无物理外键——form.app_code 对注册表是<b>逻辑引用</b>(§5.2 明令"不校验存在性亦可建
|
||
-- 表单",建 FK 等于把这条改写成强引用,快应用还没注册就先建表的老数据会直接进不来);
|
||
-- ④本表无可空列(is_deleted/sch_id 都 NOT NULL,审计列按 P5 实态 DEFAULT NULL)。
|
||
-- **零角色字段(D14/V59 红线)**:全表只有 app_code / name / sch_id / is_deleted 四个业务列
|
||
-- + BaseEntity 四审计列。任何"谁能用这个 app""app 的管理员"之类的列都不许加——
|
||
-- 把授权塞回注册表正是 v2 要出清的东西(§19 作废-1/2 的同一件事)。
|
||
-- 唯一键口径:uk_app_code 是<b>全库唯一且不含 is_deleted</b>(§17.2 原文),所以软删后的 code
|
||
-- 仍被占用、不可复用(这层落地差额登记为问题单 P125,服务侧给可诊断文案而不是撞库 500)。
|
||
-- 非幂等:MySQL 5.7 无 ADD/CREATE IF NOT EXISTS 的评审友好写法(写了反而掩盖"表已存在但列不对"的漂移)。
|
||
-- 执行前先 `SHOW TABLES LIKE 'app_registry'` 确认不存在;存量:生产零存量(本表 T16 才建),无需回填。
|
||
-- ============================================================
|
||
|
||
CREATE TABLE `app_registry` (
|
||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||
`app_code` VARCHAR(64) NOT NULL COMMENT '全局唯一人读 slug(C10 格式 ^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])$;保留字 form-center 不可注册)',
|
||
`name` VARCHAR(128) NOT NULL COMMENT '应用显示名(入口链接要贴去 UserBase,名字与那边对照用)',
|
||
`sch_id` BIGINT NOT NULL COMMENT '建立者会话校;0=平台级(仅超管可建,D14)',
|
||
`is_deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删标记;名下存在 is_deleted=0 的表单行时禁删(§5.2 在用禁删)',
|
||
`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_app_code` (`app_code`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
||
COMMENT='快应用注册表(契约 v2 §5.2:四业务字段、零角色、无审核;form.app_code 为逻辑引用不建 FK)';
|
||
|
||
-- 自验(执行后逐条核对,V59/V65):
|
||
-- SHOW CREATE TABLE app_registry\G -- 应含 UNIQUE KEY `uk_app_code` (`app_code`),且列只有上面这些
|
||
-- SELECT COUNT(*) FROM information_schema.columns
|
||
-- WHERE table_schema=DATABASE() AND table_name='app_registry'
|
||
-- AND column_name REGEXP 'role|perm|admin|user_id'; -- 必须 0 行(V59 的机械判据)
|