0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-16 19:07:41 +02:00
- 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:
silverwind 2026-04-27 12:19:57 +02:00 committed by beardev-in
parent 45832f4d68
commit 438f367ab3
No known key found for this signature in database
GPG Key ID: 625E0CB70AFF32B9
5 changed files with 35 additions and 93 deletions

View File

@ -9,7 +9,7 @@ import (
"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) {
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) {
columns := make([]*Column, 0, 5)
columns := make([]*Column, 0, len(columnsIDs))
if len(columnsIDs) == 0 {
return columns, nil
}

View File

@ -10,51 +10,36 @@ import (
// Project represents a project
// swagger:model
type Project struct {
// Unique identifier of the project
ID int64 `json:"id"`
// Project title
Title string `json:"title"`
// Project description
ID int64 `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
// Owner ID (for organization or user projects)
OwnerID int64 `json:"owner_id,omitempty"`
// Repository ID (for repository projects)
RepoID int64 `json:"repo_id,omitempty"`
// Creator ID
CreatorID int64 `json:"creator_id"`
// Whether the project is closed
IsClosed bool `json:"is_closed"`
OwnerID int64 `json:"owner_id,omitempty"`
RepoID int64 `json:"repo_id,omitempty"`
CreatorID int64 `json:"creator_id"`
IsClosed bool `json:"is_closed"`
// Template type: 0=none, 1=basic_kanban, 2=bug_triage
TemplateType int `json:"template_type"`
// Card type: 0=text_only, 1=images_and_text
CardType int `json:"card_type"`
// Project type: 1=individual, 2=repository, 3=organization
Type int `json:"type"`
// Number of open issues
NumOpenIssues int64 `json:"num_open_issues,omitempty"`
// Number of closed issues
Type int `json:"type"`
NumOpenIssues int64 `json:"num_open_issues,omitempty"`
NumClosedIssues int64 `json:"num_closed_issues,omitempty"`
// Total number of issues
NumIssues int64 `json:"num_issues,omitempty"`
// Created time
NumIssues int64 `json:"num_issues,omitempty"`
// swagger:strfmt date-time
Created time.Time `json:"created"`
// Updated time
// swagger:strfmt date-time
Updated time.Time `json:"updated"`
// Closed time
// swagger:strfmt date-time
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
// swagger:model
type CreateProjectOption struct {
// required: true
Title string `json:"title" binding:"Required"`
// Project description
Title string `json:"title" binding:"Required"`
Description string `json:"description"`
// Template type: 0=none, 1=basic_kanban, 2=bug_triage
TemplateType int `json:"template_type"`
@ -65,9 +50,7 @@ type CreateProjectOption struct {
// EditProjectOption represents options for editing a project
// swagger:model
type EditProjectOption struct {
// Project title
Title *string `json:"title,omitempty"`
// Project description
Title *string `json:"title,omitempty"`
Description *string `json:"description,omitempty"`
// Card type: 0=text_only, 1=images_and_text
CardType *int `json:"card_type,omitempty"`
@ -78,26 +61,16 @@ type EditProjectOption struct {
// ProjectColumn represents a project column (board)
// swagger:model
type ProjectColumn struct {
// Unique identifier of the column
ID int64 `json:"id"`
// Column title
Title string `json:"title"`
// Whether this is the default column
Default bool `json:"default"`
// Sorting order
Sorting int `json:"sorting"`
// 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
ID int64 `json:"id"`
Title string `json:"title"`
Default bool `json:"default"`
Sorting int `json:"sorting"`
Color string `json:"color,omitempty"`
ProjectID int64 `json:"project_id"`
CreatorID int64 `json:"creator_id"`
NumIssues int64 `json:"num_issues,omitempty"`
// swagger:strfmt date-time
Created time.Time `json:"created"`
// Updated time
// swagger:strfmt date-time
Updated time.Time `json:"updated"`
}
@ -107,17 +80,15 @@ type ProjectColumn struct {
type CreateProjectColumnOption struct {
// required: true
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"`
}
// EditProjectColumnOption represents options for editing a project column
// swagger:model
type EditProjectColumnOption struct {
// Column title
Title *string `json:"title,omitempty"`
// Column color (hex format)
Color *string `json:"color,omitempty"`
// Sorting order
Sorting *int `json:"sorting,omitempty"`
Color *string `json:"color,omitempty"`
Sorting *int `json:"sorting,omitempty"`
}

View File

@ -118,6 +118,9 @@ func ListProjects(ctx *context.APIContext) {
return
}
for _, p := range projects {
p.Repo = ctx.Repo.Repository
}
apiProjects := convert.ToProjectList(ctx, projects)
ctx.SetLinkHeader(count, listOptions.PageSize)
@ -217,6 +220,7 @@ func CreateProject(ctx *context.APIContext) {
return
}
p.Repo = ctx.Repo.Repository
ctx.JSON(http.StatusCreated, convert.ToProject(ctx, p))
}

View File

@ -35,15 +35,11 @@ func ToProject(ctx context.Context, p *project_model.Project) *api.Project {
project.ClosedDate = &t
}
// Generate project URL
if p.Type == project_model.TypeRepository && p.RepoID > 0 {
if err := p.LoadRepo(ctx); err == nil && p.Repo != nil {
project.URL = project_model.ProjectLinkForRepo(p.Repo, 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)
}
// Repo/Owner are expected to be preloaded by the caller to avoid N+1 lookups.
if p.Type == project_model.TypeRepository && p.Repo != nil {
project.URL = project_model.ProjectLinkForRepo(p.Repo, p.ID)
} else if p.Owner != nil {
project.URL = project_model.ProjectLinkForOrg(p.Owner, p.ID)
}
return project

View File

@ -24160,7 +24160,7 @@
],
"properties": {
"color": {
"description": "Column color (hex format, e.g., #FF0000)",
"description": "Column color (hex format, e.g. #FF0000)",
"type": "string",
"x-go-name": "Color"
},
@ -24185,7 +24185,6 @@
"x-go-name": "CardType"
},
"description": {
"description": "Project description",
"type": "string",
"x-go-name": "Description"
},
@ -25332,13 +25331,11 @@
"x-go-name": "Color"
},
"sorting": {
"description": "Sorting order",
"type": "integer",
"format": "int64",
"x-go-name": "Sorting"
},
"title": {
"description": "Column title",
"type": "string",
"x-go-name": "Title"
}
@ -25356,7 +25353,6 @@
"x-go-name": "CardType"
},
"description": {
"description": "Project description",
"type": "string",
"x-go-name": "Description"
},
@ -25366,7 +25362,6 @@
"x-go-name": "State"
},
"title": {
"description": "Project title",
"type": "string",
"x-go-name": "Title"
}
@ -28081,65 +28076,54 @@
"x-go-name": "CardType"
},
"closed_date": {
"description": "Closed time",
"type": "string",
"format": "date-time",
"x-go-name": "ClosedDate"
},
"created": {
"description": "Created time",
"type": "string",
"format": "date-time",
"x-go-name": "Created"
},
"creator_id": {
"description": "Creator ID",
"type": "integer",
"format": "int64",
"x-go-name": "CreatorID"
},
"description": {
"description": "Project description",
"type": "string",
"x-go-name": "Description"
},
"id": {
"description": "Unique identifier of the project",
"type": "integer",
"format": "int64",
"x-go-name": "ID"
},
"is_closed": {
"description": "Whether the project is closed",
"type": "boolean",
"x-go-name": "IsClosed"
},
"num_closed_issues": {
"description": "Number of closed issues",
"type": "integer",
"format": "int64",
"x-go-name": "NumClosedIssues"
},
"num_issues": {
"description": "Total number of issues",
"type": "integer",
"format": "int64",
"x-go-name": "NumIssues"
},
"num_open_issues": {
"description": "Number of open issues",
"type": "integer",
"format": "int64",
"x-go-name": "NumOpenIssues"
},
"owner_id": {
"description": "Owner ID (for organization or user projects)",
"type": "integer",
"format": "int64",
"x-go-name": "OwnerID"
},
"repo_id": {
"description": "Repository ID (for repository projects)",
"type": "integer",
"format": "int64",
"x-go-name": "RepoID"
@ -28151,7 +28135,6 @@
"x-go-name": "TemplateType"
},
"title": {
"description": "Project title",
"type": "string",
"x-go-name": "Title"
},
@ -28162,13 +28145,11 @@
"x-go-name": "Type"
},
"updated": {
"description": "Updated time",
"type": "string",
"format": "date-time",
"x-go-name": "Updated"
},
"url": {
"description": "Project URL",
"type": "string",
"x-go-name": "URL"
}
@ -28180,58 +28161,48 @@
"type": "object",
"properties": {
"color": {
"description": "Column color (hex format)",
"type": "string",
"x-go-name": "Color"
},
"created": {
"description": "Created time",
"type": "string",
"format": "date-time",
"x-go-name": "Created"
},
"creator_id": {
"description": "Creator ID",
"type": "integer",
"format": "int64",
"x-go-name": "CreatorID"
},
"default": {
"description": "Whether this is the default column",
"type": "boolean",
"x-go-name": "Default"
},
"id": {
"description": "Unique identifier of the column",
"type": "integer",
"format": "int64",
"x-go-name": "ID"
},
"num_issues": {
"description": "Number of issues in this column",
"type": "integer",
"format": "int64",
"x-go-name": "NumIssues"
},
"project_id": {
"description": "Project ID",
"type": "integer",
"format": "int64",
"x-go-name": "ProjectID"
},
"sorting": {
"description": "Sorting order",
"type": "integer",
"format": "int64",
"x-go-name": "Sorting"
},
"title": {
"description": "Column title",
"type": "string",
"x-go-name": "Title"
},
"updated": {
"description": "Updated time",
"type": "string",
"format": "date-time",
"x-go-name": "Updated"