Files
form-center-service/sql/t16_app_registry.sql
chenxing c41ffebb95 t16:app 注册表——四业务字段零角色 + C17 CRUD 端点族 + 在用禁删 + 入口链接生成
- 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。
2026-10-20 14:30:10 +08:00

40 lines
3.4 KiB
SQL
Raw Permalink 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.
-- ============================================================
-- 表单中心 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 的机械判据)