c199f031c5ac5ad2500c73bcfb7ddefd90d59f27
背景
- 这两个域把 SQL 与处理器放在同一文件,是全仓仅有的两个零接口测试的后端域。
直接拆会改动 SQL 与参数顺序,而硬约束要求不得变更统计口径 —— 因此按
"可注入化 -> 补契约测试 -> 再提取" 的顺序做。
改动
- ele:拆为 routes.ts(校验与组装)/ repository.ts(全部 SQL)/ model.ts(xlsx 解析、
取值清洗、筛选片段、插入值组装等纯逻辑),并改为 registerEleRoutes(app, deps) 可注入。
- feedback:拆为 routes.ts / repository.ts,同样可注入;建表与截图上传也作为依赖注入。
- 两域各补测试:ele 7 个接口契约 + 6 个模型用例,feedback 9 个接口契约。
mock pool 逐条断言 SQL 文本与参数顺序(含分页、状态白名单、批量插入的 30 列顺序)。
- 架构测试新增一条:已完整分层的三个域(vehicles / ele / feedback)必须有 repository.ts
且 routes.ts 不得出现 SQL。
等价性验证(关键)
- 把改造前的实现从 git 取出,与改造后的实现跑同一批请求(含真实 xlsx 解析路径),
对比每一步落库 SQL、参数、HTTP 状态与响应体:
feedback:6 个场景,SQL + 参数 + 状态完全一致(差异仅 DDL 已移交 db/schema 层)
ele :5 个场景,SQL + 参数 + 状态 + 响应体完全一致(仅随机 batchId/时间戳做掩码)
- 期间的修正:曾把 /mine 与 /list 的列集合统一,二者实际不同(管理列表多 user_id/user_name),
已按原样保留;测试同时锁定了这一差异。
lint / test(161) / build 全绿,可达性 0 未引用文件。
LN-BI
羚牛业务数据的统一 BI Web 应用。React 19 + Vite 前端,Hono 后端,单进程同时提供 API 与静态页面。
入口
| 入口 | 模块 | 路由 |
|---|---|---|
| 资产 BI | 资产管理、里程管理、车辆/加氢热力图、智能调度 | /asset |
| 能源 BI | 氢费 BI、电能、ETC | /energy |
| 隐藏页 | 充电记录导入(需能源角色) | /ele/import |
| 隐藏页 | 用户反馈管理 | /admin/feedback |
| 独立入口 | 氢能经营看板(与 /energy 内同一组件) |
/energy/hydrogen-board |
页面内部用 Hash 保存子页面状态,例如 /energy#hydrogen/overview。入口兼容逻辑见 src/app/routing.ts。
快速开始
需要 Node.js 22 与 npm。
npm ci
cp .env.local.example .env.local # 填入数据库等连接配置,切勿提交
npm run dev:local # 只读本地预览:前端 127.0.0.1:8115,API 127.0.0.1:3001
dev:local 会强制 DB_READ_ONLY=1、HYDROGEN_DB_READ_ONLY=1、MILEAGE_REPORT_AUTO_ARCHIVE=0、
DEV_BYPASS_AUTH=1,并且不启动建表与定时任务,适合看真实数据而不写库。不要把它暴露到公网。
常规开发(前端 3000,后端 3001,/api 由 Vite 代理):
npm run dev
命令
| 命令 | 说明 |
|---|---|
npm run dev |
前后端开发模式 |
npm run dev:local |
只读本地预览(免登录,禁写库) |
npm run lint |
类型检查(tsc --noEmit) |
npm test |
Node 内置测试运行器 |
npm run build |
生成 dist |
npm start |
生产式启动(需先 build,且必须提供环境变量) |
发布门禁是 lint + test + build 三者同时通过(CI 见 woodpecker.yml)。
目录
src/
├── app/ 应用外壳:路由解析、导航注册
├── auth/ 前端认证状态与注入
├── components/ 跨模块 UI(Shell、反馈、通用控件)
├── modules/ 前端业务域(每个域自带 api / model / components / css)
│ ├── assets/ 资产管理
│ ├── mileage/ 里程(monitoring / statistics / daily-report)
│ ├── scheduling/智能调度
│ ├── energy/ 能源(hydrogen / electric / etc)
│ ├── ele/ 电能数据导入
│ ├── admin/ 反馈后台
│ └── *-heatmap/ 两类热力图
├── shared/ 前后端共享的叶子层(角色常量、跨端 DTO、日期区间、Excel、高德接入)
└── server/
├── config.ts 环境变量集中读取 + 启动期校验
├── app.ts 应用装配(无副作用,便于测试)
├── index.ts 进程启动
├── local.ts 只读预览启动
├── db/ MySQL / PostgreSQL 连接
├── middleware/认证、只读
├── auth/ 登录(SSO 换票 / 固定密码)、权限
└── routes/ 按业务域的 HTTP 路由
架构约定
分层规则、依赖方向与「新增一个模块该放哪」见 docs/ARCHITECTURE.md。
其中 6 条硬规则由 src/architecture.test.ts 断言,违反即测试失败。
部署注意事项
JWT_SECRET必须在运行环境注入且不少于 32 字符;SSO 模式下缺失时服务会拒绝启动。 镜像内不再内置默认密钥(历史默认值等同于公开密钥,可被离线伪造令牌)。- 数据库口令、Harbor 凭据、OSS / OneOS / 高德密钥一律通过环境变量或 CI Secret 注入, 仓库内不保留真实值。历史提交中出现过的凭据都需要轮换。
- 生产环境请显式设置
NODE_ENV=production与DEV_BYPASS_AUTH=0;后者会绕过全部认证。
Languages
TypeScript
86.4%
CSS
13.5%