开发时期 · 建 · moo-scaffold
把重复劳动
在写代码时消灭
Laravel 后端「Schema 驱动」研发提效套件:写一份 YAML 当唯一事实源,一条流水线产出 Model / Resource / Controller / Request / Migration / 接口文档 / ACL / 多语言 全套代码,再附一个挂在 /scaffold 的内置研发后台。
The pain
「建表 → 写一圈文件 → 配权限 → 配多语言」这条链路,手工维护必出事
一张表 8~15 个字段,字段 / 类型 / 校验 / 注释要在 6~8 个文件里重复声明,而且彼此口径必须一致。
重复劳动
同一批字段在 Model / Migration / Request / 文档 / 权限 里抄六七遍。
口径漂移
Migration 写 varchar(128)、Request 校验写 max:64、文档又写别的 —— 三处不一致是常态。
文档滞后
接口文档靠人维护,永远落后于代码。
联调成本
改完接口要切到 Postman 重配参数、配 token、配环境。
moo-scaffold 把这条链路收敛成 单一事实源(一份 YAML)+ 一条生成流水线 + 一个可视化后台 —— 让「改 schema」成为唯一入口,其余产物自动派生、自动保持一致。
"明明有现成的,还自己造"
判断只有一条:当"和自己代码共享同一份 schema"能带来通用工具拿不到的好处时,自造才值。下面的设计器与调试器,正是这条线上的 —— 它们能做到 Navicat / Postman 结构上做不到的"零漂移"。
怕被绑死?生成出来的是标准 Laravel 代码 —— 即便日后不用 scaffold,Model / Controller / Migration 仍是你的、照常跑。耦合的是「开发期的爽」,不是「运行期的命脉」。
Architecture
同一个包,两大支柱
一个 Service Provider 下做两件相对独立的事:命令行的代码生成器,和网页端的研发后台。
Schema 驱动的代码生成器
php artisan moo:* 一条流水线:YAML → 解析成缓存 → 生成 Model / Resource / Controller / Request / Migration / 接口文档 / ACL / 多语言 / 前端脚手架。
核心契约:你只改 YAML,moo:fresh 解析成缓存,所有其它生成器只读缓存、不读 YAML。
挂在 /scaffold 的研发后台
一个网页后台覆盖「设计库表 → 调接口 → 看权限 → 改配置 → 抓错误」全研发链路:数据库设计器、接口调试器、ACL 视图、配置中心、账号、字典、运行时监控、云端控制台。
自身无数据库 —— 不建任何表,操作的都是宿主项目的 DB,自身运行期数据是磁盘 YAML。
Install
装上它 · 大概 30 秒
装到任意 Laravel 12 / PHP 8.2+ 项目。它只在开发期生效,不是运行时框架。
- !私有包,未上 Packagist —— 宿主
composer.json要先配repositories(本地 path / 生产 vcs),取得源码后再装。 - ▸装好先
moo:account:add建首个后台账号,即可登录/scaffold。
# 1. composer.json 配好 repositories 后 composer require charsen/moo-scaffold php artisan moo:init "你的名字" php artisan moo:account:add you # 2. 设计好表后,一条命令生成全套 php artisan moo:free admin Post -a
Pipeline
一条命令,跑完全链路
moo:free 顺序跑完整条流水线;也能单步跑 moo:model / moo:migration / moo:auth 等单独某一环。
*Trait.php、Enum 文件 —— schema 一变就重新覆盖。
Model.php / ModelFilter.php / ModelFactory.php / Model.ts —— 除非加 --force,不会覆盖你的改动。
新路由会自动插进宿主 routes/admin.php / routes/api.php 的标记处;给已有 controller 加单个 action 用 moo:adder,不必重跑整条流水线。
改完表,迁移自己写好
可视化编辑 scaffold/database/*.yaml,免手写 YAML。落盘即 YAML(保留注释 + 固定 key 顺序,git diff 干净)。
- ▸字段改名走
renameColumn保数据,不是 drop+add 丢数据 - ▸迁移预览:设计器内直接预览即将生成的 migration PHP,与
moo:migration同一套 diff + writer,GUI/CLI 口径一致 - ▸删表/删字段闭环:自动接力生成 drop migration、联动清 snapshot;删字段前扫全仓查谁引用,分「自动清 / 手动清」
- ▸两种 unique 语义:app 级(软删不占名额,落 Request 校验)vs DB 级(migration 强约束),不再混为一谈
- ▸基线快照随 git 同步,diff 有基准、跨成员/分支防生产冲突
- ▸AI 辅助:中文字段名 → snake_case + 类型/size 建议;输入「小区名称, 物业类型, 楼栋数」批量加字段
// 自动产出,无需手写 Schema::table('users', function (Blueprint $t) { $t->renameColumn('user_name', 'username'); // 保数据 $t->string('email', 128)->unique(); });
参数零手填,表单所见即所得
基于 YAML(而非手维护)的接口文档 + 类 Postman 调试器,长在后台里 —— 改完接口不用切 Postman。
- ▸参数从 FormRequest 校验规则 + YAML 自动派生,不用手填、不用手维护 mock
- ▸自动 Token:登录接口自动从响应抓 token、按 host 持久化,后续请求自动带上,不用复制 Bearer
- ▸多接口 tabs(软上限 10)参数值零丢失;每个接口按 host/客户端维度自动缓存「上次填了啥」
- ▸多环境 host 下拉切换;请求经后端代理转发,强制 TLS、origin 白名单防 SSRF、throttle 防滥用
- ▸表单预览:创建/编辑接口直接渲染成可操作表单,对齐前端 former 组件库(input/select/cascader/date/upload/editor…),实时输出 JSON
- ▸参数表 ↔ JSON 双向切换,粘贴整段 JSON 一键回填(含嵌套/数组)
Workbench
一个 /scaffold 后台,覆盖全研发链路
设计器、调试器只是其中两面。整个后台从设计库表一路覆盖到抓错误。
数据库设计器
/db/designer可视化改 schema、迁移预览、改名保数据、删表闭环。
API 文档 + 调试器
/apiYAML 渲染文档 + 类 Postman 调试 + 表单预览。
ACL 权限视图
/routes从真实路由反推动作级 ACL,搜索/折叠,一键跳调试。
配置中心
/config可视化改 config/scaffold.php 与 .env(env 镜像掩码只读)。
账号管理
/accounts后台登录账号 CRUD + 启停,admin/member 两角色,YAML + bcrypt。
字典浏览
/dictionaries浏览所有枚举(字段→键→值→中英标签),业务字典随手查。
运行时错误 / 慢 SQL
/runtimes本地捕获缓冲 → 推送云端,本地无查看器、访问重定向到监控云。
云端汇聚控制台
/cloud本地缓冲状态总览 + 手动推送 + 云端入口(首页拉本项目只读汇总)。
AI 辅助
DeepSeek字段/枚举翻译、拼写检查、表名简写;未配置不崩溃,填好上游即生效。
运行时错误 / 慢 SQL / 待办的真源在 监控云 —— scaffold 只留 UI 壳与重定向;3.9 起这条采集链由依赖包 moo-monitor-laravel 提供,composer 自动带入。
Trade-off
自造 vs 通用工具:各赢在哪
不是"自造一定好"。同一件事,放在一起看更清楚。
| 维度 | 手写 / 通用工具 | scaffold 自造 |
|---|---|---|
| 改表 → 迁移 | Navicat 直改库,无版本、不可复现 | GUI 改完自动出迁移,schema 进 git |
| 字段改名 | 易误用 drop+add 丢数据 | 自动 renameColumn 保数据 |
| 接口参数 | Postman 手填、手维护 mock | FormRequest 自动派生,零手填 |
| 文档 / 调试 / 前端 | 三套各自维护,迟早漂移 | 同一份 schema,改一处全同步 |
注:自造的代价是深度耦合 —— 赢在"和自己代码零漂移",出了 scaffold 生态就不适用。Postman/Navicat 赢在可移植、跨团队、生态丰富。
Philosophy
贯穿一切设计决策的四条
这是一个自用工具的取舍 —— 知道边界在哪,才敢把功能做简单。
业务面广,功能必须简单
涉及 DB、API、ACL、错误、账号、配置,但每块都不堆复杂特性 —— 「备份/快照/多步撤销/操作审计」默认劝退,能走 git 就走 git。
dev 可写 · prod 只读
所有「写」类功能只在开发环境启用,生产锁高风险写簇(设计器/账号/配置/推云)。两条强制防线:CLI only_in_local + Web EnforceScaffoldWritable。因为有这条边界,工具才不需要复杂权限模型。
UI/UE 追求完美,但完美 ≠ 复杂
视觉、交互、暗黑模式、CSP 兼容值得反复打磨 —— 但视觉投入不能当成新增功能复杂度的借口。
codegen 模板就是编码规范
stubs/*.stub 与 Foundation 基类,本身就是「PHP 项目应该长这样」的规范;改它们,按「改规范」的严肃程度对待。
不是 demo,是经得起改的工程
- ▸530+ Pest 测试(Testbench + Pest 3):生成器 / SchemaLoader / Diff / 配置 / 账号 / 接口调试 / 安全全覆盖
- ▸Playwright e2e 覆盖设计器 / 调试器关键 user flow
- ▸静态门禁:视图无内联 style / 无硬编码 hex + CSS gzip 预算 + Pint 格式化
- ▸回归锁:每个修复都补「经 revert 验证」的回归测试
安全模型(自用 ≠ 不设防)
- ▸生产锁高风险写簇;全部
moo:*命令 console-only,Web 入口禁起 Artisan - ▸登录 cookie:AES-256-CBC 加密 + HMAC-SHA256 签名,登录限流
- ▸接口代理 origin/协议白名单防 SSRF;CSP-safe(Alpine 无内联表达式)
- ▸配置/env 镜像掩码、调试历史 token 脱敏、运行时错误自动脱敏
一句话记住它
一份 YAML 是事实源,一条流水线产出全套后端代码,一个 /scaffold 后台覆盖「设计库表 → 调接口 → 看权限 → 改配置 → 抓错误」全链路。
scaffold 是这套生态的「建」。写完代码,接着是测试报障、上线监控 —— 看它怎么和另外 7 个工具咬合成一条闭环。