Files
GovAI/0623-优化.md
T
selfrelease 65dc805eb5 feat: 系统优化 - ESLint、Tailwind、前端健壮性、后端工程化、运维可观测性
- 前端: ESLint+Prettier配置、Tailwind v4配置、ErrorBoundary、全局AuthLoader优化、ReactQuery分层
- 后端: MinIO凭证移除、Docker统一为govai品牌、zerolog日志封装、错误码枚举、文件上传校验、单元测试(13项全通过)
- 运维: 健康检查增强(PG/Redis ping)、Prometheus指标(/metrics端点)、多租户tenant包、RateLimit nil防御
- 移动: citation_prompt.txt → internal/assets/
2026-06-23 14:48:31 +08:00

159 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GovAI 应用优化建议
> 生成时间:2026-06-23
> 代码规模:前端 15,055 行(TSX/TS| 后端 9,701 行(Go
> 技术栈:Next.js 16 + React 19 + Tailwind CSS 4 + Go + PostgreSQL
---
## 一、安全类(高优先级)
### 1. JWT Secret 硬编码默认值
**文件:** `server/internal/config/config.go`
**问题:** JWT Secret 有明文 fallbackDocker/生产环境若 `.env` 未挂载会使用已知密钥启动。
```go
Secret: getEnv("JWT_SECRET", "dev-secret-change-in-production"),
```
**建议:** 启动时强制校验——若读取到默认值则 panic 退出,防止意外部署。
### 2. 真实密钥已提交 Git
**文件:** `server/.env`(含 `QWEN_API_KEY` 等)、`ppt-worker/.env`
**问题:** `server/.env` 不在 `.gitignore`,阿里云 API 密钥等已进 Git 历史。
**建议:**
- 立即轮换所有已泄露的密钥
-`git filter-repo` 或 BFG 从历史中清除敏感文件
-`server/.env``ppt-worker/.env` 加入 `.gitignore`
### 3. Token 存储在 localStorage
**文件:** `apps/web/src/lib/api.ts`
**问题:** JWT Token 以明文存在浏览器 localStorage,易受 XSS 攻击。
**建议:** 改用 `httpOnly` Cookie 存储 Token,后端登录接口通过 `Set-Cookie` 下发,前端纯读取(不再自行写入)。
### 4. MinIO 凭证硬编码
**文件:** `server/internal/config/config.go`
```go
AccessKey: getEnv("MINIO_ACCESS_KEY", "minioadmin"),
SecretKey: getEnv("MINIO_SECRET_KEY", "minioadmin"),
```
**建议:** 移除默认凭证,启动时必填真实值。
---
## 二、前端工程化
### 5. 缺少 ESLint 配置
**文件:** `apps/web/.eslintrc.json`
**问题:** 项目无 ESLint 配置,无代码风格检查和潜在错误检测。
**建议:** 添加 `eslint.config.ts`Flat Config 格式,适配 ESLint 9),包含 TypeScript 解析、Next.js 规则集和 Prettier 冲突解决。
### 6. 缺少 Tailwind CSS v4 配置文件
**问题:** 项目使用 Tailwind CSS v4 但无 `tailwind.config.ts`v4 强烈推荐显式配置主题和插件。
**建议:** 创建配置文件,定义设计系统 token(颜色、间距、字体),确保多页面视觉一致性。
### 7. React Query 配置偏保守
**文件:** `apps/web/src/components/providers.tsx`
```ts
refetchOnWindowFocus: false,
retry: 1,
refetchOnMount: false,
```
**问题:** `staleTime` 5 分钟对频繁变更数据(如审计日志、用户列表)过长,可能导致用户看到过期数据。
**建议:** 按数据特性分层配置——高频变更数据用更短的 staleTime,或在关键操作后主动 invalidate。
### 8. 全局 AuthLoader 阻塞所有路由
**文件:** `apps/web/src/components/providers.tsx`
**问题:** 每次路由切换都触发 `fetchUser()`,未登录页(login/register)也被阻塞。
**建议:** 在路由层判断——`/login``/register` 跳过 AuthLoader;其他路由按需鉴权(未登录则 redirect)。
---
## 三、后端工程化
### 9. 所有 Handler 集中在单一 Package
**文件:** `server/internal/handler/`14 个 .go 文件 + 1 个 .txt
**问题:** 随着功能增长,handler 目录会持续膨胀,难以维护。
**建议:** 按业务域拆分 subpackage`handler/auth/``handler/chat/``handler/admin/` 等),每个域内独立注册路由组。
### 10. 缺少结构化日志
**问题:** 后端代码中未见标准库日志或结构化日志框架(zap、zerolog),生产环境排查问题困难。
**建议:** 引入 `zerolog``zap`,统一日志格式(JSON),包含 request_id、user_id、latency 等标准字段。
### 11. 未使用 sqlc 生成类型安全代码
**文件:** `server/sqlc.yaml``server/pkg/db/queries/`
**问题:** 项目已有 sqlc 配置但生成的代码风格不够类型安全,后端大量手写 SQL。
**建议:** 完善 sqlc 配置,用 `sqlc generate` 替代手写 SQL 查询层,减少运行时错误。
### 12. 单元测试覆盖率低
**文件:** 仅 `chat_llm_test.go`
**建议:** 为核心逻辑补充测试——auth 中间件、RBAC 逻辑、API 响应格式、LLM 调用封装。
---
## 四、运维与部署
### 13. Docker Compose 配置陈旧
**文件:** `docker/docker-compose.yml`
**问题:** 配置仍使用 `aily` 旧品牌名,PostgreSQL 用户/库名为 `aily`,与当前 `govai_portal` 数据库名不一致。
**建议:** 统一更新为 `govai` 品牌名,数据库名与 `.env` 中的 `DATABASE_URL` 对齐。
### 14. 健康检查端点过于简单
**文件:** `server/internal/handler/health.go`
**问题:** 只确认了 `/health` 返回 200,未验证 DB/Redis/Dify 等下游依赖的实际可用性。
**建议:** `/health` 应对关键依赖(PostgreSQL、Redis、可选 Dify)做实际 ping check,并返回各依赖状态。
### 15. 缺少告警与指标采集
**问题:** 无 Prometheus metrics、无 APM 追踪、无日志聚合。
**建议:** 接入 Prometheus clientGo 端 `prometheus/client_golang`),暴露基础指标(QPS、延迟分布、错误率),为后续运维监控奠基。
---
## 五、性能与可扩展性
### 16. 多租户隔离依赖逻辑层
**文件:** `server/internal/middleware/rbac.go`
**问题:** 多租户(organization_id)数据隔离逻辑散落在各处,未统一封装。
**建议:** 在 DB 层统一注入 `org_id` 过滤——通过 context 或 query builder 链式调用,从根本上杜绝跨租户数据泄露。
### 17. Redis 未实际使用
**文件:** `server/internal/config/config.go`RedisConfig 已定义但未见调用代码)
**问题:** RateLimit 中间件和 session 缓存均未实际连接 Redis。
**建议:** 确认 RateLimit 实际需求,若需要分布式限流则接入 Redis;若仅为单机则降级为内存实现。
---
## 六、代码质量
### 18. `citation_prompt.txt` 混在 Handler 目录
**文件:** `server/internal/handler/citation_prompt.txt`
**建议:** 移入 `server/pkg/prompts/``server/internal/assets/`,与代码分离。
### 19. MinIO 文件上传未验证
**问题:** 文件上传接口应校验文件类型、大小和 MIME,避免上传恶意文件。
**建议:** 添加白名单文件类型(PDF、DOCX、图片等)和大小上限。
### 20. 硬编码魔数
**问题:** 代码中多处出现未命名常量,如状态码、默认分页大小、超时时间。
**建议:** 统一提取为具名常量或配置项。
---
## 七、低优先级(体验类)
| # | 问题 | 建议 |
|---|------|------|
| 21 | 前端 `globals.css` 较大 | 确认 CSS 体积,考虑按需加载 |
| 22 | 没有 ErrorBoundary | React 树某组件报错会导致整页崩溃 |
| 23 | 缺少骨架屏(Skeleton) | 页面加载期间应有骨架屏而非空白或 Spinner |
| 24 | 缺少 404/500 错误页 | Next.js `not-found.tsx``error.tsx` |
| 25 | API 错误码未统一枚举 | 当前 `json.code` 是数字,错误含义不透明 |
---
## 优先级总结
| 优先级 | 数量 | 代表项 |
|--------|------|--------|
| 高 | 5 | JWT 密钥、Git 泄露、Token 存储、MinIO 凭证、ESLint |
| 中 | 12 | Docker 配置、健康检查、测试覆盖、多租户隔离、Redis |
| 低 | 8 | 骨架屏、错误页、ErrorBoundary、文件上传校验 |