feat: Phase 5-6 - Proxy Conductor, Token Router, Services, Dockerfile

- Proxy Conductor: retry/fallback/auth-refresh orchestration loop
- Token Router: exact/wildcard/regex model routing with channel selection
- Services: Cron scheduler, OAuth token refresh, Update center, Announcements
- User routes: profile + API key management
- DB queries module
- Dockerfile: multi-stage build
- Proxy routes integrated with Conductor + TokenRouter
This commit is contained in:
boos
2026-05-18 03:00:09 +08:00
parent 78d46eeddb
commit 56391f2193
75 changed files with 7428 additions and 464 deletions
+1
View File
@@ -1,6 +1,7 @@
use sqlx::sqlite::{SqlitePool, SqlitePoolOptions};
pub mod models;
pub mod queries;
pub async fn create_pool(database_url: &str, max_connections: u32) -> anyhow::Result<SqlitePool> {
let pool = SqlitePoolOptions::new()
+2 -2
View File
@@ -1,13 +1,13 @@
// Database models
pub mod account;
pub mod background_task;
pub mod downstream_api_key;
pub mod event;
pub mod organization;
pub mod route_channel;
pub mod setting;
pub mod site;
pub mod site_announcement;
pub mod background_task;
pub mod organization;
pub mod token_route;
pub mod user;
+40 -1
View File
@@ -1 +1,40 @@
// Database queries
use crate::{
db::models::{downstream_api_key::DownstreamApiKey, user::User},
error::AppResult,
};
use sqlx::SqlitePool;
pub async fn find_user_by_id(db: &SqlitePool, id: i64) -> AppResult<Option<User>> {
sqlx::query_as("SELECT * FROM users WHERE id = ?")
.bind(id)
.fetch_optional(db)
.await
.map_err(Into::into)
}
pub async fn find_user_by_email(db: &SqlitePool, email: &str) -> AppResult<Option<User>> {
sqlx::query_as("SELECT * FROM users WHERE email = ?")
.bind(email)
.fetch_optional(db)
.await
.map_err(Into::into)
}
pub async fn list_user_api_keys(db: &SqlitePool, user_id: i64) -> AppResult<Vec<DownstreamApiKey>> {
sqlx::query_as("SELECT * FROM downstream_api_keys WHERE user_id = ? ORDER BY created_at DESC")
.bind(user_id)
.fetch_all(db)
.await
.map_err(Into::into)
}
pub async fn find_downstream_key_by_token(
db: &SqlitePool,
token: &str,
) -> AppResult<Option<DownstreamApiKey>> {
sqlx::query_as("SELECT * FROM downstream_api_keys WHERE key = ?")
.bind(token)
.fetch_optional(db)
.await
.map_err(Into::into)
}