Files
asset_helper/backend/CLAUDE.md

11 KiB
Raw Permalink Blame History

Backend — Claude Code 项目指南

本文件为 Claude Code及其它 AI Agent提供后端项目的背景、结构说明和开发规范。

项目概述

这是一个基于 Rust 的微服务后端项目,采用 Axum + Tokio 技术栈,使用 Nginx 作为 API 网关,PostgreSQL 作为数据库,Redis 作为缓存。服务以 Docker 容器形式部署,按 DDD 限界上下文Bounded Context 划分服务边界——一个领域对外是一个微服务,内部由 Rust 模块组织。

技术栈

层级 技术
语言 Rust 2024 Edition
Web 框架 axum 0.8, tokio 1.x, tower 0.5
数据库 PostgreSQL 18.3 (sqlx 0.8)
缓存 Redis 8.6.2 (redis 0.29)
网关 Nginx 1.25 (Alpine)
部署 Docker, Docker Compose
其他 bcrypt, jsonwebtoken, uuid v7, chrono, tracing, validator

项目结构

backend/
├── services/                  # 微服务目录
│   └── user-service/          # 用户服务DDD 用户限界上下文,单一服务对外)
│       ├── Cargo.toml         # 单 crate
│       ├── Dockerfile         # 单镜像
│       ├── migrations/        # 数据库初始化 SQL
│       │   └── 001_init.sql
│       └── src/
│           ├── main.rs        # 装配 Router、连接池、AppState
│           ├── state.rs       # AppState { db, jwt_secret }
│           ├── api.rs         # 通用 ApiRequest<T> / ApiResponse<T>
│           ├── jwt.rs         # JWT Claims + generate_token
│           ├── auth/          # 认证模块
│           │   ├── mod.rs
│           │   ├── login_account.rs
│           │   └── login_email.rs
│           └── register/      # 注册模块
│               ├── mod.rs
│               ├── account.rs
│               └── email.rs
├── gateway/                   # API 网关
│   ├── Dockerfile
│   └── nginx/
│       ├── nginx.conf
│       ├── conf.d/default.conf
│       └── conf.d/services/   # 各服务路由配置
├── shared/                    # 共享代码库(当前为空,待扩展)
├── deploy/
│   └── local/redis.conf       # 本地 Redis 配置
├── scripts/
│   ├── gateway.sh             # 网关管理脚本(测试/重载/日志/证书)
│   └── init-multiple-databases.sh  # Postgres 多库初始化
└── README.md

编排已统一上移到项目根目录的 docker-compose.yml / docker-compose.dev.yml,本目录不再存放 compose 文件。

微服务架构说明

服务拆分原则

DDD 限界上下文Bounded Context 划分:每个独立的业务域对外暴露为单一微服务,内部细分通过 Rust 模块和 axum Router 组合实现,不再按操作粒度(登录/注册)拆 crate

user-service(用户域,单一服务)对外提供:

方法 网关路径 下游路径 用途
POST /api/v1/auth/login/account /auth/login/account 账号密码登录,签发 JWT
POST /api/v1/auth/login/email /auth/login/email 邮箱密码登录,签发 JWT
POST /api/v1/users/register/account /users/register/account 账号注册(写 user_main / user_login_account / user_login_password
POST /api/v1/users/register/email /users/register/email 邮箱注册(写 user_main / user_login_email / user_login_password
GET /health /health 健康检查

网关 nginx 通过 rewrite ^/api/v1(/.*)$ $1 break; 统一去除 /api/v1 前缀。

服务内部模块化布局见 项目结构auth/ 子模块负责登录认证,register/ 子模块负责账号注册,共享 state.rs / api.rs / jwt.rs

数据库模型

核心表结构(见 services/user-service/migrations/001_init.sql

  • user_main(id UUID PK, deleted BOOLEAN, create_date, modify_date)
  • user_login_account(id UUID PK, user_id FK, account VARCHAR)
  • user_login_email(id UUID PK, user_id FK, email VARCHAR)
  • user_login_password(id UUID PK, user_id FK, password VARCHAR)

采用软删除设计(deleted 字段),账号/邮箱通过部分索引保证唯一性:

CREATE UNIQUE INDEX ... ON user_login_account(account) WHERE deleted = FALSE;

开发规范

1. API 公共约定

项目中存在两类接口风格,新增服务时请遵循对应场景的约定:

注册/业务类接口(使用统一包装)

请求包装格式:

{
  "device": 1,
  "language": 1,
  "data": {
    // 业务字段
  }
}
  • device: 设备类型标识(i32
    • 1 = iOS
    • 2 = Android
    • 3 = Web
    • 4 = iPad
    • 5 = macOS
    • 6 = Windows
    • 7 = Linux
  • language: 语言标识(i32
    • 1 = 简体中文
    • 2 = 繁体中文
    • 3 = 英文
  • data: 实际业务请求体

响应包装格式:

{
  "success": true,
  "message": "User registered successfully",
  "data": {
    // 业务返回数据,失败时为 null
  }
}
  • success: 布尔值,表示业务是否成功
  • message: 可读的状态描述或错误信息
  • data: 业务数据,Option<T>,失败时返回 null

登录/认证类接口(扁平响应)

请求格式: 直接携带凭证字段(如 username/email + password)。

响应格式:

{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "message": "Login successful"
}
  • success: 布尔值
  • token: JWT Token认证失败或错误时为 null
  • message: 状态描述

健康检查

所有服务必须暴露 GET /health,成功时返回 HTTP 200

OK

错误响应HTTP 非 200

网关层返回统一 JSON 错误:

{
  "error": "Not Found",
  "message": "The requested resource was not found",
  "code": 404
}

2. 代码风格

  • 使用 Rust 2024 Edition
  • 注释使用中文
  • 服务状态通过 Arc<AppState> 注入到 Axum Handler 中。
  • 注册类接口统一使用包装请求/响应格式:
    struct ApiRequest<T> { device: i32, language: i32, data: T }
    struct ApiResponse<T> { success: bool, message: String, data: Option<T> }
    

3. 时间字段约定

所有表中的 create_datemodify_date 必须由业务层生成并传入数据库Schema中不设置 DEFAULT CURRENT_TIMESTAMP,也不使用触发器自动更新。

  • 建表时:
    create_date TIMESTAMP WITH TIME ZONE NOT NULL,
    modify_date TIMESTAMP WITH TIME ZONE NOT NULL
    
  • Rust 代码中使用 chrono::Utc::now() 生成时间戳,统一在事务开始前创建 let now = Utc::now();,确保同一笔业务中各表时间一致。
  • modify_date 更新时同样需要在业务代码中显式传入 Utc::now()

时区策略

项目采用数据库存 UTC、查询按东八区显示的策略:

  • 业务层始终使用 chrono::Utc::now() 生成 UTC 时间写入数据库。
  • 每个服务在建立数据库连接池后,执行 SET TIME ZONE 'Asia/Shanghai';,确保 TIMESTAMP WITH TIME ZONE 字段在查询时以东八区格式返回。
  • 如需在 Rust 代码中做东八区展示转换,使用 chrono::FixedOffset::east_opt(8 * 3600) 处理。

4. 环境变量

所有服务通过环境变量读取配置:

  • DATABASE_URL — PostgreSQL 连接串(必需)
  • REDIS_URL — Redis 连接串
  • SERVICE_PORT — 服务监听端口(默认 8080
  • JWT_SECRET — JWT 签名密钥
  • RUST_LOG — 日志级别

5. Docker 构建

  • 各微服务 Dockerfile 的构建上下文为 backend/ 目录(根目录 docker-compose.yml 中使用 context: ./backend)。
  • 构建采用多阶段builder + runtime基于 rust:1.94.1-alpine3.23 编译,最终运行在 alpine:3.23
  • 共享代码更新时,需确保 shared/ 目录在 Dockerfile 中被正确复制。

6. 网关与路由

  • Nginx 监听 80/443开发环境使用自签名证书。
  • 路由前缀约定:
    • /api/v1/users → 用户服务通用接口
    • /api/v1/auth → 认证接口(更严格限流)
  • 新增服务时,需在 gateway/nginx/conf.d/services/ 下创建对应 .conf 文件,并在 nginx.conf 中添加上游 upstream

常用命令

启动整套后端(含网关 + 数据库 + 缓存)

后端不再单独编排,由项目根目录的 docker compose 一并启动。详见 根目录 CLAUDE.md

# 在项目根目录
docker compose -f docker-compose.dev.yml up -d --build   # 测试
docker compose up -d --build                              # 正式

如需仅启动后端栈(不含前端)做联调:

docker compose -f docker-compose.dev.yml up -d --build \
  user-db user-redis user-service gateway

网关管理

# 测试配置
./scripts/gateway.sh test

# 生成开发证书
./scripts/gateway.sh certs

# 查看状态
./scripts/gateway.sh status

# 热重载(容器运行中)
./scripts/gateway.sh reload

本地编译运行 user-service

cd services/user-service
cargo run

扩展指南

在已有领域内新增功能(推荐)

属于同一限界上下文(如新增"用户资料修改"接口)时,不要新建 crate 或服务,而是在现有 user-service 下新增模块:

  1. services/user-service/src/ 下新增模块文件,或扩展现有 auth/ / register/ 子模块。
  2. 在子模块的 mod.rs 中通过 Router::new().route(...) 注册新路由。
  3. gateway/nginx/conf.d/services/user-service.conf 中追加对应 location 块(路径仍以 /api/v1/... 起始)。
  4. 如需新数据库表或字段,在 services/user-service/migrations/ 下追加 SQL 文件。

新增服务域(新限界上下文)

当业务边界明显独立(如订单 order-service、支付 payment-service)时再新建独立服务:

  1. services/<service-domain>/ 下创建独立 crate参考 services/user-service/ 的目录布局:单 Cargo.toml + 单 Dockerfile + 模块化的 src/)。
  2. gateway/nginx/conf.d/services/ 添加路由配置文件。
  3. gateway/nginx/nginx.conf 添加对应 upstream
  4. 在根目录 docker-compose.yml / docker-compose.dev.yml 中追加服务定义。
  5. PORT_ALLOCATION.md 申请新的百位段端口并更新分配表。

共享代码提取

当前 shared/ 目录为空。当多个服务域需要共用模型、中间件或工具函数时:

  1. shared/ 下创建子模块(如 shared/modelsshared/middleware)。
  2. 将共享 crate 以 path dependency 引入各微服务:
    [dependencies]
    shared = { path = "../../shared" }
    
  3. 更新各 Dockerfile确保 COPY shared /app/shared 在依赖缓存步骤之前执行。

注意事项

  • 当前 shared/ 为空Agent 在修改代码时若发现跨服务域重复逻辑,可提议提取到 shared/;同一服务内部的重复逻辑直接抽到模块即可,无需走 shared/
  • 网关配置文件中的 api.example.com 为占位域名,本地开发需配置 hosts 或使用 localhost