feat(ai+db): 知识库 3 表迁移 + Entity — rules/references/guides
Phase 3 Task 21: - ai_knowledge_rules: L1 规则表(条件表达式 + 动作文本) - ai_knowledge_references: L2 参考表(摘要 + pgvector 嵌入) - ai_knowledge_guides: L3 指南表(全文 + pgvector 嵌入)
This commit is contained in:
29
crates/erp-ai/src/entity/ai_knowledge_guides.rs
Normal file
29
crates/erp-ai/src/entity/ai_knowledge_guides.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "ai_knowledge_guides")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
pub tenant_id: Uuid,
|
||||
pub title: String,
|
||||
pub analysis_type: String,
|
||||
pub content: String,
|
||||
pub category: Option<String>,
|
||||
// pgvector 字段 — SeaORM 不原生支持 vector 类型,查询时用 raw SQL
|
||||
#[sea_orm(ignore)]
|
||||
pub embedding: Option<Vec<f32>>,
|
||||
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 {}
|
||||
30
crates/erp-ai/src/entity/ai_knowledge_references.rs
Normal file
30
crates/erp-ai/src/entity/ai_knowledge_references.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "ai_knowledge_references")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
pub tenant_id: Uuid,
|
||||
pub title: String,
|
||||
pub analysis_type: String,
|
||||
pub source_name: String,
|
||||
pub content_summary: String,
|
||||
// pgvector 字段 — SeaORM 不原生支持 vector 类型,查询时用 raw SQL
|
||||
#[sea_orm(ignore)]
|
||||
pub embedding: Option<Vec<f32>>,
|
||||
pub tags: Option<serde_json::Value>,
|
||||
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 {}
|
||||
27
crates/erp-ai/src/entity/ai_knowledge_rules.rs
Normal file
27
crates/erp-ai/src/entity/ai_knowledge_rules.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_knowledge_rules")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
pub tenant_id: Uuid,
|
||||
pub rule_name: String,
|
||||
pub analysis_type: String,
|
||||
pub condition_expr: String,
|
||||
pub action_text: String,
|
||||
pub priority: 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 {}
|
||||
@@ -1,5 +1,8 @@
|
||||
pub mod ai_analysis;
|
||||
pub mod ai_analysis_queue;
|
||||
pub mod ai_knowledge_guides;
|
||||
pub mod ai_knowledge_references;
|
||||
pub mod ai_knowledge_rules;
|
||||
pub mod ai_prompt;
|
||||
pub mod ai_risk_threshold;
|
||||
pub mod ai_suggestion;
|
||||
|
||||
@@ -119,6 +119,9 @@ mod m20260505_000116_seed_missing_health_menus;
|
||||
mod m20260505_000117_create_ai_tenant_configs;
|
||||
mod m20260505_000118_create_ai_analysis_queue;
|
||||
mod m20260505_000119_enable_pgvector;
|
||||
mod m20260505_000120_create_ai_knowledge_rules;
|
||||
mod m20260505_000121_create_ai_knowledge_references;
|
||||
mod m20260505_000122_create_ai_knowledge_guides;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
@@ -245,6 +248,9 @@ impl MigratorTrait for Migrator {
|
||||
Box::new(m20260505_000117_create_ai_tenant_configs::Migration),
|
||||
Box::new(m20260505_000118_create_ai_analysis_queue::Migration),
|
||||
Box::new(m20260505_000119_enable_pgvector::Migration),
|
||||
Box::new(m20260505_000120_create_ai_knowledge_rules::Migration),
|
||||
Box::new(m20260505_000121_create_ai_knowledge_references::Migration),
|
||||
Box::new(m20260505_000122_create_ai_knowledge_guides::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[derive(Iden)]
|
||||
enum AiKnowledgeRules {
|
||||
Table,
|
||||
Id,
|
||||
TenantId,
|
||||
RuleName,
|
||||
AnalysisType,
|
||||
ConditionExpr,
|
||||
ActionText,
|
||||
Priority,
|
||||
IsEnabled,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
CreatedBy,
|
||||
UpdatedBy,
|
||||
DeletedAt,
|
||||
VersionLock,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(AiKnowledgeRules::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(AiKnowledgeRules::Id).uuid().not_null().primary_key())
|
||||
.col(ColumnDef::new(AiKnowledgeRules::TenantId).uuid().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeRules::RuleName).string().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeRules::AnalysisType).string().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeRules::ConditionExpr).string().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeRules::ActionText).string().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeRules::Priority).integer().not_null().default(0))
|
||||
.col(ColumnDef::new(AiKnowledgeRules::IsEnabled).boolean().not_null().default(true))
|
||||
.col(ColumnDef::new(AiKnowledgeRules::CreatedAt).timestamp_with_time_zone().not_null().default(Expr::current_timestamp()))
|
||||
.col(ColumnDef::new(AiKnowledgeRules::UpdatedAt).timestamp_with_time_zone().not_null().default(Expr::current_timestamp()))
|
||||
.col(ColumnDef::new(AiKnowledgeRules::CreatedBy).uuid())
|
||||
.col(ColumnDef::new(AiKnowledgeRules::UpdatedBy).uuid())
|
||||
.col(ColumnDef::new(AiKnowledgeRules::DeletedAt).timestamp_with_time_zone())
|
||||
.col(ColumnDef::new(AiKnowledgeRules::VersionLock).integer().not_null().default(1))
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.if_not_exists()
|
||||
.name("idx_ai_knowledge_rules_tenant_type")
|
||||
.table(AiKnowledgeRules::Table)
|
||||
.col(AiKnowledgeRules::TenantId)
|
||||
.col(AiKnowledgeRules::AnalysisType)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(AiKnowledgeRules::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[derive(Iden)]
|
||||
enum AiKnowledgeReferences {
|
||||
Table,
|
||||
Id,
|
||||
TenantId,
|
||||
Title,
|
||||
AnalysisType,
|
||||
SourceName,
|
||||
ContentSummary,
|
||||
Embedding,
|
||||
Tags,
|
||||
IsEnabled,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
CreatedBy,
|
||||
UpdatedBy,
|
||||
DeletedAt,
|
||||
VersionLock,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(AiKnowledgeReferences::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::Id).uuid().not_null().primary_key())
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::TenantId).uuid().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::Title).string().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::AnalysisType).string().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::SourceName).string().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::ContentSummary).text().not_null())
|
||||
// vector(1536) — 兼容 OpenAI text-embedding-ada-002
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::Embedding).custom("vector"))
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::Tags).json())
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::IsEnabled).boolean().not_null().default(true))
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::CreatedAt).timestamp_with_time_zone().not_null().default(Expr::current_timestamp()))
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::UpdatedAt).timestamp_with_time_zone().not_null().default(Expr::current_timestamp()))
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::CreatedBy).uuid())
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::UpdatedBy).uuid())
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::DeletedAt).timestamp_with_time_zone())
|
||||
.col(ColumnDef::new(AiKnowledgeReferences::VersionLock).integer().not_null().default(1))
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.if_not_exists()
|
||||
.name("idx_ai_knowledge_refs_tenant_type")
|
||||
.table(AiKnowledgeReferences::Table)
|
||||
.col(AiKnowledgeReferences::TenantId)
|
||||
.col(AiKnowledgeReferences::AnalysisType)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(AiKnowledgeReferences::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[derive(Iden)]
|
||||
enum AiKnowledgeGuides {
|
||||
Table,
|
||||
Id,
|
||||
TenantId,
|
||||
Title,
|
||||
AnalysisType,
|
||||
Content,
|
||||
Category,
|
||||
Embedding,
|
||||
IsEnabled,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
CreatedBy,
|
||||
UpdatedBy,
|
||||
DeletedAt,
|
||||
VersionLock,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(AiKnowledgeGuides::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::Id).uuid().not_null().primary_key())
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::TenantId).uuid().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::Title).string().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::AnalysisType).string().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::Content).text().not_null())
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::Category).string())
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::Embedding).custom("vector"))
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::IsEnabled).boolean().not_null().default(true))
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::CreatedAt).timestamp_with_time_zone().not_null().default(Expr::current_timestamp()))
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::UpdatedAt).timestamp_with_time_zone().not_null().default(Expr::current_timestamp()))
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::CreatedBy).uuid())
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::UpdatedBy).uuid())
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::DeletedAt).timestamp_with_time_zone())
|
||||
.col(ColumnDef::new(AiKnowledgeGuides::VersionLock).integer().not_null().default(1))
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.if_not_exists()
|
||||
.name("idx_ai_knowledge_guides_tenant_type")
|
||||
.table(AiKnowledgeGuides::Table)
|
||||
.col(AiKnowledgeGuides::TenantId)
|
||||
.col(AiKnowledgeGuides::AnalysisType)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(AiKnowledgeGuides::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user