跳到主内容

开发时期 · 建 · moo-scaffold

把重复劳动写代码时消灭

Laravel 后端「Schema 驱动」研发提效套件:写一份 YAML 当唯一事实源,一条流水线产出 Model / Resource / Controller / Request / Migration / 接口文档 / ACL / 多语言 全套代码,再附一个挂在 /scaffold 的内置研发后台。

PHP 8.2+ · Laravel 12 · Composer 包 v3.9.1 · MIT 530+ 测试
单一事实源 · single source of truth
# 写一份 schema
schema.yaml moo:free
Model Migration Request Resource 接口文档 ACL
改 schema 是唯一入口,其余产物自动派生 —— 文档 / 校验 / 调试 / 前端,四端不漂移。

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 等单独某一环。

php artisan moo:free admin Estate -a
Fresh Model Resource Controller 多语言 ACL Migration 接口文档 前端脚手架
每次重写 · 别写业务逻辑

*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 建议;输入「小区名称, 物业类型, 楼栋数」批量加字段
改完 GUI → 自动生成
// 自动产出,无需手写
Schema::table('users', function (Blueprint $t) {
    $t->renameColumn('user_name', 'username'); // 保数据
    $t->string('email', 128)->unique();
});
改完即得迁移
0 手写 PHP
改名
数据无损
删字段
先查引用
研发后台 · API 文档 + 调试器

参数零手填,表单所见即所得

基于 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 一键回填(含嵌套/数组)
参数 响应 表单预览
→ 实时输出 JSON,直接进 POST

Workbench

一个 /scaffold 后台,覆盖全研发链路

设计器、调试器只是其中两面。整个后台从设计库表一路覆盖到抓错误。

数据库设计器

/db/designer

可视化改 schema、迁移预览、改名保数据、删表闭环。

API 文档 + 调试器

/api

YAML 渲染文档 + 类 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 手填、手维护 mockFormRequest 自动派生,零手填
文档 / 调试 / 前端三套各自维护,迟早漂移同一份 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 个工具咬合成一条闭环。