diff --git a/server/api/models/event.js b/server/api/models/event.js index 104e7bca..e95812f3 100644 --- a/server/api/models/event.js +++ b/server/api/models/event.js @@ -4,6 +4,7 @@ const moment = require('moment') module.exports = (sequelize, DataTypes) => { const event = sequelize.define('event', { id: { + allowNull: false, type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true diff --git a/server/api/models/tag.js b/server/api/models/tag.js index 59dd7465..a21311a1 100644 --- a/server/api/models/tag.js +++ b/server/api/models/tag.js @@ -7,7 +7,7 @@ module.exports = (sequelize, DataTypes) => { index: true, primaryKey: true }, - weigth: { type: DataTypes.INTEGER, defaultValue: 0, allowNull: false } + weigth: { type: DataTypes.INTEGER, defaultValue: 0, allowNull: false }, }, {}) tag.associate = function (models) { diff --git a/server/cli.js b/server/cli.js index 52a1f416..0bb31000 100755 --- a/server/cli.js +++ b/server/cli.js @@ -185,11 +185,10 @@ async function setupQuestionnaire(is_docker, db) { return answers } -async function upgrade (options) { +async function run_migrations (db_conf) { const Umzug = require('umzug') const Sequelize = require('sequelize') - const config = require('config') - const db = new Sequelize(config.db) + const db = new Sequelize(db_conf) const umzug = new Umzug({ storage: 'sequelize', storageOptions: { sequelize: db }, @@ -217,13 +216,15 @@ async function start (options) { If this is your first run use 'gancio setup --config ' `) process.exit(-1) } - await upgrade(options) + const config = require('config') + await run_migrations(config.db) require('./index') } async function setup (options) { consola.info(`You're going to setup gancio on this machine.`) const config = await setupQuestionnaire(options.docker, options.db) + await run_migrations(config.db) const ret = await firstrun.setup(config, options.config) if (!ret) process.exit(-1) if (options.docker) { diff --git a/server/firstrun.js b/server/firstrun.js index 2032096c..f0f6c65d 100644 --- a/server/firstrun.js +++ b/server/firstrun.js @@ -27,18 +27,11 @@ module.exports = { // sync db const db = require('./api/models') - - try { - await db.user.findAll() + const users = await db.user.findAll() + if (users.length) { consola.warn(` ⚠ Non empty db! Please move your current db elsewhere than retry.`) return false - } catch (e) { } - - consola.info(`Create tables schema`) - await db.sequelize.sync().catch(e => { - consola.error(' ⚠ ️ Error creating tables', e) - return false - }) + } // create admin user consola.info('Create admin user', admin) diff --git a/server/migrations/20190728213923-add_username.js b/server/migrations/20190728213923-add_username.js deleted file mode 100644 index 4376e432..00000000 --- a/server/migrations/20190728213923-add_username.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.addColumn('users', 'username', { - type: Sequelize.STRING, - index: true, - allowNull: false, - defaultValue: '' - }) - /* - Add altering commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.createTable('users', { id: Sequelize.INTEGER }); - */ - }, - - down: (queryInterface, Sequelize) => { - /* - Add reverting commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.dropTable('users'); - */ - } -} diff --git a/server/migrations/20190728214848-add_displayname.js b/server/migrations/20190728214848-add_displayname.js deleted file mode 100644 index 2bdd4d79..00000000 --- a/server/migrations/20190728214848-add_displayname.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict' - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.addColumn('users', 'display_name', { - type: Sequelize.STRING - }) - /* - Add altering commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.createTable('users', { id: Sequelize.INTEGER }); - */ - }, - - down: (queryInterface, Sequelize) => { - /* - Add reverting commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.dropTable('users'); - */ - } -} diff --git a/server/migrations/20190729103119-add_rsa.js b/server/migrations/20190729103119-add_rsa.js deleted file mode 100644 index 858fd928..00000000 --- a/server/migrations/20190729103119-add_rsa.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict' - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.addColumn('users', 'rsa', { - type: Sequelize.JSON - }) - /* - Add altering commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.createTable('users', { id: Sequelize.INTEGER }); - */ - }, - - down: (queryInterface, Sequelize) => { - /* - Add reverting commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.dropTable('users'); - */ - } -} diff --git a/server/migrations/20190729192753-add_followers.js b/server/migrations/20190729192753-add_followers.js deleted file mode 100644 index d7818968..00000000 --- a/server/migrations/20190729192753-add_followers.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict' - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.addColumn('users', 'followers', { - type: Sequelize.JSON - }) - /* - Add altering commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.createTable('users', { id: Sequelize.INTEGER }); - */ - }, - - down: (queryInterface, Sequelize) => { - /* - Add reverting commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.dropTable('users'); - */ - } -} diff --git a/server/migrations/20190801105908-likes.js b/server/migrations/20190801105908-likes.js deleted file mode 100644 index 6b9640ef..00000000 --- a/server/migrations/20190801105908-likes.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict' - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.addColumn('events', 'likes', { - type: Sequelize.JSON, - defaultValue: [] - }) - /* - Add altering commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.createTable('users', { id: Sequelize.INTEGER }); - */ - }, - - down: (queryInterface, Sequelize) => { - /* - Add reverting commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.dropTable('users'); - */ - } -} diff --git a/server/migrations/20190801110053-boost.js b/server/migrations/20190801110053-boost.js deleted file mode 100644 index 9b372ecb..00000000 --- a/server/migrations/20190801110053-boost.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict' - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.addColumn('events', 'boost', { - type: Sequelize.JSON, - defaultValue: [] - }) - - /* - Add altering commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.createTable('users', { id: Sequelize.INTEGER }); - */ - }, - - down: (queryInterface, Sequelize) => { - /* - Add reverting commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.dropTable('users'); - */ - } -} diff --git a/server/migrations/20190910085948-user_settings.js b/server/migrations/20190910085948-user_settings.js deleted file mode 100644 index 10c45991..00000000 --- a/server/migrations/20190910085948-user_settings.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict' - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.addColumn('users', 'settings', { - type: Sequelize.JSON, - defaultValue: {} - }) - /* - Add altering commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.createTable('users', { id: Sequelize.INTEGER }); - */ - }, - - down: (queryInterface, Sequelize) => { - /* - Add reverting commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.dropTable('users'); - */ - } -} diff --git a/server/migrations/20190911204228-recurrent.js b/server/migrations/20190911204228-recurrent.js deleted file mode 100644 index d119ede8..00000000 --- a/server/migrations/20190911204228-recurrent.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.addColumn('events', 'recurrent', { - type: Sequelize.JSON - }) - - /* - Add altering commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.createTable('users', { id: Sequelize.INTEGER }); - */ - }, - - down: (queryInterface, Sequelize) => { - /* - Add reverting commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.dropTable('users'); - */ - } -}; diff --git a/server/migrations/20190912093645-fedi_followers.js b/server/migrations/20190912093645-fedi_followers.js deleted file mode 100644 index 0394b8ed..00000000 --- a/server/migrations/20190912093645-fedi_followers.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -module.exports = { - up: (queryInterface, Sequelize) => { - return Promise.all([ - queryInterface.removeColumn('users', 'followers'), - queryInterface.createTable('user_followers', { - userId: { - type: Sequelize.INTEGER, - references: { - model: 'users', - key: 'id' - }, - primaryKey: true, - allowNull: false - }, - fedUserApId: { - primaryKey: true, - type: Sequelize.STRING, - references: { - model: 'fed_users', - key: 'ap_id' - } - }, - createdAt: { type: Sequelize.DATE, allowNull: false }, - updatedAt: { type: Sequelize.DATE, allowNull: false } - }) - ])}, - - down: (queryInterface, Sequelize) => { - return Promise.all([ - queryInterface.addColumn( - 'users', 'followers', { - type: JSON, - defaultValue: [] - }), - queryInterface.dropTable('user_followers') - ]) - /* - Add reverting commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.dropTable('users'); - */ - } -}; diff --git a/server/migrations/20190927160148-new_notification.js b/server/migrations/20190927160148-new_notification.js deleted file mode 100644 index bd1ab268..00000000 --- a/server/migrations/20190927160148-new_notification.js +++ /dev/null @@ -1,56 +0,0 @@ -'use strict'; -const { notification: Notification } = require('../api/models') - -module.exports = { - up: async (queryInterface, Sequelize) => { - - // remove all notifications - await Notification.destroy({where: []}) - - // add `action` field to notification - try { - await queryInterface.addColumn('notifications', 'action', { - type: Sequelize.ENUM, - values: ['Create', 'Update', 'Delete'] - }) - } catch {} - - // modify values of `type` field - try { - await queryInterface.removeColumn('notifications', 'type').catch() - } catch {} - - try { - await queryInterface.addColumn('notifications', 'type', { - type: Sequelize.ENUM, - values: ['mail', 'admin_email', 'ap'] - }) - } catch {} - - await queryInterface.addIndex('notifications', { - unique: true, - fields: ['action', 'type' ] - }) - - // add AP notifications - await Notification.create({ action: 'Create', type: 'ap', filters: { is_visible: true } }) - await Notification.create({ action: 'Update', type: 'ap', filters: { is_visible: true } }) - await Notification.create({ action: 'Delete', type: 'ap', filters: { is_visible: true } }) - - // send anon events via email to admin - await Notification.create({ action: 'Create', type: 'admin_email', filters: { is_visible: false } }) - - return true - }, - - down: (queryInterface, Sequelize) => { - return Promise.resolve() - /* - Add reverting commands here. - Return a promise to correctly handle asynchronicity. - - Example: - return queryInterface.dropTable('users'); - */ - } -}; diff --git a/server/migrations/20191025133803-tags.js b/server/migrations/20191025133803-tags.js new file mode 100644 index 00000000..0c2ac465 --- /dev/null +++ b/server/migrations/20191025133803-tags.js @@ -0,0 +1,31 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('tags', + { + tag: { + type: Sequelize.STRING, + allowNull: false, + index: true, + primaryKey: true + }, + weigth: { + type: Sequelize.INTEGER, + defaultValue: 0, allowNull: false + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }) + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('tags') + } +}; diff --git a/server/migrations/20191025134318-places.js b/server/migrations/20191025134318-places.js new file mode 100644 index 00000000..ef81a8df --- /dev/null +++ b/server/migrations/20191025134318-places.js @@ -0,0 +1,34 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('places', + { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + name: { + type: Sequelize.STRING, + unique: true, + index: true, + allowNull: false + }, + address: Sequelize.STRING, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }) + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('places') + } +} diff --git a/server/migrations/20191025135631-settings.js b/server/migrations/20191025135631-settings.js new file mode 100644 index 00000000..9d43eba5 --- /dev/null +++ b/server/migrations/20191025135631-settings.js @@ -0,0 +1,29 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('settings', + { + key: { + type: Sequelize.STRING, + primaryKey: true, + allowNull: false, + index: true + }, + value: Sequelize.JSON, + is_secret: Sequelize.BOOLEAN, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }) + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('settings') + } +}; diff --git a/server/migrations/20191025141447-users.js b/server/migrations/20191025141447-users.js new file mode 100644 index 00000000..a3fa4a2c --- /dev/null +++ b/server/migrations/20191025141447-users.js @@ -0,0 +1,48 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('users', + { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + username: { + type: Sequelize.STRING, + unique: { msg: 'error.nick_taken' }, + index: true, + allowNull: false + }, + display_name: Sequelize.STRING, + settings: Sequelize.JSON, + email: { + type: Sequelize.STRING, + unique: { msg: 'error.email_taken' }, + index: true, + allowNull: false + }, + description: Sequelize.TEXT, + password: Sequelize.STRING, + recover_code: Sequelize.STRING, + is_admin: Sequelize.BOOLEAN, + is_active: Sequelize.BOOLEAN, + rsa: Sequelize.JSON, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + } + ) + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('users'); + } +}; diff --git a/server/migrations/20191025142724-events.js b/server/migrations/20191025142724-events.js new file mode 100644 index 00000000..64481054 --- /dev/null +++ b/server/migrations/20191025142724-events.js @@ -0,0 +1,63 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('events', + { + id: { + allowNull: false, + type: Sequelize.INTEGER, + primaryKey: true, + autoIncrement: true + }, + title: Sequelize.STRING, + slug: Sequelize.STRING, + description: Sequelize.TEXT, + multidate: Sequelize.BOOLEAN, + start_datetime: { + type: Sequelize.INTEGER, + index: true + }, + end_datetime: { + type: Sequelize.INTEGER, + index: true + }, + image_path: Sequelize.STRING, + is_visible: Sequelize.BOOLEAN, + recurrent: Sequelize.JSON, + // parent: Sequelize.INTEGER + likes: { type: Sequelize.JSON, defaultValue: [] }, + boost: { type: Sequelize.JSON, defaultValue: [] }, + placeId: { + type: Sequelize.INTEGER, + references: { + model: 'places', + key: 'id', + }, + onUpdate: 'CASCADE', + onDelete: 'SET NULL', + }, + userId: { + type: Sequelize.INTEGER, + references: { + model: 'users', + key: 'id', + }, + onUpdate: 'CASCADE', + onDelete: 'SET NULL', + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }) + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('events') + } +}; diff --git a/server/migrations/20191025143411-comments.js b/server/migrations/20191025143411-comments.js new file mode 100644 index 00000000..248537d9 --- /dev/null +++ b/server/migrations/20191025143411-comments.js @@ -0,0 +1,41 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('comments', + { + id: { + type: Sequelize.INTEGER, + primaryKey: true, + autoIncrement: true + }, + activitypub_id: { + type: Sequelize.STRING(18), + index: true, + unique: true + }, + eventId: { + type: Sequelize.INTEGER, + references: { + model: 'events', + key: 'id', + }, + onUpdate: 'CASCADE', + onDelete: 'SET NULL', + }, + data: Sequelize.JSON, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }) + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('comments') + } +}; diff --git a/server/migrations/20190912093154-create-fed-users.js b/server/migrations/20191025145312-fed_users.js similarity index 88% rename from server/migrations/20190912093154-create-fed-users.js rename to server/migrations/20191025145312-fed_users.js index 524cef53..b72acbaa 100644 --- a/server/migrations/20190912093154-create-fed-users.js +++ b/server/migrations/20191025145312-fed_users.js @@ -1,4 +1,5 @@ 'use strict'; + module.exports = { up: (queryInterface, Sequelize) => { return queryInterface.createTable('fed_users', { @@ -17,9 +18,9 @@ module.exports = { allowNull: false, type: Sequelize.DATE } - }); + }) }, down: (queryInterface, Sequelize) => { - return queryInterface.dropTable('fed_users'); + return queryInterface.dropTable('fed_users') } -}; \ No newline at end of file +}; diff --git a/server/migrations/20191025145516-followers.js b/server/migrations/20191025145516-followers.js new file mode 100644 index 00000000..ba46651c --- /dev/null +++ b/server/migrations/20191025145516-followers.js @@ -0,0 +1,35 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('user_followers', { + userId: { + type: Sequelize.INTEGER, + references: { + model: 'users', + key: 'id' + }, + primaryKey: true, + allowNull: false, + onUpdate: 'CASCADE', + onDelete: 'CASCADE' + }, + fedUserApId: { + primaryKey: true, + type: Sequelize.STRING, + references: { + model: 'fed_users', + key: 'ap_id' + }, + onUpdate: 'CASCADE', + onDelete: 'CASCADE' + }, + createdAt: { type: Sequelize.DATE, allowNull: false }, + updatedAt: { type: Sequelize.DATE, allowNull: false } + }) + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('user_followers') + } +}; diff --git a/server/migrations/20191025150200-notifications.js b/server/migrations/20191025150200-notifications.js new file mode 100644 index 00000000..70bc9cba --- /dev/null +++ b/server/migrations/20191025150200-notifications.js @@ -0,0 +1,36 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('notifications',{ + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + filters: Sequelize.JSON, + email: Sequelize.STRING, + remove_code: Sequelize.STRING, + action: { + type: Sequelize.ENUM, + values: ['Create', 'Update', 'Delete'] + }, + type: { + type: Sequelize.ENUM, + values: ['mail', 'admin_email', 'ap'] + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }) + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('notifications') + } +}; diff --git a/server/migrations/20191025150506-notifications_index.js b/server/migrations/20191025150506-notifications_index.js new file mode 100644 index 00000000..e0057716 --- /dev/null +++ b/server/migrations/20191025150506-notifications_index.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.addIndex('notifications', { + unique: true, + fields: ['action', 'type'] + }).catch(e => {}) + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.removeIndex('notifications', + ['actions', 'type']) + } +}; diff --git a/server/migrations/20191025151459-event_tags.js b/server/migrations/20191025151459-event_tags.js new file mode 100644 index 00000000..5b7b21cb --- /dev/null +++ b/server/migrations/20191025151459-event_tags.js @@ -0,0 +1,40 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('event_tags', { + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + }, + eventId: { + type: Sequelize.INTEGER, + primaryKey: true, + references: { + model: 'events', + key: 'id', + }, + onUpdate: 'CASCADE', + onDelete: 'CASCADE', + }, + tagTag: { + primaryKey: true, + type: Sequelize.STRING, + references: { + model: 'tags', + key: 'tag', + }, + onUpdate: 'CASCADE', + onDelete: 'CASCADE', + }, + }) + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('event_tags') + } +}; diff --git a/server/migrations/20191025152224-event_notifications.js b/server/migrations/20191025152224-event_notifications.js new file mode 100644 index 00000000..64c6c9ba --- /dev/null +++ b/server/migrations/20191025152224-event_notifications.js @@ -0,0 +1,40 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('event_notifications', { + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + }, + eventId: { + type: Sequelize.INTEGER, + primaryKey: true, + references: { + model: 'events', + key: 'id', + }, + onUpdate: 'CASCADE', + onDelete: 'CASCADE', + }, + notificationId: { + primaryKey: true, + type: Sequelize.INTEGER, + references: { + model: 'notifications', + key: 'id', + }, + onUpdate: 'CASCADE', + onDelete: 'CASCADE', + } + }) + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('event_notifications') + } +}