Skip to content

Commit

Permalink
fix: Project groups are not deleted from the DB after deleting the pr…
Browse files Browse the repository at this point in the history
…oject they corresponds to gf-504 (#559)

* fix: add migration which adds trigger to detele unused project groups gf-504

* fix: add deletion of existed unused project groups and rename migration gf-555

* refactor: move unused project group deletion control to service gf-555
  • Loading branch information
GvoFor authored Sep 27, 2024
1 parent b5837ed commit 6f519dc
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { type Knex } from "knex";

const PROJECT_GROUPS_TABLE_NAME = "project_groups";
const PROJECTS_TO_PROJECT_GROUPS_TABLE_NAME = "projects_to_project_groups";

const ColumnName = {
ID: "id",
PROJECT_GROUP_ID: "project_group_id",
} as const;

function up(knex: Knex): Promise<void> {
return knex(PROJECT_GROUPS_TABLE_NAME)
.whereNotIn(
ColumnName.ID,
knex(PROJECTS_TO_PROJECT_GROUPS_TABLE_NAME).select(
ColumnName.PROJECT_GROUP_ID,
),
)
.delete();
}

function down(): Promise<void> {
return Promise.resolve();
}

export { down, up };
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ class ProjectGroupRepository implements Repository {
return Boolean(deletedRowsCount);
}

public async deleteByProjectId(projectId: number): Promise<boolean> {
const deletedRowsCount = await this.projectGroupModel
.query()
.delete()
.withGraphJoined("[projects]")
.where("projects.id", projectId);

return Boolean(deletedRowsCount);
}

public async find(id: number): Promise<null | ProjectGroupEntity> {
const projectGroup = await this.projectGroupModel
.query()
Expand Down Expand Up @@ -134,16 +144,14 @@ class ProjectGroupRepository implements Repository {
ProjectPermissionKey.MANAGE_PROJECT,
]);

return results
.filter(({ projects }) => projects.length)
.map(({ projects, ...projectGroup }) => {
const [project] = projects;
return results.map(({ projects, ...projectGroup }) => {
const [project] = projects;

return ProjectGroupEntity.initialize({
...projectGroup,
projectId: { id: (project as ProjectModel).id },
});
return ProjectGroupEntity.initialize({
...projectGroup,
projectId: { id: (project as ProjectModel).id },
});
});
}

public async findByProjectIdAndName({
Expand Down
15 changes: 15 additions & 0 deletions apps/backend/src/modules/project-groups/project-group.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,21 @@ class ProjectGroupService implements Service {

return isDeleted;
}

public async deleteByProjectId(projectId: number): Promise<boolean> {
const isDeleted =
await this.projectGroupRepository.deleteByProjectId(projectId);

if (!isDeleted) {
throw new ProjectGroupError({
message: ExceptionMessage.PROJECT_GROUP_NOT_FOUND,
status: HTTPCode.NOT_FOUND,
});
}

return isDeleted;
}

public find(): ReturnType<Service["find"]> {
return Promise.resolve(null);
}
Expand Down
8 changes: 8 additions & 0 deletions apps/backend/src/modules/projects/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { HTTPCode } from "~/libs/modules/http/http.js";
import { type Logger } from "~/libs/modules/logger/logger.js";
import { type Service } from "~/libs/types/types.js";
import { type ProjectApiKeyService } from "~/modules/project-api-keys/project-api-key.service.js";
import { type ProjectGroupService } from "~/modules/project-groups/project-groups.js";

import { type NotificationService } from "../notifications/notification.service.js";
import { type UserService } from "../users/user.service.js";
Expand All @@ -30,6 +31,7 @@ type Constructor = {
logger: Logger;
notificationService: NotificationService;
projectApiKeyService: ProjectApiKeyService;
projectGroupService: ProjectGroupService;
projectRepository: ProjectRepository;
userService: UserService;
};
Expand All @@ -41,6 +43,8 @@ class ProjectService implements Service {

private projectApiKeyService: ProjectApiKeyService;

private projectGroupService: ProjectGroupService;

private projectRepository: ProjectRepository;

private userService: UserService;
Expand All @@ -49,12 +53,14 @@ class ProjectService implements Service {
logger,
notificationService,
projectApiKeyService,
projectGroupService,
projectRepository,
userService,
}: Constructor) {
this.logger = logger;
this.notificationService = notificationService;
this.userService = userService;
this.projectGroupService = projectGroupService;
this.projectRepository = projectRepository;
this.projectApiKeyService = projectApiKeyService;
}
Expand Down Expand Up @@ -83,6 +89,8 @@ class ProjectService implements Service {
}

public async delete(id: number): Promise<boolean> {
await this.projectGroupService.deleteByProjectId(id);

const isDeleted = await this.projectRepository.delete(id);

if (!isDeleted) {
Expand Down
1 change: 1 addition & 0 deletions apps/backend/src/modules/projects/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const projectService = new ProjectService({
logger,
notificationService,
projectApiKeyService,
projectGroupService,
projectRepository,
userService,
});
Expand Down

0 comments on commit 6f519dc

Please sign in to comment.