package sop import ( "encoding/json" "fmt" "git.iwork-ai.com/xdc/iqudo-top1/internal/model" "gorm.io/datatypes" "gorm.io/gorm" ) type knowledgeNodeConfig struct { KnowledgeCardID uint64 `json:"knowledge_card_id"` KnowledgeCardVersionID uint64 `json:"knowledge_card_version_id"` } // BindKnowledgeVersions freezes the current published knowledge-card version // into every knowledge node before the SOP version becomes immutable. func BindKnowledgeVersions(tx *gorm.DB, tenantID, sopVersionID uint64) error { nodes := make([]model.SOPNode, 0) if err := tx.Where("tenant_id = ? AND sop_version_id = ? AND type = ?", tenantID, sopVersionID, "knowledge").Find(&nodes).Error; err != nil { return err } for _, node := range nodes { var config knowledgeNodeConfig if err := json.Unmarshal(node.Config, &config); err != nil || config.KnowledgeCardID == 0 { return fmt.Errorf("knowledge node %s has invalid configuration", node.NodeKey) } var version model.KnowledgeCardVersion err := tx.Table("knowledge_card_versions kv").Select("kv.*"). Joins("JOIN knowledge_cards kc ON kc.id = kv.knowledge_card_id"). Where("kv.tenant_id = ? AND kv.knowledge_card_id = ? AND kv.status = ? AND kc.tenant_id = ? AND kc.status = ?", tenantID, config.KnowledgeCardID, "published", tenantID, "published"). Order("kv.version DESC").First(&version).Error if err != nil { return fmt.Errorf("knowledge node %s has no published card version: %w", node.NodeKey, err) } updated, err := withKnowledgeVersion(node.Config, version.ID) if err != nil { return fmt.Errorf("update knowledge node %s: %w", node.NodeKey, err) } if err := tx.Model(&model.SOPNode{}).Where("id = ? AND tenant_id = ? AND sop_version_id = ?", node.ID, tenantID, sopVersionID).Update("config", updated).Error; err != nil { return err } } return nil } func withKnowledgeVersion(config datatypes.JSON, versionID uint64) (datatypes.JSON, error) { value := map[string]interface{}{} if len(config) > 0 { if err := json.Unmarshal(config, &value); err != nil { return nil, err } } value["knowledge_card_version_id"] = versionID encoded, err := json.Marshal(value) return datatypes.JSON(encoded), err }