feat: 初始化微信小程序后端骨架

- NestJS + TypeScript + Prisma + PostgreSQL 工程骨架
- 微信登录安全流程:服务端 code2Session 换 openid 后签发 JWT,
  session_key 缓存于 Redis,不信任前端 openid
- 统一响应/异常处理、JWT 全局鉴权(@Public 豁免)、Swagger 文档
- Prisma 全量核心 schema(用户/分类/商品/设计清单/地址/订单/支付/上传/定制任务)+ seed
- 业务模块空壳(商品/分类/设计清单/地址/订单/支付/上传/BullMQ 队列)
- Docker 多阶段镜像 + 本地/生产 docker-compose
- docs:密钥获取指南、COS SDK 移除记录

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-05 17:33:50 +08:00
co-authored by Claude Fable 5
commit deaa0c9ce4
73 changed files with 9533 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
# wxmp-backend
微信小程序后端 API,基于 NestJS + Prisma + PostgreSQL + Redis + BullMQ + 腾讯云 COS。
## 技术栈
| 层 | 选型 |
|---|---|
| 运行时 | Node.js 22 + TypeScript |
| 框架 | NestJS 11 |
| ORM | Prisma 6 |
| 数据库 | PostgreSQL 16 |
| 缓存/队列 | Redis 7 + BullMQ |
| 对象存储 | 腾讯云 COS |
| 鉴权 | JWTpassport-jwt |
| 文档 | Swagger / OpenAPI`/docs` |
| 部署 | Docker + docker compose |
## 目录约定
```
src/
├── common/ # 公共:统一响应、全局守卫/过滤器/拦截器、装饰器、通用 DTO
├── config/ # 环境变量读取 + Joi 启动校验
├── prisma/ # PrismaService(全局单例)
├── redis/ # ioredis 实例(全局)
├── wechat/ # 微信 SDK 封装:code2Session(已实现)、支付(占位)
├── auth/ # 微信登录 + JWT 签发与校验(已完整实现)
├── users/ # 用户查/建、/users/me
├── products/ categories/ design-list/ addresses/ # 业务(空壳+路由+DTO,逻辑 TODO)
├── orders/ payments/ upload/ # 业务(同上)
├── queue/ # BullMQ 定制任务(占位处理器)
└── health/ # 健康检查
```
统一响应格式:`{ code, message, data }`(成功 `code:0`,失败为对应 HTTP 状态码)。
## 本地启动
1. 安装依赖
```bash
npm install
```
2. 复制环境变量并填写
```bash
cp .env.example .env
# 填入 WX_APPID / WX_SECRET / JWT_SECRET 等
```
3. 起 PostgreSQL + Redis(需 Docker
```bash
npm run db:up
```
4. 初始化数据库
```bash
npx prisma migrate dev --name init
npm run prisma:seed
```
5. 启动开发服务
```bash
npm run start:dev
```
6. 访问
- 健康检查:`http://localhost:3000/health`
- Swagger 文档:`http://localhost:3000/docs`
## 微信登录流程(安全要点)
> **核心原则**:服务端以微信 `code2Session` 返回的 `openid` 为准,绝不信任前端传入的 openid。
1. 小程序端 `wx.login()` 拿到临时 `code`。
2. `POST /api/auth/login`,请求体仅需 `{ code }`。
3. 服务端 `wechat.code2Session(code)` 用服务端持有的 `appid + secret` 请求微信 `sns/jscode2session`,换得 `openid` + `session_key`。
4. `users.findOrCreateByOpenid(openid)` 查/建用户。
5. `session_key` 存入 Redis`wx:session:{userId}`,TTL 7 天),供后续解密小程序 encryptedData / 手机号。
6. 用 `@nestjs/jwt` 签发 `{ sub: userId, openid }` 的 JWT 返回 `accessToken`。
7. 小程序将 `accessToken` 存 storage,后续请求带 `Authorization: Bearer <token>``JwtAuthGuard` 默认守护所有路由,`@Public()` 标记的路由(如 `/auth/login`、`/health`)免鉴权。
无真实 appid 时,可临时 mock `WechatService.code2Session` 返回固定 openid 走通链路。
## 常用脚本
| 命令 | 说明 |
|---|---|
| `npm run start:dev` | 开发热重载 |
| `npm run build` | 编译到 `dist/` |
| `npm run prisma:migrate:dev` | 生成并应用迁移(开发) |
| `npm run prisma:migrate` | 应用迁移(生产,deploy 模式) |
| `npm run prisma:seed` | 写入种子数据 |
| `npm run db:up` / `db:down` | 起/停本地 postgres + redis |
## 环境变量
见 `.env.example`。关键项(缺失即启动失败):
- `DATABASE_URL` — PostgreSQL 连接串
- `REDIS_URL` — Redis 连接串
- `JWT_SECRET` — JWT 签名密钥(≥16 位,生产用高熵随机串)
- `JWT_EXPIRES` — access token 有效期(秒)
- `WX_APPID` / `WX_SECRET` — 微信小程序凭证(服务端持有,不下发前端)
微信支付、COS 相关变量本轮可留空。
## 当前状态与后续迭代
已实现:工程骨架、Prisma 全量 schema、微信登录 + JWT、统一响应/异常、Swagger、Docker、健康检查。
待实现(已预留模块/路由/DTO,标 `TODO`):
- 商品/分类/设计清单/地址/订单/上传的**完整业务逻辑**(分页、权限、事务、金额重算等)
- 微信支付 V3(统一下单、回调验签、查单、退款)
- COS 直传凭证 / 预签名
- BullMQ 定制任务真实处理
- 管理后台(React + Ant Design,独立仓库)
- 单元 / e2e 测试