feat(ai): 添加 ai_tenant_configs 迁移 + Entity
支持租户级 Provider 路由配置、月度 Token 预算、每日患者限制 unique 索引确保每租户一条配置,迁移号 000117
This commit is contained in:
27
crates/erp-ai/src/entity/ai_tenant_config.rs
Normal file
27
crates/erp-ai/src/entity/ai_tenant_config.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "ai_tenant_configs")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
pub tenant_id: Uuid,
|
||||
pub default_provider: String,
|
||||
pub fallback_provider: Option<String>,
|
||||
pub analysis_type_overrides: Option<Json>,
|
||||
pub monthly_token_budget: i64,
|
||||
pub daily_patient_limit: i32,
|
||||
pub is_enabled: bool,
|
||||
pub created_at: DateTimeUtc,
|
||||
pub updated_at: DateTimeUtc,
|
||||
pub created_by: Option<Uuid>,
|
||||
pub updated_by: Option<Uuid>,
|
||||
pub deleted_at: Option<DateTimeUtc>,
|
||||
pub version_lock: i32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
@@ -2,4 +2,5 @@ pub mod ai_analysis;
|
||||
pub mod ai_prompt;
|
||||
pub mod ai_risk_threshold;
|
||||
pub mod ai_suggestion;
|
||||
pub mod ai_tenant_config;
|
||||
pub mod ai_usage;
|
||||
|
||||
@@ -116,6 +116,7 @@ mod m20260505_000113_create_ble_gateways;
|
||||
mod m20260505_000114_dialysis_record_add_workflow_instance;
|
||||
mod m20260505_000115_family_member_health_proxy;
|
||||
mod m20260505_000116_seed_missing_health_menus;
|
||||
mod m20260505_000117_create_ai_tenant_configs;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
@@ -239,6 +240,7 @@ impl MigratorTrait for Migrator {
|
||||
Box::new(m20260505_000114_dialysis_record_add_workflow_instance::Migration),
|
||||
Box::new(m20260505_000115_family_member_health_proxy::Migration),
|
||||
Box::new(m20260505_000116_seed_missing_health_menus::Migration),
|
||||
Box::new(m20260505_000117_create_ai_tenant_configs::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(AiTenantConfig::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(AiTenantConfig::Id).uuid().not_null().primary_key())
|
||||
.col(ColumnDef::new(AiTenantConfig::TenantId).uuid().not_null())
|
||||
.col(
|
||||
ColumnDef::new(AiTenantConfig::DefaultProvider)
|
||||
.string_len(50)
|
||||
.not_null()
|
||||
.default("claude"),
|
||||
)
|
||||
.col(ColumnDef::new(AiTenantConfig::FallbackProvider).string_len(50).null())
|
||||
.col(ColumnDef::new(AiTenantConfig::AnalysisTypeOverrides).json().null())
|
||||
.col(
|
||||
ColumnDef::new(AiTenantConfig::MonthlyTokenBudget)
|
||||
.big_integer()
|
||||
.not_null()
|
||||
.default(1_000_000),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(AiTenantConfig::DailyPatientLimit)
|
||||
.integer()
|
||||
.not_null()
|
||||
.default(50),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(AiTenantConfig::IsEnabled)
|
||||
.boolean()
|
||||
.not_null()
|
||||
.default(true),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(AiTenantConfig::CreatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null()
|
||||
.default(Expr::current_timestamp()),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(AiTenantConfig::UpdatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null()
|
||||
.default(Expr::current_timestamp()),
|
||||
)
|
||||
.col(ColumnDef::new(AiTenantConfig::CreatedBy).uuid().null())
|
||||
.col(ColumnDef::new(AiTenantConfig::UpdatedBy).uuid().null())
|
||||
.col(ColumnDef::new(AiTenantConfig::DeletedAt).timestamp_with_time_zone().null())
|
||||
.col(
|
||||
ColumnDef::new(AiTenantConfig::VersionLock)
|
||||
.integer()
|
||||
.not_null()
|
||||
.default(1),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.if_not_exists()
|
||||
.unique()
|
||||
.name("idx_ai_tenant_configs_tenant_unique")
|
||||
.table(AiTenantConfig::Table)
|
||||
.col(AiTenantConfig::TenantId)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(AiTenantConfig::Table).to_owned())
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum AiTenantConfig {
|
||||
Table,
|
||||
Id,
|
||||
TenantId,
|
||||
DefaultProvider,
|
||||
FallbackProvider,
|
||||
AnalysisTypeOverrides,
|
||||
MonthlyTokenBudget,
|
||||
DailyPatientLimit,
|
||||
IsEnabled,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
CreatedBy,
|
||||
UpdatedBy,
|
||||
DeletedAt,
|
||||
VersionLock,
|
||||
}
|
||||
Reference in New Issue
Block a user