Skip to content

Commit 09ebb28

Browse files
authored
fix(controlplane): support soft-deleted items on name constraint (#613)
Signed-off-by: Miguel Martinez Trivino <[email protected]>
1 parent 8c0d6ca commit 09ebb28

File tree

8 files changed

+70
-8
lines changed

8 files changed

+70
-8
lines changed

app/controlplane/internal/biz/workflow_integration_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,27 @@ func (s *workflowIntegrationTestSuite) TestContractLatestAvailable() {
5656
})
5757
}
5858

59+
func (s *workflowIntegrationTestSuite) TestCreateDuplicatedName() {
60+
ctx := context.Background()
61+
62+
const workflowName = "name"
63+
existingWorkflow, err := s.Workflow.Create(ctx, &biz.WorkflowCreateOpts{OrgID: s.org.ID, Name: workflowName})
64+
require.NoError(s.T(), err)
65+
66+
s.Run("can't create a workflow with the same name", func() {
67+
_, err = s.Workflow.Create(ctx, &biz.WorkflowCreateOpts{OrgID: s.org.ID, Name: workflowName})
68+
s.ErrorContains(err, "name already taken")
69+
})
70+
71+
s.Run("but if we delete it we can", func() {
72+
err = s.Workflow.Delete(ctx, s.org.ID, existingWorkflow.ID.String())
73+
require.NoError(s.T(), err)
74+
75+
_, err = s.Workflow.Create(ctx, &biz.WorkflowCreateOpts{OrgID: s.org.ID, Name: workflowName})
76+
require.NoError(s.T(), err)
77+
})
78+
}
79+
5980
func (s *workflowIntegrationTestSuite) TestCreate() {
6081
ctx := context.Background()
6182
testCases := []struct {

app/controlplane/internal/biz/workflowcontract_integration_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,27 @@ func (s *workflowContractIntegrationTestSuite) TestUpdate() {
116116
}
117117
}
118118

119+
func (s *workflowContractIntegrationTestSuite) TestCreateDuplicatedName() {
120+
ctx := context.Background()
121+
122+
const contractName = "name"
123+
contract, err := s.WorkflowContract.Create(ctx, &biz.WorkflowContractCreateOpts{OrgID: s.org.ID, Name: contractName})
124+
require.NoError(s.T(), err)
125+
126+
s.Run("can't create a contract with the same name", func() {
127+
_, err := s.WorkflowContract.Create(ctx, &biz.WorkflowContractCreateOpts{OrgID: s.org.ID, Name: contractName})
128+
s.ErrorContains(err, "name already taken")
129+
})
130+
131+
s.Run("but if we delete it we can", func() {
132+
err = s.WorkflowContract.Delete(ctx, s.org.ID, contract.ID.String())
133+
require.NoError(s.T(), err)
134+
135+
_, err := s.WorkflowContract.Create(ctx, &biz.WorkflowContractCreateOpts{OrgID: s.org.ID, Name: contractName})
136+
require.NoError(s.T(), err)
137+
})
138+
}
139+
119140
func (s *workflowContractIntegrationTestSuite) TestCreate() {
120141
ctx := context.Background()
121142

app/controlplane/internal/data/ent/migrate/migrations/20240312141340.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ SET name = regexp_replace(
1111
-- and project
1212
UPDATE workflows
1313
SET project = regexp_replace(
14-
lower(name),
14+
lower(project),
1515
'[^a-z0-9-]',
1616
'-',
1717
'g'
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- Drop index "workflowcontract_name_organization_workflow_contracts" from table: "workflow_contracts"
2+
DROP INDEX "workflowcontract_name_organization_workflow_contracts";
3+
-- Create index "workflowcontract_name_organization_workflow_contracts" to table: "workflow_contracts"
4+
CREATE UNIQUE INDEX "workflowcontract_name_organization_workflow_contracts" ON "workflow_contracts" ("name", "organization_workflow_contracts") WHERE (deleted_at IS NULL);
5+
-- Drop index "workflow_name_organization_id" from table: "workflows"
6+
DROP INDEX "workflow_name_organization_id";
7+
-- Create index "workflow_name_organization_id" to table: "workflows"
8+
CREATE UNIQUE INDEX "workflow_name_organization_id" ON "workflows" ("name", "organization_id") WHERE (deleted_at IS NULL);

app/controlplane/internal/data/ent/migrate/migrations/atlas.sum

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
h1:jlgZQ/R2/gTBkWCCkoXvtWydFDgCgQz2vjAVrYvW/pg=
1+
h1:9ZaVZApcnCY4PP6Ahf4zW9sH3MKuvi4eSJkRBlog1X0=
22
20230706165452_init-schema.sql h1:VvqbNFEQnCvUVyj2iDYVQQxDM0+sSXqocpt/5H64k8M=
33
20230710111950-cas-backend.sql h1:A8iBuSzZIEbdsv9ipBtscZQuaBp3V5/VMw7eZH6GX+g=
44
20230712094107-cas-backends-workflow-runs.sql h1:a5rzxpVGyd56nLRSsKrmCFc9sebg65RWzLghKHh5xvI=
@@ -26,5 +26,6 @@ h1:jlgZQ/R2/gTBkWCCkoXvtWydFDgCgQz2vjAVrYvW/pg=
2626
20240303073902.sql h1:vTC9GmUjsyYzOmsEkLcVLvu+h5iJAohQnGFl+OoQLHQ=
2727
20240303145130.sql h1:IY21A96Cq7wrNXkLWqhwNGXWcJVxUG7v6PorhOxMvao=
2828
20240312102059.sql h1:nHApYqyVHcdHHivQFDw+AzPTVa4Gn3NHqmZnxVeZsoA=
29-
20240312141340.sql h1:QDVfhXAD0//TikLmOWM6hdXiEGeahrjm1xeyHlYu9f8=
30-
20240312211838.sql h1:l1anepk4TgpuRYGdcysltfM9pMVzqe/x6/QuSkqGV6w=
29+
20240312141340.sql h1:bzZd5uvibbLZcpjam/wRwr1aF+zKMF2O+wELBAraDrU=
30+
20240312211838.sql h1:cCiivFnB5mMySOzOgD72ttWGqp3a4IVWwvg+k/TNHYo=
31+
20240313115221.sql h1:mhlM4LpGHmbicQ7m/13Iw7c6pZRBzvd14ojrUTe/knM=

app/controlplane/internal/data/ent/migrate/schema.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package migrate
44

55
import (
6+
"entgo.io/ent/dialect/entsql"
67
"entgo.io/ent/dialect/sql/schema"
78
"entgo.io/ent/schema/field"
89
)
@@ -331,6 +332,9 @@ var (
331332
Name: "workflow_name_organization_id",
332333
Unique: true,
333334
Columns: []*schema.Column{WorkflowsColumns[1], WorkflowsColumns[9]},
335+
Annotation: &entsql.IndexAnnotation{
336+
Where: "deleted_at IS NULL",
337+
},
334338
},
335339
},
336340
}
@@ -361,6 +365,9 @@ var (
361365
Name: "workflowcontract_name_organization_workflow_contracts",
362366
Unique: true,
363367
Columns: []*schema.Column{WorkflowContractsColumns[1], WorkflowContractsColumns[5]},
368+
Annotation: &entsql.IndexAnnotation{
369+
Where: "deleted_at IS NULL",
370+
},
364371
},
365372
},
366373
}

app/controlplane/internal/data/ent/schema/workflow.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ func (Workflow) Edges() []ent.Edge {
7070

7171
func (Workflow) Indexes() []ent.Index {
7272
return []ent.Index{
73-
// names are unique within an organization
74-
index.Fields("name").Edges("organization").Unique(),
73+
// names are unique within a organization and affects only to non-deleted items
74+
index.Fields("name").Edges("organization").Unique().Annotations(
75+
entsql.IndexWhere("deleted_at IS NULL"),
76+
),
7577
}
7678
}

app/controlplane/internal/data/ent/schema/workflowcontract.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ func (WorkflowContract) Edges() []ent.Edge {
6161

6262
func (WorkflowContract) Indexes() []ent.Index {
6363
return []ent.Index{
64-
// names are unique within an organization
65-
index.Fields("name").Edges("organization").Unique(),
64+
// names are unique within a organization and affects only to non-deleted items
65+
index.Fields("name").Edges("organization").Unique().Annotations(
66+
entsql.IndexWhere("deleted_at IS NULL"),
67+
),
6668
}
6769
}

0 commit comments

Comments
 (0)