280 lines
4.5 KiB
Markdown
280 lines
4.5 KiB
Markdown
# 03 技术架构
|
||
|
||
## 1. 总体选择
|
||
|
||
优先采用“TypeScript 全栈 + 模块化单体 + MySQL + Redis + 对象存储 + Docker”。
|
||
|
||
推荐:
|
||
|
||
### 微信小程序
|
||
|
||
- 微信小程序原生框架
|
||
- TypeScript
|
||
- TDesign Miniprogram(优先复用成熟组件)
|
||
- 自建 API Client
|
||
- 不使用重量级跨端框架作为 V1 默认方案
|
||
|
||
### 管理后台
|
||
|
||
- Vue 3
|
||
- TypeScript
|
||
- Vite
|
||
- Pinia
|
||
- Vue Router
|
||
- TDesign Vue Next 或成熟国内 UI 组件库
|
||
- ECharts(仅统计图表需要时)
|
||
|
||
### API
|
||
|
||
- Node.js LTS
|
||
- NestJS
|
||
- TypeScript
|
||
- REST API
|
||
- Prisma 或 TypeORM 二选一;建议 Prisma,但一旦项目启动后不得混用
|
||
- OpenAPI/Swagger
|
||
- Zod/class-validator 统一选一种 DTO 校验体系,NestJS 默认可使用 class-validator
|
||
|
||
### 数据
|
||
|
||
- MySQL 8.x
|
||
- Redis 7.x
|
||
- 对象存储:腾讯云 COS 为生产默认实现
|
||
- 本地开发:MinIO 兼容 S3 API
|
||
|
||
### 部署
|
||
|
||
- Docker
|
||
- Docker Compose
|
||
- Nginx
|
||
- 腾讯云 CVM / 轻量云服务器可作为早期部署载体
|
||
- 数据库生产优先托管 MySQL;预算有限时也可独立数据库容器,但必须有可靠备份
|
||
- HTTPS
|
||
- 国内域名和备案按实际上线要求办理
|
||
|
||
---
|
||
|
||
## 2. 为什么不做微服务
|
||
|
||
当前机构规模和 V1 业务复杂度不需要微服务。
|
||
|
||
模块化单体优点:
|
||
|
||
- 部署简单;
|
||
- 成本低;
|
||
- 调试简单;
|
||
- 事务一致性容易保证;
|
||
- Codex 更容易保持全局一致;
|
||
- 后续真有规模需求时可按模块拆分。
|
||
|
||
模块边界仍必须清晰。
|
||
|
||
---
|
||
|
||
## 3. API 模块建议
|
||
|
||
```text
|
||
auth
|
||
users
|
||
profiles
|
||
beneficiaries
|
||
service-applications
|
||
service-cases
|
||
service-records
|
||
follow-ups
|
||
projects
|
||
activities
|
||
volunteers
|
||
content
|
||
files
|
||
notifications
|
||
statistics
|
||
audit
|
||
permissions
|
||
system
|
||
```
|
||
|
||
每模块:
|
||
|
||
- controller
|
||
- service
|
||
- repository
|
||
- dto
|
||
- entities/model
|
||
- policy/permission
|
||
- tests
|
||
|
||
---
|
||
|
||
## 4. 分层规则
|
||
|
||
```text
|
||
Controller
|
||
↓
|
||
Application Service
|
||
↓
|
||
Domain Rules / Policy
|
||
↓
|
||
Repository / Adapter
|
||
↓
|
||
Database / External Service
|
||
```
|
||
|
||
禁止:
|
||
|
||
- Controller 直接访问 ORM;
|
||
- 页面直接写 SQL;
|
||
- 业务层直接调用 COS/微信 SDK;
|
||
- 前端自己判断权限代替后端校验。
|
||
|
||
---
|
||
|
||
## 5. 外部 Adapter
|
||
|
||
必须封装:
|
||
|
||
- WeChatAuthAdapter
|
||
- WeChatSubscribeMessageAdapter
|
||
- ObjectStorageAdapter
|
||
- SmsAdapter(若以后使用)
|
||
- AIAdapter(二期)
|
||
- GeocodingAdapter(二期)
|
||
|
||
这样可更换供应商。
|
||
|
||
---
|
||
|
||
## 6. API 规范
|
||
|
||
统一前缀:
|
||
|
||
`/api/v1`
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {},
|
||
"requestId": "..."
|
||
}
|
||
```
|
||
|
||
错误:
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": {
|
||
"code": "APPLICATION_NOT_FOUND",
|
||
"message": "未找到该服务申请"
|
||
},
|
||
"requestId": "..."
|
||
}
|
||
```
|
||
|
||
HTTP 状态码必须正确使用,不得永远 200。
|
||
|
||
---
|
||
|
||
## 7. 认证
|
||
|
||
### 小程序端
|
||
|
||
- wx.login 获取 code;
|
||
- 后端换取微信身份;
|
||
- 服务端创建自己的 session/token;
|
||
- token 轮换/过期;
|
||
- 手机号绑定按微信开放能力和实际授权流程实现;
|
||
- openid/unionid 绝不作为前端授权依据。
|
||
|
||
### 后台
|
||
|
||
推荐:
|
||
|
||
- 用户名/手机号 + 强密码;
|
||
- 生产可增加 MFA;
|
||
- HttpOnly Secure Cookie 优先;
|
||
- 管理后台不把长期 Token 放 localStorage。
|
||
|
||
---
|
||
|
||
## 8. 权限
|
||
|
||
RBAC + 资源级 Policy。
|
||
|
||
示例:
|
||
|
||
- STAFF 可以看自己负责的工单;
|
||
- PROJECT_MANAGER 可以看自己项目范围;
|
||
- ADMIN 可跨项目;
|
||
- VOLUNTEER 只能查看分配给自己的最小必要任务信息;
|
||
- 普通小程序用户只能查看自己提交或合法关联的申请。
|
||
|
||
---
|
||
|
||
## 9. 状态机
|
||
|
||
服务申请、工单、活动、志愿者审批必须采用明确状态机。
|
||
|
||
所有 transition:
|
||
|
||
- 验证当前状态;
|
||
- 验证目标状态;
|
||
- 验证权限;
|
||
- 事务写入;
|
||
- 写 history;
|
||
- 写 audit;
|
||
- 事务提交后再触发通知。
|
||
|
||
---
|
||
|
||
## 10. 幂等
|
||
|
||
以下必须防重复:
|
||
|
||
- 服务申请提交
|
||
- 活动报名
|
||
- 状态变更
|
||
- 服务记录提交
|
||
- 回访提交
|
||
- 文件关联
|
||
- 微信回调(若未来有)
|
||
|
||
方案:
|
||
|
||
- clientRequestId / idempotencyKey
|
||
- 数据库唯一索引
|
||
- 事务
|
||
- 必要时 Redis 短锁
|
||
|
||
---
|
||
|
||
## 11. 可观测性
|
||
|
||
必须:
|
||
|
||
- requestId
|
||
- structured logging
|
||
- error tracking
|
||
- health endpoint
|
||
- readiness/liveness
|
||
- 慢接口日志
|
||
- 数据库慢查询
|
||
- 关键任务状态
|
||
|
||
日志中禁止敏感数据。
|
||
|
||
---
|
||
|
||
## 12. 备份
|
||
|
||
至少:
|
||
|
||
- MySQL 每日自动备份;
|
||
- 保留 7/30 天策略可配置;
|
||
- 对象存储版本/生命周期按预算配置;
|
||
- 每季度至少做一次恢复演练;
|
||
- 恢复步骤写入 `infra/backup/README.md`。
|
||
|
||
备份成功≠可恢复,必须验证恢复。
|