55 "errors"
66 "fmt"
77 "net/http"
8+ "time"
89
910 "github.com/go-chi/render"
1011 "github.com/google/uuid"
@@ -30,7 +31,16 @@ type CreateParameterValueRequest struct {
3031// Project is the JSON representation of a Coder project.
3132// This type matches the database object for now, but is
3233// abstracted for ease of change later on.
33- type Project database.Project
34+ type Project struct {
35+ ID uuid.UUID `json:"id"`
36+ CreatedAt time.Time `json:"created_at"`
37+ UpdatedAt time.Time `json:"updated_at"`
38+ OrganizationID string `json:"organization_id"`
39+ Name string `json:"name"`
40+ Provisioner database.ProvisionerType `json:"provisioner"`
41+ ActiveVersionID uuid.UUID `json:"active_version_id"`
42+ WorkspaceOwnerCount uint32 `json:"workspace_owner_count"`
43+ }
3444
3545// CreateProjectRequest enables callers to create a new Project.
3646type CreateProjectRequest struct {
@@ -69,11 +79,22 @@ func (api *api) projects(rw http.ResponseWriter, r *http.Request) {
6979 })
7080 return
7181 }
72- if projects == nil {
73- projects = []database.Project {}
82+ projectIDs := make ([]uuid.UUID , 0 , len (projects ))
83+ for _ , project := range projects {
84+ projectIDs = append (projectIDs , project .ID )
85+ }
86+ workspaceCounts , err := api .Database .GetWorkspaceOwnerCountsByProjectIDs (r .Context (), projectIDs )
87+ if errors .Is (err , sql .ErrNoRows ) {
88+ err = nil
89+ }
90+ if err != nil {
91+ httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
92+ Message : fmt .Sprintf ("get workspace counts: %s" , err .Error ()),
93+ })
94+ return
7495 }
7596 render .Status (r , http .StatusOK )
76- render .JSON (rw , r , projects )
97+ render .JSON (rw , r , convertProjects ( projects , workspaceCounts ) )
7798}
7899
79100// Lists all projects in an organization.
@@ -89,11 +110,22 @@ func (api *api) projectsByOrganization(rw http.ResponseWriter, r *http.Request)
89110 })
90111 return
91112 }
92- if projects == nil {
93- projects = []database.Project {}
113+ projectIDs := make ([]uuid.UUID , 0 , len (projects ))
114+ for _ , project := range projects {
115+ projectIDs = append (projectIDs , project .ID )
116+ }
117+ workspaceCounts , err := api .Database .GetWorkspaceOwnerCountsByProjectIDs (r .Context (), projectIDs )
118+ if errors .Is (err , sql .ErrNoRows ) {
119+ err = nil
120+ }
121+ if err != nil {
122+ httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
123+ Message : fmt .Sprintf ("get workspace counts: %s" , err .Error ()),
124+ })
125+ return
94126 }
95127 render .Status (r , http .StatusOK )
96- render .JSON (rw , r , projects )
128+ render .JSON (rw , r , convertProjects ( projects , workspaceCounts ) )
97129}
98130
99131// Create a new project in an organization.
@@ -162,7 +194,7 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
162194 if err != nil {
163195 return xerrors .Errorf ("insert project version: %s" , err )
164196 }
165- project = Project (dbProject )
197+ project = convertProject (dbProject , 0 )
166198 return nil
167199 })
168200 if err != nil {
@@ -241,6 +273,38 @@ func (api *api) parametersByProject(rw http.ResponseWriter, r *http.Request) {
241273 render .JSON (rw , r , apiParameterValues )
242274}
243275
276+ func convertProjects (projects []database.Project , workspaceCounts []database.GetWorkspaceOwnerCountsByProjectIDsRow ) []Project {
277+ apiProjects := make ([]Project , 0 , len (projects ))
278+ for _ , project := range projects {
279+ found := false
280+ for _ , workspaceCount := range workspaceCounts {
281+ if workspaceCount .ProjectID .String () != project .ID .String () {
282+ continue
283+ }
284+ apiProjects = append (apiProjects , convertProject (project , uint32 (workspaceCount .Count )))
285+ found = true
286+ break
287+ }
288+ if ! found {
289+ apiProjects = append (apiProjects , convertProject (project , uint32 (0 )))
290+ }
291+ }
292+ return apiProjects
293+ }
294+
295+ func convertProject (project database.Project , workspaceOwnerCount uint32 ) Project {
296+ return Project {
297+ ID : project .ID ,
298+ CreatedAt : project .CreatedAt ,
299+ UpdatedAt : project .UpdatedAt ,
300+ OrganizationID : project .OrganizationID ,
301+ Name : project .Name ,
302+ Provisioner : project .Provisioner ,
303+ ActiveVersionID : project .ActiveVersionID ,
304+ WorkspaceOwnerCount : workspaceOwnerCount ,
305+ }
306+ }
307+
244308func convertParameterValue (parameterValue database.ParameterValue ) ParameterValue {
245309 parameterValue .SourceValue = ""
246310 return ParameterValue (parameterValue )
0 commit comments