diff --git a/server/migrations/20171010042938-add-event.js b/server/migrations/20171010042938-add-event.js new file mode 100644 index 00000000..60874fbc --- /dev/null +++ b/server/migrations/20171010042938-add-event.js @@ -0,0 +1,52 @@ +module.exports = { + up: function(queryInterface, Sequelize) { + queryInterface.createTable('events', { + id: { + type: Sequelize.UUID, + allowNull: false, + primaryKey: true, + }, + name: { + type: Sequelize.STRING, + allowNull: false, + }, + data: { + type: Sequelize.JSONB, + allowNull: false, + }, + userId: { + type: Sequelize.UUID, + allowNull: true, + references: { + model: 'users', + }, + }, + collectionId: { + type: Sequelize.UUID, + allowNull: true, + references: { + model: 'collections', + }, + }, + teamId: { + type: Sequelize.UUID, + allowNull: true, + references: { + model: 'teams', + }, + }, + createdAt: { + type: Sequelize.DATE, + allowNull: false, + }, + updatedAt: { + type: Sequelize.DATE, + allowNull: false, + }, + }); + }, + + down: function(queryInterface, Sequelize) { + queryInterface.dropTable('events'); + }, +}; diff --git a/server/models/Collection.js b/server/models/Collection.js index bc272403..1ca29075 100644 --- a/server/models/Collection.js +++ b/server/models/Collection.js @@ -3,6 +3,7 @@ import slug from 'slug'; import randomstring from 'randomstring'; import { DataTypes, sequelize } from '../sequelize'; import Document from './Document'; +import Event from './Event'; import _ from 'lodash'; // $FlowIssue invalid flow-typed @@ -125,6 +126,12 @@ Collection.prototype.addDocumentToStructure = async function( options = {} ) { if (!this.documentStructure) return; + const existingData = { + old: this.documentStructure, + documentId: document, + parentDocumentId: document.parentDocumentId, + index, + }; // If moving existing document with children, use existing structure to // keep everything in shape and not loose documents @@ -163,6 +170,16 @@ Collection.prototype.addDocumentToStructure = async function( this.documentStructure = this.documentStructure; await this.save(); + await Event.create({ + name: 'Collection#addDocumentToStructure', + data: { + ...existingData, + new: this.documentStructure, + }, + collectionId: this.id, + teamId: this.teamId, + }); + return this; }; @@ -222,6 +239,12 @@ Collection.prototype.removeDocument = async function( ) { if (!this.documentStructure) return; let returnValue; + const existingData = { + old: this.documentStructure, + documentId: document, + parentDocumentId: document.parentDocumentId, + options, + }; // Helper to destroy all child documents for a document const deleteChildren = async documentId => { @@ -268,6 +291,17 @@ Collection.prototype.removeDocument = async function( ); if (options.deleteDocument) await this.save(); + + await Event.create({ + name: 'Collection#removeDocument', + data: { + ...existingData, + new: this.documentStructure, + }, + collectionId: this.id, + teamId: this.teamId, + }); + return returnValue; }; diff --git a/server/models/Event.js b/server/models/Event.js new file mode 100644 index 00000000..5d7cb0f0 --- /dev/null +++ b/server/models/Event.js @@ -0,0 +1,53 @@ +// @flow +import { DataTypes, sequelize } from '../sequelize'; + +const Event = sequelize.define('event', { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + }, + name: DataTypes.STRING, + data: DataTypes.JSONB, + + userId: { + type: 'UUID', + allowNull: true, + references: { + model: 'users', + }, + }, + + collectionId: { + type: 'UUID', + allowNull: true, + references: { + model: 'collections', + }, + }, + + teamId: { + type: 'UUID', + allowNull: true, + references: { + model: 'teams', + }, + }, +}); + +Event.associate = models => { + Event.belongsTo(models.User, { + as: 'user', + foreignKey: 'userId', + }); + Event.belongsTo(models.Collection, { + as: 'collection', + foreignKey: 'collectionId', + }); + Event.belongsTo(models.Team, { + as: 'team', + foreignKey: 'teamId', + }); +}; + +export default Event;