Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ghost/core/core/server/data/exporter/table-lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const BACKUP_TABLES = [
'outbox',
'gifts',
'welcome_email_automations',
'welcome_email_automation_runs',
'welcome_email_automated_emails'
];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const {addTable} = require('../../utils');

// The default names are too long for MySQL.
const WELCOME_EMAIL_AUTOMATION_RUNS_AUTOMATION_FK = 'wear_automation_id_foreign';
const WELCOME_EMAIL_AUTOMATION_RUNS_MEMBER_FK = 'wear_member_id_foreign';
const WELCOME_EMAIL_AUTOMATION_RUNS_NEXT_EMAIL_FK = 'wear_next_email_id_foreign';

const welcomeEmailAutomationRunsSpec = {
id: {type: 'string', maxlength: 24, nullable: false, primary: true},
welcome_email_automation_id: {type: 'string', maxlength: 24, nullable: false, references: 'welcome_email_automations.id', constraintName: WELCOME_EMAIL_AUTOMATION_RUNS_AUTOMATION_FK, cascadeDelete: true},
member_id: {type: 'string', maxlength: 24, nullable: false, references: 'members.id', constraintName: WELCOME_EMAIL_AUTOMATION_RUNS_MEMBER_FK, cascadeDelete: true},
next_welcome_email_automated_email_id: {type: 'string', maxlength: 24, nullable: true, references: 'welcome_email_automated_emails.id', constraintName: WELCOME_EMAIL_AUTOMATION_RUNS_NEXT_EMAIL_FK, cascadeDelete: false},
ready_at: {type: 'dateTime', nullable: true},
step_started_at: {type: 'dateTime', nullable: true},
step_attempts: {type: 'integer', unsigned: true, nullable: false, defaultTo: 0},
exit_reason: {type: 'string', maxlength: 50, nullable: true, validations: {isIn: [['member not found', 'email send failed', 'member unsubscribed', 'member changed status', 'finished']]}},
created_at: {type: 'dateTime', nullable: false},
updated_at: {type: 'dateTime', nullable: true}
};

module.exports = addTable('welcome_email_automation_runs', welcomeEmailAutomationRunsSpec);
12 changes: 12 additions & 0 deletions ghost/core/core/server/data/schema/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,18 @@ module.exports = {
created_at: {type: 'dateTime', nullable: false},
updated_at: {type: 'dateTime', nullable: true}
},
welcome_email_automation_runs: {
id: {type: 'string', maxlength: 24, nullable: false, primary: true},
welcome_email_automation_id: {type: 'string', maxlength: 24, nullable: false, references: 'welcome_email_automations.id', constraintName: 'wear_automation_id_foreign', cascadeDelete: true},
member_id: {type: 'string', maxlength: 24, nullable: false, references: 'members.id', constraintName: 'wear_member_id_foreign', cascadeDelete: true},
next_welcome_email_automated_email_id: {type: 'string', maxlength: 24, nullable: true, references: 'welcome_email_automated_emails.id', constraintName: 'wear_next_email_id_foreign', cascadeDelete: false},
ready_at: {type: 'dateTime', nullable: true},
step_started_at: {type: 'dateTime', nullable: true},
step_attempts: {type: 'integer', unsigned: true, nullable: false, defaultTo: 0},
exit_reason: {type: 'string', maxlength: 50, nullable: true, validations: {isIn: [['member not found', 'email send failed', 'member unsubscribed', 'member changed status', 'finished']]}},
created_at: {type: 'dateTime', nullable: false},
updated_at: {type: 'dateTime', nullable: true}
},
automated_emails: {
id: {type: 'string', maxlength: 24, nullable: false, primary: true},
status: {type: 'string', maxlength: 50, nullable: false, defaultTo: 'inactive', validations: {isIn: [['active', 'inactive']]}},
Expand Down
27 changes: 27 additions & 0 deletions ghost/core/core/server/models/welcome-email-automation-run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const ghostBookshelf = require('./base');

const WelcomeEmailAutomationRun = ghostBookshelf.Model.extend({
tableName: 'welcome_email_automation_runs',

defaults() {
return {
stepAttempts: 0
};
},

welcomeEmailAutomation() {
return this.belongsTo('WelcomeEmailAutomation', 'welcome_email_automation_id', 'id');
},

member() {
return this.belongsTo('Member', 'member_id', 'id');
},

nextWelcomeEmailAutomatedEmail() {
return this.belongsTo('WelcomeEmailAutomatedEmail', 'next_welcome_email_automated_email_id', 'id');
}
});

module.exports = {
WelcomeEmailAutomationRun: ghostBookshelf.model('WelcomeEmailAutomationRun', WelcomeEmailAutomationRun)
};
1 change: 1 addition & 0 deletions ghost/core/test/integration/exporter/exporter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ describe('Exporter', function () {
'users',
'webhooks',
'welcome_email_automated_emails',
'welcome_email_automation_runs',
'welcome_email_automations'
];

Expand Down
2 changes: 1 addition & 1 deletion ghost/core/test/unit/server/data/schema/integrity.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const validateRouteSettings = require('../../../../../core/server/services/route
*/
describe('DB version integrity', function () {
// Only these variables should need updating
const currentSchemaHash = 'f57e57fd042ecee9dd93410ae87c0454';
const currentSchemaHash = 'cddebb6f953c3515a6289e4d84679774';
const currentFixturesHash = '2f86ab1e3820e86465f9ad738dd0ee93';
const currentSettingsHash = 'a102b80d2ab0cd92325ed007c94d7da6';
const currentRoutesHash = '3d180d52c663d173a6be791ef411ed01';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const assert = require('node:assert/strict');
const models = require('../../../../core/server/models');

describe('Unit: models/welcome-email-automation-run', function () {
before(function () {
models.init();
});

describe('tableName', function () {
it('uses the correct table name', function () {
const model = new models.WelcomeEmailAutomationRun();
assert.equal(model.tableName, 'welcome_email_automation_runs');
});
});

describe('defaults', function () {
it('sets stepAttempts to 0', function () {
const model = new models.WelcomeEmailAutomationRun();
const defaults = model.defaults();
assert.equal(defaults.stepAttempts, 0);
});

it('returns only stepAttempts as a default', function () {
const model = new models.WelcomeEmailAutomationRun();
const defaults = model.defaults();
assert.deepEqual(Object.keys(defaults), ['stepAttempts']);
});
});

describe('relationships', function () {
it('has a welcomeEmailAutomation relationship', function () {
const model = new models.WelcomeEmailAutomationRun();
assert.equal(typeof model.welcomeEmailAutomation, 'function');
});

it('has a member relationship', function () {
const model = new models.WelcomeEmailAutomationRun();
assert.equal(typeof model.member, 'function');
});

it('has a nextWelcomeEmailAutomatedEmail relationship', function () {
const model = new models.WelcomeEmailAutomationRun();
assert.equal(typeof model.nextWelcomeEmailAutomatedEmail, 'function');
});
});
});
Loading