Skip to content

Commit

Permalink
Merge branch 'master' into Add-Endpoints-for-Workspace-Repo
Browse files Browse the repository at this point in the history
  • Loading branch information
MirzaHanan authored May 3, 2024
2 parents 97b8b4b + 12ee59e commit ba5ebd8
Show file tree
Hide file tree
Showing 16 changed files with 950 additions and 264 deletions.
158 changes: 158 additions & 0 deletions cypress/e2e/03_features.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { User, HostName, Workspaces, Repositories, Features } from '../support/objects/objects';



describe('Create Features for Workspace', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features`,
headers: { 'x-jwt': `${value}` },
body: Features[i]
}).its('body').then(body => {
expect(body).to.have.property('name').and.equal(Features[i].name.trim());
expect(body).to.have.property('brief').and.equal(Features[i].brief.trim());
expect(body).to.have.property('requirements').and.equal(Features[i].requirements.trim());
expect(body).to.have.property('architecture').and.equal(Features[i].architecture.trim());
});
}
})
})
})

describe('Modify name for Feature', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features`,
headers: { 'x-jwt': `${value}` },
body: {
uuid: Features[i].uuid,
name: Features[i].name + "_addtext"
}
}).its('body').then(body => {
expect(body).to.have.property('name').and.equal(Features[i].name.trim() + " _addtext");
expect(body).to.have.property('brief').and.equal(Features[i].brief.trim());
expect(body).to.have.property('requirements').and.equal(Features[i].requirements.trim());
expect(body).to.have.property('architecture').and.equal(Features[i].architecture.trim());
});
}
})
})
})

describe('Modify brief for Feature', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features`,
headers: { 'x-jwt': `${value}` },
body: {
uuid: Features[i].uuid,
brief: Features[i].brief + "_addtext"
}
}).its('body').then(body => {
expect(body).to.have.property('name').and.equal(Features[i].name.trim() + " _addtext");
expect(body).to.have.property('brief').and.equal(Features[i].brief.trim() + " _addtext");
expect(body).to.have.property('requirements').and.equal(Features[i].requirements.trim());
expect(body).to.have.property('architecture').and.equal(Features[i].architecture.trim());
});
}
})
})
})

describe('Modify requirements for Feature', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features`,
headers: { 'x-jwt': `${value}` },
body: {
uuid: Features[i].uuid,
requirements: Features[i].requirements + "_addtext"
}
}).its('body').then(body => {
expect(body).to.have.property('name').and.equal(Features[i].name.trim() + " _addtext");
expect(body).to.have.property('brief').and.equal(Features[i].brief.trim() + " _addtext");
expect(body).to.have.property('requirements').and.equal(Features[i].requirements.trim() + " _addtext");
expect(body).to.have.property('architecture').and.equal(Features[i].architecture.trim());
});
}
})
})
})

describe('Modify architecture for Feature', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features`,
headers: { 'x-jwt': `${value}` },
body: {
uuid: Features[i].uuid,
architecture: Features[i].architecture + "_addtext"
}
}).its('body').then(body => {
expect(body).to.have.property('name').and.equal(Features[i].name.trim() + " _addtext");
expect(body).to.have.property('brief').and.equal(Features[i].brief.trim() + " _addtext");
expect(body).to.have.property('requirements').and.equal(Features[i].requirements.trim() + " _addtext");
expect(body).to.have.property('architecture').and.equal(Features[i].architecture.trim() + " _addtext");
});
}
})
})
})


describe('Get Features for Workspace', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
cy.request({
method: 'GET',
url: `${HostName}/features/forworkspace/` + Features[0].workspace_uuid,
headers: { 'x-jwt': `${ value }` },
body: {}
}).then((resp) => {
expect(resp.status).to.eq(200)
for(let i = 0; i <= 2; i++) {
expect(resp.body[i]).to.have.property('name', Features[i].name.trim() + " _addtext")
expect(resp.body[i]).to.have.property('brief', Features[i].brief.trim() + " _addtext")
expect(resp.body[i]).to.have.property('requirements', Features[i].requirements.trim() + " _addtext")
expect(resp.body[i]).to.have.property('architecture', Features[i].architecture.trim() + " _addtext")
}
})
})
})
})

describe('Get Feature by uuid', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'GET',
url: `${HostName}/features/` + Features[i].uuid,
headers: { 'x-jwt': `${ value }` },
body: {}
}).then((resp) => {
expect(resp.status).to.eq(200)
expect(resp.body).to.have.property('name', Features[i].name.trim() + " _addtext")
expect(resp.body).to.have.property('brief', Features[i].brief.trim() + " _addtext")
expect(resp.body).to.have.property('requirements', Features[i].requirements.trim() + " _addtext")
expect(resp.body).to.have.property('architecture', Features[i].architecture.trim() + " _addtext")
})
}
})
})
})
10 changes: 5 additions & 5 deletions cypress/support/objects/objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const Features = [
{
uuid: 'com1kson1e49th88dbg0',
workspace_uuid: 'cohob00n1e4808utqel0',
name: 'Hive Process',
name: ' Hive Process ',
priority: 1,
brief: ' To follow a set of best practices in product development.</br>' +
'Dividing complex features into small<br>steps makes it easier to ' +
Expand All @@ -100,7 +100,7 @@ export const Features = [
' the base from which every technical decition relays on.<br/>' +
'We are going to leverage AI to help the PM write better definitions.<br/>' +
'The fields that would benefit form AI assistance are: mission, tactics, ' +
'feature brief and feature user stories',
'feature brief and feature user stories ',
requirements: ' Create a new page for a conversation format between the PM and the LLM<br/>' +
'Rely as much as possible on stakwork workflows<br/>' +
'Have history of previous definitions ',
Expand All @@ -110,17 +110,17 @@ export const Features = [
'Front<br/><br/> ',
},
{
uuid: 'com1l5on1e49tucv350g',
uuid: 'com1l5on1e49tucv350h',
workspace_uuid: 'cohob00n1e4808utqel0',
name: ' AI Assited relation between text fields ',
priority: 2,
brief: ' A product and feature\'s various definition fields: mission, tactics, ' +
'feature brief, user stories, requirements and architecture should have some ' +
'relation between each other.<br/>' + 'One way to do that is to leverage an LLM ' +
'to discern the parts of the defintion that have a connection to other definitions.<br/>' +
'The UI will need to show the user how each definition is related to other defintions.',
'The UI will need to show the user how each definition is related to other defintions. ',
requirements: 'Create a new process after a Feature text has changed. It should use the LLM to ' +
'determine de relationship between parts of the text.',
'determine de relationship between parts of the text. ',
architecture: 'Describe the architecture of the feature with the following sections:' +
'<br/><br/>Wireframes<br/><br/>Visual Schematics<br/><br/>Object Definition<br/><br/>' +
'DB Schema Changes<br/><br/>UX<br/><br/>CI/CD<br/><br/>Changes<br/><br/>Endpoints<br/><br/>' +
Expand Down
9 changes: 9 additions & 0 deletions db/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func InitDB() {
db.AutoMigrate(&BountyRoles{})
db.AutoMigrate(&UserInvoiceData{})
db.AutoMigrate(&WorkspaceRepositories{})
db.AutoMigrate(&WorkspaceFeatures{})

DB.MigrateTablesWithOrgUuid()
DB.MigrateOrganizationToWorkspace()
Expand Down Expand Up @@ -178,6 +179,8 @@ func (db database) MigrateTablesWithOrgUuid() {
if !db.db.Migrator().HasTable("bounty") {
if !db.db.Migrator().HasColumn(Bounty{}, "workspace_uuid") {
db.db.AutoMigrate(&Bounty{})
} else {
db.db.AutoMigrate(&NewBounty{})
}
}
if !db.db.Migrator().HasTable("budget_histories") {
Expand All @@ -188,16 +191,22 @@ func (db database) MigrateTablesWithOrgUuid() {
if !db.db.Migrator().HasTable("payment_histories") {
if !db.db.Migrator().HasColumn(PaymentHistory{}, "workspace_uuid") {
db.db.AutoMigrate(&PaymentHistory{})
} else {
db.db.AutoMigrate(&NewPaymentHistory{})
}
}
if !db.db.Migrator().HasTable("invoice_list") {
if !db.db.Migrator().HasColumn(InvoiceList{}, "workspace_uuid") {
db.db.AutoMigrate(&InvoiceList{})
} else {
db.db.AutoMigrate(&NewInvoiceList{})
}
}
if !db.db.Migrator().HasTable("bounty_budgets") {
if !db.db.Migrator().HasColumn(BountyBudget{}, "workspace_uuid") {
db.db.AutoMigrate(&BountyBudget{})
} else {
db.db.AutoMigrate(&NewBountyBudget{})
}
}
if !db.db.Migrator().HasTable("workspace_user_roles") {
Expand Down
2 changes: 1 addition & 1 deletion db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -1142,7 +1142,7 @@ func (db database) GetAllBounties(r *http.Request) []NewBounty {
languageArray := strings.Split(languages, ",")
languageLength := len(languageArray)

if workspaceUuid != "" && orgUuid != "" {
if workspaceUuid == "" && orgUuid != "" {
workspaceUuid = orgUuid
}

Expand Down
41 changes: 41 additions & 0 deletions db/features.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package db

import (
"strings"
"time"
)

func (db database) GetFeaturesByWorkspaceUuid(uuid string) []WorkspaceFeatures {
ms := []WorkspaceFeatures{}

db.db.Model(&WorkspaceFeatures{}).Where("workspace_uuid = ?", uuid).Order("Created").Find(&ms)

return ms
}

func (db database) GetFeatureByUuid(uuid string) WorkspaceFeatures {
ms := WorkspaceFeatures{}

db.db.Model(&WorkspaceFeatures{}).Where("uuid = ?", uuid).Find(&ms)

return ms
}

func (db database) CreateOrEditFeature(m WorkspaceFeatures) (WorkspaceFeatures, error) {
m.Name = strings.TrimSpace(m.Name)
m.Brief = strings.TrimSpace(m.Brief)
m.Requirements = strings.TrimSpace(m.Requirements)
m.Architecture = strings.TrimSpace(m.Architecture)

now := time.Now()
m.Updated = &now

if db.db.Model(&m).Where("uuid = ?", m.Uuid).Updates(&m).RowsAffected == 0 {
m.Created = &now
db.db.Create(&m)
}

db.db.Model(&WorkspaceFeatures{}).Where("uuid = ?", m.Uuid).Find(&m)

return m, nil
}
26 changes: 15 additions & 11 deletions db/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,23 +122,27 @@ type Database interface {
DeleteAllUsersFromWorkspace(uuid string) error
GetFilterStatusCount() FilterStattuCount
UserHasManageBountyRoles(pubKeyFromAuth string, uuid string) bool
BountiesPaidPercentage(r PaymentDateRange) uint
TotalSatsPosted(r PaymentDateRange) uint
TotalSatsPaid(r PaymentDateRange) uint
SatsPaidPercentage(r PaymentDateRange) uint
AveragePaidTime(r PaymentDateRange) uint
AverageCompletedTime(r PaymentDateRange) uint
TotalBountiesPosted(r PaymentDateRange) int64
TotalPaidBounties(r PaymentDateRange) int64
NewHuntersPaid(r PaymentDateRange) int64
TotalHuntersPaid(r PaymentDateRange) int64
BountiesPaidPercentage(r PaymentDateRange, workspace string) uint
TotalSatsPosted(r PaymentDateRange, workspace string) uint
TotalSatsPaid(r PaymentDateRange, workspace string) uint
SatsPaidPercentage(r PaymentDateRange, workspace string) uint
AveragePaidTime(r PaymentDateRange, workspace string) uint
AverageCompletedTime(r PaymentDateRange, workspace string) uint
TotalBountiesPosted(r PaymentDateRange, workspace string) int64
TotalPaidBounties(r PaymentDateRange, workspace string) int64
TotalAssignedBounties(r PaymentDateRange, workspace string) int64
NewHuntersPaid(r PaymentDateRange, workspace string) int64
TotalHuntersPaid(r PaymentDateRange, workspace string) int64
GetPersonByPubkey(pubkey string) Person
GetBountiesByDateRange(r PaymentDateRange, re *http.Request) []Bounty
GetBountiesByDateRange(r PaymentDateRange, re *http.Request) []NewBounty
GetBountiesByDateRangeCount(r PaymentDateRange, re *http.Request) int64
GetBountiesProviders(r PaymentDateRange, re *http.Request) []Person
PersonUniqueNameFromName(name string) (string, error)
ProcessAlerts(p Person)
UserHasAccess(pubKeyFromAuth string, uuid string, role string) bool
CreateWorkspaceRepository(m WorkspaceRepositories) (WorkspaceRepositories, error)
GetWorkspaceRepositorByWorkspaceUuid(uuid string) []WorkspaceRepositories
CreateOrEditFeature(m WorkspaceFeatures) (WorkspaceFeatures, error)
GetFeaturesByWorkspaceUuid(uuid string) []WorkspaceFeatures
GetFeatureByUuid(uuid string) WorkspaceFeatures
}
Loading

0 comments on commit ba5ebd8

Please sign in to comment.