Skip to content

Commit 74dd6d4

Browse files
committed
feat: org soft-deletion
Signed-off-by: Miguel Martinez <miguel@chainloop.dev>
1 parent 7f34140 commit 74dd6d4

19 files changed

Lines changed: 337 additions & 47 deletions

app/controlplane/pkg/biz/organization.go

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,7 @@ func (uc *OrganizationUseCase) FindByName(ctx context.Context, name string) (*Or
242242
return org, nil
243243
}
244244

245-
// Delete deletes an organization and all relevant data
246-
// This includes:
247-
// - The organization
248-
// - The associated repositories
249-
// - The associated integrations
250-
// The reason for just deleting these two associated components only is because
251-
// they have external secrets that need to be deleted as well, and for that we leverage their own delete methods
252-
// The rest of the data gets removed by the database cascade delete
245+
// Delete soft-deletes an organization and all relevant data
253246
func (uc *OrganizationUseCase) Delete(ctx context.Context, id string) error {
254247
orgUUID, err := uuid.Parse(id)
255248
if err != nil {
@@ -263,30 +256,21 @@ func (uc *OrganizationUseCase) Delete(ctx context.Context, id string) error {
263256
return NewErrNotFound("organization")
264257
}
265258

266-
// Delete all the integrations
267-
integrations, err := uc.integrationUC.List(ctx, id)
259+
// Delete all memberships for this organization
260+
// Memberships should be removed when an organization is soft-deleted
261+
// since they represent access rights that should be revoked
262+
memberships, _, err := uc.membershipRepo.FindByOrg(ctx, orgUUID, nil, nil)
268263
if err != nil {
269-
return err
270-
}
271-
272-
for _, i := range integrations {
273-
if err := uc.integrationUC.Delete(ctx, id, i.ID.String()); err != nil {
274-
return err
275-
}
276-
}
277-
278-
backends, err := uc.casBackendUseCase.List(ctx, org.ID)
279-
if err != nil {
280-
return fmt.Errorf("failed to list backends: %w", err)
264+
return fmt.Errorf("failed to find memberships: %w", err)
281265
}
282266

283-
for _, b := range backends {
284-
if err := uc.casBackendUseCase.Delete(ctx, b.ID.String()); err != nil {
285-
return fmt.Errorf("failed to delete backend: %w", err)
267+
for _, m := range memberships {
268+
if err := uc.membershipRepo.Delete(ctx, m.ID); err != nil {
269+
return fmt.Errorf("failed to delete membership: %w", err)
286270
}
287271
}
288272

289-
// Delete the organization
273+
// Soft-delete the organization
290274
return uc.orgRepo.Delete(ctx, orgUUID)
291275
}
292276

app/controlplane/pkg/data/data.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func toTimePtr(t time.Time) *time.Time {
144144
}
145145

146146
func orgScopedQuery(client *ent.Client, orgID uuid.UUID) *ent.OrganizationQuery {
147-
return client.Organization.Query().Where(organization.ID(orgID))
147+
return client.Organization.Query().Where(organization.ID(orgID), organization.DeletedAtIsNil())
148148
}
149149

150150
// WithTx initiates a transaction and wraps the DB function
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- Modify "organizations" table
2+
ALTER TABLE "organizations" ADD COLUMN "deleted_at" timestamptz NULL;
3+
-- Create index "organization_name" to table: "organizations"
4+
CREATE UNIQUE INDEX "organization_name" ON "organizations" ("name") WHERE (deleted_at IS NULL);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- Drop index "organizations_name_key" from table: "organizations"
2+
DROP INDEX "organizations_name_key";

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
h1:QaClWT8b1Nr8BRNI+5O2WAYbWl/5tTlopLggA6RQwzw=
1+
h1:RHLiR+aMRnWXumoeoZATujJDBqzz0vAwi1EJ/I7WPt4=
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=
@@ -108,3 +108,5 @@ h1:QaClWT8b1Nr8BRNI+5O2WAYbWl/5tTlopLggA6RQwzw=
108108
20250808164400.sql h1:r7S2LM8d3kbKQ7WNuggjvmNw3kcccx0rYzzklw8Q2I8=
109109
20250808165202.sql h1:Oreh9FpYwo/cdcs3Oza/+ACzScXeTRBGIEvua8RqoLo=
110110
20250812111458.sql h1:15yQlZoBymYR5GEjGLtV/j4ZZjg06u6eEzcRRl7vax4=
111+
20250817154739.sql h1:myLtenqAYBq+qUmnB2loYATdXFRHMqTbPY3ZLhON4zE=
112+
20250817161454.sql h1:Fw6tM1GqCevnUUl7Za/hbQZr6wISKmsJy7OfX11ZMQI=

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,9 +413,10 @@ var (
413413
// OrganizationsColumns holds the columns for the "organizations" table.
414414
OrganizationsColumns = []*schema.Column{
415415
{Name: "id", Type: field.TypeUUID, Unique: true},
416-
{Name: "name", Type: field.TypeString, Unique: true},
416+
{Name: "name", Type: field.TypeString},
417417
{Name: "created_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"},
418418
{Name: "updated_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"},
419+
{Name: "deleted_at", Type: field.TypeTime, Nullable: true},
419420
{Name: "block_on_policy_violation", Type: field.TypeBool, Default: false},
420421
{Name: "policies_allowed_hostnames", Type: field.TypeJSON, Nullable: true},
421422
}
@@ -424,6 +425,16 @@ var (
424425
Name: "organizations",
425426
Columns: OrganizationsColumns,
426427
PrimaryKey: []*schema.Column{OrganizationsColumns[0]},
428+
Indexes: []*schema.Index{
429+
{
430+
Name: "organization_name",
431+
Unique: true,
432+
Columns: []*schema.Column{OrganizationsColumns[1]},
433+
Annotation: &entsql.IndexAnnotation{
434+
Where: "deleted_at IS NULL",
435+
},
436+
},
437+
},
427438
}
428439
// ProjectsColumns holds the columns for the "projects" table.
429440
ProjectsColumns = []*schema.Column{

app/controlplane/pkg/data/ent/mutation.go

Lines changed: 74 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/pkg/data/ent/organization.go

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/pkg/data/ent/organization/organization.go

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/pkg/data/ent/organization/where.go

Lines changed: 55 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)