status: apply created: 2026-07-13 change:
app-first-lowcode-workbench
completed-static。completed-static。completed-static。completed-static。检查范围:
forge-admin-ui/src/views/app-center/index.vueforge-admin-ui/src/views/app-center/components/BusinessObjectTable.vueforge-admin-ui/src/views/app-center/components/AppCard.vueforge-admin-ui/src/views/app-center/components/AppFilterBar.vueforge-admin-ui/src/views/app-center/object-designer.[objectCode].vueforge-admin-ui/src/views/app-center/components/designer/*forge-admin-ui/src/api/business-app.jsforge-admin-ui/src/router/index.jsAiBusinessApp.java、BusinessAppController.java、BusinessAppService.javaBusinessAppMapper.java、BusinessAppMapper.xmlAiBusinessObject.java、AiBusinessSuite.java 及相关服务/Mapper结论:
ai_business_app 的真实语义是访问入口,现有 Controller 日志也已统一称“访问入口”。BusinessApplication 聚合,不能重命名或复用旧表。检查范围:
DbFormAddOrUpdateParam.javaDbFormController.javaFormFieldEntity.javaFormFieldWebEntity.javaEnhanceJavaEntity.javaEnhanceJsEntity.javaEnhanceSqlEntity.javaEnhanceConstant.javaHistoryController.java结论:
/lowdev/tableDesign 前端源码,未对其未公开实现作推断。读取:
AGENTS.mdcode-copilot/memory/pitfalls.mdcode-copilot/memory/decisions.mdcode-copilot/memory/preferences.mdcode-copilot/rules/automated-testing-standard.mdform-first-business-object-designer 和低代码应用相关 Spec/Tasks结论:
ui-ux-pro-max。| 文件 | 状态 | 说明 |
|---|---|---|
spec.md |
completed | 背景、现状、架构、Phase 0~5、数据、API、安全、兼容、验收和 HARD-GATE |
tasks.md |
completed | 46 个任务,按可部署阶段拆分 |
test-spec.md |
completed | P0/P1/P2 测试矩阵、命令、真实联调回填边界 |
execution-log.md |
completed | 本轮研究和文档验证记录 |
| Phase 1 Java/Mapper | completed | 新应用聚合、对象编排、入口归属、Binding 目标和删除保护 |
V1.0.27__add_business_application_aggregate.sql |
completed-static | 表结构、字典、权限和确定性回填;未在真实数据库执行 |
| Phase 2 后端聚合 | completed | 一次聚合返回对象/入口/流程/扩展/问题数,父业务域递归包含子域 |
| Phase 2 前端总览 | completed | 左业务域树、右应用列表、独立 API/路由、两步新建和初始化失败重试 |
| Phase 2 运行态验收 | pending | 未启动 Admin/Vite、未执行 Flyway;浏览器、真实 API 和性能基线待回填 |
| Phase 3 后端编排 | completed | 工作台/就绪度、表映射、设计版本校验、DDL 预览/同步和同步结果记录 |
| Phase 3 前端工作台 | completed | 七分区、对象编排、从数据库表初始化、入口和自动化按需分区 |
| Phase 3 对象设计器 | completed | 数据结构默认首屏、全分区表映射摘要、字段网格、DDL 预览/导出/确认 |
| Phase 3 运行态验收 | pending | 未启动 Admin/Vite、未连接运行数据源;真实 API、元数据、DDL 和浏览器场景待回填 |
| Phase 4 扩展治理 | completed-static | 扩展表、CRUD、版本/锁、Worker/CSS/服务注册表、状态机、审计和工作台已实现 |
| Phase 4 运行态验收 | pending | 最终复验发现本地 vitest 命令缺失;真实 Flyway/API/浏览器由用户验证 |
| Phase 5 发布协调 | completed-static | 不可变版本、运行单、就绪度、发布/恢复/回滚、轻量历史和批量查询优化已实现 |
V1.0.29__add_business_application_release_coordination.sql |
completed-static | 正式脚本已创建,未在真实数据库执行 |
| Phase 5 自动化/构建/E2E | pending | 用户明确要求停止验证,由其自行执行 |
| 时间 | 范围 | 命令 | 结果 | 警告/跳过 |
|---|---|---|---|---|
| 2026-07-13 | 文档创建 | 四个目标文件非空、标题和状态检查 | passed | 四份文档均存在且状态为 propose |
| 2026-07-13 | Markdown 差异 | 对四个未跟踪文档逐一执行 git diff --no-index --check /dev/null <file> |
passed | 每个命令仅因文件有差异返回 1,均无空白错误输出 |
| 2026-07-13 | 文档一致性 | rg 检查状态、Phase、HARD-GATE、未决占位词和禁用项 |
passed | 无未决占位标记或错误的规范目录引用;明确禁用任意 Java/SQL 和 ui-ux-pro-max |
| 2026-07-13 | 默认测试行为 | generator 目标测试命令未加 -Penable-tests |
skipped | Maven 构建成功但项目默认跳过测试;后续命令显式启用 profile |
| 2026-07-13 | 兼容测试首次启用 | -Penable-tests 执行原 Mockito 版兼容测试 |
failed | Mockito inline 无法在 Homebrew JDK 17 自附加;未修改生产代码,测试改为反射/动态代理 |
| 2026-07-13 | 访问入口兼容基线 | mvn -Penable-tests ... -Dtest=BusinessAppServiceCompatibilityTest,BusinessAppControllerCompatibilityTest ... test |
passed | 8 tests;旧 /ai/business/app 表、字段、路由和权限契约保持 |
| 2026-07-13 | Phase 1 Red 契约 | 新应用契约测试首次编译 | failed-as-expected | 在生产类型尚未完成时缺少 BusinessApplication* 契约,随后按 Spec 实现 |
| 2026-07-13 | Phase 1 中间回归 | 兼容测试 + 初版应用契约 | passed | 13 tests;随后继续补服务行为、Binding 和回填测试 |
| 2026-07-13 | 测试代码修复 | BusinessBindingApplicationTargetTest 首次全组编译 |
failed | 测试方法声明缺失;修复测试语法后生产代码无需调整 |
| 2026-07-13 | Phase 1 行为回归 | 六个 Phase 1/兼容测试类 | passed | 22 tests,0 failure、0 error |
| 2026-07-13 | Phase 1 最终目标测试 | mvn -Penable-tests -pl forge-framework/forge-plugin-parent/forge-plugin-generator -am -Dtest=BusinessApplicationServiceTest,BusinessApplicationObjectServiceTest,BusinessBindingApplicationTargetTest,BusinessApplicationPhaseOneContractTest,BusinessApplicationBackfillContractTest,BusinessApplicationControllerTest,BusinessAppServiceCompatibilityTest,BusinessAppControllerCompatibilityTest -Dsurefire.failIfNoSpecifiedTests=false test |
passed | 37 tests,0 failure、0 error、0 skipped;JDK 17 |
| 2026-07-13 | Mapper XML | xmllint --noout BusinessApplicationMapper.xml BusinessApplicationObjectMapper.xml BusinessAppMapper.xml |
passed | XML 语法通过;查询显式过滤租户和逻辑删除 |
| 2026-07-13 | Flyway 静态门禁 | rg 检查 ${...}、tenant 0、INSERT 列、逻辑删除、回填去重和兜底路径 |
passed | 无 Flyway 占位符、无 tenant 0 内置数据、无新聚合物理删除;未连接数据库 |
| 2026-07-13 | Admin 聚合构建 | mvn -pl forge-admin-server -am package -DskipTests |
passed | 42/42 Reactor 模块成功,43.293s;现有 deprecated/unchecked/Lombok builder 警告 |
| 2026-07-13 | 差异空白检查 | git diff --check |
passed | 无空白错误;用户原有 .DS_Store 和 preferences.md 改动保持未覆盖 |
| 2026-07-13 | Phase 2 Mapper Red/Green | BusinessApplicationMapperTest 首次执行后再实现聚合与子树 |
passed | 初次 3 个测试中 2 个失败;实现后 3/3 通过 |
| 2026-07-13 | Phase 2 最终目标测试 | mvn -Penable-tests ... -Dtest=BusinessApplicationMapperTest,...,BusinessAppControllerCompatibilityTest ... test |
passed | 41 tests,0 failure、0 error、0 skipped;JDK 17,15.149s |
| 2026-07-13 | Phase 2 定向 ESLint | pnpm exec eslint 检查新 API、路由、总览、工作台和四个新组件 |
passed | 0 error、0 warning;Node v20.19.0 |
| 2026-07-13 | Phase 2 前端生产构建 | NODE_OPTIONS=--max-old-space-size=8192 pnpm build |
passed | Vite 8501 modules,1m23s;仅仓库既有组件重名、import/chunk 和 CSS 注释警告 |
| 2026-07-13 | Phase 2 Mapper XML | xmllint --noout 检查 Application、ApplicationObject、App、Suite 四个 Mapper |
passed | XML 语法通过 |
| 2026-07-13 | Phase 2 总览静态契约 | rg 检查对象分组依赖、新旧 API 和三条兼容路由 |
passed | 总览无对象分组依赖;新应用/旧入口 API 分离;新应用、旧入口、旧对象设计路由并存 |
| 2026-07-13 | Phase 2 Flyway 静态复核 | rg 检查 V1.0.27 的 ${...} 和 tenant 0 内置数据 |
passed | 无 Flyway 业务占位符、无 tenant 0 内置数据;未执行数据库迁移 |
| 2026-07-13 | Phase 2 Admin 聚合构建 | mvn -pl forge-admin-server -am package -DskipTests |
passed | 42/42 Reactor 模块成功,20.845s;JDK 17 |
| 2026-07-13 | Phase 2 最终差异空白检查 | git diff --check |
passed | 无空白错误;用户原有 .DS_Store、preferences.md 状态未覆盖 |
| 2026-07-13 | Phase 3 Red 契约 | 首次执行 Workspace/TableMapping/DatabaseSync 三组测试 | failed-as-expected | 生产类型尚未实现,缺少 BusinessApplicationWorkspaceVO、BusinessObjectTableMappingService 和设计上下文接口 |
| 2026-07-13 | Phase 3 首轮 Green | 三组新增测试 | passed | 11 tests;修复测试动态代理将字符串误与 Method 对象比较的问题后全绿 |
| 2026-07-13 | Phase 1~3 合并回归 | 13 个目标测试类与兼容测试 | passed | 56 tests,0 failure、0 error、0 skipped;JDK 17,13.873s |
| 2026-07-13 | Phase 3 Controller 契约 | Workspace/readiness/table-mapping/database-diff/database-sync 映射与权限 | passed | 工作台复用 list 权限;预览使用 design 权限;同步独立要求 ai:lowcode:deploy-ddl |
| 2026-07-13 | Phase 3 DDL 边界 | 显式确认、版本冲突、无权限、allowDdl=0、MODIFY 和安全 ADD COLUMN |
passed | 预览不执行;保存对象不再触发 DDL;仅 CREATE/ADD COLUMN 可在线同步 |
| 2026-07-13 | Phase 3 Mapper XML | xmllint --noout 检查 Application/ApplicationObject/App/Suite Mapper |
passed | XML 语法通过;共享应用数和运行表摘要通过 XML 聚合返回 |
| 2026-07-13 | Phase 3 定向 ESLint | 工作台、对象设计器、API、向导和新增组件 | passed | 0 error、0 warning;Node v20.19.0 |
| 2026-07-13 | Phase 3 前端生产构建 | NODE_OPTIONS=--max-old-space-size=8192 pnpm build |
passed | Vite 8518 modules,1m09s;仅仓库既有组件重名、动态导入和 CSS 注释警告 |
| 2026-07-13 | Phase 3 Admin 聚合构建 | mvn -pl forge-admin-server -am package -DskipTests |
passed | 42/42 Reactor 模块成功,18.882s;JDK 17 |
| 2026-07-13 | Phase 3 差异检查 | git diff --check 与新增文件尾随空白扫描 |
passed | 当前差异无空白错误;未覆盖用户原有 .DS_Store 和 preferences.md 变更 |
| 2026-07-13 | Phase 1~4 后端合并回归 | generator 目标测试 | passed | 历史执行证据:75 tests,0 failure、0 error、0 skipped |
| 2026-07-13 | Phase 4 前端安全用例 | JS Worker 与 scoped CSS Vitest | passed | 历史执行证据:26 tests 通过 |
| 2026-07-13 | Phase 4 Admin 聚合构建 | mvn -pl forge-admin-server -am package -DskipTests |
passed | 历史执行证据:42/42 模块通过 |
| 2026-07-13 | Phase 4 最终前端复验尝试 | Node v20.19.0 下 pnpm exec vitest run ... |
not-run | Command "vitest" not found,本地 node_modules 恢复不完整;未进入测试执行 |
| 2026-07-13 | Phase 5 实施 | Task 35~41 代码、迁移、契约用例和发布历史前端 | completed-static | 用户明确“你不用给我验证,我自己验证”;未运行测试、Lint、构建、Flyway、API 或浏览器 |
| 2026-07-14 | 扩展中心体验增量 | 钩子矩阵、JS/CSS 引导式代码工作台、类型/处理器钩子约束、Java 服务增强失败语义、开发指南和契约用例 | completed-static | 遵照用户要求未运行测试、Lint、构建、Flyway、API 或浏览器 |
| 2026-07-14 | 扩展测试与发布阻断修复 | 所有扩展统一进入测试台、Java Schema 测试输入、分阶段测试结果、默认发布跳过未测试草稿 | completed-static | 遵照用户要求未运行测试、Lint、构建、API 或浏览器 |
| 2026-07-14 | Worker 异常诊断修复 | READY 握手、阶段化错误、初始化/执行超时、ErrorEvent 行列原因、postMessage 协议加固 | completed-static | 遵照用户要求未运行 Vitest、构建或浏览器验证 |
| 2026-07-14 | Worker window 启动异常修复 |
Vite define.global 从 window 调整为跨主线程/Worker 可用的 globalThis,消除 env.mjs 初始化阶段 ReferenceError |
completed-static | 配置变更需重启 Vite 开发服务后生效;遵照用户要求未运行构建或浏览器验证 |
| 2026-07-14 | JS 沙箱测试数据引导化 | 自动识别脚本字段/动作、加载对象字段和动作目录、类型化测试值、示例/空值预设、场景说明与高级 JSON 只读预览 | completed-static | 删除用户手工维护“允许字段逗号串 + 上下文 JSON”的双输入;遵照用户要求未运行 Lint、构建或浏览器验证 |
| 2026-07-14 | 应用总览与发布性能增量 | 业务域主题/滚动、右侧标题精简、顶部发布入口、发布历史轻量加载、发布上下文复用和批量查询 | completed-static | 按用户分工未运行测试、Lint、构建、Flyway、API、数据库日志对比或浏览器验证 |
| 2026-07-14 | 数据源/AiCrud/对象发布/列表发布缺陷修复 | 连接消息生命周期、表体最小高度、DDL 预检与执行统一白名单、草稿应用发布深链 | completed-static | 只执行静态引用与差异空白检查;按用户分工未运行测试、Lint、构建、API 或浏览器 |
| 项目 | 状态 | 原因 |
|---|---|---|
| 后端单测/构建 | pending-phase5 | Phase 4 历史 75 tests/42 模块通过;Phase 5 新增代码未运行 |
| 前端 build/lint | pending-phase5 | Phase 4 曾构建通过;最终复验依赖缺失,Phase 5 未运行 |
| Flyway 静态检查 | pending-phase5 | V1.0.27/V1.0.28 有历史静态证据;V1.0.29 未执行本轮验证 |
| Flyway 真实执行 | pending | 未获真实数据库执行授权 |
| API 验证 | pending | 未启动 Admin 服务;待真实迁移后联调 |
| 浏览器/Playwright | pending | Phase 2/3 有页面改动,但按约定未启动 Admin/Vite;待用户环境回填 P2-U01~P2-U08、P3-U01~P3-U10 |
| SQL 次数/性能 | pending-user | 已完成发布历史大字段裁剪、上下文复用和批量查询;未运行真实数据库日志与耗时对比,不能宣称性能基线已通过 |
| 真实 E2E | pending | 由用户执行 Flyway、API 和浏览器验收后回填 |
V1.0.27 迁移,回填迁移计数、未归属入口和旧入口回归证据。test-spec.md 执行 Phase 5 测试、构建、Flyway 和故障恢复验收。eval、
new Function、Blob script 或动态模块执行。Worker 在执行前关闭网络、存储、计时器和
动态加载入口,宿主以超时主动 terminate(),并校验随机 nonce、输出大小和结构化 effects。@import、URL、全局根选择器和 Forge 布局选择器,再把普通选择器统一重写到应用/页面
data-* 根节点。后端保留独立失败关闭校验,不能仅信任浏览器结果。handlerCode 查找处理器;协议不接受
Bean 名、Class 名或类路径,不使用 Class.forName、ApplicationContext#getBean(String)
等反射入口。处理器声明允许钩子、输入 Schema、超时、风险和权限。V1.0.27,Phase 4 使用下一单调版本 V1.0.28,不修改已存在脚本。结论:主页面动态执行和任意服务反射两个硬门均有可验证的失败关闭方案,可以进入 Task 26。
| 时间 | 确认人 | 内容 | 结果 |
|---|---|---|---|
| 2026-07-13 | 用户 | “确认 Spec,开始实施 Phase 1” | 已解除 Proposal 阻断,进入 apply |
ai_business_application、ai_business_application_object 及对应 Entity、DTO、VO、Mapper XML、Service、Controller。PRIMARY/DETAIL/REFERENCE/SHARED,最多一个主对象;对象继续可被多个应用复用。ai_business_app、/ai/business/app 和旧权限保持访问入口语义,仅新增可空 application_id。APPLICATION 目标;旧 APP 仍只校验访问入口 ID,语义未改变。migrated_<md5> 应用编码。legacy_<md5> 历史入口应用。BusinessApplicationVO 新增流程、扩展和待处理问题数量;分页 SQL 通过对象、入口和 APPLICATION Binding 预聚合一次返回,不做逐应用查询。FLOW/APPROVAL,其余 APPLICATION Binding 暂计为扩展;旧 APP 访问入口目标不混入。BusinessSuiteMapper 使用 MySQL 8 WITH RECURSIVE 返回当前业务域及全部子域;应用分页由 Service 自动扩展 suiteCodes。appCount 继续表示访问入口;前端父域展示对子树计数求和,与筛选口径一致。/app-center/application/:applicationCode 稳定工作台路由和 Phase 2 摘要页;旧 /app-center/app/:appId 与对象设计路由保留。businessObjectList、businessAppList、businessObjectRelations,也不再渲染 BusinessObjectTable。OUT_OF_SYNC。?panel=fields,应用上下文锁定业务域。BusinessObjectDesignContextProvider 让表映射服务复用现有对象设计上下文,不复制 ModelSchema、PageSchema 或设计版本。syncDdl/confirmSyncDdl 字段保留反序列化兼容但不再执行 DDL。allowDdl、只读状态和 DDL 类型。designerOptions.databaseSync,不新增第二套历史表;草稿和数据库同步失败互不回滚。/app-center/object/:objectCode/designer、/app-center/app/:appId、对象发布检查和版本回滚继续可用。V1.0.28 建立扩展、扩展版本和执行日志数据结构,扩展生命周期统一为草稿、测试、启用、停用和归档状态机。completed-static。V1.0.29 分离不可变应用版本和可恢复发布运行单;版本只插入,运行单记录幂等键、目标版本、六步进度、失败位置和恢复次数。PRECHECK → SNAPSHOT → OBJECTS → ENTRIES → EXTENSIONS → COMMIT;同一应用的版本号在数据库锁内预留,运行单通过 CREATED → RUNNING 条件更新认领。PARTIAL/FAILED 和脱敏摘要;回滚先校验对象设计版本、物理表/字段、入口、扩展版本和 APPLICATION Binding,只恢复兼容配置并生成新的 ROLLBACK 版本,不执行反向 DDL 或业务数据回滚。completed-static。sys_resource 授权树;新增 V1.0.30__add_business_application_workspace_route.sql,注册隐藏路由并只向已有 ai:businessApplication:list 的角色继承授权。NSpin 容器限制滚动宽度,以及操作列误用会被 Naive 子组件上下文覆盖的 --n-color。NSpin 内容内部并强制独立滚动;操作列改用私有表面变量和中性按钮,避免主题蓝色污染。仍待用户复验。clamp(320px, calc(100dvh - 360px), 680px) 明确视口高度,表头、数据行和操作列在同一滚动内容中整体横向移动,横向和纵向统一由 .table-scroll 承载。pnpm exec eslint src/views/app-center/index.vue src/views/app-center/components/ApplicationTable.vue --max-warnings 0,结果 passed,0 error、0 warning。pnpm build,结果 passed;Vite 7.3.1 转换 8670 modules,built in 1m 17s。仅保留仓库既有组件重名、动态/静态导入和 CSS // 注释警告。pnpm build:ESLint 0 error、0 warning;Vite 转换 8670 modules,built in 1m 13s,结果 passed。EMFILE,提高当前 shell 文件句柄后被环境以 listen EPERM 127.0.0.1:3000 阻止;Playwright Chromium 被 Mach IPC 权限拒绝,WebKit 未安装。未把浏览器交互写成通过,本轮未遗留启动服务。application.[applicationCode].vue:去掉包裹整个工作台的 NSpin,改为绝对定位的独立加载遮罩,阻断 Naive 组件变量向业务页面传播。application-workspace/*.vue:背景、侧栏、表头、悬停、边框及正文/次级文字统一改用 Forge design-tokens.css 的明暗主题语义变量。ui-ux-pro-max,未重做工作台结构和配色体系。cd forge-admin-ui
source ~/.nvm/nvm.sh && nvm use v20.19.0
pnpm exec eslint 'src/views/app-center/application.[applicationCode].vue' \
src/views/app-center/application-workspace/*.vue --max-warnings 0
结果:最终复跑通过,0 error、0 warning。首次执行发现 ApplicationPublishPanel.vue 有 8 个既有格式/UnoCSS 顺序警告,执行目标文件 eslint --fix 后重新检查通过。
rg -n --glob '*.vue' -- 'var\(--n-[a-z0-9-]+' \
src/views/app-center/application-workspace \
'src/views/app-center/application.[applicationCode].vue'
结果:无输出;工作台业务样式已不再依赖可能从 Naive 子组件继承的背景、文字、边框、主色或状态色变量。
source ~/.nvm/nvm.sh && nvm use v20.19.0
NODE_OPTIONS=--max-old-space-size=8192 pnpm build
结果:最终复跑通过;Vite 7.3.1 转换 8670 modules,built in 1m 41s。保留仓库既有组件重名、动态/静态 import、CSS // 注释警告,不由本轮主题修复引入。
pending-user,由用户在真实环境验收。/by-code/{applicationCode}/workspace 快照请求。KeepAlive,对象、入口、流程和扩展面板首次打开后保留状态,不再销毁重建。PROCUREMENT_WAREHOUSE_PRODUCT_RUNTIME 等技术编码不再作为入口主名称;RUNTIME/ROUTE/IFRAME/EXTERNAL/H5/API 由 V1.0.31 字典显示为中文。cd forge-admin-ui
source ~/.nvm/nvm.sh && nvm use v20.19.0
pnpm exec eslint src/api/business-application.js \
'src/views/app-center/application.[applicationCode].vue' \
src/views/app-center/application-workspace/*.vue \
'src/views/app-center/object-designer.[objectCode].vue' \
src/views/app-center/components/designer/BusinessObjectDesignerShell.vue \
--max-warnings 0
NODE_OPTIONS=--max-old-space-size=8192 pnpm build
结果:ESLint 0 error、0 warning;Vite 7.3.1 转换 8670 modules,built in 1m 50s。构建仅保留仓库既有组件重名、动态/静态 import 和 CSS // 注释警告。
静态契约检查通过:存在 KeepAlive 和单次按编码工作台 API;对象、自动化、动作面板不含 window.open 或对象设计路由;工作台不直接插值渲染 entryMode/objectRole。
首次带 -am 的目标测试命令在上游 forge-starter-datascope 被既有 Surefire/JUnit 引擎配置阻断。改为直接执行 generator 后,生产源码重新编译 518 个文件成功;测试源码编译阶段被 7 个既有测试阻断,这些测试的构造器参数未跟随 Phase 4/5 生产类新增的 BusinessApplicationChangeTracker 更新,因此本轮目标用例未执行,不表述为通过。
xmllint --noout \
forge-framework/forge-plugin-parent/forge-plugin-generator/src/main/resources/mapper/BusinessExtensionMapper.xml
rg -n '\$\{[^}]+\}|tenant_id[^\n]*(DEFAULT 0|= 0)|VALUES[^\n]*, *0 *,' \
db/migration/V1.0.31__add_business_app_entry_mode_dict.sql
结果:Mapper XML 通过;Flyway 风险扫描无输出。V1.0.31 未连接真实数据库执行。
pending-user。minmax(0, 1fr) 并独立纵向滚动。.table-scroll 承载,表头和操作列处于同一滚动内容。ResizeObserver 按列表真实可用宽度渐进隐藏业务域、资产、更新时间和状态等次要列;紧凑模式保持“应用 → 状态 → 操作”的正常顺序,应用列取消最小宽度;最窄模式隐藏状态后将操作补到第二列。grid-row: 1,消除表头错层和记录行异常增高;分页区删除冗余说明并独占整行,顶部筛选与主操作允许换行,避免每页条数和“新建应用”被裁切。snapshot_json;运行单列表不读取 snapshot_json、snapshot_hash、selection_json 和幂等键。(extension_id, version_no) 批量查询;全部对象最新发布版本使用 MySQL 8 窗口函数一次查询。markPublished 更新结果确认应用仍存在。completed-static。duration: 0;消息键按数据源 ID 隔离,成功或失败会更新为明确结果。AiCrudPage/AiTable 有数据表体与内部滚动层取消 144px 强制最小高度,分页器紧跟最后一行;无数据空状态继续保持 180px,避免空页面塌缩。LowcodeDdlService.containsUnsafeOnlineDdl;在线只接受建表、追加列及受控索引/注释。MODIFY/ALTER COLUMN 会在发布检查阶段以“查看数据库差异”阻断,并明确要求预览/导出后人工审核,不再进入执行阶段抛出模糊白名单异常。aria-label 的图标按钮,操作列统一收窄到 128px;打开工作台发布历史后消费一次性 publish=1 参数并复用现有发布确认,参数随即清理,避免刷新重复弹窗。git diff --check,结果无空白错误。DB_IMPORT 创建业务对象并自动建立 PRIMARY 关联,成功后直接进入应用“数据对象”分区,不再通过 create=database 二次打开对象向导。configKey;目标页面/表单仅在存在多个可选项时显示,单一默认项自动选中。applicationId 默认字段,避免连续打开抽屉时残留上一次应用归属。rg -n "create.?=.?database|create: 'database'|create: \"database\"" \
forge-admin-ui/src/views/app-center/index.vue
rg -n "handleAppCodeChange|runtimeModeText|targetSummary|MenuParentSelect|confirm-step|currentStep < 3|n-step title=\"确认保存\"|label=\"业务页面配置\"" \
forge-admin-ui/src/views/app-center/components/AppEntryWizard.vue
结果:两条命令均无输出;应用总览不再生成二次数据库导入参数,普通入口向导不再包含第三步确认页、入口编码输入、页面配置输入或完整菜单父级配置。
git diff --check -- \
forge-admin-ui/src/views/app-center/components/AppEntryWizard.vue \
forge-admin-ui/src/views/app-center/components/AppEditorDrawer.vue \
forge-admin-ui/src/views/app-center/index.vue \
code-copilot/changes/app-first-lowcode-workbench/spec.md \
code-copilot/changes/app-first-lowcode-workbench/tasks.md
git diff --no-index --check /dev/null <本轮相关未跟踪 Vue 文件>
结果:目标已跟踪文件和本轮相关未跟踪 Vue 文件均无空白错误。
decimal(18,2) 映射为 decimal,但默认表单使用 number 控件;前后端表单归一化随后无条件套用控件默认物理类型,导致设计态被覆盖为 int。NOT NULL,没有区分“新增/收紧字段”和“导入时本来已经是 NOT NULL 的列”,因此会错误生成把已有必填列改为可空的 MODIFY COLUMN。decimal/bigint/varchar 等数据库类型;前端表单字段同步使用同样规则。auto=true 索引不再参与映射状态或 DDL 生成,数据库已有索引不删除。LowcodeModelImportServiceTest、LowcodeDdlExplicitIndexTest 和设计器类型保护用例源码,覆盖 decimal/required 导入、searchable 不自动建索引、旧自动索引忽略和已有 NOT NULL 保持;按用户分工本轮未执行这些测试。rg -n "indexes.add\\(new IndexDefinition|field.getSearchable\\(\\).*INDEXABLE|idx_rel_|relationIndexFields|关联字段会自动创建" \
forge-server/forge-framework/forge-plugin-parent/forge-plugin-generator/src/main/java/com/mdframe/forge/plugin/generator/service/lowcode/LowcodeDdlService.java \
forge-admin-ui/src/components/lowcode-builder/model/LowcodeModelDesigner.vue
git diff --check -- <本轮相关已跟踪文件>
git diff --no-index --check /dev/null <本轮新增测试文件>
结果:旧自动索引生成路径扫描无输出;本轮相关文件无空白错误。
tf_f_order_purchase_order 后 order_no 保持 varchar(64) 与原可空性、total_amount 保持 decimal(18,2),未显式配置索引时 DDL 不出现 ADD/CREATE INDEX,显式保存索引后才出现对应预览语句。POST /ai/business/application/{id}/initialize-template。应用草稿先独立创建,模板对象、字段、关系、页面 Schema 和应用对象编排在同一事务中完成;失败回滚模板资产并保留应用草稿。simple-crud;左树右表生成主对象、树对象、REFERENCE 关系和 tree-crud;主子表生成主对象、明细对象、CHILD_LIST 关系和 master-detail-crud。V1.0.33 将旧 /ai/lowcode-models 从主导航隐藏,但保留资源、路由、API 和存量模型。V1.0.34 增加隐藏授权路由,避免权限守卫 403。rg -n '\$\{[^}]+\}' \
forge-server/db/migration/V1.0.33__hide_legacy_lowcode_model_menu.sql \
forge-server/db/migration/V1.0.34__add_business_application_preview_route.sql
rg -n "应用至少需要一个已启用的访问入口|ACTIVE_ENTRY_MISSING, (BLOCK|LEVEL_BLOCK)" \
forge-server/forge-framework/forge-plugin-parent/forge-plugin-generator/src/main/java \
forge-server/forge-framework/forge-plugin-parent/forge-plugin-generator/src/test/java
git diff --check
git diff --no-index --check /dev/null <本轮新增或原未跟踪目标文件>
结果:新迁移无 Flyway placeholder;旧入口阻断文案和阻断级别扫描无输出;V1.0.33、V1.0.34 版本唯一且单调;已跟踪与目标未跟踪文件均无空白错误。
pending-user,不表述为已通过。LowcodePreviewPane 页面,改为优先取 PRIMARY 对象 configKey 并直接新开真实 /ai/crud-page/:configKey 页面;没有可预览对象时留在工作台提示并切换到数据对象分区。AiCrudPage、列表/表单/详情和动态 CRUD API。designPreview=1 只在对象设计权限通过时允许读取未发布草稿;不带预览标识的正式运行仍要求对象已发布。DB_IMPORT 协议,对已有对象复用原对象身份;模板只配置页面布局和关系,不再要求用户填写对象名称、编码或表名。border-box + height: 100% + overflow: hidden,避免固定网格行之外的 padding 覆盖“主子表”标题;数据库/已有对象来源切换不再使用会被压缩换行的 NRadioButton,改为全宽两列分段按钮。git diff --check,未发现空白错误。git diff --no-index --check /dev/null <file>;无空白错误输出。pending-user。BusinessFieldSchemaService.normalizeFieldType 在接收到显式 fieldType 后,仍会继续按中文字段名称推断类型。TEXT、SWITCH 或其他物理语义,只要名称以“状态”或“类型”结尾,保存设计器时就会被覆盖为 DICT。dictType 或静态选项后,进入字典字段治理校验并抛出“字典字段必须配置字典类型”;对象关系查询返回 0 与该异常无关。fieldType 为空时才根据字段名称推断 DICT/MONEY/PHONE/REGION。TEXTAREA/MULTI_LINE 别名继续归一化为 MULTILINE;未知显式类型安全降级为 TEXT,不会再因字段名称二次推断为字典。DICT/SELECT/RADIO/CHECKBOX/MULTI_SELECT 字段仍要求配置字典类型或有效静态选项,没有放宽发布和运行治理。字段「订单状态」使用字典组件时必须配置字典类型或静态选项。git diff --check 以及未跟踪变更文档 git diff --no-index --check,无空白错误。PROCUREMENT_WAREHOUSE/tf_f_order 保存结果由用户验证。designPreview=true 不再复用发布阶段缓存的运行 Schema。Controller 先按 configKey 定位对象并刷新关系草稿,AiCrudConfigService 再从最新 modelSchema/pageSchema 强制编译真实 CRUD 配置;普通运行仍读取不可变发布版本。fieldSettings。既有字段从表单移除后继续保留,新拖入且不存在的字段才自动创建字段资产。BusinessApplicationDraftPreviewContractTest 源码,覆盖草稿强制编译、关系图准备、PRIMARY 发布准备和页面配置不反写字段资产。执行目标文案和调用链扫描:
rg -n "field-property-modal|显示在表单|显示在列表|作为查询条件" \
BusinessFieldManager.vue BusinessFieldPropertyPanel.vue BusinessFieldList.vue
rg -n "buildDraftRenderConfig\(config\)|!forceDraftCompile && hasStoredRuntimeConfig\(config\)|prepareRuntimeDraft\(|preparePrimaryObjectDraft\(|resolvePublishedRuntimeConfig\(config\)" \
forge-server/.../generator
rg -n "normalizeDesignerFieldPayloads\(dto.getFields|applyFormDesignerSchemaToModel\(modelSchema, formSchema\)|fieldAssetUpdated" \
BusinessObjectDesignerService.java ForgePropertyPanel.vue
rg -n "shouldRetainExistingField|isDesignerManagedField|collectBoundFieldCodes" autoFieldRegistry.js
结果:中央弹窗、三个全局页面开关和普通属性页的“公式与调试”页签扫描无输出;表单设计器仍保留 mode="formula" 的字段公式专用入口。草稿编译、预览准备、PRIMARY 发布准备和正式发布快照分支均存在;表单 Schema 反写后端调用扫描无输出;fieldAssetUpdated 只剩显式字段保存入口;旧字段过滤辅助函数无残留。
执行差异空白检查:
git diff --check -- <Phase 8 已跟踪目标文件>
git diff --no-index --check /dev/null <Phase 8 未跟踪目标文件>
结果:已跟踪与未跟踪目标文件均无 whitespace error。首次未跟踪检查包装函数误用了 zsh 只读变量 status,命令在第一个文件检查后退出;改用 result_code 后完整重跑成功,无文件写入或环境副作用。
pending-user。pending-user。rg -n "updateRequired|resolveAutomaticRequiredDefault|automaticRequiredDefault|property-section" BusinessFieldPropertyPanel.vue
rg -n "editable|startConnection|finishConnection|relationSelect|handleErConnect|erCandidateObjectCodes|buildRelationDraft|linkage-flow-editor" \
LowcodeErDiagram.vue BusinessRelationDesigner.vue
rg -n "padding: 0 8px 8px|workspace-content.is-overview|min-height: 60px|gap: 12px|min-height: 38px" \
application.[applicationCode].vue ApplicationWorkspaceHeader.vue ApplicationOverviewPanel.vue
rg -n "application-card-grid|268px|320px|min-height: 166px|application-actions|overflow-y: auto" \
ApplicationTable.vue app-center/index.vue
git diff --check -- <Phase 9 已跟踪目标文件>
结果:必填默认值、ER 编辑协议、父层关系归一化、画布对象按需加载、概览密度和紧凑卡片目标均存在;relationTypeOptions、updateRelationType、supportsPrecision、旧 handleDragMove、1180px 最小表格宽度、ResizeObserver 和横向滚动文案扫描无输出;目标代码文件无 whitespace error。
pending-user。objectIds 批量选择。config/application-manifest.json;流程、扩展和外部集成继续保留在 Forge 治理边界,不生成任意 Java/SQL。tenant_id = 1 和 NOT EXISTS;生成实体按表结构选择 TenantEntity、主键策略和逻辑删除。AppCodePanel 增加应用 scope 和对象多选,应用总览与工作台复用同一预览界面;当前参数未成功预览时下载按钮不可用。masterDetailConfig.children:派生配置为空或部分缺失时,从 pageSchema.modelRefs 中的 CHILD_LIST/DETAIL/ONE_TO_MANY 关系恢复子表外键和主表关联字段;布局声明为主子表但无法解析任何有效子关系时明确阻断,不再静默生成普通单表 Service。simple-crud 布局的问题:LowcodeCodegenService 现在使用最新页面 Schema 编译出的 layoutType 覆盖旧值,确保已经解析到子表时主 Service 真正进入 master-detail-crud 查询和事务保存分支。pageSchema.layoutType 作为第一优先级,避免绕过运行配置重编译的调用链重新使用旧布局值。${table.className}、${child.className} 原样进入 Java 文件的问题:相关元数据改为公开静态类型,并对所有生成 Java 文件执行未解析模板引用扫描;模板异常或变量残留时整体生成失败,不再记录警告后跳过文件。V1.0.35__add_business_application_codegen_permissions.sql,代码设置、预览和下载权限只继承已有应用编辑角色。BLOCK 调整为 WARN,继续显示对象名称和复用应用数量,但不再阻断当前应用发布。执行目标引用扫描,确认应用 API、批量对象选择、草稿关系刷新、manifest、文件冲突检测、预览签名、三类模板和 Mapper XML 查询均存在;旧模板中的 LambdaQueryWrapper、租户 000000 和按旧派生 Schema 空值判断扫描无输出。
执行模板 #if/#foreach/#end 数量平衡检查、V1.0.35 Flyway placeholder 扫描、BusinessApplicationObjectMapper.xml 的 xmllint --noout,均无错误输出。
对 Phase 10 目标已跟踪文件执行 git diff --check,对未跟踪文件执行 git diff --no-index --check /dev/null <file>,无 whitespace error。
增量执行主子表兜底、失败关闭、关联元数据实际渲染、子表 Service 文件、主 Service 明细方法和代码面板空间目标引用扫描,并对本轮目标文件执行差异空白检查;未运行构建或服务。
pending-user。LowcodeRuntimePage -> crud-page.vue 唯一解释链路,生成 Vue 模板不再复制字段、字典、树和主子表转换函数。DynamicCrudService、DynamicCrudExcelService,classpath 注册器以 generated_* 键提供不可变配置。/tree、异步导出任务业务端点和前端页面跳转改写。执行目标文件状态与差异空白检查:
git status --short -- <Phase 11 目标文件>
git diff --check -- <Phase 11 已跟踪目标文件>
git diff --no-index --check /dev/null <Phase 11 未跟踪目标文件>
结果:已跟踪目标文件 git diff --check 无输出;逐个检查新增 Java/Vue/测试/组装器文件,无 whitespace error。
执行薄模板、共享运行时、运行内核和公共入口引用扫描:
rg -n "transformColumns|transformFields|preloadDicts|/ai/crud/" \
templates/vm/ai-crud/index.vue.vm templates/vm/controller.java.vm
rg -n "runtimeConfig:|embeddedRuntime|props.runtimeConfig|currentTemplate|masterDetailConfig|treeConfig" \
forge-admin-ui/src/views/ai/crud-page.vue
rg -n "generatedRuntimeConfigBuilder.build|META-INF/forge-lowcode|runtimeConfigKey|-protocol.json|-coverage.json" \
VelocityCodegenStrategy.java
rg -n "DynamicCrudService|DynamicCrudExcelService|selectPage|selectTree|insert|updateById|deleteById" \
templates/vm/controller.java.vm
结果:生成 Vue/Controller 模板的复制转换函数和 /ai/crud/ 扫描无输出;内嵌运行配置、模板 Catalog、树/主子配置、公共运行键派生、四类资产路径和动态内核委托引用均存在。
执行 Velocity 指令与协议契约扫描:
rg -o '#(if|foreach)\b' <Phase 11 模板> | wc -l
rg -o '#end\b' <Phase 11 模板> | wc -l
rg -n "futureRelation|futureOption|futurePageCapability|unsupported|generated_\*|配置键冲突" \
GeneratedLowcodeRuntimeConfigBuilderTest.java LowcodeProtocolSnapshotBuilderTest.java \
GeneratedLowcodeConfigRegistryTest.java
结果:本轮三个薄模板不包含条件指令,开闭数量均为 0;新增测试源码包含未来嵌套字段、普通键派生、URL 改写、unsupported 空集、非法协议和资源键冲突契约。
pending-user,不表述为已通过。LowcodeRuntimePage + runtime-config.json 保留;下载后端从动态 CRUD 委托改为标准 MyBatis-Plus Controller/Service/Mapper/XML。ServiceExtension around 链,支持增强或完整替换分页、列表、树、详情、增改删、批量删除和导入;用户正式 custom 实现不进入生成集合。.java.example;后续后端协议能力统一进入公共 Velocity 编译入口。REQUIRES_EXTENSION。执行下载后端依赖与静态分层扫描:
rg -n "DynamicCrudService|DynamicCrudExcelService|GeneratedLowcodeConfigRegistry|META-INF/forge-lowcode|generatedConfigRegistry" \
templates/vm/controller.java.vm VelocityCodegenStrategy.java \
GeneratedLowcodeRuntimeConfigBuilder.java LowcodeProtocolSnapshotBuilder.java
rg -n "extends ServiceImpl|selectGeneratedPage|selectTreeRows|aroundPage|aroundInsert|CREATE_ONCE_SAMPLE|LowcodeStaticCodegenContributor|STATIC_MYBATIS_PLUS" \
templates/vm VelocityCodegenStrategy.java LowcodeProtocolSnapshotBuilder.java
rg -n "LambdaQueryWrapper" templates/vm/service.java.vm templates/vm/serviceImpl.java.vm \
templates/vm/mapper.java.vm templates/vm/mapper.xml.vm
结果:第一组和 LambdaQueryWrapper 扫描无输出;生成 Service、Mapper XML、扩展链、所有权、静态编译模式和贡献器引用均存在。DynamicCrudService.getConfig 继续直接调用数据库配置服务并保留授权设计预览分支,在线运行未移除。
执行 Apache Velocity 2.3 实际渲染:
simple: controller/service/serviceImpl/serviceExtension/businessExtension/excel/README rendered
master: controller/service/serviceImpl/serviceExtension/businessExtension/excel/README rendered
tree: controller/service/serviceImpl/serviceExtension/businessExtension/excel/README rendered
query.java.vm=883
mapper.xml.vm=2497
结果:单表、主子表、左树右表及 eq/ne/like/left_like/right_like/gt/ge/gte/lt/le/lte/in/between 查询模板均完成渲染;无残留 #if/#end/${...}/$object.property。扩展链泛型另用 JDK 17 最小等价代码执行 javac,编译成功。
执行 XML、SQL 和差异空白检查:
xmllint --noout templates/vm/mapper.xml.vm
rg -n "WHERE NOT EXISTS|data_source_bean|excelImportService.importData" \
templates/vm/sql/excel.sql.vm templates/vm/controller.java.vm
git diff --check -- <Phase 12 已跟踪目标文件>
git diff --no-index --check /dev/null <Phase 12 未跟踪目标文件>
结果:Mapper XML 静态解析成功;Excel 元数据使用防重复插入并指向生成 Service;tracked 和逐个 untracked 目标文件均无 whitespace error。
校验过程先尝试 JShell,因沙箱禁止 JDI 监听端口且 local 模式未继承外部 classpath,未执行到模板;随后使用 JDK 17 source-file mode 完成同等 Velocity 校验。该工具限制不影响代码结果,也未启动服务或修改数据库。
pending-user,不表述为已通过。VelocityCodegenStrategy.java:164 报“从 lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量”。generate(AiCrudConfig config, ...) 先把规范化结果重新赋给方法参数 config,随后 staticCodegenContributors.orderedStream().filter(...) 捕获该变量。config 只用于解析来源键和业务 API,规范化结果只赋值一次给 codegenConfig;字段解析、模板上下文、静态贡献器、SQL、前端资产和协议快照全部显式使用 codegenConfig。NONE 不再生成字段 @Desensitize 或实体 import;真实策略统一大写后生成。options.codegen;前端保存、预览、下载和预览签名携带同一字段,空表前缀列表不会在 GET 序列化时丢失。执行 tracked 与 untracked 差异空白检查:
git diff --check -- <Phase 13 已跟踪目标文件>
git diff --no-index --check /dev/null <Phase 13 未跟踪目标文件>
结果:已跟踪目标命令退出码 0;9 个未跟踪目标均只有 --no-index 的正常差异退出码 1,检查输出为空,无 whitespace error。
执行前端脚本语法检查:
node --check forge-admin-ui/src/api/business-app.js
node --check forge-admin-ui/src/api/business-application.js
awk '/<script setup>/{active=1; next} /<\/script>/{active=0} active' \
forge-admin-ui/src/views/app-center/components/AppCodePanel.vue | node --check --input-type=module
结果:三个检查退出码均为 0;新增设置表单、payload、空数组归一化和下载参数序列化无 JS 语法错误。
执行 Velocity 与协议引用检查:
rg -o '#(if|foreach)\b' templates/vm/README.md.vm | wc -l
rg -o '#end\b' templates/vm/README.md.vm | wc -l
rg -o '#(if|foreach)\b' templates/vm/entity.java.vm | wc -l
rg -o '#end\b' templates/vm/entity.java.vm | wc -l
rg -n '@Desensitize\(type = DesensitizeType\.NONE\)' <生成器模板和 Java 源码>
rg -n 'entityPrefix|stripTablePrefixes|backendBasePath|mapperXmlBasePath|frontendApiBasePath|includeBackend|includeFrontend|includeExcelSql' \
<请求 DTO、三类 Service、Assembler、Velocity 策略和 AppCodePanel>
结果:README 指令 6/6、Entity 指令 17/17;没有 DesensitizeType.NONE 注解输出;新增设置在请求 DTO、应用、访问入口、低代码服务、公共装配器、生成策略和前端面板中均存在。JS/Vue 语法、模板条件和引用扫描均通过。
pending-user,不表述为已通过。ApplicationTable.vue 使用 repeat(auto-fill, minmax(268px, 320px)),自动重复轨道按固定 320px 上限计算列数;中小屏内容区实际可以容纳三张 268px 卡片时仍只生成两列,右侧形成大块空白。repeat(auto-fill, minmax(min(100%, 268px), 1fr)):列数按 268px 基准和容器真实宽度计算,当前行余量由已有轨道等分;auto-fill 继续保留空轨道,宽屏少量应用不会拉成整行大卡片。pending-user。