diff --git a/backend/plugins/q_dev/api/blueprint_v200.go b/backend/plugins/q_dev/api/blueprint_v200.go index a7a01598206..e3b845cb8ba 100644 --- a/backend/plugins/q_dev/api/blueprint_v200.go +++ b/backend/plugins/q_dev/api/blueprint_v200.go @@ -71,6 +71,7 @@ func makeDataSourcePipelinePlanV200( op := &tasks.QDevOptions{ ConnectionId: s3Slice.ConnectionId, S3Prefix: s3Slice.Prefix, + ScopeId: s3Slice.Id, } // Pass empty entities array to enable all subtasks diff --git a/backend/plugins/q_dev/models/migrationscripts/20251209_add_scope_id_fields.go b/backend/plugins/q_dev/models/migrationscripts/20251209_add_scope_id_fields.go new file mode 100644 index 00000000000..d7819ff6160 --- /dev/null +++ b/backend/plugins/q_dev/models/migrationscripts/20251209_add_scope_id_fields.go @@ -0,0 +1,68 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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 migrationscripts + +import ( + "github.com/apache/incubator-devlake/core/context" + "github.com/apache/incubator-devlake/core/errors" + "github.com/apache/incubator-devlake/core/plugin" +) + +var _ plugin.MigrationScript = (*addScopeIdFields)(nil) + +type addScopeIdFields struct{} + +func (*addScopeIdFields) Up(basicRes context.BasicRes) errors.Error { + db := basicRes.GetDal() + + // Add scope_id column to _tool_q_dev_user_data table + // This field links user data to QDevS3Slice scope, which can then be mapped to projects via project_mapping + err := db.Exec(` + ALTER TABLE _tool_q_dev_user_data + ADD COLUMN IF NOT EXISTS scope_id VARCHAR(255) DEFAULT NULL + `) + if err != nil { + // Try alternative syntax for databases that don't support IF NOT EXISTS + _ = db.Exec(`ALTER TABLE _tool_q_dev_user_data ADD COLUMN scope_id VARCHAR(255) DEFAULT NULL`) + } + + // Add index on scope_id for better query performance + _ = db.Exec(`CREATE INDEX IF NOT EXISTS idx_q_dev_user_data_scope_id ON _tool_q_dev_user_data(scope_id)`) + + // Add scope_id column to _tool_q_dev_s3_file_meta table + err = db.Exec(` + ALTER TABLE _tool_q_dev_s3_file_meta + ADD COLUMN IF NOT EXISTS scope_id VARCHAR(255) DEFAULT NULL + `) + if err != nil { + _ = db.Exec(`ALTER TABLE _tool_q_dev_s3_file_meta ADD COLUMN scope_id VARCHAR(255) DEFAULT NULL`) + } + + // Add index on scope_id + _ = db.Exec(`CREATE INDEX IF NOT EXISTS idx_q_dev_s3_file_meta_scope_id ON _tool_q_dev_s3_file_meta(scope_id)`) + + return nil +} + +func (*addScopeIdFields) Version() uint64 { + return 20251209000001 +} + +func (*addScopeIdFields) Name() string { + return "add scope_id field to QDevUserData and QDevS3FileMeta for project association" +} diff --git a/backend/plugins/q_dev/models/migrationscripts/register.go b/backend/plugins/q_dev/models/migrationscripts/register.go index 427b3ac611e..86971e53931 100644 --- a/backend/plugins/q_dev/models/migrationscripts/register.go +++ b/backend/plugins/q_dev/models/migrationscripts/register.go @@ -30,5 +30,6 @@ func All() []plugin.MigrationScript { new(addMissingMetrics), new(addS3SliceTable), new(addScopeConfigIdToS3Slice), + new(addScopeIdFields), } } diff --git a/backend/plugins/q_dev/models/s3_file_meta.go b/backend/plugins/q_dev/models/s3_file_meta.go index 003cbc16aa1..09f7480ad80 100644 --- a/backend/plugins/q_dev/models/s3_file_meta.go +++ b/backend/plugins/q_dev/models/s3_file_meta.go @@ -29,6 +29,7 @@ type QDevS3FileMeta struct { ConnectionId uint64 `gorm:"primaryKey"` FileName string `gorm:"primaryKey;type:varchar(255)"` S3Path string `gorm:"type:varchar(512)" json:"s3Path"` + ScopeId string `gorm:"type:varchar(255);index" json:"scopeId"` Processed bool `gorm:"default:false"` ProcessedTime *time.Time `gorm:"default:null"` } diff --git a/backend/plugins/q_dev/models/user_data.go b/backend/plugins/q_dev/models/user_data.go index 75907121ebf..a668db78bdd 100644 --- a/backend/plugins/q_dev/models/user_data.go +++ b/backend/plugins/q_dev/models/user_data.go @@ -30,6 +30,7 @@ type QDevUserData struct { UserId string `gorm:"index" json:"userId"` Date time.Time `gorm:"index" json:"date"` DisplayName string `gorm:"type:varchar(255)" json:"displayName"` // New field for user display name + ScopeId string `gorm:"index;type:varchar(255)" json:"scopeId"` CodeReview_FindingsCount int CodeReview_SucceededEventCount int diff --git a/backend/plugins/q_dev/tasks/s3_data_extractor.go b/backend/plugins/q_dev/tasks/s3_data_extractor.go index 8612ae03b44..03f8a6f5f85 100644 --- a/backend/plugins/q_dev/tasks/s3_data_extractor.go +++ b/backend/plugins/q_dev/tasks/s3_data_extractor.go @@ -161,6 +161,7 @@ func createUserDataWithDisplayName(logger interface { }, headers []string, record []string, fileMeta *models.QDevS3FileMeta, identityClient UserDisplayNameResolver) (*models.QDevUserData, errors.Error) { userData := &models.QDevUserData{ ConnectionId: fileMeta.ConnectionId, + ScopeId: fileMeta.ScopeId, } // 创建字段映射 diff --git a/backend/plugins/q_dev/tasks/s3_file_collector.go b/backend/plugins/q_dev/tasks/s3_file_collector.go index e889d60db10..ae88fb97aa4 100644 --- a/backend/plugins/q_dev/tasks/s3_file_collector.go +++ b/backend/plugins/q_dev/tasks/s3_file_collector.go @@ -87,6 +87,7 @@ func CollectQDevS3Files(taskCtx plugin.SubTaskContext) errors.Error { ConnectionId: data.Options.ConnectionId, FileName: *object.Key, S3Path: *object.Key, + ScopeId: data.Options.ScopeId, Processed: false, } diff --git a/backend/plugins/q_dev/tasks/task_data.go b/backend/plugins/q_dev/tasks/task_data.go index 79cf1c90235..00c58f11e49 100644 --- a/backend/plugins/q_dev/tasks/task_data.go +++ b/backend/plugins/q_dev/tasks/task_data.go @@ -28,6 +28,7 @@ type QDevApiParams struct { type QDevOptions struct { ConnectionId uint64 `json:"connectionId"` S3Prefix string `json:"s3Prefix"` + ScopeId string `json:"scopeId"` } type QDevTaskData struct {