65dc805eb5
- 前端: 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/
159 lines
7.2 KiB
Markdown
159 lines
7.2 KiB
Markdown
# 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 有明文 fallback,Docker/生产环境若 `.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 client(Go 端 `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、文件上传校验 |
|