Added paranoid, debugging and fixes to document deleting on atlas collections

This commit is contained in:
Jori Lallo
2016-08-14 10:50:42 +02:00
parent bcb39d823f
commit 792def3249
8 changed files with 97 additions and 28 deletions

View File

@@ -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",

View File

@@ -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 = {

View File

@@ -13,6 +13,6 @@ module.exports = {
},
down: function (queryInterface, Sequelize) {
queryInterface.removeColumn('documents', 'creatorId');
queryInterface.removeColumn('atlases', 'creatorId');
}
};

View File

@@ -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');
}
};

View 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']);
}
};

View File

@@ -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 = [];

View File

@@ -58,6 +58,7 @@ const Document = sequelize.define('document', {
},
},
}, {
paranoid: true,
hooks: {
beforeValidate: (doc) => {
doc.urlId = randomstring.generate(15);

View File

@@ -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({