统一 Node 22 与后端安全运行基线(07-15-production-trust-closeout-cleanup)
这个提交包含在:
+18
-24
@@ -1,12 +1,12 @@
|
||||
# hyb-oa Client Runbook (P1-5)
|
||||
|
||||
## 1. 前置条件
|
||||
- Node.js >= 20
|
||||
- Node.js `>=22 <23`
|
||||
- 后端服务可用(`http://127.0.0.1:3000`)
|
||||
|
||||
## 2. 安装与启动
|
||||
```bash
|
||||
cd /home/shunli/Projects/hyb-oa/client
|
||||
cd client
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
@@ -15,19 +15,23 @@ npm run dev
|
||||
|
||||
## 3. 本地联调建议顺序
|
||||
```bash
|
||||
cd /home/shunli/Projects/hyb-oa
|
||||
cd ..
|
||||
|
||||
export POSTGRES_PASSWORD="<local-only-db-password>"
|
||||
export JWT_SECRET="<local-only-jwt-secret>"
|
||||
docker compose up -d db
|
||||
|
||||
cd /home/shunli/Projects/hyb-oa/server
|
||||
cd server
|
||||
npm run prisma:migrate:deploy
|
||||
npm run seed:dev
|
||||
SEED_DEV_ALLOW=1 SEED_DEV_DATABASE_CONFIRM=hyb_oa npm run seed:dev
|
||||
npm run dev
|
||||
|
||||
cd /home/shunli/Projects/hyb-oa/client
|
||||
cd ../client
|
||||
npm run dev
|
||||
```
|
||||
|
||||
根级 Compose 要求显式提供本地数据库口令和 JWT 密钥;不要把真实值写入仓库,并让 `server/.env` 的 `DATABASE_URL` 使用同一数据库口令。
|
||||
|
||||
## 3.1 试运行/单域托管部署(推荐)
|
||||
试运行/上线演练建议使用仓库内置部署包(server 托管 `client/dist`,同域 cookie 更稳定):
|
||||
- `deploy/trialrun/runbook.md`
|
||||
@@ -39,19 +43,9 @@ npm run dev
|
||||
- 前端在 401 时自动调用 `/api/auth/refresh` 并重试一次请求。
|
||||
- 登录与刷新请求都会附带 `x-device-fingerprint`。
|
||||
|
||||
## 4.1 开发环境默认账号(seed:dev)
|
||||
仅用于本地联调(`cd server && npm run seed:dev`):
|
||||
## 4.1 开发账号(seed:dev)
|
||||
|
||||
| 角色 | 账号 | 密码 |
|
||||
|---|---|---|
|
||||
| employee | `[email protected]` | `EmployeePassword1234` |
|
||||
| manager | `[email protected]` | `ManagerPassword1234` |
|
||||
| finance | `[email protected]` | `FinancePassword1234` |
|
||||
| finance_mgr | `[email protected]` | `FinanceMgrPassword1234` |
|
||||
| admin | `[email protected]` | `AdminPassword1234` |
|
||||
| ceo | `[email protected]` | `CeoPassword1234` |
|
||||
|
||||
忘记密码:登录页提供邮箱验证码找回;管理员重置密码仍作为试运行/生产兜底。
|
||||
`seed:dev` 仅用于本机开发库,必须显式允许并确认数据库名;账号与口令以本地受控 `SEED_*` 配置为准,脚本不输出口令。默认不会覆盖已有账号密码;新建账号和主动设置 `SEED_DEV_RESET_PASSWORDS=1` 后轮换的账号,首次登录都必须改密。
|
||||
|
||||
## 5. 菜单与权限(当前壳层)
|
||||
- 仪表盘:登录即可访问。
|
||||
@@ -74,7 +68,7 @@ npm run dev
|
||||
- API 层保留后端错误码原文,前端仅做可读化。
|
||||
|
||||
## 6. 风格资源复用策略(锁定)
|
||||
- 视觉 Token 来源:`/home/shunli/Projects/hyb-web`。
|
||||
- 视觉 Token 来源:`<design-source-repo>`。
|
||||
- 采用“复制到 client + 单向同步”,不做跨仓软链与自动联动。
|
||||
- 如需同步风格,请记录来源 commit 并通过评审。
|
||||
|
||||
@@ -90,18 +84,18 @@ npm run test:e2e
|
||||
## 8.1 Playwright E2E(E15)
|
||||
前置:本地启动 DB + server(建议 `SERVE_CLIENT_DIST=true` 单域托管),并启用 mock OCR:
|
||||
```bash
|
||||
cd /home/shunli/Projects/hyb-oa
|
||||
cd ..
|
||||
docker compose up -d db
|
||||
|
||||
cd /home/shunli/Projects/hyb-oa/server
|
||||
cd server
|
||||
OCR_PROVIDER=mock OCR_POLL_CRON="*/5 * * * * *" npm run prisma:migrate:deploy
|
||||
OCR_PROVIDER=mock OCR_POLL_CRON="*/5 * * * * *" npm run seed:dev
|
||||
SEED_DEV_ALLOW=1 SEED_DEV_DATABASE_CONFIRM=hyb_oa OCR_PROVIDER=mock OCR_POLL_CRON="*/5 * * * * *" npm run seed:dev
|
||||
OCR_PROVIDER=mock OCR_POLL_CRON="*/5 * * * * *" SERVE_CLIENT_DIST=true npm run dev
|
||||
```
|
||||
|
||||
执行:
|
||||
```bash
|
||||
cd /home/shunli/Projects/hyb-oa/client
|
||||
cd ../client
|
||||
npm install
|
||||
npx playwright install --with-deps
|
||||
npm run test:e2e
|
||||
@@ -109,7 +103,7 @@ npm run test:e2e
|
||||
|
||||
## 9. 仓库级最小门禁
|
||||
```bash
|
||||
cd /home/shunli/Projects/hyb-oa
|
||||
cd ..
|
||||
./scripts/check-minimal.sh
|
||||
```
|
||||
|
||||
|
||||
+16
-13
@@ -21,7 +21,7 @@
|
||||
"qrcode.react": "^4.2.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.22.0",
|
||||
"react-router-dom": "^6.30.4",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^2.6.1"
|
||||
},
|
||||
@@ -36,6 +36,9 @@
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.1.0",
|
||||
"vite-plugin-pwa": "^0.20.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22 <23"
|
||||
}
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
@@ -2880,9 +2883,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz",
|
||||
"integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==",
|
||||
"version": "1.23.3",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.3.tgz",
|
||||
"integrity": "sha512-4An71tdz9X8+3sI4Qqqd2LWd9vS39J7sqd9EU4Scw7TJE/qB10Flv/UuqbPVgfQV9XoK8Np6jNquZitnZq5i+Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -6265,12 +6268,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.30.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz",
|
||||
"integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==",
|
||||
"version": "6.30.4",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.4.tgz",
|
||||
"integrity": "sha512-SVUsDe+DybHM/WmYKIVYhZh1o5Dcuf16yM6WjG02Q9XVFMZIJyHYhwrr6bFBXZkVP6z69kNkMyBCujt8FaFLJA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.23.2"
|
||||
"@remix-run/router": "1.23.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -6280,13 +6283,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.30.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz",
|
||||
"integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==",
|
||||
"version": "6.30.4",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.4.tgz",
|
||||
"integrity": "sha512-q4HvNl+mmDdkS0g+MqiBZNteQJCuimWoOyHMy4T/RQLAn9Z29+E91QXRaxOujeMl2HTzRSS0KFPd7lxX3PjV0Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.23.2",
|
||||
"react-router": "6.30.3"
|
||||
"@remix-run/router": "1.23.3",
|
||||
"react-router": "6.30.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
|
||||
+4
-1
@@ -3,6 +3,9 @@
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=22 <23"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "npm run typecheck && vite build",
|
||||
@@ -35,7 +38,7 @@
|
||||
"qrcode.react": "^4.2.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.22.0",
|
||||
"react-router-dom": "^6.30.4",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^2.6.1"
|
||||
},
|
||||
|
||||
在新工单中引用
屏蔽一个用户