A production-validated Webman monolithic monorepo scaffold: backend PHP 8.4 + Webman 2 + ThinkORM 4 + MySQL 8.0, frontend React + TypeScript (user side Vite, admin side Umi Max + Ant Design Pro). Frontend and backend in the same repository, deployed on the same domain, with frontend build artifacts dropped directly into Webman's public/。
Confirm before use
Ask everything at once with AskQuestion, don't follow up one by one:
- Project slug(lowercase English, used for localStorage key, DB name, log prefix), e.g.
myapp - Which ends are needed: backend only / backend + user side / backend + user side + admin panel
- User side authentication method: account and password / SMS verification code / email / other
- Whether multilingual support is needed(i18n for the APP side; the admin panel is always fixed to Simplified Chinese, no i18n)
- Whether scheduled tasks, Redis queues, object storage are needed(assembled on demand, by default only scheduled tasks are installed)
__APP_SLUG__ is a placeholder in all templates; after answering, replace it globally.
Target structure
project/
├── app/ # Webman 后端
│ ├── command/ # CLI + 计划任务命令(继承 AbstractTaskCommand)
│ ├── controller/api/ # APP 端控制器 → /api/*
│ ├── controller/admin/ # 后台控制器 → /admin-api/*
│ ├── enum/MessageCode.php # 统一错误码
│ ├── exception/Handler.php
│ ├── middleware/ # 全部以 Middleware 结尾
│ ├── model/ service/ util/
│ ├── process/ # 常驻进程(TaskScheduler 等)
│ ├── validate/{api,admin}/# 镜像控制器目录
│ ├── view/{index,admin}/ # 前端构建产出的 index.html 落点
│ └── functions.php # success() / fail()
├── config/ # 含 route.php、middleware.php、ratelimit.php、task.php…
├── database/ # schema.sql / seed.sql / migrations/
├── docs/ # ARCHITECTURE / DEVELOPMENT_PLAN / …
├── public/ # 前端构建输出(assets/、admin/)
├── resource/translations/ # 后端语言包 {locale}/messages.php
├── tests/ # PHPUnit
├── web/ # 用户端 React + Vite
├── admin/ # 管理后台 Umi Max + Ant Design Pro
└── .cursor/rules/ # 四件套规范
Initialization flow
Copy this checklist and proceed item by item:
- [ ] 步骤 1:后端骨架(composer create-project + 依赖)
- [ ] 步骤 2:核心基础设施(响应/异常/中间件/路由/配置)
- [ ] 步骤 3:数据库(schema.sql + seed.sql + migrations/)
- [ ] 步骤 4:i18n(后端语言包 + CLI)
- [ ] 步骤 5:用户端 /web
- [ ] 步骤 6:管理后台 /admin(可选)
- [ ] 步骤 7:docs 文档集 + .cursor/rules
- [ ] 步骤 8:验收自检
You can also first use the script to lay out the directories and templates in one go, then verify and trim step by step below:
scripts/init.sh <项目路径> <app_slug> [--with-admin] [--force]
- Without
--with-admin, the script strips admin-related middleware, models, configuration, routes and RBAC table creation statements, producing a clean "backend + user side" skeleton - By default existing files are not overwritten; to overwrite add
--force - The script only lays out files, replaces
__APP_SLUG__placeholders, and does not executecomposer/npminstallation
Step 1: Backend skeleton
composer create-project workerman/webman <project>
cd <project>
composer require webman/think-orm webman/think-cache webman/redis webman/console \
workerman/crontab symfony/translation vlucas/phpdotenv tinywan/jwt webman/limiter
composer require --dev phpunit/phpunit phpstan/phpstan phpstan/phpstan-deprecation-rules
Always use php84for PHP commands, always use composer。
Step 2: Core infrastructure
Copy one by one according to templates/backend/ . These are themust preserve semantics as-isparts:
| File | Purpose |
|---|---|
app/functions.php |
success() / fail() —— the project's only response exit |
app/enum/MessageCode.php |
Error code constant table |
app/exception/Handler.php |
Three exception types → unified response |
app/middleware/*.php |
Middleware chain, order has hard dependencies |
app/controller/api/BaseController.php |
userId() / jwtExtend() |
app/command/AbstractTaskCommand.php |
Scheduled task execution framework |
app/process/TaskScheduler.php |
Scheduled task scheduling process |
config/*.php |
Routing, middleware, exceptions, auth whitelist, rate limiting, tasks, logging, ORM |
config/autoload.php must load app/functions.php, otherwise success() / fail() is unavailable.
For detailed description see references/backend.md。
Step 3: Database
All three are indispensable, see references/conventions.md §Database:
database/schema.sql—— table structuresingle source of truth, full DDLdatabase/seed.sql—— seed data, idempotent styledatabase/migrations/YYYY_MM_DD_描述.sql—— idempotent incremental script
Do not directly modify an existing database: after generating the migration script, tell the user the path, and the user executes it manually.
Step 4: i18n
- Backend:
resource/translations/{locale}/messages.php, flatkey => 译文array,zh_CNis the only source of truth - Frontend:
web/src/i18n/locales/zh_CN.json, nested JSON, likewise using Chinese as the source of truth - Language is passed to the backend via the
X-Langheader,LocaleMiddlewarenormalizes - Placeholder: backend
%var%(symfony), frontend{{var}}(i18next) - The admin panel does not do i18n, copy is hardcoded in Simplified Chinese
Step 5: Client side /web
Vite 6 + React 18 + TypeScript + Ant Design 5 + Tailwind(preflight: false) + axios + Zustand + React Query + react-router Hash routing.
Key:vite.config.ts output the build artifacts to ../public, after building move index.html to app/view/index/index.html. See references/frontend-web.md。
Step 6: Admin panel /admin (optional)
Umi Max 4 + Ant Design Pro + ProComponents,publicPath: '/admin/',outputPath: '../public/admin', postbuild moves index.html to app/view/admin/index.html. See references/frontend-admin.md。
Step 7: Documentation and conventions
docs/:ARCHITECTURE.md(product requirements + core business rules),DEVELOPMENT_PLAN.md(phased development plan), add when there is an admin panelADMIN_DEVELOPMENT_PLAN.md, add when there are multiple languagesI18N_MANAGEMENT.md, add before launchOPERATIONS.md.cursor/rules/:default-rules.mdc(alwaysApply)+backend-conventions.mdc/frontend-conventions.mdc/admin-conventions.mdc(triggered by globs)
Templates are in templates/docs/ and templates/rules/, see references/cursor-rules.md。
Step 8: Acceptance self-check
php84 start.php start -d # 后端起得来
curl -X POST http://127.0.0.1:8787/api/ping # {"code":0,"message":"success","data":{...}}
php84 vendor/bin/phpstan analyse # 静态检查通过
php84 vendor/bin/phpunit # 测试通过
cd web && pnpm build # 产物落 public/ + app/view/index/index.html
cd admin && npm run build # 产物落 public/admin/ + app/view/admin/index.html
Then check item by item: unregistered routes return 404 (default routes are disabled), error responses carry CORS headers, after switching X-Lang the message language changes accordingly.
Core conventions (non-negotiable)
These conventions run through the whole project, write them into default-rules.mdc:
- All APIs are always POST, parameters go in the JSON request body. Route prefixes: APP side
/api/, admin side/admin-api/ - Unified response
{ "code": 0, "message": "success", "data": {} };code=0means success - Default routes are globally disabled(
Route::disableDefaultRoute()): interfaces must be explicitly registered inconfig/route.php, otherwise 404 - Authentication failures return a response instead of throwing an exception, ensuring the response still passes through the outer CORS middleware
- Parameter validation convention over configuration:
app\controller\api\XxxController→app\validate\api\XxxValidate, scenario name = method name - Amounts must not use FLOAT, always
DECIMAL; precision is fixed per business indefault-rules.mdcHardened - DB change trio:
schema.sql+seed.sql+migrations/idempotent script, do not modify the database directly - Frontend and backend on the same domain: Hash routing + build artifacts placed in
public/, no backend catch-all needed - APP side is multilingual, admin panel is fixed in Chinese
Middleware chain order
The order has hard dependencies and must not be adjusted arbitrarily:
CorsMiddleware 最外层,保证错误响应也带跨域头
→ LocaleMiddleware 识别语言,进程常驻必须每请求重设
→ AuthMiddleware /api/* JWT
→ AdminAuthMiddleware /admin-api/* 独立 JWT
→ RateLimitMiddleware 必须晚于鉴权:by:user 依赖 Context 里的 userId/adminId
→ AdminPermissionMiddleware RBAC 权限码
→ ValidateMiddleware 参数校验
→ AdminOperationLogMiddleware 后台写操作审计
Common pitfalls
- Adding a controller methoddoes not equaladding an interface—you must go to
config/route.phpto register - Webman processes are resident:
LocaleMiddlewaremust be explicitly set on every requestlocale(...), otherwise languages get mixed up - The frontend artifact directory is Webman's
public/,emptyOutDirmust befalse, only cleanassets/ - The scheduled task scheduling process is fixed to
count => 1, otherwise multiple workers trigger it repeatedly - When adding funding-type / password-verifying write interfaces, you must also register in
config/ratelimit.phpRegisterby: userrate limit
Template list
templates/ Files under can be copied directly into the project. Anything with __APP_SLUG__ needs to be replaced.
| Directory | Contents |
|---|---|
templates/backend/app/ |
functions.php、MessageCode、Handler, 7 middlewares,BaseController/AdminBaseController、PingController、AbstractTaskCommand、TaskScheduler、ClientIp/Locale、RateLimiter/AdminPermissionService, example validators, 6 models |
templates/backend/config/ |
route.php、middleware.php、exception.php、autoload.php、auth.php、admin.php、ratelimit.php、task.php、translation.php、log.php、think-orm.php、redis.php、process.php, JWT plugin configuration |
templates/backend/resource/ |
zh_CN / en language packs |
templates/web/ |
vite.config.ts、client.ts、types/api.ts, i18n, theme, store, router, App/main, layout and example pages, Tailwind/PostCSS/tsconfig |
templates/admin/ |
Umi config.ts/routes.ts/proxy.ts/defaultSettings.ts、app.tsx、requestErrorConfig.ts、access.ts、adminPost, ProTable adapter,postbuild.js |
templates/database/ |
schema.sql、seed.sql, migration script template |
templates/docs/ |
ARCHITECTURE / DEVELOPMENT_PLAN / I18N_MANAGEMENT / OPERATIONS skeleton |
templates/rules/ |
four-piece set .mdc |
templates/ root |
README.md、gitignore |
In SQL and config, the @admin-only markers are for init.sh stripping the admin backend; when copying manually, delete the marker lines or whole blocks as needed.
Reference documents
- references/backend.md — backend layering, routing, responses, middleware, exceptions, validation, tasks, queues, logging, and notes on resident processes
- references/frontend-web.md — user-side directory, HTTP wrapper, i18n, state, theme, build integration, mobile
- references/frontend-admin.md — admin Umi configuration, request layer, permissions, ProTable templates
- references/conventions.md — environment variables, database, documentation set, testing, static checks
- references/cursor-rules.md — responsibility boundaries and tailoring guidance for the rules of the four-piece set