From 3ce68ebd3023077e4e7b46b3221e26968566af8c Mon Sep 17 00:00:00 2001 From: Takeshi Kimata <117462761+kimatata@users.noreply.github.com> Date: Sun, 26 May 2024 14:46:00 +0900 Subject: [PATCH] Cretate delete project confirm dialog --- .../migrations/20240212022145-create-folders.js | 2 +- backend/migrations/20240212082050-create-runs.js | 2 +- backend/models/folders.js | 1 + backend/models/projects.js | 4 +++- backend/routes/projects/delete.js | 16 +++++++++++++++- backend/seeders/seed.js | 4 ++-- frontend/src/app/[locale]/TokenProvider.tsx | 4 ++-- 7 files changed, 25 insertions(+), 8 deletions(-) diff --git a/backend/migrations/20240212022145-create-folders.js b/backend/migrations/20240212022145-create-folders.js index dd50285..01f60dc 100644 --- a/backend/migrations/20240212022145-create-folders.js +++ b/backend/migrations/20240212022145-create-folders.js @@ -25,7 +25,7 @@ module.exports = { type: Sequelize.INTEGER, allowNull: false, references: { - model: 'Projects', + model: 'projects', key: 'id', onDelete: 'CASCADE', onUpdate: 'CASCADE', diff --git a/backend/migrations/20240212082050-create-runs.js b/backend/migrations/20240212082050-create-runs.js index 674ba6d..dad3e1d 100644 --- a/backend/migrations/20240212082050-create-runs.js +++ b/backend/migrations/20240212082050-create-runs.js @@ -29,7 +29,7 @@ module.exports = { type: Sequelize.INTEGER, allowNull: false, references: { - model: 'Projects', + model: 'projects', key: 'id', }, onUpdate: 'CASCADE', diff --git a/backend/models/folders.js b/backend/models/folders.js index ea0d732..a0b3880 100644 --- a/backend/models/folders.js +++ b/backend/models/folders.js @@ -25,6 +25,7 @@ function defineFolder(sequelize, DataTypes) { Folder.associate = (models) => { Folder.belongsTo(models.Project, { foreignKey: 'projectId', onDelete: 'CASCADE' }); + Folder.hasMany(models.Case, { foreignKey: 'folderId' }); }; return Folder; diff --git a/backend/models/projects.js b/backend/models/projects.js index c56293e..b7edb96 100644 --- a/backend/models/projects.js +++ b/backend/models/projects.js @@ -24,7 +24,9 @@ function defineProject(sequelize, DataTypes) { }); Project.associate = (models) => { - Project.hasMany(models.Folder, { foreignKey: 'projectId' }); + Project.belongsTo(models.User, { foreignKey: 'userId', onDelete: 'CASCADE' }); + Project.hasMany(models.Folder, { foreignKey: 'projectId', onDelete: 'CASCADE' }); + Project.hasMany(models.Run, { foreignKey: 'projectId', onDelete: 'CASCADE' }); }; return Project; diff --git a/backend/routes/projects/delete.js b/backend/routes/projects/delete.js index 68f9b5a..14df553 100644 --- a/backend/routes/projects/delete.js +++ b/backend/routes/projects/delete.js @@ -1,23 +1,37 @@ const express = require('express'); const router = express.Router(); const defineProject = require('../../models/projects'); +const defineFolder = require('../../models/folders'); +const defineRun = require('../../models/runs'); const { DataTypes } = require('sequelize'); module.exports = function (sequelize) { const { verifySignedIn, verifyProjectOwner } = require('../../middleware/auth')(sequelize); const Project = defineProject(sequelize, DataTypes); + const Folder = defineFolder(sequelize, DataTypes); + const Run = defineRun(sequelize, DataTypes); router.delete('/:projectId', verifySignedIn, verifyProjectOwner, async (req, res) => { const projectId = req.params.projectId; + const t = await sequelize.transaction(); + try { const project = await Project.findByPk(projectId); if (!project) { + await t.rollback(); return res.status(404).send('Project not found'); } - await project.destroy(); + + await Folder.destroy({ where: { projectId: projectId }, transaction: t }); + await Run.destroy({ where: { projectId: projectId }, transaction: t }); + + await project.destroy({ transaction: t }); + + await t.commit(); res.status(204).send(); } catch (error) { console.error(error); + await t.rollback(); res.status(500).send('Internal Server Error'); } }); diff --git a/backend/seeders/seed.js b/backend/seeders/seed.js index 535be73..9847795 100644 --- a/backend/seeders/seed.js +++ b/backend/seeders/seed.js @@ -7,7 +7,7 @@ module.exports = { const hashedPassword = await bcrypt.hash('password', 10); // Add projects table records - await queryInterface.bulkInsert('Users', [ + await queryInterface.bulkInsert('users', [ { email: 'admin@testplat.com', password: hashedPassword, @@ -20,7 +20,7 @@ module.exports = { ]); // Add projects table records - await queryInterface.bulkInsert('Projects', [ + await queryInterface.bulkInsert('projects', [ { name: 'TestPlat Test', detail: "Test Plat's Manual test", diff --git a/frontend/src/app/[locale]/TokenProvider.tsx b/frontend/src/app/[locale]/TokenProvider.tsx index e71999e..ce51f02 100644 --- a/frontend/src/app/[locale]/TokenProvider.tsx +++ b/frontend/src/app/[locale]/TokenProvider.tsx @@ -72,9 +72,9 @@ const TokenProvider = ({ locale, children }: TokenProps) => { }, []); useEffect(() => { - // check current path is private. pravate path is '/account/*' or '/projects/*' + // check current path is private. pravate path is '/account' or '/projects/*' const isPrivatePath = (pathname: string) => { - return /^\/(account|projects)\/.*/.test(pathname); + return /^\/account(\/)?$/.test(pathname) || /^\/projects(\/)?$/.test(pathname); }; const checkSignInPage = () => {