chore: Unify backend express project into ESM (#281)

This commit is contained in:
kimatata
2025-09-15 22:46:46 +09:00
committed by GitHub
parent 72fd3af24f
commit 761869736e
83 changed files with 2129 additions and 2328 deletions

View File

@@ -61,11 +61,11 @@ COPY backend/package.json backend/package-lock.json* ./
RUN npm ci RUN npm ci
WORKDIR /app WORKDIR /app
# Copy custom combined_server.js that combines frontend and backend # Copy custom entrypoint.js that combines frontend and backend
COPY combined_server.js ./ COPY entrypoint.js ./
# Expose the port # Expose the port
EXPOSE 8000 EXPOSE 8000
# Run database migrations and start the combined server # Run database migrations and start the combined server
CMD ["node", "combined_server.js"] CMD ["node", "entrypoint.js"]

View File

@@ -1,7 +1,12 @@
const path = require('path'); import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const databasePath = path.resolve(__dirname, '../database/database.sqlite'); const databasePath = path.resolve(__dirname, '../database/database.sqlite');
module.exports = { export default {
development: { development: {
dialect: 'sqlite', dialect: 'sqlite',
storage: databasePath, storage: databasePath,

View File

@@ -1,5 +1,4 @@
const server = require('./server'); import server from './server.js';
const PORT = process.env.PORT || 8001; const PORT = process.env.PORT || 8001;
server.listen(PORT, () => { server.listen(PORT, () => {

View File

@@ -1,9 +1,9 @@
const jwt = require('jsonwebtoken'); import jwt from 'jsonwebtoken';
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const { roles, defaultDangerKey } = require('../routes/users/authSettings'); import { roles, defaultDangerKey } from '../routes/users/authSettings.js';
const defineUser = require('../models/users'); import defineUser from '../models/users.js';
function authMiddleware(sequelize) { export default function authMiddleware(sequelize) {
/** /**
* Verify user sined in * Verify user sined in
* *
@@ -53,5 +53,3 @@ function authMiddleware(sequelize) {
verifyAdmin, verifyAdmin,
}; };
} }
module.exports = authMiddleware;

View File

@@ -1,12 +1,12 @@
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const { memberRoles } = require('../routes/users/authSettings'); import { memberRoles } from '../routes/users/authSettings.js';
const defineMember = require('../models/members'); import defineMember from '../models/members.js';
const defineProject = require('../models/projects'); import defineProject from '../models/projects.js';
const defineFolder = require('../models/folders'); import defineFolder from '../models/folders.js';
const defineCase = require('../models/cases'); import defineCase from '../models/cases.js';
const defineRun = require('../models/runs'); import defineRun from '../models/runs.js';
function verifyEditableMiddleware(sequelize) { export default function verifyEditableMiddleware(sequelize) {
/** /**
* Verify user has project * Verify user has project
* (have to be called after verifySignedIn() middleware) * (have to be called after verifySignedIn() middleware)
@@ -291,5 +291,3 @@ function verifyEditableMiddleware(sequelize) {
verifyProjectReporterFromRunId, verifyProjectReporterFromRunId,
}; };
} }
module.exports = verifyEditableMiddleware;

View File

@@ -1,11 +1,11 @@
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineMember = require('../models/members'); import defineMember from '../models/members.js';
const defineProject = require('../models/projects'); import defineProject from '../models/projects.js';
const defineFolder = require('../models/folders'); import defineFolder from '../models/folders.js';
const defineCase = require('../models/cases'); import defineCase from '../models/cases.js';
const defineRun = require('../models/runs'); import defineRun from '../models/runs.js';
function verifyVisibleMiddleware(sequelize) { export default function verifyVisibleMiddleware(sequelize) {
/** /**
* Verify user can read project by projectId * Verify user can read project by projectId
* (have to be called after verifySignedIn() middleware) * (have to be called after verifySignedIn() middleware)
@@ -160,5 +160,3 @@ function verifyVisibleMiddleware(sequelize) {
verifyProjectVisibleFromRunId, verifyProjectVisibleFromRunId,
}; };
} }
module.exports = verifyVisibleMiddleware;

View File

@@ -1,46 +1,41 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
},
password: {
type: Sequelize.STRING,
allowNull: false,
},
username: {
type: Sequelize.STRING,
allowNull: false,
},
role: {
type: Sequelize.INTEGER,
allowNull: false,
},
avatarPath: {
type: Sequelize.STRING,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
}
/** @type {import('sequelize-cli').Migration} */ export async function down(queryInterface) {
module.exports = { await queryInterface.dropTable('users');
up: async (queryInterface, Sequelize) => { }
await queryInterface.createTable('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
},
password: {
type: Sequelize.STRING,
allowNull: false,
},
username: {
type: Sequelize.STRING,
allowNull: false,
},
role: {
type: Sequelize.INTEGER,
allowNull: false,
},
avatarPath: {
type: Sequelize.STRING,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
},
down: async (queryInterface) => {
await queryInterface.dropTable('users');
},
};

View File

@@ -1,48 +1,43 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('projects', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
detail: {
type: Sequelize.STRING,
allowNull: true,
},
isPublic: {
type: Sequelize.BOOLEAN,
allowNull: false,
},
userId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
},
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
}
/** @type {import('sequelize-cli').Migration} */ export async function down(queryInterface) {
module.exports = { await queryInterface.dropTable('projects');
up: async (queryInterface, Sequelize) => { }
await queryInterface.createTable('projects', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
detail: {
type: Sequelize.STRING,
allowNull: true,
},
isPublic: {
type: Sequelize.BOOLEAN,
allowNull: false,
},
userId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
},
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
},
down: async (queryInterface) => {
await queryInterface.dropTable('projects');
},
};

View File

@@ -1,48 +1,43 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('folders', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
detail: {
type: Sequelize.STRING,
allowNull: true,
},
parentFolderId: {
type: Sequelize.INTEGER,
allowNull: true,
},
projectId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'projects',
key: 'id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
},
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
}
/** @type {import('sequelize-cli').Migration} */ export async function down(queryInterface) {
module.exports = { await queryInterface.dropTable('folders');
up: async (queryInterface, Sequelize) => { }
await queryInterface.createTable('folders', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
detail: {
type: Sequelize.STRING,
allowNull: true,
},
parentFolderId: {
type: Sequelize.INTEGER,
allowNull: true,
},
projectId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'projects',
key: 'id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
},
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
},
async down(queryInterface) {
await queryInterface.dropTable('folders');
},
};

View File

@@ -1,52 +1,47 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('runs', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
configurations: {
type: Sequelize.STRING,
allowNull: true,
},
description: {
type: Sequelize.STRING,
allowNull: true,
},
state: {
type: Sequelize.INTEGER,
allowNull: true,
},
projectId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'projects',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
}
/** @type {import('sequelize-cli').Migration} */ export async function down(queryInterface) {
module.exports = { await queryInterface.dropTable('runs');
async up(queryInterface, Sequelize) { }
await queryInterface.createTable('runs', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
configurations: {
type: Sequelize.STRING,
allowNull: true,
},
description: {
type: Sequelize.STRING,
allowNull: true,
},
state: {
type: Sequelize.INTEGER,
allowNull: true,
},
projectId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'projects',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
async down(queryInterface) {
await queryInterface.dropTable('runs');
},
};

View File

@@ -1,72 +1,67 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('cases', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
folderId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'folders',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
title: {
type: Sequelize.STRING,
allowNull: false,
},
state: {
type: Sequelize.INTEGER,
allowNull: false,
},
priority: {
type: Sequelize.INTEGER,
allowNull: false,
},
type: {
type: Sequelize.INTEGER,
allowNull: false,
},
automationStatus: {
type: Sequelize.INTEGER,
allowNull: false,
},
description: {
type: Sequelize.STRING,
allowNull: true,
},
template: {
type: Sequelize.INTEGER,
allowNull: false,
},
preConditions: {
type: Sequelize.STRING,
allowNull: true,
},
expectedResults: {
type: Sequelize.STRING,
allowNull: true,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
}
/** @type {import('sequelize-cli').Migration} */ export async function down(queryInterface) {
module.exports = { await queryInterface.dropTable('cases');
async up(queryInterface, Sequelize) { }
await queryInterface.createTable('cases', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
folderId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'folders',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
title: {
type: Sequelize.STRING,
allowNull: false,
},
state: {
type: Sequelize.INTEGER,
allowNull: false,
},
priority: {
type: Sequelize.INTEGER,
allowNull: false,
},
type: {
type: Sequelize.INTEGER,
allowNull: false,
},
automationStatus: {
type: Sequelize.INTEGER,
allowNull: false,
},
description: {
type: Sequelize.STRING,
allowNull: true,
},
template: {
type: Sequelize.INTEGER,
allowNull: false,
},
preConditions: {
type: Sequelize.STRING,
allowNull: true,
},
expectedResults: {
type: Sequelize.STRING,
allowNull: true,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
async down(queryInterface) {
await queryInterface.dropTable('cases');
},
};

View File

@@ -1,34 +1,29 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('steps', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
step: {
type: Sequelize.STRING,
allowNull: false,
},
result: {
type: Sequelize.STRING,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
}
/** @type {import('sequelize-cli').Migration} */ export async function down(queryInterface) {
module.exports = { await queryInterface.dropTable('steps');
up: async (queryInterface, Sequelize) => { }
await queryInterface.createTable('steps', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
step: {
type: Sequelize.STRING,
allowNull: false,
},
result: {
type: Sequelize.STRING,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
},
down: async (queryInterface) => {
await queryInterface.dropTable('steps');
},
};

View File

@@ -1,52 +1,47 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('caseSteps', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
caseId: {
type: Sequelize.INTEGER,
references: {
model: 'cases',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
stepId: {
type: Sequelize.INTEGER,
references: {
model: 'steps',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
stepNo: {
type: Sequelize.INTEGER,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
/** @type {import('sequelize-cli').Migration} */ await queryInterface.addIndex('caseSteps', ['caseId', 'stepId'], {
module.exports = { unique: true,
up: async (queryInterface, Sequelize) => { });
await queryInterface.createTable('caseSteps', { }
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
caseId: {
type: Sequelize.INTEGER,
references: {
model: 'cases',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
stepId: {
type: Sequelize.INTEGER,
references: {
model: 'steps',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
stepNo: {
type: Sequelize.INTEGER,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
await queryInterface.addIndex('caseSteps', ['caseId', 'stepId'], { export async function down(queryInterface) {
unique: true, await queryInterface.dropTable('caseSteps');
}); }
},
down: async (queryInterface) => {
await queryInterface.dropTable('caseSteps');
},
};

View File

@@ -1,38 +1,33 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('attachments', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
title: {
type: Sequelize.STRING,
allowNull: false,
},
detail: {
type: Sequelize.STRING,
allowNull: true,
},
path: {
type: Sequelize.STRING,
allowNull: false,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
}
/** @type {import('sequelize-cli').Migration} */ export async function down(queryInterface) {
module.exports = { await queryInterface.dropTable('attachments');
async up(queryInterface, Sequelize) { }
await queryInterface.createTable('attachments', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
title: {
type: Sequelize.STRING,
allowNull: false,
},
detail: {
type: Sequelize.STRING,
allowNull: true,
},
path: {
type: Sequelize.STRING,
allowNull: false,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
async down(queryInterface) {
await queryInterface.dropTable('attachments');
},
};

View File

@@ -1,48 +1,43 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('caseAttachments', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
caseId: {
type: Sequelize.INTEGER,
references: {
model: 'cases',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
attachmentId: {
type: Sequelize.INTEGER,
references: {
model: 'attachments',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
/** @type {import('sequelize-cli').Migration} */ await queryInterface.addIndex('caseAttachments', ['caseId', 'attachmentId'], {
module.exports = { unique: true,
up: async (queryInterface, Sequelize) => { });
await queryInterface.createTable('caseAttachments', { }
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
caseId: {
type: Sequelize.INTEGER,
references: {
model: 'cases',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
attachmentId: {
type: Sequelize.INTEGER,
references: {
model: 'attachments',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
await queryInterface.addIndex('caseAttachments', ['caseId', 'attachmentId'], { export async function down(queryInterface) {
unique: true, await queryInterface.dropTable('caseAttachments');
}); }
},
down: async (queryInterface) => {
await queryInterface.dropTable('caseAttachments');
},
};

View File

@@ -1,52 +1,47 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('runCases', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
runId: {
type: Sequelize.INTEGER,
references: {
model: 'runs',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
caseId: {
type: Sequelize.INTEGER,
references: {
model: 'cases',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
status: {
type: Sequelize.INTEGER,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
/** @type {import('sequelize-cli').Migration} */ await queryInterface.addIndex('runCases', ['runId', 'caseId'], {
module.exports = { unique: true,
up: async (queryInterface, Sequelize) => { });
await queryInterface.createTable('runCases', { }
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
runId: {
type: Sequelize.INTEGER,
references: {
model: 'runs',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
caseId: {
type: Sequelize.INTEGER,
references: {
model: 'cases',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
status: {
type: Sequelize.INTEGER,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
await queryInterface.addIndex('runCases', ['runId', 'caseId'], { export async function down(queryInterface) {
unique: true, await queryInterface.dropTable('runCases');
}); }
},
down: async (queryInterface) => {
await queryInterface.dropTable('runCases');
},
};

View File

@@ -1,52 +1,47 @@
'use strict'; export async function up(queryInterface, Sequelize) {
await queryInterface.createTable('members', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
userId: {
type: Sequelize.INTEGER,
references: {
model: 'users',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
projectId: {
type: Sequelize.INTEGER,
references: {
model: 'projects',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
role: {
type: Sequelize.INTEGER,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
/** @type {import('sequelize-cli').Migration} */ await queryInterface.addIndex('members', ['userId', 'projectId'], {
module.exports = { unique: true,
up: async (queryInterface, Sequelize) => { });
await queryInterface.createTable('members', { }
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
userId: {
type: Sequelize.INTEGER,
references: {
model: 'users',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
projectId: {
type: Sequelize.INTEGER,
references: {
model: 'projects',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
role: {
type: Sequelize.INTEGER,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
});
await queryInterface.addIndex('members', ['userId', 'projectId'], { export async function down(queryInterface) {
unique: true, await queryInterface.dropTable('members');
}); }
},
down: async (queryInterface) => {
await queryInterface.dropTable('members');
},
};

View File

@@ -1,26 +1,21 @@
'use strict'; export async function up(queryInterface) {
/**
* Add altering commands here.
*
* Example:
* await queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
/** @type {import('sequelize-cli').Migration} */ await queryInterface.renameColumn('users', 'createdAt', 'created_at');
module.exports = { await queryInterface.renameColumn('users', 'updatedAt', 'updated_at');
async up(queryInterface) { await queryInterface.renameColumn('users', 'avatarPath', 'avatar_path');
/** }
* Add altering commands here.
*
* Example:
* await queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
await queryInterface.renameColumn('users', 'createdAt', 'created_at'); export async function down() {
await queryInterface.renameColumn('users', 'updatedAt', 'updated_at'); /**
await queryInterface.renameColumn('users', 'avatarPath', 'avatar_path'); * Add reverting commands here.
}, *
* Example:
async down() { * await queryInterface.dropTable('users');
/** */
* Add reverting commands here. }
*
* Example:
* await queryInterface.dropTable('users');
*/
},
};

View File

@@ -1,13 +1,9 @@
'use strict'; export async function up(queryInterface) {
// Rename column 'path' to 'filename' in 'Attachments' table
await queryInterface.renameColumn('Attachments', 'path', 'filename');
}
module.exports = { export async function down(queryInterface) {
up: async (queryInterface) => { // Revert column name from 'filename' back to 'path'
// Rename column 'path' to 'filename' in 'Attachments' table await queryInterface.renameColumn('Attachments', 'filename', 'path');
await queryInterface.renameColumn('Attachments', 'path', 'filename'); }
},
down: async (queryInterface) => {
// Revert column name from 'filename' back to 'path'
await queryInterface.renameColumn('Attachments', 'filename', 'path');
},
};

View File

@@ -1,22 +1,17 @@
'use strict'; export async function up(queryInterface) {
await queryInterface.addConstraint('folders', {
fields: ['parentFolderId'],
type: 'foreign key',
name: 'fk_folders_parentFolderId',
references: {
table: 'folders',
field: 'id',
},
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
}
/** @type {import('sequelize-cli').Migration} */ export async function down(queryInterface) {
module.exports = { await queryInterface.removeConstraint('folders', 'fk_folders_parentFolderId');
async up(queryInterface) { }
await queryInterface.addConstraint('folders', {
fields: ['parentFolderId'],
type: 'foreign key',
name: 'fk_folders_parentFolderId',
references: {
table: 'folders',
field: 'id',
},
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
},
async down(queryInterface) {
await queryInterface.removeConstraint('folders', 'fk_folders_parentFolderId');
},
};

View File

@@ -23,4 +23,4 @@ function defineAttachment(sequelize, DataTypes) {
return Attachment; return Attachment;
} }
module.exports = defineAttachment; export default defineAttachment;

View File

@@ -24,4 +24,4 @@ function defineCaseAttachment(sequelize, DataTypes) {
return CaseAttachment; return CaseAttachment;
} }
module.exports = defineCaseAttachment; export default defineCaseAttachment;

View File

@@ -28,4 +28,4 @@ function defineCaseStep(sequelize, DataTypes) {
return CaseStep; return CaseStep;
} }
module.exports = defineCaseStep; export default defineCaseStep;

View File

@@ -60,4 +60,4 @@ function defineCase(sequelize, DataTypes) {
return Case; return Case;
} }
module.exports = defineCase; export default defineCase;

View File

@@ -37,4 +37,4 @@ function defineFolder(sequelize, DataTypes) {
return Folder; return Folder;
} }
module.exports = defineFolder; export default defineFolder;

View File

@@ -1,12 +1,13 @@
'use strict'; import fs from 'fs';
import path from 'path';
const fs = require('fs'); import { fileURLToPath } from 'url';
const path = require('path'); import process from 'process';
const process = require('process'); import Sequelize from 'sequelize';
const Sequelize = require('sequelize'); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const basename = path.basename(__filename); const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development'; import configDefault from '../config/config';
const config = require(__dirname + '/../config/config.json')[env]; const config = configDefault[process.env.NODE_ENV || 'development'];
const db = {}; const db = {};
let sequelize; let sequelize;
@@ -16,14 +17,15 @@ if (config.use_env_variable) {
sequelize = new Sequelize(config.database, config.username, config.password, config); sequelize = new Sequelize(config.database, config.username, config.password, config);
} }
fs.readdirSync(__dirname) const modelFiles = fs.readdirSync(__dirname).filter((file) => {
.filter((file) => { return file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js' && file.indexOf('.test.js') === -1;
return file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js' && file.indexOf('.test.js') === -1; });
})
.forEach((file) => { for (const file of modelFiles) {
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes); const module = await import(path.join(__dirname, file));
db[model.name] = model; const model = module.default(sequelize, Sequelize.DataTypes);
}); db[model.name] = model;
}
Object.keys(db).forEach((modelName) => { Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) { if (db[modelName].associate) {
@@ -34,4 +36,4 @@ Object.keys(db).forEach((modelName) => {
db.sequelize = sequelize; db.sequelize = sequelize;
db.Sequelize = Sequelize; db.Sequelize = Sequelize;
module.exports = db; export default db;

View File

@@ -28,4 +28,4 @@ function defineMember(sequelize, DataTypes) {
return Member; return Member;
} }
module.exports = defineMember; export default defineMember;

View File

@@ -32,4 +32,4 @@ function defineProject(sequelize, DataTypes) {
return Project; return Project;
} }
module.exports = defineProject; export default defineProject;

View File

@@ -28,4 +28,4 @@ function defineRunCase(sequelize, DataTypes) {
return RunCase; return RunCase;
} }
module.exports = defineRunCase; export default defineRunCase;

View File

@@ -34,4 +34,4 @@ function defineRun(sequelize, DataTypes) {
return Run; return Run;
} }
module.exports = defineRun; export default defineRun;

View File

@@ -19,4 +19,4 @@ function defineStep(sequelize, DataTypes) {
return Step; return Step;
} }
module.exports = defineStep; export default defineStep;

View File

@@ -1,9 +1,3 @@
/**
*
* @param {import('sequelize').Sequelize} sequelize
* @param {*} DataTypes
* @returns
*/
function defineUser(sequelize, DataTypes) { function defineUser(sequelize, DataTypes) {
const User = sequelize.define( const User = sequelize.define(
'User', 'User',
@@ -39,4 +33,4 @@ function defineUser(sequelize, DataTypes) {
return User; return User;
} }
module.exports = defineUser; export default defineUser;

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
"name": "unittcms-backend", "name": "unittcms-backend",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"type": "module",
"scripts": { "scripts": {
"start": "node --env-file=.env index", "start": "node --env-file=.env index",
"dev": "node index", "dev": "node index",
@@ -19,8 +20,8 @@
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"papaparse": "^5.5.2", "papaparse": "^5.5.2",
"sequelize": "^6.37.5", "sequelize": "^6.37.7",
"sequelize-cli": "^6.6.2", "sequelize-cli": "^6.6.3",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
"xmlbuilder2": "^3.1.1" "xmlbuilder2": "^3.1.1"
} }

View File

@@ -1,13 +1,17 @@
const fs = require('fs'); import fs from 'fs';
const path = require('path'); import path from 'path';
const express = require('express'); import { fileURLToPath } from 'url';
import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineAttachment = require('../../models/attachments'); import defineAttachment from '../../models/attachments.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
module.exports = function (sequelize) { export default function (sequelize) {
const Attachment = defineAttachment(sequelize, DataTypes); const Attachment = defineAttachment(sequelize, DataTypes);
// TODO middleware to verify user permission to delete attachment
router.delete('/:attachmentId', async (req, res) => { router.delete('/:attachmentId', async (req, res) => {
const attachmentId = req.params.attachmentId; const attachmentId = req.params.attachmentId;
const t = await sequelize.transaction(); const t = await sequelize.transaction();
@@ -41,4 +45,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,12 +1,17 @@
const fs = require('fs'); import fs from 'fs';
const path = require('path'); import path from 'path';
const express = require('express'); import { fileURLToPath } from 'url';
import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineAttachment = require('../../models/attachments'); import defineAttachment from '../../models/attachments.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
module.exports = function (sequelize) { export default function (sequelize) {
const Attachment = defineAttachment(sequelize, DataTypes); const Attachment = defineAttachment(sequelize, DataTypes);
// TODO middleware to verify user permission to get attachment
router.get('/download/:attachmentId', async (req, res) => { router.get('/download/:attachmentId', async (req, res) => {
const attachmentId = req.params.attachmentId; const attachmentId = req.params.attachmentId;
@@ -30,4 +35,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,13 +1,16 @@
const fs = require('fs'); import fs from 'fs';
const path = require('path'); import path from 'path';
const express = require('express'); import { fileURLToPath } from 'url';
import multer from 'multer';
import express from 'express';
const router = express.Router(); const router = express.Router();
const multer = require('multer'); import { DataTypes } from 'sequelize';
const { DataTypes } = require('sequelize'); import defineAttachment from '../../models/attachments.js';
const defineAttachment = require('../../models/attachments'); import defineCaseAttachment from '../../models/caseAttachments.js';
const defineCaseAttachment = require('../../models/caseAttachments'); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
module.exports = function (sequelize) { export default function (sequelize) {
const Attachment = defineAttachment(sequelize, DataTypes); const Attachment = defineAttachment(sequelize, DataTypes);
const CaseAttachment = defineCaseAttachment(sequelize, DataTypes); const CaseAttachment = defineCaseAttachment(sequelize, DataTypes);
@@ -46,6 +49,7 @@ module.exports = function (sequelize) {
const upload = multer({ storage }); const upload = multer({ storage });
// TODO middleware to verify user permission to upload files
router.post('/', upload.array('files', 10), async (req, res) => { router.post('/', upload.array('files', 10), async (req, res) => {
const t = await sequelize.transaction(); const t = await sequelize.transaction();
try { try {
@@ -79,4 +83,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineCase = require('../../models/cases'); import defineCase from '../../models/cases.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectDeveloperFromProjectId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectDeveloperFromProjectId } = editableMiddleware(sequelize);
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
router.post('/bulkdelete', verifySignedIn, verifyProjectDeveloperFromProjectId, async (req, res) => { router.post('/bulkdelete', verifySignedIn, verifyProjectDeveloperFromProjectId, async (req, res) => {
@@ -24,4 +26,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,13 +1,15 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const Papa = require('papaparse'); import Papa from 'papaparse';
const defineCase = require('../../models/cases'); import defineCase from '../../models/cases.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
module.exports = function (sequelize) { export default function (sequelize) {
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectVisibleFromFolderId } = require('../../middleware/verifyVisible')(sequelize); const { verifyProjectVisibleFromFolderId } = visibilityMiddleware(sequelize);
router.get('/download', verifySignedIn, verifyProjectVisibleFromFolderId, async (req, res) => { router.get('/download', verifySignedIn, verifyProjectVisibleFromFolderId, async (req, res) => {
const { folderId, type } = req.query; const { folderId, type } = req.query;
@@ -51,4 +53,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineCase = require('../../models/cases'); import defineCase from '../../models/cases.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectDeveloperFromCaseId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectDeveloperFromCaseId } = editableMiddleware(sequelize);
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
router.put('/:caseId', verifySignedIn, verifyProjectDeveloperFromCaseId, async (req, res) => { router.put('/:caseId', verifySignedIn, verifyProjectDeveloperFromCaseId, async (req, res) => {
@@ -30,4 +32,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,14 +1,14 @@
import express from 'express'; import express from 'express';
const router = express.Router(); const router = express.Router();
import { DataTypes, Op } from 'sequelize'; import { DataTypes, Op } from 'sequelize';
import defineCase from '../../models/cases'; import defineCase from '../../models/cases.js';
import authMiddleware from '../../middleware/auth.js'; import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible'; import visibilityMiddleware from '../../middleware/verifyVisible.js';
export default function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = authMiddleware(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const Case = defineCase(sequelize, DataTypes);
const { verifyProjectVisibleFromFolderId } = visibilityMiddleware(sequelize); const { verifyProjectVisibleFromFolderId } = visibilityMiddleware(sequelize);
const Case = defineCase(sequelize, DataTypes);
router.get('/', verifySignedIn, verifyProjectVisibleFromFolderId, async (req, res) => { router.get('/', verifySignedIn, verifyProjectVisibleFromFolderId, async (req, res) => {
const { folderId, priority, type, q } = req.query; const { folderId, priority, type, q } = req.query;

View File

@@ -5,7 +5,7 @@ import { Sequelize, Op } from 'sequelize';
import casesIndexRoute from './index'; import casesIndexRoute from './index';
// mock of authentication middleware // mock of authentication middleware
vi.mock('../../middleware/auth', () => ({ vi.mock('../../middleware/auth.js', () => ({
default: () => ({ default: () => ({
verifySignedIn: vi.fn((req, res, next) => { verifySignedIn: vi.fn((req, res, next) => {
req.userId = 1; req.userId = 1;
@@ -13,7 +13,7 @@ vi.mock('../../middleware/auth', () => ({
}), }),
}), }),
})); }));
vi.mock('../../middleware/verifyVisible', () => ({ vi.mock('../../middleware/verifyVisible.js', () => ({
default: () => ({ default: () => ({
verifyProjectVisibleFromFolderId: vi.fn((req, res, next) => { verifyProjectVisibleFromFolderId: vi.fn((req, res, next) => {
next(); next();
@@ -25,7 +25,7 @@ vi.mock('../../middleware/verifyVisible', () => ({
const mockCase = { const mockCase = {
findAll: vi.fn(), findAll: vi.fn(),
}; };
vi.mock('../../models/cases', () => ({ vi.mock('../../models/cases.js', () => ({
default: () => mockCase, default: () => mockCase,
})); }));

View File

@@ -1,12 +1,14 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineProject = require('../../models/projects'); import defineProject from '../../models/projects.js';
const defineFolder = require('../../models/folders'); import defineFolder from '../../models/folders.js';
const defineCase = require('../../models/cases'); import defineCase from '../../models/cases.js';
const defineRunCase = require('../../models/runCases'); import defineRunCase from '../../models/runCases.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
module.exports = function (sequelize) { export default function (sequelize) {
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
@@ -17,8 +19,8 @@ module.exports = function (sequelize) {
Case.belongsTo(Folder, { foreignKey: 'folderId' }); Case.belongsTo(Folder, { foreignKey: 'folderId' });
Case.hasMany(RunCase, { foreignKey: 'caseId' }); Case.hasMany(RunCase, { foreignKey: 'caseId' });
RunCase.belongsTo(Case, { foreignKey: 'caseId' }); RunCase.belongsTo(Case, { foreignKey: 'caseId' });
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectVisibleFromProjectId } = require('../../middleware/verifyVisible')(sequelize); const { verifyProjectVisibleFromProjectId } = visibilityMiddleware(sequelize);
router.get('/byproject', verifySignedIn, verifyProjectVisibleFromProjectId, async (req, res) => { router.get('/byproject', verifySignedIn, verifyProjectVisibleFromProjectId, async (req, res) => {
const { projectId } = req.query; const { projectId } = req.query;
@@ -51,4 +53,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,7 +1,9 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineCase = require('../../models/cases'); import defineCase from '../../models/cases.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
const requiredFields = ['title', 'state', 'priority', 'type', 'automationStatus', 'template']; const requiredFields = ['title', 'state', 'priority', 'type', 'automationStatus', 'template'];
@@ -13,9 +15,9 @@ function isEmpty(value) {
} }
} }
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectDeveloperFromFolderId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectDeveloperFromFolderId } = editableMiddleware(sequelize);
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
router.post('/', verifySignedIn, verifyProjectDeveloperFromFolderId, async (req, res) => { router.post('/', verifySignedIn, verifyProjectDeveloperFromFolderId, async (req, res) => {
@@ -56,4 +58,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineCase = require('../../models/cases'); import defineCase from '../../models/cases.js';
const defineStep = require('../../models/steps'); import defineStep from '../../models/steps.js';
const defineAttachment = require('../../models/attachments'); import defineAttachment from '../../models/attachments.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
module.exports = function (sequelize) { export default function (sequelize) {
const Case = defineCase(sequelize, DataTypes); const Case = defineCase(sequelize, DataTypes);
const Step = defineStep(sequelize, DataTypes); const Step = defineStep(sequelize, DataTypes);
const Attachment = defineAttachment(sequelize, DataTypes); const Attachment = defineAttachment(sequelize, DataTypes);
@@ -13,8 +15,8 @@ module.exports = function (sequelize) {
Step.belongsToMany(Case, { through: 'caseSteps' }); Step.belongsToMany(Case, { through: 'caseSteps' });
Case.belongsToMany(Attachment, { through: 'caseAttachments' }); Case.belongsToMany(Attachment, { through: 'caseAttachments' });
Attachment.belongsToMany(Case, { through: 'caseAttachments' }); Attachment.belongsToMany(Case, { through: 'caseAttachments' });
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectVisibleFromCaseId } = require('../../middleware/verifyVisible')(sequelize); const { verifyProjectVisibleFromCaseId } = visibilityMiddleware(sequelize);
router.get('/:caseId', verifySignedIn, verifyProjectVisibleFromCaseId, async (req, res) => { router.get('/:caseId', verifySignedIn, verifyProjectVisibleFromCaseId, async (req, res) => {
const caseId = req.params.caseId; const caseId = req.params.caseId;
@@ -43,4 +45,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineFolder = require('../../models/folders'); import defineFolder from '../../models/folders.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectDeveloperFromFolderId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectDeveloperFromFolderId } = editableMiddleware(sequelize);
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
router.delete('/:folderId', verifySignedIn, verifyProjectDeveloperFromFolderId, async (req, res) => { router.delete('/:folderId', verifySignedIn, verifyProjectDeveloperFromFolderId, async (req, res) => {
@@ -24,4 +26,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineFolder = require('../../models/folders'); import defineFolder from '../../models/folders.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectDeveloperFromFolderId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectDeveloperFromFolderId } = editableMiddleware(sequelize);
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
router.put('/:folderId', verifySignedIn, verifyProjectDeveloperFromFolderId, async (req, res) => { router.put('/:folderId', verifySignedIn, verifyProjectDeveloperFromFolderId, async (req, res) => {
@@ -30,4 +32,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineFolder = require('../../models/folders'); import defineFolder from '../../models/folders.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectVisibleFromProjectId } = require('../../middleware/verifyVisible')(sequelize); const { verifyProjectVisibleFromProjectId } = visibilityMiddleware(sequelize);
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
router.get('/', verifySignedIn, verifyProjectVisibleFromProjectId, async (req, res) => { router.get('/', verifySignedIn, verifyProjectVisibleFromProjectId, async (req, res) => {
@@ -29,4 +31,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineFolder = require('../../models/folders'); import defineFolder from '../../models/folders.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectDeveloperFromProjectId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectDeveloperFromProjectId } = editableMiddleware(sequelize);
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
router.post('/', verifySignedIn, verifyProjectDeveloperFromProjectId, async (req, res) => { router.post('/', verifySignedIn, verifyProjectDeveloperFromProjectId, async (req, res) => {
@@ -31,4 +33,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,10 +1,10 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
module.exports = function () { export default function () {
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
res.json({ status: 'ok' }); res.json({ status: 'ok' });
}); });
return router; return router;
}; }

View File

@@ -1,15 +1,17 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineProject = require('../../models/projects'); import defineProject from '../../models/projects.js';
const defineFolder = require('../../models/folders'); import defineFolder from '../../models/folders.js';
const defineCase = require('../../models/cases'); import defineCase from '../../models/cases.js';
const defineRun = require('../../models/runs'); import defineRun from '../../models/runs.js';
const defineRunCase = require('../../models/runCases'); import defineRunCase from '../../models/runCases.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectVisibleFromProjectId } = require('../../middleware/verifyVisible')(sequelize); const { verifyProjectVisibleFromProjectId } = visibilityMiddleware(sequelize);
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
@@ -49,4 +51,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,9 +1,10 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
// "/" GET export default function () {
router.get('/', (req, res) => { router.get('/', (req, res) => {
res.send('This is UnitTCMS API server'); res.send('This is UnitTCMS API server');
}); });
module.exports = router; return router;
}

View File

@@ -1,11 +1,12 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineMember = require('../../models/members'); import defineMember from '../../models/members.js';
const defineProject = require('../../models/projects'); import defineProject from '../../models/projects.js';
import authMiddleware from '../../middleware/auth.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const Member = defineMember(sequelize, DataTypes); const Member = defineMember(sequelize, DataTypes);
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
@@ -45,4 +46,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineMember = require('../../models/members'); import defineMember from '../../models/members.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectManagerFromProjectId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectManagerFromProjectId } = editableMiddleware(sequelize);
const Member = defineMember(sequelize, DataTypes); const Member = defineMember(sequelize, DataTypes);
router.delete('/', verifySignedIn, verifyProjectManagerFromProjectId, async (req, res) => { router.delete('/', verifySignedIn, verifyProjectManagerFromProjectId, async (req, res) => {
@@ -34,4 +36,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineMember = require('../../models/members'); import defineMember from '../../models/members.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectManagerFromProjectId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectManagerFromProjectId } = editableMiddleware(sequelize);
const Member = defineMember(sequelize, DataTypes); const Member = defineMember(sequelize, DataTypes);
router.put('/', verifySignedIn, verifyProjectManagerFromProjectId, async (req, res) => { router.put('/', verifySignedIn, verifyProjectManagerFromProjectId, async (req, res) => {
@@ -38,4 +40,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,12 +1,14 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineUser = require('../../models/users'); import defineUser from '../../models/users.js';
const defineMember = require('../../models/members'); import defineMember from '../../models/members.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectVisibleFromProjectId } = require('../../middleware/verifyVisible')(sequelize); const { verifyProjectVisibleFromProjectId } = visibilityMiddleware(sequelize);
const User = defineUser(sequelize, DataTypes); const User = defineUser(sequelize, DataTypes);
const Member = defineMember(sequelize, DataTypes); const Member = defineMember(sequelize, DataTypes);
Member.belongsTo(User, { foreignKey: 'userId' }); Member.belongsTo(User, { foreignKey: 'userId' });
@@ -37,4 +39,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,12 +1,14 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineMember = require('../../models/members'); import defineMember from '../../models/members.js';
const { memberRoles } = require('../../routes/users/authSettings'); import { memberRoles } from '../../routes/users/authSettings.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectManagerFromProjectId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectManagerFromProjectId } = editableMiddleware(sequelize);
const Member = defineMember(sequelize, DataTypes); const Member = defineMember(sequelize, DataTypes);
router.post('/', verifySignedIn, verifyProjectManagerFromProjectId, async (req, res) => { router.post('/', verifySignedIn, verifyProjectManagerFromProjectId, async (req, res) => {
@@ -41,4 +43,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,13 +1,15 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineProject = require('../../models/projects'); import defineProject from '../../models/projects.js';
const defineFolder = require('../../models/folders'); import defineFolder from '../../models/folders.js';
const defineRun = require('../../models/runs'); import defineRun from '../../models/runs.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectOwner } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectOwner } = editableMiddleware(sequelize);
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
@@ -38,4 +40,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineProject = require('../../models/projects'); import defineProject from '../../models/projects.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectOwner } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectOwner } = editableMiddleware(sequelize);
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
router.put('/:projectId', verifySignedIn, verifyProjectOwner, async (req, res) => { router.put('/:projectId', verifySignedIn, verifyProjectOwner, async (req, res) => {
@@ -29,4 +31,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,12 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes, Op } = require('sequelize'); import { DataTypes, Op } from 'sequelize';
const defineProject = require('../../models/projects'); import defineProject from '../../models/projects.js';
const defineMember = require('../../models/members'); import defineMember from '../../models/members.js';
import authMiddleware from '../../middleware/auth.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
const Member = defineMember(sequelize, DataTypes); const Member = defineMember(sequelize, DataTypes);
Project.hasMany(Member, { foreignKey: 'projectId' }); Project.hasMany(Member, { foreignKey: 'projectId' });
@@ -49,4 +50,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,10 +1,11 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineProject = require('../../models/projects'); import defineProject from '../../models/projects.js';
import authMiddleware from '../../middleware/auth.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
router.post('/', verifySignedIn, async (req, res) => { router.post('/', verifySignedIn, async (req, res) => {
@@ -24,4 +25,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,12 +1,14 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineProject = require('../../models/projects'); import defineProject from '../../models/projects.js';
const defineFolder = require('../../models/folders'); import defineFolder from '../../models/folders.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectVisibleFromProjectId } = require('../../middleware/verifyVisible')(sequelize); const { verifyProjectVisibleFromProjectId } = visibilityMiddleware(sequelize);
const Project = defineProject(sequelize, DataTypes); const Project = defineProject(sequelize, DataTypes);
const Folder = defineFolder(sequelize, DataTypes); const Folder = defineFolder(sequelize, DataTypes);
Project.hasMany(Folder, { foreignKey: 'projectId' }); Project.hasMany(Folder, { foreignKey: 'projectId' });
@@ -36,4 +38,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineRunCase = require('../../models/runCases'); import defineRunCase from '../../models/runCases.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectReporterFromRunId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectReporterFromRunId } = editableMiddleware(sequelize);
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
router.post('/update', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => { router.post('/update', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => {
@@ -71,4 +73,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineRunCase = require('../../models/runCases'); import defineRunCase from '../../models/runCases.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectVisibleFromRunId } = require('../../middleware/verifyVisible')(sequelize); const { verifyProjectVisibleFromRunId } = visibilityMiddleware(sequelize);
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
router.get('/', verifySignedIn, verifyProjectVisibleFromRunId, async (req, res) => { router.get('/', verifySignedIn, verifyProjectVisibleFromRunId, async (req, res) => {
@@ -29,4 +31,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineRun = require('../../models/runs'); import defineRun from '../../models/runs.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectReporterFromRunId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectReporterFromRunId } = editableMiddleware(sequelize);
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
router.delete('/:runId', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => { router.delete('/:runId', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => {
@@ -24,4 +26,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,17 +1,18 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const Papa = require('papaparse'); import { DataTypes } from 'sequelize';
const { create } = require('xmlbuilder2'); import Papa from 'papaparse';
import { create } from 'xmlbuilder2';
import defineRun from '../../models/runs.js';
import defineRunCase from '../../models/runCases.js';
import defineCase from '../../models/cases.js';
import defineFolder from '../../models/folders.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
const defineRun = require('../../models/runs'); export default function (sequelize) {
const defineRunCase = require('../../models/runCases'); const { verifySignedIn } = authMiddleware(sequelize);
const defineCase = require('../../models/cases'); const { verifyProjectVisibleFromRunId } = visibilityMiddleware(sequelize);
const defineFolder = require('../../models/folders');
module.exports = function (sequelize) {
const { DataTypes } = require('sequelize');
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
const { verifyProjectVisibleFromRunId } = require('../../middleware/verifyVisible')(sequelize);
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
@@ -123,4 +124,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,12 +1,14 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineRun = require('../../models/runs'); import defineRun from '../../models/runs.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectReporterFromRunId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectReporterFromRunId } = editableMiddleware(sequelize);
router.put('/:runId', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => { router.put('/:runId', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => {
const runId = req.params.runId; const runId = req.params.runId;
@@ -27,4 +29,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineRun = require('../../models/runs'); import defineRun from '../../models/runs.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectVisibleFromProjectId } = require('../../middleware/verifyVisible')(sequelize); const { verifyProjectVisibleFromProjectId } = visibilityMiddleware(sequelize);
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
router.get('/', verifySignedIn, verifyProjectVisibleFromProjectId, async (req, res) => { router.get('/', verifySignedIn, verifyProjectVisibleFromProjectId, async (req, res) => {
@@ -29,4 +31,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,13 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineRun = require('../../models/runs'); import defineRun from '../../models/runs.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectReporterFromProjectId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectReporterFromProjectId } = editableMiddleware(sequelize);
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
router.post('/', verifySignedIn, verifyProjectReporterFromProjectId, async (req, res) => { router.post('/', verifySignedIn, verifyProjectReporterFromProjectId, async (req, res) => {
@@ -32,4 +34,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,12 +1,14 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes, literal } = require('sequelize'); import { DataTypes, literal } from 'sequelize';
const defineRun = require('../../models/runs'); import defineRun from '../../models/runs.js';
const defineRunCase = require('../../models/runCases'); import defineRunCase from '../../models/runCases.js';
import authMiddleware from '../../middleware/auth.js';
import visibilityMiddleware from '../../middleware/verifyVisible.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectVisibleFromRunId } = require('../../middleware/verifyVisible')(sequelize); const { verifyProjectVisibleFromRunId } = visibilityMiddleware(sequelize);
const Run = defineRun(sequelize, DataTypes); const Run = defineRun(sequelize, DataTypes);
const RunCase = defineRunCase(sequelize, DataTypes); const RunCase = defineRunCase(sequelize, DataTypes);
@@ -40,4 +42,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,14 +1,16 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineStep = require('../../models/steps'); import defineStep from '../../models/steps.js';
const defineCaseStep = require('../../models/caseSteps'); import defineCaseStep from '../../models/caseSteps.js';
import authMiddleware from '../../middleware/auth.js';
import editableMiddleware from '../../middleware/verifyEditable.js';
module.exports = function (sequelize) { export default function (sequelize) {
const Step = defineStep(sequelize, DataTypes); const Step = defineStep(sequelize, DataTypes);
const CaseStep = defineCaseStep(sequelize, DataTypes); const CaseStep = defineCaseStep(sequelize, DataTypes);
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const { verifyProjectDeveloperFromCaseId } = require('../../middleware/verifyEditable')(sequelize); const { verifyProjectDeveloperFromCaseId } = editableMiddleware(sequelize);
router.post('/update', verifySignedIn, verifyProjectDeveloperFromCaseId, async (req, res) => { router.post('/update', verifySignedIn, verifyProjectDeveloperFromCaseId, async (req, res) => {
const caseId = req.query.caseId; const caseId = req.query.caseId;
@@ -87,4 +89,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -2,4 +2,4 @@ const roles = [{ uid: 'administrator' }, { uid: 'user' }];
const memberRoles = [{ uid: 'manager' }, { uid: 'developer' }, { uid: 'reporter' }]; const memberRoles = [{ uid: 'manager' }, { uid: 'developer' }, { uid: 'reporter' }];
const defaultDangerKey = 'test-plat-default-key'; const defaultDangerKey = 'test-plat-default-key';
module.exports = { roles, memberRoles, defaultDangerKey }; export { roles, memberRoles, defaultDangerKey };

View File

@@ -1,10 +1,11 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineUser = require('../../models/users'); import defineUser from '../../models/users.js';
import authMiddleware from '../../middleware/auth.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const User = defineUser(sequelize, DataTypes); const User = defineUser(sequelize, DataTypes);
router.get('/find/:userId', verifySignedIn, async (req, res) => { router.get('/find/:userId', verifySignedIn, async (req, res) => {
@@ -33,4 +34,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,10 +1,11 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const defineUser = require('../../models/users'); import defineUser from '../../models/users.js';
import authMiddleware from '../../middleware/auth.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn, verifyAdmin } = require('../../middleware/auth')(sequelize); const { verifySignedIn, verifyAdmin } = authMiddleware(sequelize);
const User = defineUser(sequelize, DataTypes); const User = defineUser(sequelize, DataTypes);
router.get('/', verifySignedIn, verifyAdmin, async (req, res) => { router.get('/', verifySignedIn, verifyAdmin, async (req, res) => {
@@ -20,4 +21,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,11 +1,12 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes, Op } = require('sequelize'); import { DataTypes, Op } from 'sequelize';
const defineUser = require('../../models/users'); import defineUser from '../../models/users.js';
const defineMember = require('../../models/members'); import defineMember from '../../models/members.js';
import authMiddleware from '../../middleware/auth.js';
module.exports = function (sequelize) { export default function (sequelize) {
const { verifySignedIn } = require('../../middleware/auth')(sequelize); const { verifySignedIn } = authMiddleware(sequelize);
const User = defineUser(sequelize, DataTypes); const User = defineUser(sequelize, DataTypes);
const Member = defineMember(sequelize, DataTypes); const Member = defineMember(sequelize, DataTypes);
@@ -42,4 +43,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,12 +1,12 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const bcrypt = require('bcrypt'); import bcrypt from 'bcrypt';
const jwt = require('jsonwebtoken'); import jwt from 'jsonwebtoken';
const defineUser = require('../../models/users'); import defineUser from '../../models/users.js';
const { defaultDangerKey } = require('./authSettings'); import { defaultDangerKey } from './authSettings.js';
module.exports = function (sequelize) { export default function (sequelize) {
const User = defineUser(sequelize, DataTypes); const User = defineUser(sequelize, DataTypes);
const secretKey = process.env.SECRET_KEY || defaultDangerKey; const secretKey = process.env.SECRET_KEY || defaultDangerKey;
@@ -39,4 +39,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -1,12 +1,12 @@
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
const { DataTypes } = require('sequelize'); import { DataTypes } from 'sequelize';
const bcrypt = require('bcrypt'); import bcrypt from 'bcrypt';
const jwt = require('jsonwebtoken'); import jwt from 'jsonwebtoken';
const defineUser = require('../../models/users'); import defineUser from '../../models/users.js';
const { roles, defaultDangerKey } = require('./authSettings'); import { roles, defaultDangerKey } from './authSettings.js';
module.exports = function (sequelize) { export default function (sequelize) {
const User = defineUser(sequelize, DataTypes); const User = defineUser(sequelize, DataTypes);
const secretKey = process.env.SECRET_KEY || defaultDangerKey; const secretKey = process.env.SECRET_KEY || defaultDangerKey;
@@ -42,4 +42,4 @@ module.exports = function (sequelize) {
}); });
return router; return router;
}; }

View File

@@ -3,13 +3,13 @@ import request from 'supertest';
import express from 'express'; import express from 'express';
import { Sequelize } from 'sequelize'; import { Sequelize } from 'sequelize';
import updateRoute from './update'; import updateRoute from './update';
import { roles } from './authSettings'; import { roles } from './authSettings.js';
const adminRoleIndex = roles.findIndex((entry) => entry.uid === 'administrator'); const adminRoleIndex = roles.findIndex((entry) => entry.uid === 'administrator');
const userRoleIndex = roles.findIndex((entry) => entry.uid === 'user'); const userRoleIndex = roles.findIndex((entry) => entry.uid === 'user');
// mock of authentication middleware // mock of authentication middleware
vi.mock('../../middleware/auth', () => ({ vi.mock('../../middleware/auth.js', () => ({
default: () => ({ default: () => ({
verifySignedIn: vi.fn((req, res, next) => { verifySignedIn: vi.fn((req, res, next) => {
req.userId = 1; // Mock user ID req.userId = 1; // Mock user ID
@@ -27,7 +27,7 @@ const mockUser = {
count: vi.fn(), count: vi.fn(),
update: vi.fn(), update: vi.fn(),
}; };
vi.mock('../../models/users', () => ({ vi.mock('../../models/users.js', () => ({
default: () => mockUser, default: () => mockUser,
})); }));

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,12 @@
const path = require('path'); import path from 'path';
const express = require('express'); import express from 'express';
const RateLimit = require('express-rate-limit'); import cors from 'cors';
const { Sequelize } = require('sequelize'); import RateLimit from 'express-rate-limit';
import { Sequelize } from 'sequelize';
const __dirname = path.dirname(new URL(import.meta.url).pathname);
const app = express(); const app = express();
// enable frontend access // enable frontend access
const cors = require('cors');
const frontendOrigin = process.env.FRONTEND_ORIGIN || 'http://localhost:8000'; const frontendOrigin = process.env.FRONTEND_ORIGIN || 'http://localhost:8000';
const corsOptions = { const corsOptions = {
origin: frontendOrigin, origin: frontendOrigin,
@@ -36,116 +37,113 @@ const sequelize = new Sequelize({
}); });
// "/" // "/"
const indexRoute = require('./routes/index'); import indexRoute from './routes/index.js';
app.use('/', indexRoute); app.use('/', indexRoute());
// "/health" // "/health"
const healthIndexRoute = require('./routes/health/index')(); import healthIndexRoute from './routes/health/index.js';
app.use('/health', healthIndexRoute); app.use('/health', healthIndexRoute());
// "users" // "users"
const usersIndexRoute = require('./routes/users/index')(sequelize); import usersIndexRoute from './routes/users/index.js';
const usersFindRoute = require('./routes/users/find')(sequelize); import usersFindRoute from './routes/users/find.js';
const usersSearchRoute = require('./routes/users/search')(sequelize); import usersSearchRoute from './routes/users/search.js';
const signUpRoute = require('./routes/users/signup')(sequelize); import usersUpdateRoute from './routes/users/update.js';
const signInRoute = require('./routes/users/signin')(sequelize); import signUpRoute from './routes/users/signup.js';
app.use('/users', usersIndexRoute); import signInRoute from './routes/users/signin.js';
app.use('/users', usersFindRoute); app.use('/users', usersIndexRoute(sequelize));
app.use('/users', usersSearchRoute); app.use('/users', usersFindRoute(sequelize));
app.use('/users', signUpRoute); app.use('/users', usersSearchRoute(sequelize));
app.use('/users', signInRoute); app.use('/users', usersUpdateRoute(sequelize));
// ESM import app.use('/users', signUpRoute(sequelize));
(async () => { app.use('/users', signInRoute(sequelize));
const updateRoute = await import('./routes/users/update.mjs');
app.use('/users', updateRoute.default(sequelize));
})();
// "/projects" // "/projects"
const projectsIndexRoute = require('./routes/projects/index')(sequelize); import projectsIndexRoute from './routes/projects/index.js';
const projectsShowRoute = require('./routes/projects/show')(sequelize); import projectsShowRoute from './routes/projects/show.js';
const projectsNewRoute = require('./routes/projects/new')(sequelize); import projectsNewRoute from './routes/projects/new.js';
const projectsEditRoute = require('./routes/projects/edit')(sequelize); import projectsEditRoute from './routes/projects/edit.js';
const projectsDeleteRoute = require('./routes/projects/delete')(sequelize); import projectsDeleteRoute from './routes/projects/delete.js';
app.use('/projects', projectsIndexRoute); app.use('/projects', projectsIndexRoute(sequelize));
app.use('/projects', projectsShowRoute); app.use('/projects', projectsShowRoute(sequelize));
app.use('/projects', projectsNewRoute); app.use('/projects', projectsNewRoute(sequelize));
app.use('/projects', projectsEditRoute); app.use('/projects', projectsEditRoute(sequelize));
app.use('/projects', projectsDeleteRoute); app.use('/projects', projectsDeleteRoute(sequelize));
// "/folders" // "/folders"
const foldersIndexRoute = require('./routes/folders/index')(sequelize); import foldersIndexRoute from './routes/folders/index.js';
const foldersNewRoute = require('./routes/folders/new')(sequelize); import foldersNewRoute from './routes/folders/new.js';
const foldersEditRoute = require('./routes/folders/edit')(sequelize); import foldersEditRoute from './routes/folders/edit.js';
const foldersDeleteRoute = require('./routes/folders/delete')(sequelize); import foldersDeleteRoute from './routes/folders/delete.js';
app.use('/folders', foldersIndexRoute); app.use('/folders', foldersIndexRoute(sequelize));
app.use('/folders', foldersNewRoute); app.use('/folders', foldersNewRoute(sequelize));
app.use('/folders', foldersEditRoute); app.use('/folders', foldersEditRoute(sequelize));
app.use('/folders', foldersDeleteRoute); app.use('/folders', foldersDeleteRoute(sequelize));
// "/cases" // "/cases"
// "/cases" import casesDownloadRoute from './routes/cases/download.js';
const casesDownloadRoute = require('./routes/cases/download')(sequelize); import casesIndexRoute from './routes/cases/index.js';
const casesIndexRoute = require('./routes/cases/index')(sequelize); import casesIndexByProjectIdRoute from './routes/cases/indexByProjectId.js';
const casesIndexByProjectIdRoute = require('./routes/cases/indexByProjectId')(sequelize); import casesShowRoute from './routes/cases/show.js';
const casesShowRoute = require('./routes/cases/show')(sequelize); import casesNewRoute from './routes/cases/new.js';
const casesNewRoute = require('./routes/cases/new')(sequelize); import casesEditRoute from './routes/cases/edit.js';
const casesEditRoute = require('./routes/cases/edit')(sequelize); import casesDeleteRoute from './routes/cases/delete.js';
const casesDeleteRoute = require('./routes/cases/delete')(sequelize); app.use('/cases', casesDownloadRoute(sequelize));
app.use('/cases', casesDownloadRoute); app.use('/cases', casesIndexRoute(sequelize));
app.use('/cases', casesIndexRoute); app.use('/cases', casesIndexByProjectIdRoute(sequelize));
app.use('/cases', casesIndexByProjectIdRoute); app.use('/cases', casesShowRoute(sequelize));
app.use('/cases', casesShowRoute); app.use('/cases', casesNewRoute(sequelize));
app.use('/cases', casesNewRoute); app.use('/cases', casesEditRoute(sequelize));
app.use('/cases', casesEditRoute); app.use('/cases', casesDeleteRoute(sequelize));
app.use('/cases', casesDeleteRoute);
// "/steps" // "/steps"
const stepsEditRoute = require('./routes/steps/edit')(sequelize); import stepsEditRoute from './routes/steps/edit.js';
app.use('/steps', stepsEditRoute); app.use('/steps', stepsEditRoute(sequelize));
// "/attachments" // "/attachments"
const attachmentsNewRoute = require('./routes/attachments/new')(sequelize); import attachmentsNewRoute from './routes/attachments/new.js';
const attachmentsDeleteRoute = require('./routes/attachments/delete')(sequelize); import attachmentsDeleteRoute from './routes/attachments/delete.js';
const attachmentsDownloadRoute = require('./routes/attachments/download')(sequelize); import attachmentsDownloadRoute from './routes/attachments/download.js';
app.use('/attachments', attachmentsNewRoute); app.use('/attachments', attachmentsNewRoute(sequelize));
app.use('/attachments', attachmentsDeleteRoute); app.use('/attachments', attachmentsDeleteRoute(sequelize));
app.use('/attachments', attachmentsDownloadRoute); app.use('/attachments', attachmentsDownloadRoute(sequelize));
// "/runs" // "/runs"
const runsDownloadRoute = require('./routes/runs/download')(sequelize); import runsDownloadRoute from './routes/runs/download.js';
const runsIndexRoute = require('./routes/runs/index')(sequelize); import runsIndexRoute from './routes/runs/index.js';
const runsShowRoute = require('./routes/runs/show')(sequelize); import runsShowRoute from './routes/runs/show.js';
const runsNewRoute = require('./routes/runs/new')(sequelize); import runsNewRoute from './routes/runs/new.js';
const runsEditRoute = require('./routes/runs/edit')(sequelize); import runsEditRoute from './routes/runs/edit.js';
const runDeleteRoute = require('./routes/runs/delete')(sequelize); import runDeleteRoute from './routes/runs/delete.js';
app.use('/runs', runsDownloadRoute);
app.use('/runs', runsIndexRoute); app.use('/runs', runsDownloadRoute(sequelize));
app.use('/runs', runsShowRoute); app.use('/runs', runsIndexRoute(sequelize));
app.use('/runs', runsNewRoute); app.use('/runs', runsShowRoute(sequelize));
app.use('/runs', runsEditRoute); app.use('/runs', runsNewRoute(sequelize));
app.use('/runs', runDeleteRoute); app.use('/runs', runsEditRoute(sequelize));
app.use('/runs', runDeleteRoute(sequelize));
// "/runcases" // "/runcases"
const runCaseIndexRoute = require('./routes/runcases/index')(sequelize); import runCaseIndexRoute from './routes/runcases/index.js';
const runCaseEditRoute = require('./routes/runcases/edit')(sequelize); import runCaseEditRoute from './routes/runcases/edit.js';
app.use('/runcases', runCaseIndexRoute); app.use('/runcases', runCaseIndexRoute(sequelize));
app.use('/runcases', runCaseEditRoute); app.use('/runcases', runCaseEditRoute(sequelize));
// "/members" // "/members"
const membersIndexRoute = require('./routes/members/index')(sequelize); import membersIndexRoute from './routes/members/index.js';
const membersNewRoute = require('./routes/members/new')(sequelize); import membersNewRoute from './routes/members/new.js';
const membersEditRoute = require('./routes/members/edit')(sequelize); import membersEditRoute from './routes/members/edit.js';
const membersDeleteRoute = require('./routes/members/delete')(sequelize); import membersDeleteRoute from './routes/members/delete.js';
const membersCheckRoute = require('./routes/members/check')(sequelize); import membersCheckRoute from './routes/members/check.js';
app.use('/members', membersIndexRoute); app.use('/members', membersIndexRoute(sequelize));
app.use('/members', membersNewRoute); app.use('/members', membersNewRoute(sequelize));
app.use('/members', membersEditRoute); app.use('/members', membersEditRoute(sequelize));
app.use('/members', membersDeleteRoute); app.use('/members', membersDeleteRoute(sequelize));
app.use('/members', membersCheckRoute); app.use('/members', membersCheckRoute(sequelize));
// "/home" // "/home"
const homeIndexRoute = require('./routes/home/index')(sequelize); import homeIndexRoute from './routes/home/index.js';
app.use('/home', homeIndexRoute); app.use('/home', homeIndexRoute(sequelize));
if (!process.env.SECRET_KEY) { if (!process.env.SECRET_KEY) {
console.log( console.log(
@@ -154,4 +152,4 @@ if (!process.env.SECRET_KEY) {
} }
// Export the app instead of starting the server // Export the app instead of starting the server
module.exports = app; export default app;

View File

@@ -1,9 +1,15 @@
import { createServer as createHttpServer } from 'http';
import path from 'path';
import fs from 'fs';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Use express from backend node_modules // Use express from backend node_modules
const { createServer: createHttpServer } = require('http'); import expressModule from './backend/node_modules/express/index.js';
const path = require('path'); const express = expressModule.default || expressModule;
const fs = require('fs');
const { execSync } = require('child_process');
const express = require('./backend/node_modules/express');
async function runMigrations() { async function runMigrations() {
try { try {
@@ -13,9 +19,7 @@ async function runMigrations() {
cwd: path.join(__dirname, 'backend'), cwd: path.join(__dirname, 'backend'),
stdio: 'inherit', stdio: 'inherit',
}); });
console.log('Database migrations completed successfully.'); console.log('Database migrations completed successfully.');
if (process.env.IS_DEMO === 'true' || process.env.IS_DEMO === '1') { if (process.env.IS_DEMO === 'true' || process.env.IS_DEMO === '1') {
console.log('Demo mode detected. Seeding the database...'); console.log('Demo mode detected. Seeding the database...');
execSync('npx sequelize-cli db:seed:all', { execSync('npx sequelize-cli db:seed:all', {
@@ -30,15 +34,14 @@ async function runMigrations() {
} }
} }
function startServer() { async function startServer() {
try { try {
const server = express(); const server = express();
const httpServer = createHttpServer(server); const httpServer = createHttpServer(server);
// Import the backend app // Import the backend app
const backendApp = require('./backend/server'); const backendAppModule = await import('./backend/server.js');
const backendApp = backendAppModule.default || backendAppModule;
// Use the backend app for /api routes
server.use('/api', backendApp); server.use('/api', backendApp);
// For Next.js standalone build // For Next.js standalone build
@@ -46,21 +49,18 @@ function startServer() {
const nextServerPath = './node_modules/next/dist/server/next.js'; const nextServerPath = './node_modules/next/dist/server/next.js';
if (fs.existsSync(nextServerPath)) { if (fs.existsSync(nextServerPath)) {
// Import Next.js // Import Next.js
const next = require(nextServerPath); const nextModule = await import(nextServerPath);
const next = nextModule.default || nextModule;
// Initialize Next.js app // Initialize Next.js app
const dev = process.env.NODE_ENV !== 'production'; const dev = process.env.NODE_ENV !== 'production';
const nextApp = next({ dev, dir: path.join(__dirname, '.') }); const nextApp = next({ dev, dir: path.join(__dirname, '.') });
const handle = nextApp.getRequestHandler(); const handle = nextApp.getRequestHandler();
await nextApp.prepare();
console.log('nextjs prepared');
// Prepare Next.js // Use Next.js to handle all other routes
nextApp.prepare().then(() => { server.all('*', (req, res) => handle(req, res));
console.log('nextjs prepared');
// Use Next.js to handle all other routes
server.all('*', (req, res) => {
return handle(req, res);
});
});
} else { } else {
console.error('Next.js module not found at:', nextServerPath); console.error('Next.js module not found at:', nextServerPath);
server.all('*', (req, res) => { server.all('*', (req, res) => {
@@ -79,9 +79,11 @@ function startServer() {
} }
} }
runMigrations().then(() => { runMigrations()
startServer(); .then(() => {
}).catch(error => { startServer();
console.error('Failed to start application:', error); })
process.exit(1); .catch((error) => {
}); console.error('Failed to start application:', error);
process.exit(1);
});

View File

@@ -2,6 +2,7 @@
"name": "unittcms", "name": "unittcms",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"type": "module",
"scripts": { "scripts": {
"format:check": "prettier --check frontend/**/*.{js,ts,jsx,tsx,json} backend/**/*.{js,ts,json}", "format:check": "prettier --check frontend/**/*.{js,ts,jsx,tsx,json} backend/**/*.{js,ts,json}",
"format": "prettier --write frontend/**/*.{js,ts,jsx,tsx,json} backend/**/*.{js,ts,json}", "format": "prettier --write frontend/**/*.{js,ts,jsx,tsx,json} backend/**/*.{js,ts,json}",