This is an automated email from the ASF dual-hosted git repository.

klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 77f8f469b Feat support q dev dora (#8659)
77f8f469b is described below

commit 77f8f469b1c7e469d997b112a195e6d0311cfc2b
Author: Warren Chen <[email protected]>
AuthorDate: Wed Dec 10 10:08:37 2025 +0800

    Feat support q dev dora (#8659)
    
    * feat: add new dashboard to integrate q dev and dora
    
    * feat: support q dev with dora in infra
---
 backend/plugins/q_dev/api/blueprint_v200.go        |  1 +
 .../20251209_add_scope_id_fields.go                | 68 ++++++++++++++++++++++
 .../q_dev/models/migrationscripts/register.go      |  1 +
 backend/plugins/q_dev/models/s3_file_meta.go       |  1 +
 backend/plugins/q_dev/models/user_data.go          |  1 +
 backend/plugins/q_dev/tasks/s3_data_extractor.go   |  1 +
 backend/plugins/q_dev/tasks/s3_file_collector.go   |  1 +
 backend/plugins/q_dev/tasks/task_data.go           |  1 +
 8 files changed, 75 insertions(+)

diff --git a/backend/plugins/q_dev/api/blueprint_v200.go 
b/backend/plugins/q_dev/api/blueprint_v200.go
index a7a015982..e3b845cb8 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 000000000..d7819ff61
--- /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 427b3ac61..86971e539 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 003cbc16a..09f7480ad 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 75907121e..a668db78b 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 8612ae03b..03f8a6f5f 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 e889d60db..ae88fb97a 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 79cf1c902..00c58f11e 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 {

Reply via email to