klesh commented on code in PR #3679:
URL: 
https://github.com/apache/incubator-devlake/pull/3679#discussion_r1023470327


##########
api/plugininfo/plugininifo.go:
##########
@@ -178,3 +180,47 @@ func Get(c *gin.Context) {
 
        shared.ApiOutputSuccess(c, info, http.StatusOK)
 }
+
+// @Get name list of plugins
+// @Description GET /plugins
+// @Description RETURN SAMPLE
+// @Tags framework/plugins
+// @Success 200

Review Comment:
   We should define a struct for the API Response and append it to the 200 
response



##########
services/project.go:
##########
@@ -0,0 +1,157 @@
+/*
+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 services
+
+import (
+       "github.com/apache/incubator-devlake/errors"
+       "github.com/apache/incubator-devlake/models"
+       "github.com/apache/incubator-devlake/plugins/helper"
+)
+
+// ProjectQuery used to query projects as the api project input
+type ProjectQuery struct {
+       Page     int `form:"page"`
+       PageSize int `form:"pageSize"`
+}
+
+// CreateProject accepts a project instance and insert it to database
+func CreateProject(project *models.Project) errors.Error {
+       enProject, err := encryptProject(project)

Review Comment:
   Why? does a project have any encrypted field? If not, the `xxxxDbProject` 
functions are also unnecessary.



##########
api/plugininfo/plugininifo.go:
##########
@@ -178,3 +180,47 @@ func Get(c *gin.Context) {
 
        shared.ApiOutputSuccess(c, info, http.StatusOK)
 }
+
+// @Get name list of plugins
+// @Description GET /plugins
+// @Description RETURN SAMPLE
+// @Tags framework/plugins
+// @Success 200
+// @Failure 400  {string} errcode.Error "Bad Request"
+// @Router /plugins [get]
+func GetPluginNames(c *gin.Context) {

Review Comment:
   The function name is not accurate, maybe `GetPluginMetas`?



##########
services/project_helper.go:
##########
@@ -0,0 +1,170 @@
+/*
+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 services
+
+import (
+       goerror "errors"
+       "fmt"
+
+       "github.com/apache/incubator-devlake/config"
+       "github.com/apache/incubator-devlake/errors"
+       "github.com/apache/incubator-devlake/models"
+       "github.com/apache/incubator-devlake/plugins/core"
+       "gorm.io/gorm"
+)
+
+// CreateDbProject accepts a project instance and insert it to database
+func CreateDbProject(project *models.Project) errors.Error {
+       err := db.Create(project).Error
+       if err != nil {
+               return errors.Default.Wrap(err, "error creating DB project")
+       }
+       return nil
+}
+
+// CreateDbProjectMetric accepts a project metric instance and insert it to 
database
+func CreateDbProjectMetric(projectMetric *models.ProjectMetric) errors.Error {
+       err := db.Create(projectMetric).Error
+       if err != nil {
+               return errors.Default.Wrap(err, "error creating DB project 
metric")
+       }
+       return nil
+}
+
+// SaveDbProject save a project instance and update it to database
+func SaveDbProject(project *models.Project) errors.Error {
+       err := db.Save(project).Error
+       if err != nil {
+               return errors.Default.Wrap(err, "error saving DB project")
+       }
+       return nil
+}
+
+// SaveDbProjectMetric save a project instance and update it to database
+func SaveDbProjectMetric(projectMetric *models.ProjectMetric) errors.Error {
+       err := db.Save(projectMetric).Error
+       if err != nil {
+               return errors.Default.Wrap(err, "error saving DB project 
metric")
+       }
+       return nil
+}
+
+// GetDbProjects returns a paginated list of Project based on `query`
+func GetDbProjects(query *ProjectQuery) ([]*models.Project, int64, 
errors.Error) {
+       projects := make([]*models.Project, 0)
+       db := db.Model(projects).Order("created_at desc")
+
+       var count int64
+       err := db.Count(&count).Error
+       if err != nil {
+               return nil, 0, errors.Default.Wrap(err, "error getting DB count 
of project")
+       }
+       db = processDbClausesWithPager(db, query.PageSize, query.Page)
+
+       err = db.Find(&projects).Error
+       if err != nil {
+               return nil, 0, errors.Default.Wrap(err, "error finding DB 
project")
+       }
+
+       return projects, count, nil
+}
+
+// GetDbProject returns the detail of a given project name
+func GetDbProject(name string) (*models.Project, errors.Error) {
+       project := &models.Project{}
+       project.Name = name
+
+       err := db.First(project).Error
+       if err != nil {
+               if goerror.Is(err, gorm.ErrRecordNotFound) {
+                       return nil, errors.NotFound.Wrap(err, 
fmt.Sprintf("could not find project [%s] in DB", name))
+               }
+               return nil, errors.Default.Wrap(err, "error getting project 
from DB")
+       }
+
+       return project, nil
+}
+
+// GetDbProjectMetric returns the detail of a given project name
+func GetDbProjectMetric(projectName string, pluginName string) 
(*models.ProjectMetric, errors.Error) {
+       projectMetric := &models.ProjectMetric{}
+       projectMetric.ProjectName = projectName
+       projectMetric.PluginName = pluginName
+
+       err := db.First(projectMetric).Error
+       if err != nil {
+               if goerror.Is(err, gorm.ErrRecordNotFound) {
+                       return nil, errors.NotFound.Wrap(err, 
fmt.Sprintf("could not find project metric [%s][%s] in DB", projectName, 
pluginName))
+               }
+               return nil, errors.Default.Wrap(err, "error getting project 
metric from DB")
+       }
+
+       return projectMetric, nil
+}
+
+// encryptProject
+func encryptProject(project *models.Project) (*models.Project, errors.Error) {
+       encKey := config.GetConfig().GetString(core.EncodeKeyEnvStr)
+
+       describeEncrypt, err := core.Encrypt(encKey, project.Description)
+       if err != nil {
+               return nil, err
+       }
+       project.Description = describeEncrypt
+
+       return project, nil
+}
+
+// encryptProjectMetric
+func encryptProjectMetric(projectMetric *models.ProjectMetric) 
(*models.ProjectMetric, errors.Error) {
+       encKey := config.GetConfig().GetString(core.EncodeKeyEnvStr)
+
+       pluginOption, err := core.Encrypt(encKey, projectMetric.PluginOption)
+       if err != nil {
+               return nil, err
+       }
+       projectMetric.PluginOption = pluginOption
+
+       return projectMetric, nil
+}
+
+// decryptProject
+func decryptProject(project *models.Project) (*models.Project, errors.Error) {
+       encKey := config.GetConfig().GetString(core.EncodeKeyEnvStr)
+
+       describe, err := core.Decrypt(encKey, project.Description)

Review Comment:
   No... I don't think it needs to be encrypted either.



##########
models/migrationscripts/20221109_add_project_tables.go:
##########
@@ -0,0 +1,69 @@
+/*
+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/errors"
+       "github.com/apache/incubator-devlake/helpers/migrationhelper"
+       "github.com/apache/incubator-devlake/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/plugins/core"
+)
+
+var _ core.MigrationScript = (*addProjectTables)(nil)
+
+type addProjectTables struct{}
+
+type Project struct {
+       Name        string `gorm:"primaryKey;type:varchar(255)"`
+       Description string `gorm:"type:text"`
+
+       archived.NoPKModel
+}
+
+func (Project) TableName() string {
+       return "_devlake_projects"

Review Comment:
   No, it is `projects`, belongs to Domain Layer



##########
services/project_helper.go:
##########
@@ -0,0 +1,170 @@
+/*
+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 services
+
+import (
+       goerror "errors"
+       "fmt"
+
+       "github.com/apache/incubator-devlake/config"
+       "github.com/apache/incubator-devlake/errors"
+       "github.com/apache/incubator-devlake/models"
+       "github.com/apache/incubator-devlake/plugins/core"
+       "gorm.io/gorm"
+)
+
+// CreateDbProject accepts a project instance and insert it to database
+func CreateDbProject(project *models.Project) errors.Error {
+       err := db.Create(project).Error
+       if err != nil {
+               return errors.Default.Wrap(err, "error creating DB project")
+       }
+       return nil
+}
+
+// CreateDbProjectMetric accepts a project metric instance and insert it to 
database
+func CreateDbProjectMetric(projectMetric *models.ProjectMetric) errors.Error {
+       err := db.Create(projectMetric).Error
+       if err != nil {
+               return errors.Default.Wrap(err, "error creating DB project 
metric")
+       }
+       return nil
+}
+
+// SaveDbProject save a project instance and update it to database
+func SaveDbProject(project *models.Project) errors.Error {
+       err := db.Save(project).Error
+       if err != nil {
+               return errors.Default.Wrap(err, "error saving DB project")
+       }
+       return nil
+}
+
+// SaveDbProjectMetric save a project instance and update it to database
+func SaveDbProjectMetric(projectMetric *models.ProjectMetric) errors.Error {
+       err := db.Save(projectMetric).Error
+       if err != nil {
+               return errors.Default.Wrap(err, "error saving DB project 
metric")
+       }
+       return nil
+}
+
+// GetDbProjects returns a paginated list of Project based on `query`
+func GetDbProjects(query *ProjectQuery) ([]*models.Project, int64, 
errors.Error) {
+       projects := make([]*models.Project, 0)
+       db := db.Model(projects).Order("created_at desc")
+
+       var count int64
+       err := db.Count(&count).Error
+       if err != nil {
+               return nil, 0, errors.Default.Wrap(err, "error getting DB count 
of project")
+       }
+       db = processDbClausesWithPager(db, query.PageSize, query.Page)
+
+       err = db.Find(&projects).Error
+       if err != nil {
+               return nil, 0, errors.Default.Wrap(err, "error finding DB 
project")
+       }
+
+       return projects, count, nil
+}
+
+// GetDbProject returns the detail of a given project name
+func GetDbProject(name string) (*models.Project, errors.Error) {
+       project := &models.Project{}
+       project.Name = name
+
+       err := db.First(project).Error
+       if err != nil {
+               if goerror.Is(err, gorm.ErrRecordNotFound) {
+                       return nil, errors.NotFound.Wrap(err, 
fmt.Sprintf("could not find project [%s] in DB", name))
+               }
+               return nil, errors.Default.Wrap(err, "error getting project 
from DB")
+       }
+
+       return project, nil
+}
+
+// GetDbProjectMetric returns the detail of a given project name
+func GetDbProjectMetric(projectName string, pluginName string) 
(*models.ProjectMetric, errors.Error) {
+       projectMetric := &models.ProjectMetric{}
+       projectMetric.ProjectName = projectName
+       projectMetric.PluginName = pluginName
+
+       err := db.First(projectMetric).Error
+       if err != nil {
+               if goerror.Is(err, gorm.ErrRecordNotFound) {
+                       return nil, errors.NotFound.Wrap(err, 
fmt.Sprintf("could not find project metric [%s][%s] in DB", projectName, 
pluginName))
+               }
+               return nil, errors.Default.Wrap(err, "error getting project 
metric from DB")
+       }
+
+       return projectMetric, nil
+}
+
+// encryptProject
+func encryptProject(project *models.Project) (*models.Project, errors.Error) {
+       encKey := config.GetConfig().GetString(core.EncodeKeyEnvStr)
+
+       describeEncrypt, err := core.Encrypt(encKey, project.Description)
+       if err != nil {
+               return nil, err
+       }
+       project.Description = describeEncrypt
+
+       return project, nil
+}
+
+// encryptProjectMetric
+func encryptProjectMetric(projectMetric *models.ProjectMetric) 
(*models.ProjectMetric, errors.Error) {
+       encKey := config.GetConfig().GetString(core.EncodeKeyEnvStr)
+
+       pluginOption, err := core.Encrypt(encKey, projectMetric.PluginOption)
+       if err != nil {
+               return nil, err
+       }
+       projectMetric.PluginOption = pluginOption
+
+       return projectMetric, nil
+}
+
+// decryptProject
+func decryptProject(project *models.Project) (*models.Project, errors.Error) {
+       encKey := config.GetConfig().GetString(core.EncodeKeyEnvStr)
+
+       describe, err := core.Decrypt(encKey, project.Description)
+       if err != nil {
+               return nil, err
+       }
+       project.Description = describe
+
+       return project, nil
+}
+
+// decryptProjectMetric
+func decryptProjectMetric(projectMetric *models.ProjectMetric) 
(*models.ProjectMetric, errors.Error) {
+       encKey := config.GetConfig().GetString(core.EncodeKeyEnvStr)
+
+       pluginOption, err := core.Decrypt(encKey, projectMetric.PluginOption)

Review Comment:
   I don't think this field would contain sensitive information.



##########
services/project_helper.go:
##########
@@ -0,0 +1,170 @@
+/*
+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 services

Review Comment:
   Not necessary



##########
models/migrationscripts/20221109_add_project_tables.go:
##########
@@ -0,0 +1,69 @@
+/*
+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/errors"
+       "github.com/apache/incubator-devlake/helpers/migrationhelper"
+       "github.com/apache/incubator-devlake/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/plugins/core"
+)
+
+var _ core.MigrationScript = (*addProjectTables)(nil)
+
+type addProjectTables struct{}
+
+type Project struct {
+       Name        string `gorm:"primaryKey;type:varchar(255)"`
+       Description string `gorm:"type:text"`
+
+       archived.NoPKModel
+}
+
+func (Project) TableName() string {
+       return "_devlake_projects"
+}
+
+type ProjectMetric struct {
+       ProjectName  string `gorm:"primaryKey;type:varchar(255)"`
+       PluginName   string `gorm:"primaryKey;type:varchar(255)"`
+       PluginOption string `gorm:"type:text"`
+
+       archived.NoPKModel
+}
+
+func (ProjectMetric) TableName() string {
+       return "_devlake_project_metrics"

Review Comment:
   Same as above



##########
api/project/project.go:
##########
@@ -0,0 +1,235 @@
+/*
+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 project
+
+import (
+       "net/http"
+
+       "github.com/apache/incubator-devlake/api/shared"
+       "github.com/apache/incubator-devlake/errors"
+       "github.com/apache/incubator-devlake/models"
+       "github.com/apache/incubator-devlake/services"
+       "github.com/gin-gonic/gin"
+)
+
+// @Summary Create and run a new project
+// @Description Create and run a new project
+// @Tags framework/projects
+// @Accept application/json
+// @Param project body models.Project true "json"
+// @Success 200  {object} models.Project
+// @Failure 400  {string} errcode.Error "Bad Request"
+// @Failure 500  {string} errcode.Error "Internal Error"
+// @Router /projects/:projectName [get]
+func GetProject(c *gin.Context) {
+       projectName := c.Param("projectName")
+
+       project, err := services.GetProject(projectName)
+       if err != nil {
+               shared.ApiOutputError(c, errors.Default.Wrap(err, "error 
getting project"))
+               return
+       }
+
+       shared.ApiOutputSuccess(c, project, http.StatusOK)
+}
+
+// @Summary Get list of projects
+// @Description GET /projects?page=1&pagesize=10
+// @Tags framework/projects
+// @Param page query int true "query"
+// @Param pagesize query int true "query"
+// @Success 200  {object} gin.H

Review Comment:
   No, define a struct for that, make sure the swag web page could show the 
correct response example.  `git.H` is obviously incorrect. 



##########
services/project.go:
##########
@@ -0,0 +1,157 @@
+/*
+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 services
+
+import (
+       "github.com/apache/incubator-devlake/errors"
+       "github.com/apache/incubator-devlake/models"
+       "github.com/apache/incubator-devlake/plugins/helper"
+)
+
+// ProjectQuery used to query projects as the api project input
+type ProjectQuery struct {
+       Page     int `form:"page"`
+       PageSize int `form:"pageSize"`
+}
+
+// CreateProject accepts a project instance and insert it to database
+func CreateProject(project *models.Project) errors.Error {
+       enProject, err := encryptProject(project)

Review Comment:
   Same to the below APIs



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to