2026-04-30 12:36:03 +08:00
//
// Copyright 2026 The InfiniFlow Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package dao
import (
2026-07-27 15:06:48 +08:00
"context"
2026-04-30 12:36:03 +08:00
"ragflow/internal/entity"
2026-07-07 17:22:08 +08:00
"ragflow/internal/utility"
2026-04-30 12:36:03 +08:00
"strings"
2026-07-27 15:06:48 +08:00
"gorm.io/gorm"
2026-04-30 12:36:03 +08:00
)
// SkillSearchConfigDAO data access object for skill search config
type SkillSearchConfigDAO struct { }
const defaultSkillSpaceID = "default"
func normalizeSpaceID ( spaceID string ) string {
spaceID = strings . TrimSpace ( spaceID )
if spaceID == "" {
return defaultSkillSpaceID
}
return spaceID
}
// NewSkillSearchConfigDAO creates a new SkillSearchConfigDAO
func NewSkillSearchConfigDAO ( ) * SkillSearchConfigDAO {
return & SkillSearchConfigDAO { }
}
// Create creates a new skill search config
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) Create ( ctx context . Context , db * gorm . DB , config * entity . SkillSearchConfig ) error {
return db . WithContext ( ctx ) . Create ( config ) . Error
2026-04-30 12:36:03 +08:00
}
// GetByID retrieves a skill search config by ID
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) GetByID ( ctx context . Context , db * gorm . DB , id string ) ( * entity . SkillSearchConfig , error ) {
2026-04-30 12:36:03 +08:00
var config entity . SkillSearchConfig
2026-07-27 15:06:48 +08:00
err := db . WithContext ( ctx ) . Where ( "id = ? AND status = ?" , id , "1" ) . First ( & config ) . Error
2026-04-30 12:36:03 +08:00
if err != nil {
return nil , err
}
return & config , nil
}
// GetByTenantID retrieves a skill search config by tenant ID
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) GetByTenantID ( ctx context . Context , db * gorm . DB , tenantID , spaceID string ) ( * entity . SkillSearchConfig , error ) {
2026-04-30 12:36:03 +08:00
var config entity . SkillSearchConfig
2026-07-27 15:06:48 +08:00
err := db . WithContext ( ctx ) . Where ( "tenant_id = ? AND space_id = ? AND status = ?" , tenantID , normalizeSpaceID ( spaceID ) , "1" ) . First ( & config ) . Error
2026-04-30 12:36:03 +08:00
if err != nil {
return nil , err
}
return & config , nil
}
// GetLatestByTenantID retrieves the latest skill search config by tenant ID (ordered by update_time desc)
// Prioritizes configs with non-empty embd_id to return user-saved configs over auto-created ones
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) GetLatestByTenantID ( ctx context . Context , db * gorm . DB , tenantID , spaceID string ) ( * entity . SkillSearchConfig , error ) {
2026-04-30 12:36:03 +08:00
var config entity . SkillSearchConfig
// First try to get the latest config with non-empty embd_id (user-saved config)
2026-07-27 15:06:48 +08:00
err := db . WithContext ( ctx ) . Where ( "tenant_id = ? AND space_id = ? AND status = ? AND embd_id != ?" , tenantID , normalizeSpaceID ( spaceID ) , "1" , "" ) . Order ( "update_time desc" ) . First ( & config ) . Error
2026-04-30 12:36:03 +08:00
if err == nil {
return & config , nil
}
// If no user-saved config found, get any config
2026-07-27 15:06:48 +08:00
err = db . WithContext ( ctx ) . Where ( "tenant_id = ? AND space_id = ? AND status = ?" , tenantID , normalizeSpaceID ( spaceID ) , "1" ) . Order ( "update_time desc" ) . First ( & config ) . Error
2026-04-30 12:36:03 +08:00
if err != nil {
return nil , err
}
return & config , nil
}
// GetByTenantAndEmbdID retrieves a skill search config by tenant ID and embedding ID
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) GetByTenantAndEmbdID ( ctx context . Context , db * gorm . DB , tenantID , spaceID , embdID string ) ( * entity . SkillSearchConfig , error ) {
2026-04-30 12:36:03 +08:00
var config entity . SkillSearchConfig
2026-07-27 15:06:48 +08:00
err := db . WithContext ( ctx ) . Where ( "tenant_id = ? AND space_id = ? AND embd_id = ? AND status = ?" , tenantID , normalizeSpaceID ( spaceID ) , embdID , "1" ) . First ( & config ) . Error
2026-04-30 12:36:03 +08:00
if err != nil {
return nil , err
}
return & config , nil
}
// GetOrCreate retrieves existing config or creates default one
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) GetOrCreate ( ctx context . Context , db * gorm . DB , tenantID , spaceID , embdID string ) ( * entity . SkillSearchConfig , error ) {
2026-04-30 12:36:03 +08:00
spaceID = normalizeSpaceID ( spaceID )
2026-07-27 15:06:48 +08:00
config , err := dao . GetByTenantAndEmbdID ( ctx , db , tenantID , spaceID , embdID )
2026-04-30 12:36:03 +08:00
if err == nil {
return config , nil
}
// Create default config
2026-07-27 15:06:48 +08:00
return dao . CreateWithTenantSpace ( ctx , db , tenantID , spaceID , embdID )
2026-04-30 12:36:03 +08:00
}
// CreateWithTenantSpace creates a new config for tenant+space
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) CreateWithTenantSpace ( ctx context . Context , db * gorm . DB , tenantID , spaceID , embdID string ) ( * entity . SkillSearchConfig , error ) {
2026-04-30 12:36:03 +08:00
spaceID = normalizeSpaceID ( spaceID )
defaultFieldConfig := entity . DefaultFieldConfig ( )
fieldConfigMap := entity . JSONMap {
"name" : map [ string ] interface { } {
"enabled" : defaultFieldConfig . Name . Enabled ,
"weight" : defaultFieldConfig . Name . Weight ,
} ,
"tags" : map [ string ] interface { } {
"enabled" : defaultFieldConfig . Tags . Enabled ,
"weight" : defaultFieldConfig . Tags . Weight ,
} ,
"description" : map [ string ] interface { } {
"enabled" : defaultFieldConfig . Description . Enabled ,
"weight" : defaultFieldConfig . Description . Weight ,
} ,
"content" : map [ string ] interface { } {
"enabled" : defaultFieldConfig . Content . Enabled ,
"weight" : defaultFieldConfig . Content . Weight ,
} ,
}
defaultConfig := & entity . SkillSearchConfig {
2026-07-07 17:22:08 +08:00
ID : utility . GenerateUUID ( ) ,
2026-04-30 12:36:03 +08:00
TenantID : tenantID ,
SpaceID : spaceID ,
EmbdID : embdID ,
VectorSimilarityWeight : 0.3 ,
SimilarityThreshold : 0.2 ,
FieldConfig : fieldConfigMap ,
TopK : 10 ,
Status : "1" ,
}
2026-07-27 15:06:48 +08:00
if err := dao . Create ( ctx , db , defaultConfig ) ; err != nil {
2026-04-30 12:36:03 +08:00
return nil , err
}
return defaultConfig , nil
}
// DeleteAllByTenantSpace deletes all configs for a tenant+space (for cleanup before creating new one)
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) DeleteAllByTenantSpace ( ctx context . Context , db * gorm . DB , tenantID , spaceID string ) error {
2026-04-30 12:36:03 +08:00
spaceID = normalizeSpaceID ( spaceID )
2026-07-27 15:06:48 +08:00
return db . WithContext ( ctx ) . Model ( & entity . SkillSearchConfig { } ) .
2026-04-30 12:36:03 +08:00
Where ( "tenant_id = ? AND space_id = ?" , tenantID , spaceID ) .
Update ( "status" , "0" ) . Error
}
// DeleteAllByTenantSpaceExceptID deletes all active configs for a tenant+space except the specified ID
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) DeleteAllByTenantSpaceExceptID ( ctx context . Context , db * gorm . DB , tenantID , spaceID , exceptID string ) error {
2026-04-30 12:36:03 +08:00
spaceID = normalizeSpaceID ( spaceID )
2026-07-27 15:06:48 +08:00
return db . WithContext ( ctx ) . Model ( & entity . SkillSearchConfig { } ) .
2026-04-30 12:36:03 +08:00
Where ( "tenant_id = ? AND space_id = ? AND id != ? AND status = ?" , tenantID , spaceID , exceptID , "1" ) .
Update ( "status" , "0" ) . Error
}
// Update updates a skill search config with the given updates map
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) Update ( ctx context . Context , db * gorm . DB , id string , updates map [ string ] interface { } ) error {
return db . WithContext ( ctx ) . Model ( & entity . SkillSearchConfig { } ) . Where ( "id = ? AND status = ?" , id , "1" ) . Updates ( updates ) . Error
2026-04-30 12:36:03 +08:00
}
// UpdateByTenantID updates config by tenant ID
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) UpdateByTenantID ( ctx context . Context , db * gorm . DB , tenantID , spaceID string , updates map [ string ] interface { } ) error {
result := db . WithContext ( ctx ) . Model ( & entity . SkillSearchConfig { } ) . Where ( "tenant_id = ? AND space_id = ? AND status = ?" , tenantID , normalizeSpaceID ( spaceID ) , "1" ) . Updates ( updates )
2026-04-30 12:36:03 +08:00
return result . Error
}
// UpdateByTenantAndEmbdID updates config by tenant ID and embedding ID
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) UpdateByTenantAndEmbdID ( ctx context . Context , db * gorm . DB , tenantID , spaceID , embdID string , updates map [ string ] interface { } ) error {
result := db . WithContext ( ctx ) . Model ( & entity . SkillSearchConfig { } ) . Where ( "tenant_id = ? AND space_id = ? AND embd_id = ? AND status = ?" , tenantID , normalizeSpaceID ( spaceID ) , embdID , "1" ) . Updates ( updates )
2026-04-30 12:36:03 +08:00
return result . Error
}
// Delete deletes a skill search config by ID (soft delete)
2026-07-27 15:06:48 +08:00
func ( dao * SkillSearchConfigDAO ) Delete ( ctx context . Context , db * gorm . DB , id string ) error {
return db . WithContext ( ctx ) . Model ( & entity . SkillSearchConfig { } ) . Where ( "id = ?" , id ) . Update ( "status" , "0" ) . Error
2026-04-30 12:36:03 +08:00
}