package multitable import ( "fmt" "time" "git.iwork-ai.com/xdc/iqudo-top1/internal/model" "gorm.io/gorm" "gorm.io/gorm/clause" ) func EnqueueBackfill(db *gorm.DB) (int, error) { resources := []struct { name string model interface{} }{ {"scenario", &model.Scenario{}}, {"scenario_field", &model.ScenarioField{}}, {"scenario_rule", &model.ScenarioRule{}}, {"sop", &model.SOP{}}, {"knowledge_item", &model.KnowledgeItem{}}, {"knowledge_relation", &model.KnowledgeRelation{}}, {"sop_run", &model.SOPRun{}}, } count := 0 for _, resource := range resources { var rows []struct{ ID, TenantID uint64 } if err := db.Model(resource.model).Select("id, tenant_id").Scan(&rows).Error; err != nil { return count, fmt.Errorf("list %s: %w", resource.name, err) } for _, row := range rows { event := model.MultiTableOutbox{ TenantID: row.TenantID, Resource: resource.name, ResourceID: row.ID, Action: "backfill", Payload: []byte(`{}`), DedupeKey: fmt.Sprintf("backfill:%s:%d", resource.name, row.ID), Status: "pending", Attempts: 0, AvailableAt: time.Now(), LastError: "", } if err := db.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "dedupe_key"}}, DoUpdates: clause.Assignments(map[string]interface{}{"status": "pending", "attempts": 0, "available_at": time.Now(), "last_error": ""})}).Create(&event).Error; err != nil { return count, fmt.Errorf("enqueue %s %d: %w", resource.name, row.ID, err) } count++ } } return count, nil }