feat: 完善生产级 Rust Web 模板

This commit is contained in:
2026-07-21 16:00:03 +08:00
parent fb30d5da1a
commit ce89569bf3
58 changed files with 2042 additions and 349 deletions
+14
View File
@@ -183,3 +183,17 @@ curl http://localhost:3000/health
---
**提示**:建议使用 Postman、Insomnia 或类似工具测试 API 接口。
# 新增通用接口
所有受保护接口使用 `Authorization: Bearer <access_token>`。Refresh Token 不能访问受保护接口。
| 方法 | 路径 | 认证 | 条件 |
|---|---|---|---|
| POST | `/auth/logout` | 是 | Redis 可用 |
| POST | `/auth/request-verification-code` | 否 | 邮件启用且 Redis 可用 |
| POST | `/auth/reset-password` | 否 | 邮件启用且 Redis 可用 |
| GET/PUT/DELETE | `/api/user/profile` | 是 | 始终注册 |
| GET | `/api/email/latest-log` | 是 | 邮件启用 |
| GET | `/api/email/queue-status` | 是 | 邮件启用 |
请求可通过 `Accept-Language: zh-CN``Accept-Language: en` 选择认证错误语言。
+20
View File
@@ -533,3 +533,23 @@ volumes:
---
**提示**:使用 `.env.example` 作为模板,不要提交包含敏感信息的 `.env` 文件到版本控制。
# 可选基础设施与 Web 防护
Redis 和邮件能力默认关闭。常用环境变量:
```text
REDIS_ENABLED=false
EMAIL_ENABLED=false
EMAIL_SMTP_HOST=smtp.example.com
EMAIL_SMTP_PORT=587
EMAIL_SMTP_USERNAME=
EMAIL_SMTP_PASSWORD=
EMAIL_FROM_EMAIL=noreply@example.com
SERVER_REQUEST_TIMEOUT_SECONDS=30
SERVER_MAX_BODY_BYTES=1048576
SERVER_CONCURRENCY_LIMIT=256
SERVER_RATE_LIMIT_PER_MINUTE=120
SERVER_CORS_ORIGINS=["https://app.example.com"]
```
生产环境必须设置非默认 JWT 密钥,且 `cors_origins` 不允许包含 `*`
+12
View File
@@ -14,6 +14,18 @@ CREATE TABLE IF NOT EXISTS users (
password_hash VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL COMMENT '创建时间',
updated_at DATETIME NOT NULL COMMENT '更新时间'
,deleted_at DATETIME NULL COMMENT '软删除时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS user_profiles (
user_id VARCHAR(10) PRIMARY KEY,
display_name VARCHAR(80), avatar_url VARCHAR(2048), bio VARCHAR(500),
created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS email_logs (
id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id VARCHAR(10), recipient VARCHAR(255) NOT NULL,
kind VARCHAR(32) NOT NULL, status VARCHAR(32) NOT NULL, error TEXT, created_at DATETIME NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ============================================
+5
View File
@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS users (id VARCHAR(10) PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, deleted_at DATETIME NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE INDEX idx_users_email ON users(email);
CREATE TABLE IF NOT EXISTS user_profiles (user_id VARCHAR(10) PRIMARY KEY, display_name VARCHAR(80), avatar_url VARCHAR(2048), bio VARCHAR(500), created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS email_logs (id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id VARCHAR(10), recipient VARCHAR(255) NOT NULL, kind VARCHAR(32) NOT NULL, status VARCHAR(32) NOT NULL, error TEXT, created_at DATETIME NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE INDEX idx_email_logs_user_created ON email_logs(user_id, created_at DESC);
+5
View File
@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS users (id VARCHAR(10) PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, deleted_at TIMESTAMP NULL);
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
CREATE TABLE IF NOT EXISTS user_profiles (user_id VARCHAR(10) PRIMARY KEY, display_name VARCHAR(80), avatar_url VARCHAR(2048), bio VARCHAR(500), created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL);
CREATE TABLE IF NOT EXISTS email_logs (id BIGSERIAL PRIMARY KEY, user_id VARCHAR(10), recipient VARCHAR(255) NOT NULL, kind VARCHAR(32) NOT NULL, status VARCHAR(32) NOT NULL, error TEXT, created_at TIMESTAMP NOT NULL);
CREATE INDEX IF NOT EXISTS idx_email_logs_user_created ON email_logs(user_id, created_at DESC);
+5
View File
@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS users (id TEXT PRIMARY KEY, email TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, deleted_at DATETIME NULL);
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
CREATE TABLE IF NOT EXISTS user_profiles (user_id TEXT PRIMARY KEY, display_name TEXT, avatar_url TEXT, bio TEXT, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL);
CREATE TABLE IF NOT EXISTS email_logs (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT, recipient TEXT NOT NULL, kind TEXT NOT NULL, status TEXT NOT NULL, error TEXT, created_at DATETIME NOT NULL);
CREATE INDEX IF NOT EXISTS idx_email_logs_user_created ON email_logs(user_id, created_at DESC);