refactor(saas): 架构重构 + 性能优化 — 借鉴 loco-rs 模式

Phase 0: 知识库
- docs/knowledge-base/loco-rs-patterns.md — loco-rs 10 个可借鉴模式研究

Phase 1: 数据层重构
- crates/zclaw-saas/src/models/ — 15 个 FromRow 类型化模型
- Login 3 次查询合并为 1 次 AccountLoginRow 查询
- 所有 service 文件从元组解构迁移到 FromRow 结构体

Phase 2: Worker + Scheduler 系统
- crates/zclaw-saas/src/workers/ — Worker trait + 5 个具体实现
- crates/zclaw-saas/src/scheduler.rs — TOML 声明式调度器
- crates/zclaw-saas/src/tasks/ — CLI 任务系统

Phase 3: 性能修复
- Relay N+1 查询 → 精准 SQL (relay/handlers.rs)
- Config RwLock → AtomicU32 无锁 rate limit (state.rs, middleware.rs)
- SSE std::sync::Mutex → tokio::sync::Mutex (relay/service.rs)
- /auth/refresh 阻塞清理 → Scheduler 定期执行

Phase 4: 多环境配置
- config/saas-{development,production,test}.toml
- ZCLAW_ENV 环境选择 + ZCLAW_SAAS_CONFIG 精确覆盖
- scheduler 配置集成到 TOML
This commit is contained in:
iven
2026-03-29 19:21:48 +08:00
parent 5fdf96c3f5
commit 8b9d506893
64 changed files with 3348 additions and 520 deletions

View File

@@ -0,0 +1,75 @@
//! Account 表相关模型
use sqlx::FromRow;
/// accounts 表完整行 (含 last_login_at)
#[derive(Debug, FromRow)]
pub struct AccountRow {
pub id: String,
pub username: String,
pub email: String,
pub display_name: String,
pub role: String,
pub status: String,
pub totp_enabled: bool,
pub last_login_at: Option<String>,
pub created_at: String,
}
/// accounts 表行 (不含 last_login_at用于 auth/me 等场景)
#[derive(Debug, FromRow)]
pub struct AccountAuthRow {
pub id: String,
pub username: String,
pub email: String,
pub display_name: String,
pub role: String,
pub status: String,
pub totp_enabled: bool,
pub created_at: String,
}
/// Login 一次性查询行(合并用户信息 + password_hash + totp_secret
#[derive(Debug, FromRow)]
pub struct AccountLoginRow {
pub id: String,
pub username: String,
pub email: String,
pub display_name: String,
pub role: String,
pub status: String,
pub totp_enabled: bool,
pub password_hash: String,
pub totp_secret: Option<String>,
pub created_at: String,
}
/// operation_logs 表行
#[derive(Debug, FromRow)]
pub struct OperationLogRow {
pub id: i64,
pub account_id: Option<String>,
pub action: String,
pub target_type: Option<String>,
pub target_id: Option<String>,
pub details: Option<String>,
pub ip_address: Option<String>,
pub created_at: String,
}
/// Dashboard 统计聚合行
#[derive(Debug, FromRow)]
pub struct DashboardStatsRow {
pub total_accounts: i64,
pub active_accounts: i64,
pub active_providers: i64,
pub active_models: i64,
}
/// Dashboard 今日统计聚合行
#[derive(Debug, FromRow)]
pub struct DashboardTodayRow {
pub tasks_today: i64,
pub tokens_input: i64,
pub tokens_output: i64,
}