mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-17 10:13:37 +02:00
Simplify
- Drop lazy LoadRepo/LoadOwner in convert.ToProject; rely on caller preloading. ListProjects sets Repo from ctx.Repo.Repository on each project; CreateProject does the same on the new project. Avoids N+1 queries for repo-scoped list endpoints. - Strip redundant API struct field comments that just restate the field name; keep the ones that document enum values. - Pre-allocate GetColumnsByIDs result slice with len(columnsIDs). - Fix CountProjectColumns doc comment (was "CountColumns"). Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
This commit is contained in:
parent
45832f4d68
commit
438f367ab3
@ -9,7 +9,7 @@ import (
|
|||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CountColumns returns the total number of columns for a project
|
// CountProjectColumns returns the total number of columns for a project
|
||||||
func CountProjectColumns(ctx context.Context, projectID int64) (int64, error) {
|
func CountProjectColumns(ctx context.Context, projectID int64) (int64, error) {
|
||||||
return db.GetEngine(ctx).Where("project_id=?", projectID).Count(&Column{})
|
return db.GetEngine(ctx).Where("project_id=?", projectID).Count(&Column{})
|
||||||
}
|
}
|
||||||
@ -28,7 +28,7 @@ func GetProjectColumns(ctx context.Context, projectID int64, opts db.ListOptions
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetColumnsByIDs(ctx context.Context, projectID int64, columnsIDs []int64) (ColumnList, error) {
|
func GetColumnsByIDs(ctx context.Context, projectID int64, columnsIDs []int64) (ColumnList, error) {
|
||||||
columns := make([]*Column, 0, 5)
|
columns := make([]*Column, 0, len(columnsIDs))
|
||||||
if len(columnsIDs) == 0 {
|
if len(columnsIDs) == 0 {
|
||||||
return columns, nil
|
return columns, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,51 +10,36 @@ import (
|
|||||||
// Project represents a project
|
// Project represents a project
|
||||||
// swagger:model
|
// swagger:model
|
||||||
type Project struct {
|
type Project struct {
|
||||||
// Unique identifier of the project
|
ID int64 `json:"id"`
|
||||||
ID int64 `json:"id"`
|
Title string `json:"title"`
|
||||||
// Project title
|
|
||||||
Title string `json:"title"`
|
|
||||||
// Project description
|
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
// Owner ID (for organization or user projects)
|
OwnerID int64 `json:"owner_id,omitempty"`
|
||||||
OwnerID int64 `json:"owner_id,omitempty"`
|
RepoID int64 `json:"repo_id,omitempty"`
|
||||||
// Repository ID (for repository projects)
|
CreatorID int64 `json:"creator_id"`
|
||||||
RepoID int64 `json:"repo_id,omitempty"`
|
IsClosed bool `json:"is_closed"`
|
||||||
// Creator ID
|
|
||||||
CreatorID int64 `json:"creator_id"`
|
|
||||||
// Whether the project is closed
|
|
||||||
IsClosed bool `json:"is_closed"`
|
|
||||||
// Template type: 0=none, 1=basic_kanban, 2=bug_triage
|
// Template type: 0=none, 1=basic_kanban, 2=bug_triage
|
||||||
TemplateType int `json:"template_type"`
|
TemplateType int `json:"template_type"`
|
||||||
// Card type: 0=text_only, 1=images_and_text
|
// Card type: 0=text_only, 1=images_and_text
|
||||||
CardType int `json:"card_type"`
|
CardType int `json:"card_type"`
|
||||||
// Project type: 1=individual, 2=repository, 3=organization
|
// Project type: 1=individual, 2=repository, 3=organization
|
||||||
Type int `json:"type"`
|
Type int `json:"type"`
|
||||||
// Number of open issues
|
NumOpenIssues int64 `json:"num_open_issues,omitempty"`
|
||||||
NumOpenIssues int64 `json:"num_open_issues,omitempty"`
|
|
||||||
// Number of closed issues
|
|
||||||
NumClosedIssues int64 `json:"num_closed_issues,omitempty"`
|
NumClosedIssues int64 `json:"num_closed_issues,omitempty"`
|
||||||
// Total number of issues
|
NumIssues int64 `json:"num_issues,omitempty"`
|
||||||
NumIssues int64 `json:"num_issues,omitempty"`
|
|
||||||
// Created time
|
|
||||||
// swagger:strfmt date-time
|
// swagger:strfmt date-time
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
// Updated time
|
|
||||||
// swagger:strfmt date-time
|
// swagger:strfmt date-time
|
||||||
Updated time.Time `json:"updated"`
|
Updated time.Time `json:"updated"`
|
||||||
// Closed time
|
|
||||||
// swagger:strfmt date-time
|
// swagger:strfmt date-time
|
||||||
ClosedDate *time.Time `json:"closed_date,omitempty"`
|
ClosedDate *time.Time `json:"closed_date,omitempty"`
|
||||||
// Project URL
|
URL string `json:"url,omitempty"`
|
||||||
URL string `json:"url,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateProjectOption represents options for creating a project
|
// CreateProjectOption represents options for creating a project
|
||||||
// swagger:model
|
// swagger:model
|
||||||
type CreateProjectOption struct {
|
type CreateProjectOption struct {
|
||||||
// required: true
|
// required: true
|
||||||
Title string `json:"title" binding:"Required"`
|
Title string `json:"title" binding:"Required"`
|
||||||
// Project description
|
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
// Template type: 0=none, 1=basic_kanban, 2=bug_triage
|
// Template type: 0=none, 1=basic_kanban, 2=bug_triage
|
||||||
TemplateType int `json:"template_type"`
|
TemplateType int `json:"template_type"`
|
||||||
@ -65,9 +50,7 @@ type CreateProjectOption struct {
|
|||||||
// EditProjectOption represents options for editing a project
|
// EditProjectOption represents options for editing a project
|
||||||
// swagger:model
|
// swagger:model
|
||||||
type EditProjectOption struct {
|
type EditProjectOption struct {
|
||||||
// Project title
|
Title *string `json:"title,omitempty"`
|
||||||
Title *string `json:"title,omitempty"`
|
|
||||||
// Project description
|
|
||||||
Description *string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
// Card type: 0=text_only, 1=images_and_text
|
// Card type: 0=text_only, 1=images_and_text
|
||||||
CardType *int `json:"card_type,omitempty"`
|
CardType *int `json:"card_type,omitempty"`
|
||||||
@ -78,26 +61,16 @@ type EditProjectOption struct {
|
|||||||
// ProjectColumn represents a project column (board)
|
// ProjectColumn represents a project column (board)
|
||||||
// swagger:model
|
// swagger:model
|
||||||
type ProjectColumn struct {
|
type ProjectColumn struct {
|
||||||
// Unique identifier of the column
|
ID int64 `json:"id"`
|
||||||
ID int64 `json:"id"`
|
Title string `json:"title"`
|
||||||
// Column title
|
Default bool `json:"default"`
|
||||||
Title string `json:"title"`
|
Sorting int `json:"sorting"`
|
||||||
// Whether this is the default column
|
Color string `json:"color,omitempty"`
|
||||||
Default bool `json:"default"`
|
ProjectID int64 `json:"project_id"`
|
||||||
// Sorting order
|
CreatorID int64 `json:"creator_id"`
|
||||||
Sorting int `json:"sorting"`
|
NumIssues int64 `json:"num_issues,omitempty"`
|
||||||
// Column color (hex format)
|
|
||||||
Color string `json:"color,omitempty"`
|
|
||||||
// Project ID
|
|
||||||
ProjectID int64 `json:"project_id"`
|
|
||||||
// Creator ID
|
|
||||||
CreatorID int64 `json:"creator_id"`
|
|
||||||
// Number of issues in this column
|
|
||||||
NumIssues int64 `json:"num_issues,omitempty"`
|
|
||||||
// Created time
|
|
||||||
// swagger:strfmt date-time
|
// swagger:strfmt date-time
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
// Updated time
|
|
||||||
// swagger:strfmt date-time
|
// swagger:strfmt date-time
|
||||||
Updated time.Time `json:"updated"`
|
Updated time.Time `json:"updated"`
|
||||||
}
|
}
|
||||||
@ -107,17 +80,15 @@ type ProjectColumn struct {
|
|||||||
type CreateProjectColumnOption struct {
|
type CreateProjectColumnOption struct {
|
||||||
// required: true
|
// required: true
|
||||||
Title string `json:"title" binding:"Required"`
|
Title string `json:"title" binding:"Required"`
|
||||||
// Column color (hex format, e.g., #FF0000)
|
// Column color (hex format, e.g. #FF0000)
|
||||||
Color string `json:"color,omitempty"`
|
Color string `json:"color,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditProjectColumnOption represents options for editing a project column
|
// EditProjectColumnOption represents options for editing a project column
|
||||||
// swagger:model
|
// swagger:model
|
||||||
type EditProjectColumnOption struct {
|
type EditProjectColumnOption struct {
|
||||||
// Column title
|
|
||||||
Title *string `json:"title,omitempty"`
|
Title *string `json:"title,omitempty"`
|
||||||
// Column color (hex format)
|
// Column color (hex format)
|
||||||
Color *string `json:"color,omitempty"`
|
Color *string `json:"color,omitempty"`
|
||||||
// Sorting order
|
Sorting *int `json:"sorting,omitempty"`
|
||||||
Sorting *int `json:"sorting,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,6 +118,9 @@ func ListProjects(ctx *context.APIContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, p := range projects {
|
||||||
|
p.Repo = ctx.Repo.Repository
|
||||||
|
}
|
||||||
apiProjects := convert.ToProjectList(ctx, projects)
|
apiProjects := convert.ToProjectList(ctx, projects)
|
||||||
|
|
||||||
ctx.SetLinkHeader(count, listOptions.PageSize)
|
ctx.SetLinkHeader(count, listOptions.PageSize)
|
||||||
@ -217,6 +220,7 @@ func CreateProject(ctx *context.APIContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.Repo = ctx.Repo.Repository
|
||||||
ctx.JSON(http.StatusCreated, convert.ToProject(ctx, p))
|
ctx.JSON(http.StatusCreated, convert.ToProject(ctx, p))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,15 +35,11 @@ func ToProject(ctx context.Context, p *project_model.Project) *api.Project {
|
|||||||
project.ClosedDate = &t
|
project.ClosedDate = &t
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate project URL
|
// Repo/Owner are expected to be preloaded by the caller to avoid N+1 lookups.
|
||||||
if p.Type == project_model.TypeRepository && p.RepoID > 0 {
|
if p.Type == project_model.TypeRepository && p.Repo != nil {
|
||||||
if err := p.LoadRepo(ctx); err == nil && p.Repo != nil {
|
project.URL = project_model.ProjectLinkForRepo(p.Repo, p.ID)
|
||||||
project.URL = project_model.ProjectLinkForRepo(p.Repo, p.ID)
|
} else if p.Owner != nil {
|
||||||
}
|
project.URL = project_model.ProjectLinkForOrg(p.Owner, p.ID)
|
||||||
} else if p.OwnerID > 0 {
|
|
||||||
if err := p.LoadOwner(ctx); err == nil && p.Owner != nil {
|
|
||||||
project.URL = project_model.ProjectLinkForOrg(p.Owner, p.ID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return project
|
return project
|
||||||
|
|||||||
31
templates/swagger/v1_json.tmpl
generated
31
templates/swagger/v1_json.tmpl
generated
@ -24160,7 +24160,7 @@
|
|||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"color": {
|
"color": {
|
||||||
"description": "Column color (hex format, e.g., #FF0000)",
|
"description": "Column color (hex format, e.g. #FF0000)",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Color"
|
"x-go-name": "Color"
|
||||||
},
|
},
|
||||||
@ -24185,7 +24185,6 @@
|
|||||||
"x-go-name": "CardType"
|
"x-go-name": "CardType"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Project description",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Description"
|
"x-go-name": "Description"
|
||||||
},
|
},
|
||||||
@ -25332,13 +25331,11 @@
|
|||||||
"x-go-name": "Color"
|
"x-go-name": "Color"
|
||||||
},
|
},
|
||||||
"sorting": {
|
"sorting": {
|
||||||
"description": "Sorting order",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "Sorting"
|
"x-go-name": "Sorting"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"description": "Column title",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Title"
|
"x-go-name": "Title"
|
||||||
}
|
}
|
||||||
@ -25356,7 +25353,6 @@
|
|||||||
"x-go-name": "CardType"
|
"x-go-name": "CardType"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Project description",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Description"
|
"x-go-name": "Description"
|
||||||
},
|
},
|
||||||
@ -25366,7 +25362,6 @@
|
|||||||
"x-go-name": "State"
|
"x-go-name": "State"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"description": "Project title",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Title"
|
"x-go-name": "Title"
|
||||||
}
|
}
|
||||||
@ -28081,65 +28076,54 @@
|
|||||||
"x-go-name": "CardType"
|
"x-go-name": "CardType"
|
||||||
},
|
},
|
||||||
"closed_date": {
|
"closed_date": {
|
||||||
"description": "Closed time",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "date-time",
|
"format": "date-time",
|
||||||
"x-go-name": "ClosedDate"
|
"x-go-name": "ClosedDate"
|
||||||
},
|
},
|
||||||
"created": {
|
"created": {
|
||||||
"description": "Created time",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "date-time",
|
"format": "date-time",
|
||||||
"x-go-name": "Created"
|
"x-go-name": "Created"
|
||||||
},
|
},
|
||||||
"creator_id": {
|
"creator_id": {
|
||||||
"description": "Creator ID",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "CreatorID"
|
"x-go-name": "CreatorID"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Project description",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Description"
|
"x-go-name": "Description"
|
||||||
},
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"description": "Unique identifier of the project",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "ID"
|
"x-go-name": "ID"
|
||||||
},
|
},
|
||||||
"is_closed": {
|
"is_closed": {
|
||||||
"description": "Whether the project is closed",
|
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"x-go-name": "IsClosed"
|
"x-go-name": "IsClosed"
|
||||||
},
|
},
|
||||||
"num_closed_issues": {
|
"num_closed_issues": {
|
||||||
"description": "Number of closed issues",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "NumClosedIssues"
|
"x-go-name": "NumClosedIssues"
|
||||||
},
|
},
|
||||||
"num_issues": {
|
"num_issues": {
|
||||||
"description": "Total number of issues",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "NumIssues"
|
"x-go-name": "NumIssues"
|
||||||
},
|
},
|
||||||
"num_open_issues": {
|
"num_open_issues": {
|
||||||
"description": "Number of open issues",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "NumOpenIssues"
|
"x-go-name": "NumOpenIssues"
|
||||||
},
|
},
|
||||||
"owner_id": {
|
"owner_id": {
|
||||||
"description": "Owner ID (for organization or user projects)",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "OwnerID"
|
"x-go-name": "OwnerID"
|
||||||
},
|
},
|
||||||
"repo_id": {
|
"repo_id": {
|
||||||
"description": "Repository ID (for repository projects)",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "RepoID"
|
"x-go-name": "RepoID"
|
||||||
@ -28151,7 +28135,6 @@
|
|||||||
"x-go-name": "TemplateType"
|
"x-go-name": "TemplateType"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"description": "Project title",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Title"
|
"x-go-name": "Title"
|
||||||
},
|
},
|
||||||
@ -28162,13 +28145,11 @@
|
|||||||
"x-go-name": "Type"
|
"x-go-name": "Type"
|
||||||
},
|
},
|
||||||
"updated": {
|
"updated": {
|
||||||
"description": "Updated time",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "date-time",
|
"format": "date-time",
|
||||||
"x-go-name": "Updated"
|
"x-go-name": "Updated"
|
||||||
},
|
},
|
||||||
"url": {
|
"url": {
|
||||||
"description": "Project URL",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "URL"
|
"x-go-name": "URL"
|
||||||
}
|
}
|
||||||
@ -28180,58 +28161,48 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"color": {
|
"color": {
|
||||||
"description": "Column color (hex format)",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Color"
|
"x-go-name": "Color"
|
||||||
},
|
},
|
||||||
"created": {
|
"created": {
|
||||||
"description": "Created time",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "date-time",
|
"format": "date-time",
|
||||||
"x-go-name": "Created"
|
"x-go-name": "Created"
|
||||||
},
|
},
|
||||||
"creator_id": {
|
"creator_id": {
|
||||||
"description": "Creator ID",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "CreatorID"
|
"x-go-name": "CreatorID"
|
||||||
},
|
},
|
||||||
"default": {
|
"default": {
|
||||||
"description": "Whether this is the default column",
|
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"x-go-name": "Default"
|
"x-go-name": "Default"
|
||||||
},
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"description": "Unique identifier of the column",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "ID"
|
"x-go-name": "ID"
|
||||||
},
|
},
|
||||||
"num_issues": {
|
"num_issues": {
|
||||||
"description": "Number of issues in this column",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "NumIssues"
|
"x-go-name": "NumIssues"
|
||||||
},
|
},
|
||||||
"project_id": {
|
"project_id": {
|
||||||
"description": "Project ID",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "ProjectID"
|
"x-go-name": "ProjectID"
|
||||||
},
|
},
|
||||||
"sorting": {
|
"sorting": {
|
||||||
"description": "Sorting order",
|
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "Sorting"
|
"x-go-name": "Sorting"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"description": "Column title",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Title"
|
"x-go-name": "Title"
|
||||||
},
|
},
|
||||||
"updated": {
|
"updated": {
|
||||||
"description": "Updated time",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "date-time",
|
"format": "date-time",
|
||||||
"x-go-name": "Updated"
|
"x-go-name": "Updated"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user