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

zhangliang2022 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 2be936a48 feat: add  migration script linter (#5648)
2be936a48 is described below

commit 2be936a4869b88b9a81dcfb10759c19cce0aebd0
Author: Klesh Wong <[email protected]>
AuthorDate: Tue Jul 11 16:12:07 2023 +0800

    feat: add  migration script linter (#5648)
    
    * feat: add  migration script linter
    
    * fix: migration script linting errors
    
    * fix: linting
    
    * fix: typos
    
    * fix: package path
---
 .github/workflows/migration-script-lint.yml        |  37 ++++
 backend/Makefile                                   |   3 +
 backend/core/migration/linter/main.go              | 205 +++++++++++++++++++++
 .../20220918_commit_line_change.go                 |   4 +-
 .../migrationscripts/20220927_add_snapshot.go      |   4 +-
 backend/plugins/jira/api/connection.go             |   2 +-
 .../models/migrationscripts/archived/assignment.go |   5 +-
 .../models/migrationscripts/archived/incident.go   |   5 +-
 .../models/migrationscripts/archived/service.go    |   4 +-
 .../archived/transformation_rules.go               |   6 +-
 .../models/migrationscripts/archived/user.go       |   6 +-
 .../20230321_expend_project_key.go                 |  38 ++--
 .../models/migrationscripts/archived/bug_commit.go |   3 +-
 .../migrationscripts/20230314_add_init_tables.go   |  24 +--
 .../models/migrationscripts/archived/account.go    |  51 +++++
 .../migrationscripts/archived/connection.go}       |  18 +-
 .../models/migrationscripts/archived/input.go}     |  15 +-
 .../models/migrationscripts/archived/project.go    |  61 ++++++
 .../models/migrationscripts/archived/sprint.go}    |  27 ++-
 .../models/migrationscripts/archived/task.go       |  75 ++++++++
 .../migrationscripts/archived/task_activity.go}    |  23 ++-
 .../migrationscripts/archived/task_comment.go}     |  17 +-
 .../migrationscripts/archived/task_flow_status.go  |  45 +++++
 .../migrationscripts/archived/task_scenario.go     |  53 ++++++
 .../models/migrationscripts/archived/task_tag.go}  |  22 ++-
 .../migrationscripts/archived/task_tag_task.go}    |  16 +-
 .../migrationscripts/archived/task_worktime.go}    |  33 ++--
 .../migrationscripts/20221121_add_init_tables.go   |   2 +-
 .../migrationscripts/20230601_add_scope_config.go  |   2 +-
 .../20230605_add_issue_repo_commits.go             |   2 +-
 .../20230608_add_init_changelog_tables.go          |   2 +-
 .../20230705_add_execution_stories.go              |   2 +-
 .../{ => migrationscripts}/archived/account.go     |   0
 .../models/{ => migrationscripts}/archived/bug.go  |   0
 .../{ => migrationscripts}/archived/bug_commits.go |   0
 .../{ => migrationscripts}/archived/changelog.go   |   0
 .../{ => migrationscripts}/archived/connection.go  |   0
 .../{ => migrationscripts}/archived/department.go  |   0
 .../{ => migrationscripts}/archived/execution.go   |   0
 .../archived/execution_stories.go                  |   0
 .../archived/execution_summary.go                  |   0
 .../{ => migrationscripts}/archived/product.go     |   0
 .../archived/product_summary.go                    |   0
 .../{ => migrationscripts}/archived/project.go     |  68 +++----
 .../archived/project_stories.go                    |   0
 .../archived/scope_config.go                       |   0
 .../{ => migrationscripts}/archived/story.go       |   0
 .../archived/story_commits.go                      |   0
 .../models/{ => migrationscripts}/archived/task.go |   0
 .../archived/task_commits.go                       |   0
 50 files changed, 720 insertions(+), 160 deletions(-)

diff --git a/.github/workflows/migration-script-lint.yml 
b/.github/workflows/migration-script-lint.yml
new file mode 100644
index 000000000..0429f0379
--- /dev/null
+++ b/.github/workflows/migration-script-lint.yml
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+name: migration-script-lint
+on:
+  push:
+    tags:
+      - v*
+    branches:
+      - main
+  pull_request:
+jobs:
+  migration-script-lint:
+    name: migration-script-lint
+    runs-on: ubuntu-latest
+    container: mericodev/lake-builder:latest
+    steps:
+      - uses: actions/checkout@v3
+      - name: migration script linting
+        run: |
+          go version
+          cd backend
+          go run core/migration/linter/main.go -p backend $(find . -path 
"**/migrationscripts/**.go")
diff --git a/backend/Makefile b/backend/Makefile
index c55a019f9..977eea918 100644
--- a/backend/Makefile
+++ b/backend/Makefile
@@ -168,3 +168,6 @@ clean:
 
 build-server-image:
        docker build -t $(IMAGE_REPO)/devlake:$(TAG) --build-arg TAG=$(TAG) 
--build-arg SHA=$(SHA) --file ./Dockerfile .
+
+migration-script-lint:
+       go run core/migration/linter/main.go -- $$(find . -path 
'**/migrationscripts/**.go')
diff --git a/backend/core/migration/linter/main.go 
b/backend/core/migration/linter/main.go
new file mode 100644
index 000000000..bf9190b72
--- /dev/null
+++ b/backend/core/migration/linter/main.go
@@ -0,0 +1,205 @@
+/*
+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 main
+
+import (
+       "bufio"
+       "fmt"
+       "go/ast"
+       "go/parser"
+       "go/token"
+       "os"
+       "path"
+       "strconv"
+       "strings"
+       "text/template"
+
+       "github.com/spf13/cobra"
+)
+
+var moduleName = ""
+
+func init() {
+       // prepare the module name
+       line := firstLineFromFile("go.mod")
+       moduleName = strings.Split(line, " ")[1]
+}
+
+func firstLineFromFile(path string) string {
+       inFile, err := os.Open(path)
+       if err != nil {
+               panic(err)
+       }
+       defer inFile.Close()
+
+       scanner := bufio.NewScanner(inFile)
+       for scanner.Scan() {
+               return scanner.Text()
+       }
+       panic(fmt.Errorf("empty file: " + path))
+}
+
+const (
+       LINT_ERROR   = "error"
+       LINT_WARNING = "warning"
+)
+
+type LintMessage struct {
+       Level  string
+       File   string
+       Line   int
+       Col    int
+       EndCol int
+       Title  string
+       Msg    string
+}
+
+func lintMigrationScript(file string, allowedPkgs map[string]bool) 
[]LintMessage {
+       msgs := make([]LintMessage, 0)
+       src, err := os.ReadFile(file)
+       if err != nil {
+               msgs = append(msgs, LintMessage{
+                       Level: LINT_ERROR,
+                       File:  file,
+                       Title: "Error reading file",
+                       Msg:   err.Error(),
+               })
+               return msgs
+       }
+       fset := token.NewFileSet()
+       f, err := parser.ParseFile(fset, file, src, 0)
+       if err != nil {
+               msgs = append(msgs, LintMessage{
+                       Level: LINT_ERROR,
+                       File:  file,
+                       Title: "Error parsing file",
+                       Msg:   err.Error(),
+               })
+               return msgs
+       }
+       // ast.Print(fset, f)
+       ast.Inspect(f, func(n ast.Node) bool {
+               switch x := n.(type) {
+               case *ast.ImportSpec:
+                       importedPkgName, err := strconv.Unquote(x.Path.Value)
+                       if err != nil {
+                               panic(err)
+                       }
+                       // it is ok to use subpackages
+                       filePkgName := path.Join(moduleName, path.Dir(file))
+                       if strings.HasPrefix(importedPkgName, filePkgName) {
+                               return true
+                       }
+                       // it is ok to use external libs, their behaviors are 
considered stable
+                       if !strings.HasPrefix(importedPkgName, moduleName) {
+                               return true
+                       }
+                       // it is ok if the package is whitelisted
+                       if allowedPkgs[importedPkgName] {
+                               return true
+                       }
+                       // we have a problem
+                       // migration scripts are Immutable, meaning their 
behaviors should not be changed over time
+                       // Relying on other packages may break the constraint 
and cause unexpected side-effects.
+                       // You may add the package to the whitelist by the -a 
option if you are sure it is OK
+                       pos := fset.Position(n.Pos())
+                       msgs = append(msgs, LintMessage{
+                               Level:  LINT_WARNING,
+                               File:   file,
+                               Title:  "Package not allowed",
+                               Msg:    fmt.Sprintf("%s imports forbidden 
package %s", file, x.Path.Value),
+                               Line:   pos.Line,
+                               Col:    pos.Column,
+                               EndCol: pos.Column + len(x.Path.Value),
+                       })
+               }
+               return true
+       })
+       return msgs
+}
+
+func main() {
+       cmd := &cobra.Command{Use: "migration script linter"}
+       prefix := cmd.Flags().StringP("prefix", "p", "", "path prefix if your 
go.mod resides in a subfolder")
+       allowedPkg := cmd.Flags().StringArrayP(
+               "allowed-pkg",
+               "a",
+               []string{
+                       "github.com/apache/incubator-devlake/core/config",
+                       "github.com/apache/incubator-devlake/core/context",
+                       "github.com/apache/incubator-devlake/core/dal",
+                       "github.com/apache/incubator-devlake/core/errors",
+                       
"github.com/apache/incubator-devlake/helpers/migrationhelper",
+                       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived",
+                       "github.com/apache/incubator-devlake/core/plugin",
+                       
"github.com/apache/incubator-devlake/helpers/pluginhelper/api",
+               },
+               "package that allowed to be used in a migration script. e.g.: 
github.com/apache/incubator-devlake/core/context",
+       )
+
+       cmd.Run = func(cmd *cobra.Command, args []string) {
+               allowedPkgs := make(map[string]bool, len(*allowedPkg))
+               for _, p := range *allowedPkg {
+                       allowedPkgs[p] = true
+               }
+               warningTpl, err := template.New("warning").Parse("::warning 
file={{ .File }},line={{ .Line }},col={{ .Col }},endColumn={{ .EndCol }}::{{ 
.Msg }}")
+               if err != nil {
+                       panic(err)
+               }
+               errorTpl, err := template.New("error").Parse("::error file={{ 
.File }},line={{ .Line }},endLine={{ .Col }},title={{ .Title }}::{{ .Msg }}")
+               if err != nil {
+                       panic(err)
+               }
+               localTpl, err := template.New("local").Parse("{{ .Level }}: {{ 
.Msg }}\n\t{{ .File }}:{{ .Line }}:{{ .Col }}")
+               if err != nil {
+                       panic(err)
+               }
+               exitCode := 0
+               for _, file := range args {
+                       msgs := lintMigrationScript(file, allowedPkgs)
+                       if len(msgs) == 0 {
+                               continue
+                       }
+                       for _, msg := range msgs {
+                               var tpl *template.Template
+                               if *prefix != "" {
+                                       // github actions need root relative 
path for annotation to show up in the PR
+                                       msg.File = path.Join(*prefix, file)
+                                       tpl = errorTpl
+                                       if msg.Level == LINT_WARNING {
+                                               tpl = warningTpl
+                                       }
+                               } else {
+                                       // we are running locally in the 
`backend` folder, use another format to make fixing easier
+                                       tpl = localTpl
+                               }
+                               err = tpl.Execute(os.Stderr, msg)
+                               if err != nil {
+                                       panic(err)
+                               }
+                               os.Stderr.WriteString("\n")
+                               exitCode = 1
+                       }
+               }
+               os.Exit(exitCode)
+       }
+       err := cmd.Execute()
+       if err != nil {
+               panic(err)
+       }
+}
diff --git 
a/backend/core/models/migrationscripts/20220918_commit_line_change.go 
b/backend/core/models/migrationscripts/20220918_commit_line_change.go
index 909254ee8..d6dcdc422 100644
--- a/backend/core/models/migrationscripts/20220918_commit_line_change.go
+++ b/backend/core/models/migrationscripts/20220918_commit_line_change.go
@@ -20,7 +20,7 @@ package migrationscripts
 import (
        "github.com/apache/incubator-devlake/core/context"
        "github.com/apache/incubator-devlake/core/errors"
-       "github.com/apache/incubator-devlake/core/models/domainlayer"
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
        "github.com/apache/incubator-devlake/core/plugin"
 )
 
@@ -29,7 +29,7 @@ var _ plugin.MigrationScript = (*commitLineChange)(nil)
 type commitLineChange struct{}
 
 type commitLineChange20220918 struct {
-       domainlayer.DomainEntity
+       archived.DomainEntity
        Id          string `gorm:"type:varchar(255);primaryKey"`
        CommitSha   string `gorm:"type:varchar(40);"`
        NewFilePath string `gorm:"type:varchar(255);"`
diff --git a/backend/core/models/migrationscripts/20220927_add_snapshot.go 
b/backend/core/models/migrationscripts/20220927_add_snapshot.go
index 83272a266..02f06d977 100644
--- a/backend/core/models/migrationscripts/20220927_add_snapshot.go
+++ b/backend/core/models/migrationscripts/20220927_add_snapshot.go
@@ -20,14 +20,14 @@ package migrationscripts
 import (
        "github.com/apache/incubator-devlake/core/context"
        "github.com/apache/incubator-devlake/core/errors"
-       "github.com/apache/incubator-devlake/core/models/common"
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
        "github.com/apache/incubator-devlake/core/plugin"
 )
 
 var _ plugin.MigrationScript = (*addRepoSnapshot)(nil)
 
 type repoSnapshot20220918 struct {
-       common.NoPKModel
+       archived.NoPKModel
        RepoId    string `gorm:"primaryKey;type:varchar(255)"`
        CommitSha string `gorm:"primaryKey;type:varchar(40);"`
        FilePath  string `gorm:"primaryKey;type:varchar(255);"`
diff --git a/backend/plugins/jira/api/connection.go 
b/backend/plugins/jira/api/connection.go
index 36fe609ca..6720afd13 100644
--- a/backend/plugins/jira/api/connection.go
+++ b/backend/plugins/jira/api/connection.go
@@ -95,7 +95,7 @@ func TestConnection(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutput,
        if resBody.DeploymentType == models.DeploymentServer {
                // only support 8.x.x or higher
                if versions := resBody.VersionNumbers; len(versions) == 3 && 
versions[0] < 7 {
-                       return nil, errors.Default.New(fmt.Sprintf("%s Support 
JIRA Server 8+ only", serverInfoFail))
+                       return nil, errors.Default.New(fmt.Sprintf("%s Support 
JIRA Server 7+ only", serverInfoFail))
                }
        }
        if res.StatusCode != http.StatusOK {
diff --git 
a/backend/plugins/pagerduty/models/migrationscripts/archived/assignment.go 
b/backend/plugins/pagerduty/models/migrationscripts/archived/assignment.go
index 23f0b63f4..144405d28 100644
--- a/backend/plugins/pagerduty/models/migrationscripts/archived/assignment.go
+++ b/backend/plugins/pagerduty/models/migrationscripts/archived/assignment.go
@@ -18,12 +18,13 @@ limitations under the License.
 package archived
 
 import (
-       "github.com/apache/incubator-devlake/core/models/common"
        "time"
+
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
 )
 
 type Assignment struct {
-       common.NoPKModel
+       archived.NoPKModel
        ConnectionId   uint64
        IncidentNumber int    `gorm:"primaryKey"`
        UserId         string `gorm:"primaryKey"`
diff --git 
a/backend/plugins/pagerduty/models/migrationscripts/archived/incident.go 
b/backend/plugins/pagerduty/models/migrationscripts/archived/incident.go
index fdc6cadc6..632dd8678 100644
--- a/backend/plugins/pagerduty/models/migrationscripts/archived/incident.go
+++ b/backend/plugins/pagerduty/models/migrationscripts/archived/incident.go
@@ -18,12 +18,13 @@ limitations under the License.
 package archived
 
 import (
-       "github.com/apache/incubator-devlake/core/models/common"
        "time"
+
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
 )
 
 type Incident struct {
-       common.NoPKModel
+       archived.NoPKModel
        ConnectionId uint64 `gorm:"primaryKey"`
        Number       int    `gorm:"primaryKey"`
        Url          string
diff --git 
a/backend/plugins/pagerduty/models/migrationscripts/archived/service.go 
b/backend/plugins/pagerduty/models/migrationscripts/archived/service.go
index 065aab1e4..5d7af2c2c 100644
--- a/backend/plugins/pagerduty/models/migrationscripts/archived/service.go
+++ b/backend/plugins/pagerduty/models/migrationscripts/archived/service.go
@@ -18,12 +18,12 @@ limitations under the License.
 package archived
 
 import (
-       "github.com/apache/incubator-devlake/core/models/common"
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
 )
 
 type (
        Service struct {
-               common.NoPKModel
+               archived.NoPKModel
                ConnectionId uint64 `gorm:"primaryKey"`
                Id           string `gorm:"primaryKey;autoIncremental:false"`
                Url          string
diff --git 
a/backend/plugins/pagerduty/models/migrationscripts/archived/transformation_rules.go
 
b/backend/plugins/pagerduty/models/migrationscripts/archived/transformation_rules.go
index 2da5581fb..97de3630b 100644
--- 
a/backend/plugins/pagerduty/models/migrationscripts/archived/transformation_rules.go
+++ 
b/backend/plugins/pagerduty/models/migrationscripts/archived/transformation_rules.go
@@ -17,10 +17,12 @@ limitations under the License.
 
 package archived
 
-import "github.com/apache/incubator-devlake/core/models/common"
+import (
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+)
 
 type TransformationRules struct {
-       common.Model
+       archived.Model
        Name         string 
`gorm:"type:varchar(255);index:idx_name_github,unique"`
        ConnectionId uint64
 }
diff --git a/backend/plugins/pagerduty/models/migrationscripts/archived/user.go 
b/backend/plugins/pagerduty/models/migrationscripts/archived/user.go
index af8033f83..a98b8f507 100644
--- a/backend/plugins/pagerduty/models/migrationscripts/archived/user.go
+++ b/backend/plugins/pagerduty/models/migrationscripts/archived/user.go
@@ -17,12 +17,10 @@ limitations under the License.
 
 package archived
 
-import (
-       "github.com/apache/incubator-devlake/core/models/common"
-)
+import 
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
 
 type User struct {
-       common.NoPKModel
+       archived.NoPKModel
        ConnectionId uint64 `gorm:"primaryKey"`
        Id           string `gorm:"primaryKey;autoIncremental:false"`
        Url          string
diff --git 
a/backend/plugins/sonarqube/models/migrationscripts/20230321_expend_project_key.go
 
b/backend/plugins/sonarqube/models/migrationscripts/20230321_expend_project_key.go
index 21a09e5b0..aa2ba160a 100644
--- 
a/backend/plugins/sonarqube/models/migrationscripts/20230321_expend_project_key.go
+++ 
b/backend/plugins/sonarqube/models/migrationscripts/20230321_expend_project_key.go
@@ -20,20 +20,20 @@ package migrationscripts
 import (
        "github.com/apache/incubator-devlake/core/context"
        "github.com/apache/incubator-devlake/core/errors"
-       "github.com/apache/incubator-devlake/core/models/common"
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
        "github.com/apache/incubator-devlake/helpers/migrationhelper"
        "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 )
 
 type SonarqubeProject20230206Before struct {
-       common.NoPKModel `json:"-" mapstructure:"-"`
-       ConnectionId     uint64           `json:"connectionId" 
validate:"required" gorm:"primaryKey"`
-       ProjectKey       string           `json:"projectKey" 
validate:"required" gorm:"type:varchar(64);primaryKey"`
-       Name             string           `json:"name" gorm:"type:varchar(255)"`
-       Qualifier        string           `json:"qualifier" 
gorm:"type:varchar(255)"`
-       Visibility       string           `json:"visibility" 
gorm:"type:varchar(64)"`
-       LastAnalysisDate *api.Iso8601Time `json:"lastAnalysisDate"`
-       Revision         string           `json:"revision" 
gorm:"type:varchar(128)"`
+       archived.NoPKModel `json:"-" mapstructure:"-"`
+       ConnectionId       uint64           `json:"connectionId" 
validate:"required" gorm:"primaryKey"`
+       ProjectKey         string           `json:"projectKey" 
validate:"required" gorm:"type:varchar(64);primaryKey"`
+       Name               string           `json:"name" 
gorm:"type:varchar(255)"`
+       Qualifier          string           `json:"qualifier" 
gorm:"type:varchar(255)"`
+       Visibility         string           `json:"visibility" 
gorm:"type:varchar(64)"`
+       LastAnalysisDate   *api.Iso8601Time `json:"lastAnalysisDate"`
+       Revision           string           `json:"revision" 
gorm:"type:varchar(128)"`
 }
 
 func (SonarqubeProject20230206Before) TableName() string {
@@ -41,14 +41,14 @@ func (SonarqubeProject20230206Before) TableName() string {
 }
 
 type SonarqubeProject20230206After struct {
-       common.NoPKModel `json:"-" mapstructure:"-"`
-       ConnectionId     uint64           `json:"connectionId" 
validate:"required" gorm:"primaryKey"`
-       ProjectKey       string           `json:"projectKey" 
validate:"required" gorm:"type:varchar(255);primaryKey"` // expand this
-       Name             string           `json:"name" gorm:"type:varchar(255)"`
-       Qualifier        string           `json:"qualifier" 
gorm:"type:varchar(255)"`
-       Visibility       string           `json:"visibility" 
gorm:"type:varchar(64)"`
-       LastAnalysisDate *api.Iso8601Time `json:"lastAnalysisDate"`
-       Revision         string           `json:"revision" 
gorm:"type:varchar(128)"`
+       archived.NoPKModel `json:"-" mapstructure:"-"`
+       ConnectionId       uint64           `json:"connectionId" 
validate:"required" gorm:"primaryKey"`
+       ProjectKey         string           `json:"projectKey" 
validate:"required" gorm:"type:varchar(255);primaryKey"` // expand this
+       Name               string           `json:"name" 
gorm:"type:varchar(255)"`
+       Qualifier          string           `json:"qualifier" 
gorm:"type:varchar(255)"`
+       Visibility         string           `json:"visibility" 
gorm:"type:varchar(64)"`
+       LastAnalysisDate   *api.Iso8601Time `json:"lastAnalysisDate"`
+       Revision           string           `json:"revision" 
gorm:"type:varchar(128)"`
 }
 
 func (SonarqubeProject20230206After) TableName() string {
@@ -78,7 +78,7 @@ type SonarqubeIssue20230206Before struct {
        EndOffset    int
        CreationDate *api.Iso8601Time
        UpdateDate   *api.Iso8601Time
-       common.NoPKModel
+       archived.NoPKModel
 }
 
 func (SonarqubeIssue20230206Before) TableName() string {
@@ -108,7 +108,7 @@ type SonarqubeIssue20230206After struct {
        EndOffset    int
        CreationDate *api.Iso8601Time
        UpdateDate   *api.Iso8601Time
-       common.NoPKModel
+       archived.NoPKModel
 }
 
 func (SonarqubeIssue20230206After) TableName() string {
diff --git 
a/backend/plugins/tapd/models/migrationscripts/archived/bug_commit.go 
b/backend/plugins/tapd/models/migrationscripts/archived/bug_commit.go
index 780c49352..749d34ad8 100644
--- a/backend/plugins/tapd/models/migrationscripts/archived/bug_commit.go
+++ b/backend/plugins/tapd/models/migrationscripts/archived/bug_commit.go
@@ -18,9 +18,10 @@ limitations under the License.
 package archived
 
 import (
+       "time"
+
        
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
        helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
-       "time"
 )
 
 type TapdBugCommit struct {
diff --git 
a/backend/plugins/teambition/models/migrationscripts/20230314_add_init_tables.go
 
b/backend/plugins/teambition/models/migrationscripts/20230314_add_init_tables.go
index 07a1ea527..2b854b00f 100644
--- 
a/backend/plugins/teambition/models/migrationscripts/20230314_add_init_tables.go
+++ 
b/backend/plugins/teambition/models/migrationscripts/20230314_add_init_tables.go
@@ -21,7 +21,7 @@ import (
        "github.com/apache/incubator-devlake/core/context"
        "github.com/apache/incubator-devlake/core/errors"
        "github.com/apache/incubator-devlake/helpers/migrationhelper"
-       "github.com/apache/incubator-devlake/plugins/teambition/models"
+       
"github.com/apache/incubator-devlake/plugins/teambition/models/migrationscripts/archived"
 )
 
 type addInitTables struct{}
@@ -29,17 +29,17 @@ type addInitTables struct{}
 func (*addInitTables) Up(basicRes context.BasicRes) errors.Error {
        return migrationhelper.AutoMigrateTables(
                basicRes,
-               &models.TeambitionConnection{},
-               &models.TeambitionAccount{},
-               &models.TeambitionTask{},
-               &models.TeambitionTaskActivity{},
-               &models.TeambitionSprint{},
-               &models.TeambitionTaskTag{},
-               &models.TeambitionTaskTagTask{},
-               &models.TeambitionTaskWorktime{},
-               &models.TeambitionProject{},
-               &models.TeambitionTaskFlowStatus{},
-               &models.TeambitionTaskScenario{},
+               &archived.TeambitionConnection{},
+               &archived.TeambitionAccount{},
+               &archived.TeambitionTask{},
+               &archived.TeambitionTaskActivity{},
+               &archived.TeambitionSprint{},
+               &archived.TeambitionTaskTag{},
+               &archived.TeambitionTaskTagTask{},
+               &archived.TeambitionTaskWorktime{},
+               &archived.TeambitionProject{},
+               &archived.TeambitionTaskFlowStatus{},
+               &archived.TeambitionTaskScenario{},
        )
 }
 
diff --git 
a/backend/plugins/teambition/models/migrationscripts/archived/account.go 
b/backend/plugins/teambition/models/migrationscripts/archived/account.go
new file mode 100644
index 000000000..0fb6a6240
--- /dev/null
+++ b/backend/plugins/teambition/models/migrationscripts/archived/account.go
@@ -0,0 +1,51 @@
+/*
+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 archived
+
+import (
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+)
+
+type TeambitionAccount struct {
+       ConnectionId   uint64 `gorm:"primaryKey;type:BIGINT"`
+       UserId         string `gorm:"primaryKey;type:varchar(100)" 
json:"userId"`
+       MemberId       string `gorm:"type:varchar(100)"`
+       IsDisabled     int    `json:"isDisabled"`
+       Role           uint64
+       AvatarUrl      string           `gorm:"type:varchar(255)"`
+       Birthday       string           `gorm:"type:varchar(100)"`
+       City           string           `gorm:"type:varchar(100)"`
+       Province       string           `gorm:"type:varchar(100)"`
+       Country        string           `gorm:"type:varchar(100)"`
+       Email          string           `gorm:"type:varchar(255)"`
+       EntryTime      *api.Iso8601Time `json:"entryTime"`
+       Name           string           `gorm:"index;type:varchar(255)"`
+       Phone          string           `gorm:"type:varchar(100)"`
+       Title          string           `gorm:"type:varchar(255)"`
+       Pinyin         string           `gorm:"type:varchar(255)"`
+       Py             string           `gorm:"type:varchar(255)"`
+       StaffType      string           `gorm:"type:varchar(255)"`
+       EmployeeNumber string           `gorm:"type:varchar(100)"`
+
+       archived.NoPKModel
+}
+
+func (TeambitionAccount) TableName() string {
+       return "_tool_teambition_accounts"
+}
diff --git 
a/backend/plugins/pagerduty/models/migrationscripts/archived/transformation_rules.go
 b/backend/plugins/teambition/models/migrationscripts/archived/connection.go
similarity index 70%
copy from 
backend/plugins/pagerduty/models/migrationscripts/archived/transformation_rules.go
copy to 
backend/plugins/teambition/models/migrationscripts/archived/connection.go
index 2da5581fb..8300023e6 100644
--- 
a/backend/plugins/pagerduty/models/migrationscripts/archived/transformation_rules.go
+++ b/backend/plugins/teambition/models/migrationscripts/archived/connection.go
@@ -17,14 +17,16 @@ limitations under the License.
 
 package archived
 
-import "github.com/apache/incubator-devlake/core/models/common"
-
-type TransformationRules struct {
-       common.Model
-       Name         string 
`gorm:"type:varchar(255);index:idx_name_github,unique"`
-       ConnectionId uint64
+type TeambitionConnection struct {
+       Endpoint         string
+       Proxy            string
+       RateLimitPerHour int
+       AppId            string
+       SecretKey        string `gorm:"serializer:encdec"`
+       TenantId         string
+       TenantType       string
 }
 
-func (*TransformationRules) TableName() string {
-       return "_tool_pagerduty_transformation_rules"
+func (TeambitionConnection) TableName() string {
+       return "_tool_teambition_connections"
 }
diff --git a/backend/plugins/pagerduty/models/migrationscripts/archived/user.go 
b/backend/plugins/teambition/models/migrationscripts/archived/input.go
similarity index 71%
copy from backend/plugins/pagerduty/models/migrationscripts/archived/user.go
copy to backend/plugins/teambition/models/migrationscripts/archived/input.go
index af8033f83..4f18c9512 100644
--- a/backend/plugins/pagerduty/models/migrationscripts/archived/user.go
+++ b/backend/plugins/teambition/models/migrationscripts/archived/input.go
@@ -18,17 +18,10 @@ limitations under the License.
 package archived
 
 import (
-       "github.com/apache/incubator-devlake/core/models/common"
+       "time"
 )
 
-type User struct {
-       common.NoPKModel
-       ConnectionId uint64 `gorm:"primaryKey"`
-       Id           string `gorm:"primaryKey;autoIncremental:false"`
-       Url          string
-       Name         string
-}
-
-func (User) TableName() string {
-       return "_tool_pagerduty_users"
+type Input struct {
+       TaskId  string
+       Updated *time.Time
 }
diff --git 
a/backend/plugins/teambition/models/migrationscripts/archived/project.go 
b/backend/plugins/teambition/models/migrationscripts/archived/project.go
new file mode 100644
index 000000000..fd0eccb14
--- /dev/null
+++ b/backend/plugins/teambition/models/migrationscripts/archived/project.go
@@ -0,0 +1,61 @@
+/*
+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 archived
+
+import (
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+)
+
+type TeambitionProject struct {
+       ConnectionId   uint64 `gorm:"primaryKey;type:BIGINT"`
+       Id             string `gorm:"primaryKey;type:varchar(100)"`
+       Name           string `gorm:"type:varchar(255)"`
+       Logo           string `gorm:"type:varchar(255)"`
+       Description    string `gorm:"type:text"`
+       OrganizationId string `gorm:"type:varchar(255)"`
+       Visibility     string `gorm:"typechar(100)"`
+       IsTemplate     bool
+       CreatorId      string `gorm:"type:varchar(100)"`
+       IsArchived     bool
+       IsSuspended    bool
+       UniqueIdPrefix string `gorm:"type:varchar(255)"`
+       Created        *api.Iso8601Time
+       Updated        *api.Iso8601Time
+       StartDate      *api.Iso8601Time
+       EndDate        *api.Iso8601Time
+       Customfields   []TeambitionProjectCustomField 
`gorm:"serializer:json;type:text"`
+
+       archived.NoPKModel
+}
+
+type TeambitionProjectCustomField struct {
+       CustomfieldId string                       `json:"customfieldId"`
+       Type          string                       `json:"type"`
+       Value         []TeambitionCustomFieldValue `json:"value"`
+}
+
+type TeambitionProjectCustomFieldValue struct {
+       Id         string `json:"id"`
+       Title      string `json:"title"`
+       MetaString string `json:"metaString"`
+}
+
+func (TeambitionProject) TableName() string {
+       return "_tool_teambition_projects"
+}
diff --git a/backend/plugins/zentao/models/archived/execution_summary.go 
b/backend/plugins/teambition/models/migrationscripts/archived/sprint.go
similarity index 54%
copy from backend/plugins/zentao/models/archived/execution_summary.go
copy to backend/plugins/teambition/models/migrationscripts/archived/sprint.go
index 308085ddd..1b0b541ef 100644
--- a/backend/plugins/zentao/models/archived/execution_summary.go
+++ b/backend/plugins/teambition/models/migrationscripts/archived/sprint.go
@@ -19,18 +19,29 @@ package archived
 
 import (
        
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 )
 
-type ZentaoExecutionSummary struct {
-       ConnectionId uint64 `gorm:"primaryKey;type:BIGINT  NOT NULL"`
-       Id           int64  `gorm:"primaryKey;type:BIGINT  NOT 
NULL;autoIncrement:false"`
+type TeambitionSprint struct {
+       ConnectionId uint64 `gorm:"primaryKey;type:BIGINT"`
+       Id           string `gorm:"primaryKey;type:varchar(100)"`
        Name         string `gorm:"type:varchar(255)"`
-       Project      int64
-       Code         string `gorm:"type:varchar(255)"`
-       Type         string `gorm:"type:varchar(255)"`
+       ExecutorId   string `gorm:"type:varchar(100)"`
+       Description  string `gorm:"type:text"`
+       Status       string `gorm:"varchar(255)"`
+       ProjectId    string `gorm:"type:varchar(100)"`
+       CreatorId    string `gorm:"type:varchar(100)"`
+       StartDate    *api.Iso8601Time
+       DueDate      *api.Iso8601Time
+       Accomplished *api.Iso8601Time
+       Created      *api.Iso8601Time
+       Updated      *api.Iso8601Time
+       Payload      any      `gorm:"serializer:json;type:text"`
+       Labels       []string `gorm:"serializer:json;type:text"`
+
        archived.NoPKModel
 }
 
-func (ZentaoExecutionSummary) TableName() string {
-       return "_tool_zentao_execution_summary"
+func (TeambitionSprint) TableName() string {
+       return "_tool_teambition_sprints"
 }
diff --git 
a/backend/plugins/teambition/models/migrationscripts/archived/task.go 
b/backend/plugins/teambition/models/migrationscripts/archived/task.go
new file mode 100644
index 000000000..7faad9efc
--- /dev/null
+++ b/backend/plugins/teambition/models/migrationscripts/archived/task.go
@@ -0,0 +1,75 @@
+/*
+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 archived
+
+import (
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+)
+
+type TeambitionTask struct {
+       ConnectionId   uint64   `gorm:"primaryKey;type:BIGINT"`
+       ProjectId      string   `gorm:"primaryKey;type:varchar(100)"`
+       Id             string   `gorm:"primaryKey;type:varchar(100)"`
+       Content        string   `gorm:"type:varchar(255)"`
+       Note           string   `gorm:"type:varchar(255)"`
+       AncestorIds    []string `gorm:"serializer:json;type:text"`
+       ParentTaskId   string   `gorm:"type:varchar(100)"`
+       TfsId          string   `gorm:"type:varchar(100)"`
+       TasklistId     string   `gorm:"type:varchar(100)"`
+       StageId        string   `gorm:"type:varchar(100)"`
+       TagIds         []string `gorm:"serializer:json;type:text"`
+       CreatorId      string   `gorm:"type:varchar(100)"`
+       ExecutorId     string   `gorm:"type:varchar(100)"`
+       InvolveMembers []string `gorm:"serializer:json;type:text"`
+       Priority       int
+       StoryPoint     string   `gorm:"varchar(255)"`
+       Recurrence     []string `gorm:"serializer:json;type:text"`
+       IsDone         bool
+       IsArchived     bool
+       Visible        string `gorm:"varchar(100)"`
+       UniqueId       int64
+       StartDate      *api.Iso8601Time
+       DueDate        *api.Iso8601Time
+       AccomplishTime *api.Iso8601Time
+       Created        *api.Iso8601Time
+       Updated        *api.Iso8601Time
+       SfcId          string                  `gorm:"type:varchar(100)"`
+       SprintId       string                  `gorm:"type:varchar(100)"`
+       Customfields   []TeambitionCustomField 
`gorm:"serializer:json;type:text"`
+
+       StdType   string `gorm:"type:varchar(100)"`
+       StdStatus string `gorm:"type:varchar(100)"`
+
+       archived.NoPKModel
+}
+
+type TeambitionCustomField struct {
+       CfId string `gorm:"varchar(100)"`
+       Type string `gorm:"varchar(100)"`
+}
+
+type TeambitionCustomFieldValue struct {
+       Id         string `gorm:"varchar(100)"`
+       Title      string `gorm:"varchar(100)"`
+       MetaString string `gorm:"varchar(100)"`
+}
+
+func (TeambitionTask) TableName() string {
+       return "_tool_teambition_tasks"
+}
diff --git a/backend/plugins/zentao/models/archived/product_summary.go 
b/backend/plugins/teambition/models/migrationscripts/archived/task_activity.go
similarity index 53%
copy from backend/plugins/zentao/models/archived/product_summary.go
copy to 
backend/plugins/teambition/models/migrationscripts/archived/task_activity.go
index 6b603e947..25071db8a 100644
--- a/backend/plugins/zentao/models/archived/product_summary.go
+++ 
b/backend/plugins/teambition/models/migrationscripts/archived/task_activity.go
@@ -19,16 +19,25 @@ package archived
 
 import (
        
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 )
 
-type ZentaoProductSummary struct {
+type TeambitionTaskActivity struct {
+       ConnectionId      uint64 `gorm:"primaryKey;type:BIGINT"`
+       Id                string `gorm:"primaryKey;type:varchar(100)"`
+       ProjectId         string `gorm:"primaryKey;type:varchar(100)"`
+       TaskId            string `gorm:"primaryKey;type:varchar(100)"`
+       CreatorId         string `gorm:"type:varchar(100)"`
+       Action            string `gorm:"type:varchar(100)"`
+       BoundToObjectId   string `gorm:"type:varchar(100)"`
+       BoundToObjectType string `gorm:"type:varchar(100)"`
+       CreateTime        *api.Iso8601Time
+       UpdateTime        *api.Iso8601Time
+       Content           string `gorm:"type:text"`
+
        archived.NoPKModel
-       ConnectionId uint64 `gorm:"primaryKey"`
-       ProjectId    int64  `gorm:"primaryKey"`
-       Id           int64  `gorm:"primaryKey;autoIncrement:false"`
-       Name         string `gorm:"type:VARCHAR(255)"`
 }
 
-func (ZentaoProductSummary) TableName() string {
-       return "_tool_zentao_product_summary"
+func (TeambitionTaskActivity) TableName() string {
+       return "_tool_teambition_task_activities"
 }
diff --git 
a/backend/plugins/pagerduty/models/migrationscripts/archived/transformation_rules.go
 b/backend/plugins/teambition/models/migrationscripts/archived/task_comment.go
similarity index 71%
copy from 
backend/plugins/pagerduty/models/migrationscripts/archived/transformation_rules.go
copy to 
backend/plugins/teambition/models/migrationscripts/archived/task_comment.go
index 2da5581fb..69787cef7 100644
--- 
a/backend/plugins/pagerduty/models/migrationscripts/archived/transformation_rules.go
+++ 
b/backend/plugins/teambition/models/migrationscripts/archived/task_comment.go
@@ -17,14 +17,11 @@ limitations under the License.
 
 package archived
 
-import "github.com/apache/incubator-devlake/core/models/common"
-
-type TransformationRules struct {
-       common.Model
-       Name         string 
`gorm:"type:varchar(255);index:idx_name_github,unique"`
-       ConnectionId uint64
-}
-
-func (*TransformationRules) TableName() string {
-       return "_tool_pagerduty_transformation_rules"
+type TeambitionTaskComment struct {
+       Comment              string
+       IsOnlyNotifyMentions bool
+       IsDingtalkPM         bool
+       RenderMode           string
+       Attachments          []string
+       DingFiles            []string
 }
diff --git 
a/backend/plugins/teambition/models/migrationscripts/archived/task_flow_status.go
 
b/backend/plugins/teambition/models/migrationscripts/archived/task_flow_status.go
new file mode 100644
index 000000000..4186501bc
--- /dev/null
+++ 
b/backend/plugins/teambition/models/migrationscripts/archived/task_flow_status.go
@@ -0,0 +1,45 @@
+/*
+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 archived
+
+import (
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+)
+
+type TeambitionTaskFlowStatus struct {
+       ConnectionId                uint64 `gorm:"primaryKey;type:BIGINT"`
+       ProjectId                   string `gorm:"primaryKey;type:varchar(100)"`
+       Id                          string `gorm:"primaryKey;type:varchar(100)"`
+       Name                        string `gorm:"type:varchar(100)"`
+       Pos                         int64
+       TaskflowId                  string   `gorm:"type:varchar(100)"`
+       RejectStatusIds             []string `gorm:"serializer:json;type:text"`
+       Kind                        string   `gorm:"varchar(100)"`
+       CreatorId                   string   `gorm:"varchar(100)"`
+       IsDeleted                   bool
+       IsTaskflowstatusruleexector bool
+       Created                     *api.Iso8601Time
+       Updated                     *api.Iso8601Time
+
+       archived.NoPKModel
+}
+
+func (TeambitionTaskFlowStatus) TableName() string {
+       return "_tool_teambition_task_flow_status"
+}
diff --git 
a/backend/plugins/teambition/models/migrationscripts/archived/task_scenario.go 
b/backend/plugins/teambition/models/migrationscripts/archived/task_scenario.go
new file mode 100644
index 000000000..b6c7e6936
--- /dev/null
+++ 
b/backend/plugins/teambition/models/migrationscripts/archived/task_scenario.go
@@ -0,0 +1,53 @@
+/*
+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 archived
+
+import (
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+)
+
+type TeambitionTaskScenario struct {
+       ConnectionId      uint64                    
`gorm:"primaryKey;type:BIGINT"`
+       ProjectId         string                    
`gorm:"primaryKey;type:varchar(100)"`
+       Id                string                    
`gorm:"primaryKey;type:varchar(100)"`
+       Name              string                    `gorm:"type:varchar(100)"`
+       Icon              string                    `gorm:"type:varchar(100)"`
+       Type              string                    `gorm:"type:varchar(100)"`
+       Scenariofields    []TeambitionScenarioField 
`gorm:"serializer:json;type:text"`
+       CreatorId         string                    `gorm:"type:varchar(100)"`
+       Source            string                    `gorm:"type:varchar(100)"`
+       BoundToObjectId   string                    `gorm:"type:varchar(100)"`
+       BoundToObjectType string                    `gorm:"type:varchar(100)"`
+       TaskflowId        string                    `gorm:"type:varchar(100)"`
+       IsArchived        bool
+       Created           *api.Iso8601Time
+       Updated           *api.Iso8601Time
+
+       archived.NoPKModel
+}
+
+type TeambitionScenarioField struct {
+       CustomfieldId string
+       FieldType     string
+       Required      bool
+}
+
+func (TeambitionTaskScenario) TableName() string {
+       return "_tool_teambition_task_scenarios"
+}
diff --git a/backend/plugins/zentao/models/archived/product_summary.go 
b/backend/plugins/teambition/models/migrationscripts/archived/task_tag.go
similarity index 58%
copy from backend/plugins/zentao/models/archived/product_summary.go
copy to backend/plugins/teambition/models/migrationscripts/archived/task_tag.go
index 6b603e947..fe1a63699 100644
--- a/backend/plugins/zentao/models/archived/product_summary.go
+++ b/backend/plugins/teambition/models/migrationscripts/archived/task_tag.go
@@ -19,16 +19,24 @@ package archived
 
 import (
        
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 )
 
-type ZentaoProductSummary struct {
+type TeambitionTaskTag struct {
+       ConnectionId   uint64 `gorm:"primaryKey;type:BIGINT"`
+       Id             string `gorm:"primaryKey;type:varchar(100)"`
+       CreatorId      string `gorm:"type:varchar(100)"`
+       ProjectId      string `gorm:"type:varchar(100)"`
+       OrganizationId string `gorm:"type:varchar(100)"`
+       Name           string `gorm:"type:varchar(100)"`
+       Color          string `gorm:"type:varchar(100)"`
+       IsArchived     bool
+       Created        *api.Iso8601Time
+       Updated        *api.Iso8601Time
+
        archived.NoPKModel
-       ConnectionId uint64 `gorm:"primaryKey"`
-       ProjectId    int64  `gorm:"primaryKey"`
-       Id           int64  `gorm:"primaryKey;autoIncrement:false"`
-       Name         string `gorm:"type:VARCHAR(255)"`
 }
 
-func (ZentaoProductSummary) TableName() string {
-       return "_tool_zentao_product_summary"
+func (TeambitionTaskTag) TableName() string {
+       return "_tool_teambition_task_tags"
 }
diff --git a/backend/plugins/zentao/models/archived/execution_stories.go 
b/backend/plugins/teambition/models/migrationscripts/archived/task_tag_task.go
similarity index 68%
copy from backend/plugins/zentao/models/archived/execution_stories.go
copy to 
backend/plugins/teambition/models/migrationscripts/archived/task_tag_task.go
index 8b818f0b7..784dae6d9 100644
--- a/backend/plugins/zentao/models/archived/execution_stories.go
+++ 
b/backend/plugins/teambition/models/migrationscripts/archived/task_tag_task.go
@@ -21,14 +21,16 @@ import (
        
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
 )
 
-type ZentaoExecutionStory struct {
+type TeambitionTaskTagTask struct {
+       ConnectionId uint64 `gorm:"primaryKey;type:BIGINT"`
+       ProjectId    string `gorm:"primaryKey;type:varchar(100)"`
+       TaskId       string `gorm:"primaryKey;type:varchar(100)"`
+       TaskTagId    string `gorm:"primaryKey;type:varchar(100)"`
+       Name         string `gorm:"type:varchar(100)"`
+
        archived.NoPKModel
-       ConnectionId uint64 `gorm:"primaryKey"`
-       ProjectId    int64  `gorm:"primaryKey"`
-       ExecutionId  int64  `gorm:"primaryKey"`
-       StoryId      int64  `gorm:"primaryKey"`
 }
 
-func (ZentaoExecutionStory) TableName() string {
-       return "_tool_zentao_execution_stories"
+func (TeambitionTaskTagTask) TableName() string {
+       return "_tool_teambition_task_tag_tasks"
 }
diff --git a/backend/plugins/zentao/models/archived/department.go 
b/backend/plugins/teambition/models/migrationscripts/archived/task_worktime.go
similarity index 52%
copy from backend/plugins/zentao/models/archived/department.go
copy to 
backend/plugins/teambition/models/migrationscripts/archived/task_worktime.go
index 3c35039c7..dcdf65ab6 100644
--- a/backend/plugins/zentao/models/archived/department.go
+++ 
b/backend/plugins/teambition/models/migrationscripts/archived/task_worktime.go
@@ -19,23 +19,28 @@ package archived
 
 import (
        
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 )
 
-type ZentaoDepartment struct {
-       ConnectionId uint64 `gorm:"primaryKey;type:BIGINT  NOT NULL"`
-       ID           int64  `json:"id" gorm:"primaryKey;type:BIGINT  NOT 
NULL;autoIncrement:false" `
-       Name         string `json:"name" gorm:"type:varchar(100);index"`
-       Parent       int    `json:"parent" gorm:"type:BIGINT  NOT NULL"`
-       Path         string `json:"path" gorm:"type:varchar(100)"`
-       Grade        int    `json:"grade"`
-       OrderIn      int    `json:"order"`
-       Position     string `json:"position" gorm:"type:varchar(100)"`
-       DeptFunction string `json:"function" gorm:"type:varchar(100)"`
-       Manager      string `json:"manager" gorm:"type:varchar(100)"`
-       ManagerName  string `json:"managerName" gorm:"type:varchar(100)"`
+type TeambitionTaskWorktime struct {
+       ConnectionId uint64 `gorm:"primaryKey;type:BIGINT"`
+       ProjectId    string `gorm:"primaryKey;type:varchar(100)"`
+       TaskId       string `gorm:"primaryKey;type:varchar(100)"`
+       WorktimeId   string `gorm:"primaryKey;type:varchar(100)"`
+       ObjectType   string `gorm:"type:varchar(100)"`
+       ObjectId     string `gorm:"type:varchar(100)"`
+       Worktime     uint64
+       UserId       string `gorm:"type:varchar(100)"`
+       Date         *api.Iso8601Time
+       Description  string `gorm:"type:text"`
+       OrgId        string `gorm:"type:varchar(100)"`
+       SubmitterId  string `gorm:"type:varchar(100)"`
+       CreatedAt    *api.Iso8601Time
+       UpdatedAt    *api.Iso8601Time
+
        archived.NoPKModel
 }
 
-func (ZentaoDepartment) TableName() string {
-       return "_tool_zentao_departments"
+func (TeambitionTaskWorktime) TableName() string {
+       return "_tool_teambition_task_worktime"
 }
diff --git 
a/backend/plugins/zentao/models/migrationscripts/20221121_add_init_tables.go 
b/backend/plugins/zentao/models/migrationscripts/20221121_add_init_tables.go
index 0ad604909..7845f775c 100644
--- a/backend/plugins/zentao/models/migrationscripts/20221121_add_init_tables.go
+++ b/backend/plugins/zentao/models/migrationscripts/20221121_add_init_tables.go
@@ -21,7 +21,7 @@ import (
        "github.com/apache/incubator-devlake/core/context"
        "github.com/apache/incubator-devlake/core/errors"
        "github.com/apache/incubator-devlake/helpers/migrationhelper"
-       "github.com/apache/incubator-devlake/plugins/zentao/models/archived"
+       
"github.com/apache/incubator-devlake/plugins/zentao/models/migrationscripts/archived"
 )
 
 type addInitTables struct{}
diff --git 
a/backend/plugins/zentao/models/migrationscripts/20230601_add_scope_config.go 
b/backend/plugins/zentao/models/migrationscripts/20230601_add_scope_config.go
index e00be67bc..38b0f4f4f 100644
--- 
a/backend/plugins/zentao/models/migrationscripts/20230601_add_scope_config.go
+++ 
b/backend/plugins/zentao/models/migrationscripts/20230601_add_scope_config.go
@@ -21,7 +21,7 @@ import (
        "github.com/apache/incubator-devlake/core/context"
        "github.com/apache/incubator-devlake/core/errors"
        "github.com/apache/incubator-devlake/helpers/migrationhelper"
-       "github.com/apache/incubator-devlake/plugins/zentao/models/archived"
+       
"github.com/apache/incubator-devlake/plugins/zentao/models/migrationscripts/archived"
 )
 
 type addScopeConfigTables struct{}
diff --git 
a/backend/plugins/zentao/models/migrationscripts/20230605_add_issue_repo_commits.go
 
b/backend/plugins/zentao/models/migrationscripts/20230605_add_issue_repo_commits.go
index a50cb4aba..004d665ee 100644
--- 
a/backend/plugins/zentao/models/migrationscripts/20230605_add_issue_repo_commits.go
+++ 
b/backend/plugins/zentao/models/migrationscripts/20230605_add_issue_repo_commits.go
@@ -21,7 +21,7 @@ import (
        "github.com/apache/incubator-devlake/core/context"
        "github.com/apache/incubator-devlake/core/errors"
        "github.com/apache/incubator-devlake/helpers/migrationhelper"
-       "github.com/apache/incubator-devlake/plugins/zentao/models/archived"
+       
"github.com/apache/incubator-devlake/plugins/zentao/models/migrationscripts/archived"
 )
 
 type addIssueRepoCommitsTables struct{}
diff --git 
a/backend/plugins/zentao/models/migrationscripts/20230608_add_init_changelog_tables.go
 
b/backend/plugins/zentao/models/migrationscripts/20230608_add_init_changelog_tables.go
index ffd4f25f7..1d44e517c 100644
--- 
a/backend/plugins/zentao/models/migrationscripts/20230608_add_init_changelog_tables.go
+++ 
b/backend/plugins/zentao/models/migrationscripts/20230608_add_init_changelog_tables.go
@@ -21,7 +21,7 @@ import (
        "github.com/apache/incubator-devlake/core/context"
        "github.com/apache/incubator-devlake/core/errors"
        "github.com/apache/incubator-devlake/helpers/migrationhelper"
-       "github.com/apache/incubator-devlake/plugins/zentao/models/archived"
+       
"github.com/apache/incubator-devlake/plugins/zentao/models/migrationscripts/archived"
 )
 
 type addInitChangelogTables struct{}
diff --git 
a/backend/plugins/zentao/models/migrationscripts/20230705_add_execution_stories.go
 
b/backend/plugins/zentao/models/migrationscripts/20230705_add_execution_stories.go
index 234451cf3..41ac0f695 100644
--- 
a/backend/plugins/zentao/models/migrationscripts/20230705_add_execution_stories.go
+++ 
b/backend/plugins/zentao/models/migrationscripts/20230705_add_execution_stories.go
@@ -21,7 +21,7 @@ import (
        "github.com/apache/incubator-devlake/core/context"
        "github.com/apache/incubator-devlake/core/errors"
        "github.com/apache/incubator-devlake/helpers/migrationhelper"
-       "github.com/apache/incubator-devlake/plugins/zentao/models/archived"
+       
"github.com/apache/incubator-devlake/plugins/zentao/models/migrationscripts/archived"
 )
 
 type addExecutionStoryAndExecutionSummary struct{}
diff --git a/backend/plugins/zentao/models/archived/account.go 
b/backend/plugins/zentao/models/migrationscripts/archived/account.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/account.go
rename to backend/plugins/zentao/models/migrationscripts/archived/account.go
diff --git a/backend/plugins/zentao/models/archived/bug.go 
b/backend/plugins/zentao/models/migrationscripts/archived/bug.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/bug.go
rename to backend/plugins/zentao/models/migrationscripts/archived/bug.go
diff --git a/backend/plugins/zentao/models/archived/bug_commits.go 
b/backend/plugins/zentao/models/migrationscripts/archived/bug_commits.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/bug_commits.go
rename to backend/plugins/zentao/models/migrationscripts/archived/bug_commits.go
diff --git a/backend/plugins/zentao/models/archived/changelog.go 
b/backend/plugins/zentao/models/migrationscripts/archived/changelog.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/changelog.go
rename to backend/plugins/zentao/models/migrationscripts/archived/changelog.go
diff --git a/backend/plugins/zentao/models/archived/connection.go 
b/backend/plugins/zentao/models/migrationscripts/archived/connection.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/connection.go
rename to backend/plugins/zentao/models/migrationscripts/archived/connection.go
diff --git a/backend/plugins/zentao/models/archived/department.go 
b/backend/plugins/zentao/models/migrationscripts/archived/department.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/department.go
rename to backend/plugins/zentao/models/migrationscripts/archived/department.go
diff --git a/backend/plugins/zentao/models/archived/execution.go 
b/backend/plugins/zentao/models/migrationscripts/archived/execution.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/execution.go
rename to backend/plugins/zentao/models/migrationscripts/archived/execution.go
diff --git a/backend/plugins/zentao/models/archived/execution_stories.go 
b/backend/plugins/zentao/models/migrationscripts/archived/execution_stories.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/execution_stories.go
rename to 
backend/plugins/zentao/models/migrationscripts/archived/execution_stories.go
diff --git a/backend/plugins/zentao/models/archived/execution_summary.go 
b/backend/plugins/zentao/models/migrationscripts/archived/execution_summary.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/execution_summary.go
rename to 
backend/plugins/zentao/models/migrationscripts/archived/execution_summary.go
diff --git a/backend/plugins/zentao/models/archived/product.go 
b/backend/plugins/zentao/models/migrationscripts/archived/product.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/product.go
rename to backend/plugins/zentao/models/migrationscripts/archived/product.go
diff --git a/backend/plugins/zentao/models/archived/product_summary.go 
b/backend/plugins/zentao/models/migrationscripts/archived/product_summary.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/product_summary.go
rename to 
backend/plugins/zentao/models/migrationscripts/archived/product_summary.go
diff --git a/backend/plugins/zentao/models/archived/project.go 
b/backend/plugins/zentao/models/migrationscripts/archived/project.go
similarity index 57%
rename from backend/plugins/zentao/models/archived/project.go
rename to backend/plugins/zentao/models/migrationscripts/archived/project.go
index e8aa1eba9..5c7418577 100644
--- a/backend/plugins/zentao/models/archived/project.go
+++ b/backend/plugins/zentao/models/migrationscripts/archived/project.go
@@ -18,44 +18,44 @@ limitations under the License.
 package archived
 
 import (
-       "github.com/apache/incubator-devlake/core/models/common"
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
        helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 )
 
 type ZentaoProject struct {
-       common.NoPKModel `json:"-"`
-       ConnectionId     uint64              `json:"connectionid" 
mapstructure:"connectionid" gorm:"primaryKey;type:BIGINT  NOT NULL"`
-       Id               int64               `json:"id" mapstructure:"id" 
gorm:"primaryKey;type:BIGINT  NOT NULL;autoIncrement:false"`
-       Project          int64               `json:"project" 
mapstructure:"project"`
-       Model            string              `json:"model" mapstructure:"model"`
-       Type             string              `json:"type" mapstructure:"type"`
-       ProjectType      string              `json:"projectType" 
mapstructure:"projectType"`
-       Lifetime         string              `json:"lifetime" 
mapstructure:"lifetime"`
-       Budget           string              `json:"budget" 
mapstructure:"budget"`
-       BudgetUnit       string              `json:"budgetUnit" 
mapstructure:"budgetUnit"`
-       Attribute        string              `json:"attribute" 
mapstructure:"attribute"`
-       Percent          int                 `json:"percent" 
mapstructure:"percent"`
-       Milestone        string              `json:"milestone" 
mapstructure:"milestone"`
-       Output           string              `json:"output" 
mapstructure:"output"`
-       Auth             string              `json:"auth" mapstructure:"auth"`
-       Parent           int64               `json:"parent" 
mapstructure:"parent"`
-       Path             string              `json:"path" mapstructure:"path"`
-       Grade            int                 `json:"grade" mapstructure:"grade"`
-       Name             string              `json:"name" mapstructure:"name"`
-       Code             string              `json:"code" mapstructure:"code"`
-       PlanBegin        *helper.Iso8601Time `json:"begin" mapstructure:"begin"`
-       PlanEnd          *helper.Iso8601Time `json:"end" mapstructure:"end"`
-       RealBegan        *helper.Iso8601Time `json:"realBegan" 
mapstructure:"realBegan"`
-       RealEnd          *helper.Iso8601Time `json:"realEnd" 
mapstructure:"realEnd"`
-       Days             int                 `json:"days" mapstructure:"days"`
-       Status           string              `json:"status" 
mapstructure:"status"`
-       SubStatus        string              `json:"subStatus" 
mapstructure:"subStatus"`
-       Pri              string              `json:"pri" mapstructure:"pri"`
-       Description      string              `json:"desc" mapstructure:"desc"`
-       Version          int                 `json:"version" 
mapstructure:"version"`
-       ParentVersion    int                 `json:"parentVersion" 
mapstructure:"parentVersion"`
-       PlanDuration     int                 `json:"planDuration" 
mapstructure:"planDuration"`
-       RealDuration     int                 `json:"realDuration" 
mapstructure:"realDuration"`
+       archived.NoPKModel `json:"-"`
+       ConnectionId       uint64              `json:"connectionid" 
mapstructure:"connectionid" gorm:"primaryKey;type:BIGINT  NOT NULL"`
+       Id                 int64               `json:"id" mapstructure:"id" 
gorm:"primaryKey;type:BIGINT  NOT NULL;autoIncrement:false"`
+       Project            int64               `json:"project" 
mapstructure:"project"`
+       Model              string              `json:"model" 
mapstructure:"model"`
+       Type               string              `json:"type" mapstructure:"type"`
+       ProjectType        string              `json:"projectType" 
mapstructure:"projectType"`
+       Lifetime           string              `json:"lifetime" 
mapstructure:"lifetime"`
+       Budget             string              `json:"budget" 
mapstructure:"budget"`
+       BudgetUnit         string              `json:"budgetUnit" 
mapstructure:"budgetUnit"`
+       Attribute          string              `json:"attribute" 
mapstructure:"attribute"`
+       Percent            int                 `json:"percent" 
mapstructure:"percent"`
+       Milestone          string              `json:"milestone" 
mapstructure:"milestone"`
+       Output             string              `json:"output" 
mapstructure:"output"`
+       Auth               string              `json:"auth" mapstructure:"auth"`
+       Parent             int64               `json:"parent" 
mapstructure:"parent"`
+       Path               string              `json:"path" mapstructure:"path"`
+       Grade              int                 `json:"grade" 
mapstructure:"grade"`
+       Name               string              `json:"name" mapstructure:"name"`
+       Code               string              `json:"code" mapstructure:"code"`
+       PlanBegin          *helper.Iso8601Time `json:"begin" 
mapstructure:"begin"`
+       PlanEnd            *helper.Iso8601Time `json:"end" mapstructure:"end"`
+       RealBegan          *helper.Iso8601Time `json:"realBegan" 
mapstructure:"realBegan"`
+       RealEnd            *helper.Iso8601Time `json:"realEnd" 
mapstructure:"realEnd"`
+       Days               int                 `json:"days" mapstructure:"days"`
+       Status             string              `json:"status" 
mapstructure:"status"`
+       SubStatus          string              `json:"subStatus" 
mapstructure:"subStatus"`
+       Pri                string              `json:"pri" mapstructure:"pri"`
+       Description        string              `json:"desc" mapstructure:"desc"`
+       Version            int                 `json:"version" 
mapstructure:"version"`
+       ParentVersion      int                 `json:"parentVersion" 
mapstructure:"parentVersion"`
+       PlanDuration       int                 `json:"planDuration" 
mapstructure:"planDuration"`
+       RealDuration       int                 `json:"realDuration" 
mapstructure:"realDuration"`
        //OpenedBy       string    `json:"openedBy" mapstructure:"openedBy"`
        OpenedDate    *helper.Iso8601Time `json:"openedDate" 
mapstructure:"openedDate"`
        OpenedVersion string              `json:"openedVersion" 
mapstructure:"openedVersion"`
diff --git a/backend/plugins/zentao/models/archived/project_stories.go 
b/backend/plugins/zentao/models/migrationscripts/archived/project_stories.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/project_stories.go
rename to 
backend/plugins/zentao/models/migrationscripts/archived/project_stories.go
diff --git a/backend/plugins/zentao/models/archived/scope_config.go 
b/backend/plugins/zentao/models/migrationscripts/archived/scope_config.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/scope_config.go
rename to 
backend/plugins/zentao/models/migrationscripts/archived/scope_config.go
diff --git a/backend/plugins/zentao/models/archived/story.go 
b/backend/plugins/zentao/models/migrationscripts/archived/story.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/story.go
rename to backend/plugins/zentao/models/migrationscripts/archived/story.go
diff --git a/backend/plugins/zentao/models/archived/story_commits.go 
b/backend/plugins/zentao/models/migrationscripts/archived/story_commits.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/story_commits.go
rename to 
backend/plugins/zentao/models/migrationscripts/archived/story_commits.go
diff --git a/backend/plugins/zentao/models/archived/task.go 
b/backend/plugins/zentao/models/migrationscripts/archived/task.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/task.go
rename to backend/plugins/zentao/models/migrationscripts/archived/task.go
diff --git a/backend/plugins/zentao/models/archived/task_commits.go 
b/backend/plugins/zentao/models/migrationscripts/archived/task_commits.go
similarity index 100%
rename from backend/plugins/zentao/models/archived/task_commits.go
rename to 
backend/plugins/zentao/models/migrationscripts/archived/task_commits.go

Reply via email to