4f38522759
- app/main.py: AdminSPA 纯 ASGI 挂载 /admin(dist 存在=StaticFiles html
+ SPA fallback(非 /admin/api 的 404 回 index.html 200);缺失=503 说明页);
ADMIN_DIST env 覆盖、请求期现势解析(构建后不重启生效/测试可注入)。
/health 分级: {status, tenants:[{slug,status,engine_ok}], domains}——
懒建未就绪 engine_ok=None 不探库;单租户库损坏只 degraded 仍 200,
不让 healthcheck 杀容器。
- host_middleware: /admin 与 /admin/ 前缀豁免租户解析(平台面;/admin-evil
仍 404,前缀精确到斜杠)。
- admin: .env.production VITE_BASE_URL=/admin/(产物资源引用与挂载同源,
单一事实源,不靠构建期 env 注入);package.json 钉 packageManager
pnpm@10.7.1(corepack 与本地同版本)。
- Dockerfile 两阶段: node:20-alpine 构建 admin/dist(corepack 按清单钉版)
→ python:3.13-slim 只带运行时(app/static/seed_profiles/scripts+dist,
含 tzdata 使 TZ 生效)。
- docker-compose: 生产编排(8018/env_file 可缺省/TZ/数据 bind mount/
mem_limit 768m/日志轮转/python urllib healthcheck/restart)。
- .dockerignore 防泄(.env 不进镜像)+ .gitattributes 钉部署文件 LF。
- tests/test_admin_serving.py: 假 dist 夹具 7 例(服务/fallback 边界/
Host 豁免/缺失降级/health 分级含坏库 degraded)。
Co-Authored-By: Claude Code <noreply@anthropic.com>
89 lines
2.5 KiB
JSON
89 lines
2.5 KiB
JSON
{
|
|
"name": "all-kefu-admin",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"type": "module",
|
|
"packageManager": "pnpm@10.7.1",
|
|
"engines": {
|
|
"node": ">=20.19.0",
|
|
"pnpm": ">=8.8.0"
|
|
},
|
|
"pnpm": {
|
|
"onlyBuiltDependencies": [
|
|
"@parcel/watcher",
|
|
"@tailwindcss/oxide",
|
|
"core-js",
|
|
"esbuild",
|
|
"es5-ext",
|
|
"vue-demi"
|
|
]
|
|
},
|
|
"scripts": {
|
|
"dev": "vite",
|
|
"build": "vue-tsc --noEmit && vite build",
|
|
"serve": "vite preview",
|
|
"test": "vitest run",
|
|
"lint": "eslint",
|
|
"fix": "eslint --fix",
|
|
"lint:prettier": "prettier --write \"**/*.{js,cjs,ts,json,tsx,vue,html,md}\"",
|
|
"lint:stylelint": "stylelint \"**/*.{css,scss,vue}\" --fix",
|
|
"clean:dev": "tsx scripts/clean-dev.ts"
|
|
},
|
|
"dependencies": {
|
|
"@element-plus/icons-vue": "^2.3.2",
|
|
"@iconify/vue": "^5.0.0",
|
|
"@tailwindcss/vite": "^4.1.14",
|
|
"@vue/reactivity": "^3.5.21",
|
|
"@vueuse/core": "^13.9.0",
|
|
"axios": "^1.12.2",
|
|
"crypto-js": "^4.2.0",
|
|
"echarts": "^6.0.0",
|
|
"element-plus": "^2.11.2",
|
|
"mitt": "^3.0.1",
|
|
"nprogress": "^0.2.0",
|
|
"ohash": "^2.0.11",
|
|
"pinia": "^3.0.3",
|
|
"pinia-plugin-persistedstate": "^4.3.0",
|
|
"tailwindcss": "^4.1.14",
|
|
"vue": "^3.5.21",
|
|
"vue-draggable-plus": "^0.6.0",
|
|
"vue-i18n": "^9.14.0",
|
|
"vue-router": "^4.5.1"
|
|
},
|
|
"devDependencies": {
|
|
"@eslint/js": "^9.9.1",
|
|
"@types/node": "^24.0.5",
|
|
"@typescript-eslint/eslint-plugin": "^8.3.0",
|
|
"@typescript-eslint/parser": "^8.3.0",
|
|
"@vitejs/plugin-vue": "^6.0.1",
|
|
"@vue/compiler-sfc": "^3.0.5",
|
|
"eslint": "^9.9.1",
|
|
"eslint-config-prettier": "^9.1.0",
|
|
"eslint-plugin-prettier": "^5.2.1",
|
|
"eslint-plugin-vue": "^9.27.0",
|
|
"globals": "^15.9.0",
|
|
"happy-dom": "^21.0.1",
|
|
"prettier": "^3.5.3",
|
|
"rollup-plugin-visualizer": "^5.12.0",
|
|
"sass": "^1.81.0",
|
|
"stylelint": "^16.20.0",
|
|
"stylelint-config-html": "^1.1.0",
|
|
"stylelint-config-recess-order": "^4.6.0",
|
|
"stylelint-config-recommended-scss": "^14.1.0",
|
|
"stylelint-config-recommended-vue": "^1.5.0",
|
|
"stylelint-config-standard": "^36.0.1",
|
|
"terser": "^5.36.0",
|
|
"tsx": "^4.20.3",
|
|
"typescript": "~5.6.3",
|
|
"typescript-eslint": "^8.9.0",
|
|
"unplugin-auto-import": "^20.2.0",
|
|
"unplugin-element-plus": "^0.10.0",
|
|
"unplugin-vue-components": "^29.1.0",
|
|
"vite": "^7.1.5",
|
|
"vite-plugin-compression": "^0.5.1",
|
|
"vite-plugin-vue-devtools": "^7.7.6",
|
|
"vitest": "^3.2.4",
|
|
"vue-tsc": "~2.1.6"
|
|
}
|
|
}
|