feat: enable soft delete for organizations (#16584)

- Add deleted column to organizations table
- Add trigger to check for existing workspaces, templates, groups and
members in a org before allowing the soft delete

---------

Co-authored-by: Steven Masley <stevenmasley@gmail.com>
Co-authored-by: Steven Masley <Emyrk@users.noreply.github.com>
This commit is contained in:
Jaayden Halko
2025-02-24 12:59:41 -05:00
committed by GitHub
co-authored by Steven Masley Steven Masley
parent dfa33b11d9
commit 546a549dcf
28 changed files with 605 additions and 215 deletions
+25 -18
View File
@@ -2157,19 +2157,6 @@ func (q *FakeQuerier) DeleteOldWorkspaceAgentStats(_ context.Context) error {
return nil
}
func (q *FakeQuerier) DeleteOrganization(_ context.Context, id uuid.UUID) error {
q.mutex.Lock()
defer q.mutex.Unlock()
for i, org := range q.organizations {
if org.ID == id && !org.IsDefault {
q.organizations = append(q.organizations[:i], q.organizations[i+1:]...)
return nil
}
}
return sql.ErrNoRows
}
func (q *FakeQuerier) DeleteOrganizationMember(ctx context.Context, arg database.DeleteOrganizationMemberParams) error {
err := validateDatabaseType(arg)
if err != nil {
@@ -3688,12 +3675,12 @@ func (q *FakeQuerier) GetOrganizationByID(_ context.Context, id uuid.UUID) (data
return q.getOrganizationByIDNoLock(id)
}
func (q *FakeQuerier) GetOrganizationByName(_ context.Context, name string) (database.Organization, error) {
func (q *FakeQuerier) GetOrganizationByName(_ context.Context, params database.GetOrganizationByNameParams) (database.Organization, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
for _, organization := range q.organizations {
if organization.Name == name {
if organization.Name == params.Name && organization.Deleted == params.Deleted {
return organization, nil
}
}
@@ -3740,17 +3727,17 @@ func (q *FakeQuerier) GetOrganizations(_ context.Context, args database.GetOrgan
return tmp, nil
}
func (q *FakeQuerier) GetOrganizationsByUserID(_ context.Context, userID uuid.UUID) ([]database.Organization, error) {
func (q *FakeQuerier) GetOrganizationsByUserID(_ context.Context, arg database.GetOrganizationsByUserIDParams) ([]database.Organization, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
organizations := make([]database.Organization, 0)
for _, organizationMember := range q.organizationMembers {
if organizationMember.UserID != userID {
if organizationMember.UserID != arg.UserID {
continue
}
for _, organization := range q.organizations {
if organization.ID != organizationMember.OrganizationID {
if organization.ID != organizationMember.OrganizationID || organization.Deleted != arg.Deleted {
continue
}
organizations = append(organizations, organization)
@@ -9822,6 +9809,26 @@ func (q *FakeQuerier) UpdateOrganization(_ context.Context, arg database.UpdateO
return database.Organization{}, sql.ErrNoRows
}
func (q *FakeQuerier) UpdateOrganizationDeletedByID(_ context.Context, arg database.UpdateOrganizationDeletedByIDParams) error {
if err := validateDatabaseType(arg); err != nil {
return err
}
q.mutex.Lock()
defer q.mutex.Unlock()
for index, organization := range q.organizations {
if organization.ID != arg.ID || organization.IsDefault {
continue
}
organization.Deleted = true
organization.UpdatedAt = arg.UpdatedAt
q.organizations[index] = organization
return nil
}
return sql.ErrNoRows
}
func (q *FakeQuerier) UpdateProvisionerDaemonLastSeenAt(_ context.Context, arg database.UpdateProvisionerDaemonLastSeenAtParams) error {
err := validateDatabaseType(arg)
if err != nil {