diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e663841..6dfaaf7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -2,7 +2,6 @@ name: Go CI on: push: - pull_request: jobs: build-test-lint: @@ -41,3 +40,4 @@ jobs: - name: Run staticcheck run: staticcheck ./... + diff --git a/api/README.md b/api/README.md index 8836ea2..6e644f2 100644 --- a/api/README.md +++ b/api/README.md @@ -70,17 +70,18 @@ All field names are identical to the ones found in the JSON response data. ### Item -| Field | Type | Description | -| ----------- | ------ | ------------------------------------ | -| id | uint | Unique ID | -| list | uint | ID of list this item is in | -| title | string | Items title | -| description | string | Items description | -| creator | uint | ID of user that created this item | -| assignee | uint | ID of user this item is assigned to | -| branch | string | Name of branch this item is tracking | -| createdAt | uint | Unix time of creation | -| updatedAt | uint | Unix time of last update | +| Field | Type | Description | +| ----------- | ------ | -------------------------------------------------------------------- | +| id | uint | Unique ID | +| status | uint | Item status. See `Status` enum. | +| title | string | Items title | +| description | string | Items description | +| creator | uint | ID of user that created this item | +| assignee | uint | ID of user this item is assigned to | +| branch | string | Name of branch this item is tracking | +| createdAt | uint | Unix time of creation | +| updatedAt | uint | Unix time of last update | +| data | string | Additional data field. Usually for board-specific item data as JSON. | ### ID @@ -90,3 +91,15 @@ When creating new objects you get its ID in response. | ----- | ---- | ---------------- | | id | uint | ID of new object | +### Status + +Item status is one of the following values. They are automatically updated if the item contains github repo/branch info. + +| Name | Value | Description | +| ---------------- | ----- | -------------------------------------------------------- | +| StatusBacklog | 0 | Item has been created with little to no details | +| StatusReady | 1 | Item is ready to be worked on and has sufficient details | +| StatusInProgress | 2 | Item is being worked on and tracks a branch | +| StatusInReview | 3 | Item has a pull request open | +| StatusClosed | 4 | Items pull request was merged or closed | + diff --git a/api/database/database_test.go b/api/database/database_test.go index f1508eb..1d35c3f 100644 --- a/api/database/database_test.go +++ b/api/database/database_test.go @@ -54,7 +54,7 @@ func TestDatabase(t *testing.T) { Title: "Initial Task", Description: "Setup project", ConnectedBranch: "main", - List: 1, + Status: StatusInProgress, CreatorID: userID, AssigneeID: userID, } @@ -76,33 +76,33 @@ func TestDatabase(t *testing.T) { assert(t, len(users) >= 2, "expected at least 2 users, got %d", len(users)) }) - t.Run("Get all items from list", func(t *testing.T) { + t.Run("Get all items with status", func(t *testing.T) { board := Board{} assertNoErr(t, db.db.Create(&board).Error) item := Item{ BoardID: board.ID, - Title: "List Test", - List: 2, + Title: "Status Test", + Status: StatusInReview, } _, err := db.CreateItem(item) assertNoErr(t, err) - items, err := db.GetAllItemsFromList(board.ID, 2) + items, err := db.GetAllItemsWithStatus(board.ID, StatusInReview) assertNoErr(t, err) - assert(t, len(items) > 0, "expected at least 1 item in list 2") + assert(t, len(items) > 0, "expected at least 1 item with status 2") }) - t.Run("Move item to list", func(t *testing.T) { + t.Run("Set item status", func(t *testing.T) { items, _ := db.GetAllItems() item := items[0] - err := db.MoveItemToList(item.ID, 3) + err := db.ChangeItemStatus(item.ID, StatusClosed) assertNoErr(t, err) movedItem, err := db.GetItemById(item.ID) assertNoErr(t, err) - assert(t, movedItem.List == 3, "item was not moved to list 3") + assert(t, movedItem.Status == StatusClosed, "item was not set to status 3") }) t.Run("Change item title", func(t *testing.T) { @@ -150,4 +150,16 @@ func TestDatabase(t *testing.T) { _, err = db.GetUserById(id) assert(t, err != nil, "user should have been deleted") }) + + t.Run("Get and set item data", func(t *testing.T) { + id, err := db.CreateItem(Item{}) + assertNoErr(t, err) + + str := "Hello World" + assertNoErr(t, db.SetItemData(id, str)) + + data, err := db.GetItemData(id) + assertNoErr(t, err) + assert(t, data == str, "data didnt match expected value") + }) } diff --git a/api/database/model.go b/api/database/model.go index c394d57..e836d7c 100644 --- a/api/database/model.go +++ b/api/database/model.go @@ -25,6 +25,16 @@ type Board struct { Users []User `gorm:"many2many:board_users;" json:"users"` } +type Status uint + +const ( + StatusBacklog Status = iota // Item has been created with little to no details + StatusReady // Item is ready to be worked on and has sufficient details + StatusInProgress // Item is being worked on and tracks a branch + StatusInReview // Item has a pull request open + StatusClosed // Items pull request was merged or closed +) + type Item struct { Model BoardID uint `json:"boardId"` @@ -33,13 +43,15 @@ type Item struct { Title string `json:"title"` Description string `json:"description"` ConnectedBranch string `json:"connectedBranch"` - List uint `json:"list"` + Status Status `json:"status"` CreatorID uint `json:"-"` Creator User `gorm:"foreignKey:CreatorID" json:"creator"` AssigneeID uint `json:"-"` Assignee User `gorm:"foreignKey:AssigneeID" json:"assignee"` + + Data string `json:"data"` } type User struct { diff --git a/api/database/query.go b/api/database/query.go index 52a1b61..668e1eb 100644 --- a/api/database/query.go +++ b/api/database/query.go @@ -64,17 +64,17 @@ func (db *Database) DeleteItemByID(id uint) error { return nil } -func (db *Database) GetAllItemsFromList(boardId, list uint) ([]Item, error) { +func (db *Database) GetAllItemsWithStatus(boardId uint, list Status) ([]Item, error) { var items []Item - if res := db.db.Find(&items, "list = ?", list); res.Error != nil { - return nil, errors.New("could not find all items from list") + if res := db.db.Find(&items, "status = ?", list); res.Error != nil { + return nil, errors.New("could not find items with status") } return items, nil } -func (db *Database) MoveItemToList(id uint, list uint) error { - if res := db.db.Model(&Item{}).Where("id = ?", id).Update("list", list); res.Error != nil { - return errors.New("could not move item") +func (db *Database) ChangeItemStatus(id uint, list Status) error { + if res := db.db.Model(&Item{}).Where("id = ?", id).Update("status", list); res.Error != nil { + return errors.New("could not set item status") } return nil } @@ -92,3 +92,18 @@ func (db *Database) ChangeItemDescription(id uint, description string) error { } return nil } + +func (db *Database) SetItemData(id uint, data string) error { + if res := db.db.Model(&Item{}).Where("id = ?", id).Update("data", data); res.Error != nil { + return errors.New("could not set data field") + } + return nil +} + +func (db *Database) GetItemData(id uint) (data string, err error) { + var item Item + if res := db.db.First(&item, id); res.Error != nil { + return data, errors.New("item not found") + } + return item.Data, nil +}