Better efficency for loading teams (#128)
Fix staticcheck Better performance for getting teams on a namespace Better performance for getting teams on a list Fix lint Fix swagger Signed-off-by: kolaente <k@knt.li> Make loading a single full team more efficent Signed-off-by: kolaente <k@knt.li> Make loading teams more efficent Signed-off-by: kolaente <k@knt.li> Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/api/pulls/128
This commit is contained in:
parent
2abb858859
commit
f603b41d99
10 changed files with 124 additions and 47 deletions
1
go.mod
1
go.mod
|
@ -58,6 +58,7 @@ require (
|
||||||
github.com/onsi/gomega v1.4.3 // indirect
|
github.com/onsi/gomega v1.4.3 // indirect
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/pelletier/go-toml v1.4.0 // indirect
|
github.com/pelletier/go-toml v1.4.0 // indirect
|
||||||
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/prometheus/client_golang v0.9.2
|
github.com/prometheus/client_golang v0.9.2
|
||||||
github.com/samedi/caldav-go v3.0.0+incompatible
|
github.com/samedi/caldav-go v3.0.0+incompatible
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b
|
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b
|
||||||
|
|
|
@ -186,6 +186,16 @@ func (tl *TeamList) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
||||||
return nil, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
teams := []*Team{}
|
||||||
|
for _, t := range all {
|
||||||
|
teams = append(teams, &t.Team)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = addMoreInfoToTeams(teams)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
totalItems, err = x.
|
totalItems, err = x.
|
||||||
Table("teams").
|
Table("teams").
|
||||||
Join("INNER", "team_list", "team_id = teams.id").
|
Join("INNER", "team_list", "team_id = teams.id").
|
||||||
|
|
|
@ -171,6 +171,16 @@ func (tn *TeamNamespace) ReadAll(a web.Auth, search string, page int, perPage in
|
||||||
return nil, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
teams := []*Team{}
|
||||||
|
for _, t := range all {
|
||||||
|
teams = append(teams, &t.Team)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = addMoreInfoToTeams(teams)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
numberOfTotalItems, err = x.Table("teams").
|
numberOfTotalItems, err = x.Table("teams").
|
||||||
Join("INNER", "team_namespaces", "team_id = teams.id").
|
Join("INNER", "team_namespaces", "team_id = teams.id").
|
||||||
Where("team_namespaces.namespace_id = ?", tn.NamespaceID).
|
Where("team_namespaces.namespace_id = ?", tn.NamespaceID).
|
||||||
|
|
|
@ -236,7 +236,7 @@ func (t *Task) addNewAssigneeByID(newAssigneeID int64, list *List) (err error) {
|
||||||
// @Param s query string false "Search assignees by their username."
|
// @Param s query string false "Search assignees by their username."
|
||||||
// @Param taskID path int true "Task ID"
|
// @Param taskID path int true "Task ID"
|
||||||
// @Security JWTKeyAuth
|
// @Security JWTKeyAuth
|
||||||
// @Success 200 {array} models.User "The assignees"
|
// @Success 200 {array} user.User "The assignees"
|
||||||
// @Failure 500 {object} models.Message "Internal error"
|
// @Failure 500 {object} models.Message "Internal error"
|
||||||
// @Router /tasks/{taskID}/assignees [get]
|
// @Router /tasks/{taskID}/assignees [get]
|
||||||
func (la *TaskAssginee) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, numberOfTotalItems int64, err error) {
|
func (la *TaskAssginee) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, numberOfTotalItems int64, err error) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"code.vikunja.io/api/pkg/metrics"
|
"code.vikunja.io/api/pkg/metrics"
|
||||||
"code.vikunja.io/api/pkg/user"
|
"code.vikunja.io/api/pkg/user"
|
||||||
"code.vikunja.io/web"
|
"code.vikunja.io/web"
|
||||||
|
"github.com/go-xorm/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Team holds a team object
|
// Team holds a team object
|
||||||
|
@ -53,15 +54,6 @@ func (Team) TableName() string {
|
||||||
|
|
||||||
// AfterLoad gets the created by user object
|
// AfterLoad gets the created by user object
|
||||||
func (t *Team) AfterLoad() {
|
func (t *Team) AfterLoad() {
|
||||||
// Get the owner
|
|
||||||
t.CreatedBy, _ = user.GetUserByID(t.CreatedByID)
|
|
||||||
|
|
||||||
// Get all members
|
|
||||||
x.Select("*").
|
|
||||||
Table("users").
|
|
||||||
Join("INNER", "team_members", "team_members.user_id = users.id").
|
|
||||||
Where("team_id = ?", t.ID).
|
|
||||||
Find(&t.Members)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TeamMember defines the relationship between a user and a team
|
// TeamMember defines the relationship between a user and a team
|
||||||
|
@ -93,23 +85,76 @@ func (TeamMember) TableName() string {
|
||||||
type TeamUser struct {
|
type TeamUser struct {
|
||||||
user.User `xorm:"extends"`
|
user.User `xorm:"extends"`
|
||||||
// Whether or not the member is an admin of the team. See the docs for more about what a team admin can do
|
// Whether or not the member is an admin of the team. See the docs for more about what a team admin can do
|
||||||
Admin bool `json:"admin"`
|
Admin bool `json:"admin"`
|
||||||
|
TeamID int64 `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTeamByID gets a team by its ID
|
// GetTeamByID gets a team by its ID
|
||||||
func GetTeamByID(id int64) (team Team, err error) {
|
func GetTeamByID(id int64) (team *Team, err error) {
|
||||||
if id < 1 {
|
if id < 1 {
|
||||||
return team, ErrTeamDoesNotExist{id}
|
return team, ErrTeamDoesNotExist{id}
|
||||||
}
|
}
|
||||||
|
|
||||||
exists, err := x.Where("id = ?", id).Get(&team)
|
t := Team{}
|
||||||
|
|
||||||
|
exists, err := x.
|
||||||
|
Where("id = ?", id).
|
||||||
|
Get(&t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
return team, ErrTeamDoesNotExist{id}
|
return &t, ErrTeamDoesNotExist{id}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
teamSlice := []*Team{&t}
|
||||||
|
err = addMoreInfoToTeams(teamSlice)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
team = &t
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func addMoreInfoToTeams(teams []*Team) (err error) {
|
||||||
|
// Put the teams in a map to make assigning more info to it more efficient
|
||||||
|
teamMap := make(map[int64]*Team, len(teams))
|
||||||
|
var teamIDs []int64
|
||||||
|
var ownerIDs []int64
|
||||||
|
for _, team := range teams {
|
||||||
|
teamMap[team.ID] = team
|
||||||
|
teamIDs = append(teamIDs, team.ID)
|
||||||
|
ownerIDs = append(ownerIDs, team.CreatedByID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all owners and team members
|
||||||
|
users := []*TeamUser{}
|
||||||
|
err = x.Select("*").
|
||||||
|
Table("users").
|
||||||
|
Join("LEFT", "team_members", "team_members.user_id = users.id").
|
||||||
|
Join("LEFT", "teams", "team_members.team_id = teams.id").
|
||||||
|
Or(
|
||||||
|
builder.In("team_id", teamIDs),
|
||||||
|
builder.And(
|
||||||
|
builder.In("users.id", ownerIDs),
|
||||||
|
builder.Expr("teams.created_by_id = users.id"),
|
||||||
|
builder.In("teams.id", teamIDs),
|
||||||
|
),
|
||||||
|
).
|
||||||
|
Find(&users)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, u := range users {
|
||||||
|
if _, exists := teamMap[u.TeamID]; !exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
u.Email = ""
|
||||||
|
teamMap[u.TeamID].CreatedBy = &u.User
|
||||||
|
teamMap[u.TeamID].Members = append(teamMap[u.TeamID].Members, u)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,9 +169,12 @@ func GetTeamByID(id int64) (team Team, err error) {
|
||||||
// @Success 200 {object} models.Team "The team"
|
// @Success 200 {object} models.Team "The team"
|
||||||
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the team"
|
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the team"
|
||||||
// @Failure 500 {object} models.Message "Internal error"
|
// @Failure 500 {object} models.Message "Internal error"
|
||||||
// @Router /lists/{id} [get]
|
// @Router /teams/{id} [get]
|
||||||
func (t *Team) ReadOne() (err error) {
|
func (t *Team) ReadOne() (err error) {
|
||||||
*t, err = GetTeamByID(t.ID)
|
team, err := GetTeamByID(t.ID)
|
||||||
|
if team != nil {
|
||||||
|
*t = *team
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +208,11 @@ func (t *Team) ReadAll(a web.Auth, search string, page int, perPage int) (result
|
||||||
return nil, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = addMoreInfoToTeams(all)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
numberOfTotalItems, err = x.
|
numberOfTotalItems, err = x.
|
||||||
Table("teams").
|
Table("teams").
|
||||||
Join("INNER", "team_members", "team_members.team_id = teams.id").
|
Join("INNER", "team_members", "team_members.team_id = teams.id").
|
||||||
|
@ -282,7 +335,10 @@ func (t *Team) Update() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the newly updated team
|
// Get the newly updated team
|
||||||
*t, err = GetTeamByID(t.ID)
|
team, err := GetTeamByID(t.ID)
|
||||||
|
if team != nil {
|
||||||
|
*t = *team
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ type Token struct {
|
||||||
// @tags user
|
// @tags user
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param credentials body models.UserLogin true "The login credentials"
|
// @Param credentials body user.UserLogin true "The login credentials"
|
||||||
// @Success 200 {object} v1.Token
|
// @Success 200 {object} v1.Token
|
||||||
// @Failure 400 {object} models.Message "Invalid user password model."
|
// @Failure 400 {object} models.Message "Invalid user password model."
|
||||||
// @Failure 403 {object} models.Message "Invalid username or password."
|
// @Failure 403 {object} models.Message "Invalid username or password."
|
||||||
|
|
|
@ -31,8 +31,8 @@ import (
|
||||||
// @tags user
|
// @tags user
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param credentials body models.APIUserPassword true "The user credentials"
|
// @Param credentials body user.APIUserPassword true "The user credentials"
|
||||||
// @Success 200 {object} models.User
|
// @Success 200 {object} user.User
|
||||||
// @Failure 400 {object} code.vikunja.io/web.HTTPError "No or invalid user register object provided / User already exists."
|
// @Failure 400 {object} code.vikunja.io/web.HTTPError "No or invalid user register object provided / User already exists."
|
||||||
// @Failure 500 {object} models.Message "Internal error"
|
// @Failure 500 {object} models.Message "Internal error"
|
||||||
// @Router /register [post]
|
// @Router /register [post]
|
||||||
|
|
|
@ -33,7 +33,7 @@ import (
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param s query string false "Search for a user by its name."
|
// @Param s query string false "Search for a user by its name."
|
||||||
// @Security JWTKeyAuth
|
// @Security JWTKeyAuth
|
||||||
// @Success 200 {array} models.User "All (found) users."
|
// @Success 200 {array} user.User "All (found) users."
|
||||||
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Something's invalid."
|
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Something's invalid."
|
||||||
// @Failure 500 {object} models.Message "Internal server error."
|
// @Failure 500 {object} models.Message "Internal server error."
|
||||||
// @Router /users [get]
|
// @Router /users [get]
|
||||||
|
@ -61,7 +61,7 @@ func UserList(c echo.Context) error {
|
||||||
// @Param s query string false "Search for a user by its name."
|
// @Param s query string false "Search for a user by its name."
|
||||||
// @Security JWTKeyAuth
|
// @Security JWTKeyAuth
|
||||||
// @Param id path int true "List ID"
|
// @Param id path int true "List ID"
|
||||||
// @Success 200 {array} models.User "All (found) users."
|
// @Success 200 {array} user.User "All (found) users."
|
||||||
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Something's invalid."
|
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Something's invalid."
|
||||||
// @Failure 401 {object} code.vikunja.io/web.HTTPError "The user does not have the right to see the list."
|
// @Failure 401 {object} code.vikunja.io/web.HTTPError "The user does not have the right to see the list."
|
||||||
// @Failure 500 {object} models.Message "Internal server error."
|
// @Failure 500 {object} models.Message "Internal server error."
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Security JWTKeyAuth
|
// @Security JWTKeyAuth
|
||||||
// @Success 200 {object} models.User
|
// @Success 200 {object} user.User
|
||||||
// @Failure 404 {object} code.vikunja.io/web.HTTPError "User does not exist."
|
// @Failure 404 {object} code.vikunja.io/web.HTTPError "User does not exist."
|
||||||
// @Failure 500 {object} models.Message "Internal server error."
|
// @Failure 500 {object} models.Message "Internal server error."
|
||||||
// @Router /user [get]
|
// @Router /user [get]
|
||||||
|
|
|
@ -664,7 +664,7 @@ var doc = `{
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1589,7 +1589,7 @@ var doc = `{
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.UserLogin"
|
"$ref": "#/definitions/user.UserLogin"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -2688,7 +2688,7 @@ var doc = `{
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
|
@ -3347,7 +3347,7 @@ var doc = `{
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -4251,7 +4251,7 @@ var doc = `{
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"404": {
|
"404": {
|
||||||
|
@ -4529,7 +4529,7 @@ var doc = `{
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -4626,7 +4626,7 @@ var doc = `{
|
||||||
"description": "A list with all assignees",
|
"description": "A list with all assignees",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4638,7 +4638,7 @@ var doc = `{
|
||||||
"description": "An array of users who are assigned to this task",
|
"description": "An array of users who are assigned to this task",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attachments": {
|
"attachments": {
|
||||||
|
@ -4655,7 +4655,7 @@ var doc = `{
|
||||||
"createdBy": {
|
"createdBy": {
|
||||||
"description": "The user who initially created the task.",
|
"description": "The user who initially created the task.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "The task description.",
|
"description": "The task description.",
|
||||||
|
@ -4771,7 +4771,7 @@ var doc = `{
|
||||||
"created_by": {
|
"created_by": {
|
||||||
"description": "The user who created this label",
|
"description": "The user who created this label",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "The label description.",
|
"description": "The label description.",
|
||||||
|
@ -4847,7 +4847,7 @@ var doc = `{
|
||||||
"shared_by": {
|
"shared_by": {
|
||||||
"description": "The user who shared this list",
|
"description": "The user who shared this list",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"sharing_type": {
|
"sharing_type": {
|
||||||
"description": "The kind of this link. 0 = undefined, 1 = without password, 2 = with password (currently not implemented).",
|
"description": "The kind of this link. 0 = undefined, 1 = without password, 2 = with password (currently not implemented).",
|
||||||
|
@ -4885,7 +4885,7 @@ var doc = `{
|
||||||
"owner": {
|
"owner": {
|
||||||
"description": "The user who created this list.",
|
"description": "The user who created this list.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"description": "The title of the list. You'll see this in the namespace overview.",
|
"description": "The title of the list. You'll see this in the namespace overview.",
|
||||||
|
@ -4959,7 +4959,7 @@ var doc = `{
|
||||||
"owner": {
|
"owner": {
|
||||||
"description": "The user who owns this namespace",
|
"description": "The user who owns this namespace",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"updated": {
|
"updated": {
|
||||||
"description": "A unix timestamp when this namespace was last updated. You cannot change this value.",
|
"description": "A unix timestamp when this namespace was last updated. You cannot change this value.",
|
||||||
|
@ -5024,7 +5024,7 @@ var doc = `{
|
||||||
"owner": {
|
"owner": {
|
||||||
"description": "The user who owns this namespace",
|
"description": "The user who owns this namespace",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"updated": {
|
"updated": {
|
||||||
"description": "A unix timestamp when this namespace was last updated. You cannot change this value.",
|
"description": "A unix timestamp when this namespace was last updated. You cannot change this value.",
|
||||||
|
@ -5065,7 +5065,7 @@ var doc = `{
|
||||||
"description": "An array of users who are assigned to this task",
|
"description": "An array of users who are assigned to this task",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attachments": {
|
"attachments": {
|
||||||
|
@ -5082,7 +5082,7 @@ var doc = `{
|
||||||
"createdBy": {
|
"createdBy": {
|
||||||
"description": "The user who initially created the task.",
|
"description": "The user who initially created the task.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "The task description.",
|
"description": "The task description.",
|
||||||
|
@ -5181,7 +5181,7 @@ var doc = `{
|
||||||
"description": "An array of users who are assigned to this task",
|
"description": "An array of users who are assigned to this task",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attachments": {
|
"attachments": {
|
||||||
|
@ -5198,7 +5198,7 @@ var doc = `{
|
||||||
"createdBy": {
|
"createdBy": {
|
||||||
"description": "The user who initially created the task.",
|
"description": "The user who initially created the task.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "The task description.",
|
"description": "The task description.",
|
||||||
|
@ -5307,7 +5307,7 @@ var doc = `{
|
||||||
},
|
},
|
||||||
"created_by": {
|
"created_by": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"file": {
|
"file": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -5331,7 +5331,7 @@ var doc = `{
|
||||||
"created_by": {
|
"created_by": {
|
||||||
"description": "The user who created this relation",
|
"description": "The user who created this relation",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"other_task_id": {
|
"other_task_id": {
|
||||||
"description": "The ID of the other task, the task which is being related.",
|
"description": "The ID of the other task, the task which is being related.",
|
||||||
|
@ -5357,7 +5357,7 @@ var doc = `{
|
||||||
"createdBy": {
|
"createdBy": {
|
||||||
"description": "The user who created this team.",
|
"description": "The user who created this team.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "The team's description.",
|
"description": "The team's description.",
|
||||||
|
@ -5507,7 +5507,7 @@ var doc = `{
|
||||||
"createdBy": {
|
"createdBy": {
|
||||||
"description": "The user who created this team.",
|
"description": "The user who created this team.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/user.User"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "The team's description.",
|
"description": "The team's description.",
|
||||||
|
@ -5539,7 +5539,7 @@ var doc = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"models.User": {
|
"user.User": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"avatarUrl": {
|
"avatarUrl": {
|
||||||
|
@ -5571,7 +5571,7 @@ var doc = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"models.UserLogin": {
|
"user.UserLogin": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"password": {
|
"password": {
|
||||||
|
|
Loading…
Reference in a new issue