Added paranoid, debugging and fixes to document deleting on atlas collections
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
"build:webpack": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js --progress",
|
||||
"build:analyze": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js --json | webpack-bundle-size-analyzer",
|
||||
"build": "npm run clean && npm run build:webpack",
|
||||
"start": "cross-env NODE_ENV=development DEBUG=1 ./node_modules/.bin/nodemon --watch server index.js",
|
||||
"start": "cross-env NODE_ENV=development DEBUG=sql ./node_modules/.bin/nodemon --watch server index.js",
|
||||
"lint": "eslint frontend",
|
||||
"deploy": "git push heroku master",
|
||||
"heroku-postbuild": "npm run build && npm run sequelize db:migrate",
|
||||
|
||||
@@ -52,7 +52,8 @@ router.post('documents.search', auth(), async (ctx) => {
|
||||
const sql = `
|
||||
SELECT * FROM documents
|
||||
WHERE "searchVector" @@ plainto_tsquery('english', :query) AND
|
||||
"teamId" = '${user.teamId}'::uuid
|
||||
"teamId" = '${user.teamId}'::uuid AND
|
||||
"deletedAt" IS NULL
|
||||
ORDER BY ts_rank(documents."searchVector", plainto_tsquery('english', :query))
|
||||
DESC;
|
||||
`;
|
||||
@@ -199,12 +200,13 @@ router.post('documents.delete', auth(), async (ctx) => {
|
||||
} catch (e) {
|
||||
throw httpErrors.BadRequest('Error while deleting');
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
await document.destroy();
|
||||
} catch (e) {
|
||||
throw httpErrors.BadRequest('Error while deleting');
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the actual document
|
||||
try {
|
||||
await document.destroy();
|
||||
} catch (e) {
|
||||
throw httpErrors.BadRequest('Error while deleting document');
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
|
||||
@@ -13,6 +13,6 @@ module.exports = {
|
||||
},
|
||||
|
||||
down: function (queryInterface, Sequelize) {
|
||||
queryInterface.removeColumn('documents', 'creatorId');
|
||||
queryInterface.removeColumn('atlases', 'creatorId');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
up: function (queryInterface, Sequelize) {
|
||||
queryInterface.addColumn(
|
||||
'atlases',
|
||||
'deletedAt',
|
||||
{
|
||||
type: Sequelize.DATE,
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
|
||||
queryInterface.addColumn(
|
||||
'documents',
|
||||
'deletedAt',
|
||||
{
|
||||
type: Sequelize.DATE,
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
down: function (queryInterface, Sequelize) {
|
||||
queryInterface.removeColumn('atlases', 'deletedAt');
|
||||
queryInterface.removeColumn('documents', 'deletedAt');
|
||||
}
|
||||
};
|
||||
41
server/migrations/20160814083127-paranoia-indeces.js
Normal file
41
server/migrations/20160814083127-paranoia-indeces.js
Normal file
@@ -0,0 +1,41 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
up: function (queryInterface, Sequelize) {
|
||||
// Remove old indeces
|
||||
queryInterface.removeIndex('documents', ['urlId']);
|
||||
queryInterface.removeIndex('documents', ['id', 'atlasId']);
|
||||
queryInterface.removeIndex('documents', ['id', 'teamId']);
|
||||
queryInterface.removeIndex('documents', ['parentDocumentId', 'atlasId']);
|
||||
|
||||
queryInterface.removeIndex('atlases', ['id', 'teamId']);
|
||||
|
||||
// Add new ones
|
||||
queryInterface.addIndex('documents', ['id', 'deletedAt']);
|
||||
queryInterface.addIndex('documents', ['urlId', 'deletedAt']);
|
||||
queryInterface.addIndex('documents', ['id', 'atlasId', 'deletedAt']);
|
||||
queryInterface.addIndex('documents', ['id', 'teamId', 'deletedAt']);
|
||||
queryInterface.addIndex('documents', ['parentDocumentId', 'atlasId', 'deletedAt']);
|
||||
|
||||
queryInterface.addIndex('atlases', ['id', 'deletedAt']);
|
||||
queryInterface.addIndex('atlases', ['id', 'teamId', 'deletedAt']);
|
||||
},
|
||||
|
||||
down: function (queryInterface, Sequelize) {
|
||||
queryInterface.addIndex('documents', ['urlId']);
|
||||
queryInterface.addIndex('documents', ['id', 'atlasId']);
|
||||
queryInterface.addIndex('documents', ['id', 'teamId']);
|
||||
queryInterface.addIndex('documents', ['parentDocumentId', 'atlasId']);
|
||||
|
||||
queryInterface.addIndex('atlases', ['id', 'teamId']);
|
||||
|
||||
queryInterface.removeIndex('documents', ['id', 'deletedAt']);
|
||||
queryInterface.removeIndex('documents', ['urlId', 'deletedAt']);
|
||||
queryInterface.removeIndex('documents', ['id', 'atlasId', 'deletedAt']);
|
||||
queryInterface.removeIndex('documents', ['id', 'teamId', 'deletedAt']);
|
||||
queryInterface.removeIndex('documents', ['parentDocumentId', 'atlasId', 'deletedAt']);
|
||||
|
||||
queryInterface.removeIndex('atlases', ['id', 'deletedAt']);
|
||||
queryInterface.removeIndex('atlases', ['id', 'teamId', 'deletedAt']);
|
||||
}
|
||||
};
|
||||
@@ -18,26 +18,28 @@ const Atlas = sequelize.define('atlas', {
|
||||
navigationTree: DataTypes.JSONB,
|
||||
}, {
|
||||
tableName: 'atlases',
|
||||
paranoid: true,
|
||||
hooks: {
|
||||
afterCreate: async (atlas) => {
|
||||
if (atlas.type !== 'atlas') return;
|
||||
afterCreate: async (collection) => {
|
||||
if (collection.type !== 'atlas') return;
|
||||
|
||||
await Document.create({
|
||||
parentDocumentId: null,
|
||||
atlasId: atlas.id,
|
||||
teamId: atlas.teamId,
|
||||
userId: atlas.creatorId,
|
||||
lastModifiedById: atlas.creatorId,
|
||||
atlasId: collection.id,
|
||||
teamId: collection.teamId,
|
||||
userId: collection.creatorId,
|
||||
lastModifiedById: collection.creatorId,
|
||||
title: 'Introduction',
|
||||
text: '# Introduction',
|
||||
});
|
||||
await collection.buildStructure();
|
||||
await collection.save();
|
||||
},
|
||||
},
|
||||
instanceMethods: {
|
||||
async getStructure() {
|
||||
if (this.navigationTree) {
|
||||
return this.navigationTree;
|
||||
}
|
||||
async buildStructure() {
|
||||
console.log('start');
|
||||
if (this.navigationTree) return this.navigationTree;
|
||||
|
||||
const getNodeForDocument = async (document) => {
|
||||
const children = await Document.findAll({ where: {
|
||||
@@ -47,7 +49,7 @@ const Atlas = sequelize.define('atlas', {
|
||||
|
||||
const childNodes = [];
|
||||
await Promise.all(children.map(async (child) => {
|
||||
childNodes.push(await getNodeForDocument(child));
|
||||
return childNodes.push(await getNodeForDocument(child));
|
||||
}));
|
||||
|
||||
return {
|
||||
@@ -65,11 +67,8 @@ const Atlas = sequelize.define('atlas', {
|
||||
},
|
||||
});
|
||||
|
||||
if (rootDocument) {
|
||||
return await getNodeForDocument(rootDocument);
|
||||
} else {
|
||||
return true; // TODO should create a root doc
|
||||
}
|
||||
this.navigationTree = await getNodeForDocument(rootDocument);
|
||||
return this.navigationTree;
|
||||
},
|
||||
async updateNavigationTree(tree = this.navigationTree) {
|
||||
const nodeIds = [];
|
||||
|
||||
@@ -58,6 +58,7 @@ const Document = sequelize.define('document', {
|
||||
},
|
||||
},
|
||||
}, {
|
||||
paranoid: true,
|
||||
hooks: {
|
||||
beforeValidate: (doc) => {
|
||||
doc.urlId = randomstring.generate(15);
|
||||
|
||||
@@ -59,9 +59,7 @@ export function presentCollection(collection, includeRecentDocuments=false) {
|
||||
type: collection.type,
|
||||
};
|
||||
|
||||
if (collection.type === 'atlas') {
|
||||
data.navigationTree = await collection.getStructure();
|
||||
}
|
||||
if (collection.type === 'atlas') data.navigationTree = collection.navigationTree;
|
||||
|
||||
if (includeRecentDocuments) {
|
||||
const documents = await Document.findAll({
|
||||
|
||||
Reference in New Issue
Block a user