@dhyasama/totem-models 12.35.0 → 12.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Document.js +5 -5
- package/lib/Meeting.js +4 -3
- package/lib/Message.js +2 -0
- package/lib/MetricSource.js +38 -0
- package/lib/News.js +30 -0
- package/lib/Note.js +3 -3
- package/package.json +1 -1
- package/test/MetricSource.js +61 -0
- package/test/News.js +11 -0
package/lib/Document.js
CHANGED
|
@@ -6,6 +6,7 @@ module.exports = function(mongoose, config) {
|
|
|
6
6
|
|
|
7
7
|
Schema = mongoose.Schema,
|
|
8
8
|
utilities = require('@dhyasama/totem-utilities'),
|
|
9
|
+
metricSources = require('./MetricSource')(mongoose),
|
|
9
10
|
_ = require('underscore');
|
|
10
11
|
|
|
11
12
|
var Document = new Schema({
|
|
@@ -148,11 +149,10 @@ module.exports = function(mongoose, config) {
|
|
|
148
149
|
});
|
|
149
150
|
|
|
150
151
|
const doc = await query;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
await doc.deleteOne();
|
|
152
|
+
// Always attempt the unlink so retrying a partially failed deletion also
|
|
153
|
+
// repairs metric references after the source itself is already gone.
|
|
154
|
+
if (doc) await doc.deleteOne();
|
|
155
|
+
await metricSources.unlink('Document', id, options.CUSTOMER_ID);
|
|
156
156
|
return doc;
|
|
157
157
|
};
|
|
158
158
|
|
package/lib/Meeting.js
CHANGED
|
@@ -4,7 +4,8 @@ module.exports = function(mongoose, config) {
|
|
|
4
4
|
|
|
5
5
|
var
|
|
6
6
|
|
|
7
|
-
Schema = mongoose.Schema
|
|
7
|
+
Schema = mongoose.Schema,
|
|
8
|
+
metricSources = require('./MetricSource')(mongoose);
|
|
8
9
|
|
|
9
10
|
let moment = require('moment');
|
|
10
11
|
|
|
@@ -159,8 +160,8 @@ module.exports = function(mongoose, config) {
|
|
|
159
160
|
|
|
160
161
|
let query = this.findOne({ _id: meetingId, customer: options.CUSTOMER_ID });
|
|
161
162
|
const meeting = await query;
|
|
162
|
-
if (
|
|
163
|
-
await
|
|
163
|
+
if (meeting) await meeting.deleteOne();
|
|
164
|
+
await metricSources.unlink('Meeting', meetingId, options.CUSTOMER_ID);
|
|
164
165
|
return meeting;
|
|
165
166
|
};
|
|
166
167
|
|
package/lib/Message.js
CHANGED
|
@@ -10,6 +10,7 @@ module.exports = function(mongoose, config) {
|
|
|
10
10
|
_ = require('underscore'),
|
|
11
11
|
moment = require('moment'),
|
|
12
12
|
helpers = require('../helpers'),
|
|
13
|
+
metricSources = require('./MetricSource')(mongoose),
|
|
13
14
|
Document = mongoose.model('Document');
|
|
14
15
|
|
|
15
16
|
let Message = new Schema({
|
|
@@ -66,6 +67,7 @@ module.exports = function(mongoose, config) {
|
|
|
66
67
|
'_id': messageId,
|
|
67
68
|
'customer': customerId
|
|
68
69
|
});
|
|
70
|
+
await metricSources.unlink('Message', messageId, customerId);
|
|
69
71
|
return result;
|
|
70
72
|
};
|
|
71
73
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var SOURCE_MODELS = ['Document', 'Meeting', 'Message', 'News', 'Note'];
|
|
4
|
+
|
|
5
|
+
module.exports = function(mongoose) {
|
|
6
|
+
return {
|
|
7
|
+
unlink: async function(model, ref, customerId) {
|
|
8
|
+
if (SOURCE_MODELS.indexOf(model) === -1) {
|
|
9
|
+
throw new Error('model must be a supported metric source');
|
|
10
|
+
}
|
|
11
|
+
if (!ref) { throw new Error('ref is required'); }
|
|
12
|
+
if (!customerId && model !== 'News') { throw new Error('customerId is required'); }
|
|
13
|
+
|
|
14
|
+
var source = { model: model, ref: ref };
|
|
15
|
+
var Financials = mongoose.model('Financials');
|
|
16
|
+
var filter = {
|
|
17
|
+
$or: [
|
|
18
|
+
{ 'snapshots.metrics.sources': { $elemMatch: source } },
|
|
19
|
+
{ 'snapshots.metrics.previous.sources': { $elemMatch: source } }
|
|
20
|
+
]
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// News is global and has no customer field. All current source models are
|
|
24
|
+
// tenant-owned and must only affect the deleting customer.
|
|
25
|
+
if (customerId) filter.customer = customerId;
|
|
26
|
+
|
|
27
|
+
return Financials.updateMany(
|
|
28
|
+
filter,
|
|
29
|
+
{
|
|
30
|
+
$pull: {
|
|
31
|
+
'snapshots.$[].metrics.$[].sources': source,
|
|
32
|
+
'snapshots.$[].metrics.$[].previous.sources': source
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
};
|
package/lib/News.js
CHANGED
|
@@ -7,6 +7,7 @@ module.exports = function(mongoose, config) {
|
|
|
7
7
|
|
|
8
8
|
Schema = mongoose.Schema,
|
|
9
9
|
helpers = require('../helpers'),
|
|
10
|
+
metricSources = require('./MetricSource')(mongoose),
|
|
10
11
|
moment = require('moment'),
|
|
11
12
|
|
|
12
13
|
News = new Schema({
|
|
@@ -15,6 +16,8 @@ module.exports = function(mongoose, config) {
|
|
|
15
16
|
|
|
16
17
|
text: { type: String, required: false, default: null },
|
|
17
18
|
|
|
19
|
+
html: { type: String, required: false, default: null },
|
|
20
|
+
|
|
18
21
|
summary: { type: String, required: false, default: null },
|
|
19
22
|
|
|
20
23
|
pageUrl: { type: String, required: false, default: null },
|
|
@@ -27,6 +30,13 @@ module.exports = function(mongoose, config) {
|
|
|
27
30
|
|
|
28
31
|
sentiment: { type: Number, required: false, default: null },
|
|
29
32
|
|
|
33
|
+
analysis: {
|
|
34
|
+
insights: [{
|
|
35
|
+
text: { type: String },
|
|
36
|
+
category: { type: String, enum: ['highlight', 'lowlight', 'goal', 'ask'] }
|
|
37
|
+
}]
|
|
38
|
+
},
|
|
39
|
+
|
|
30
40
|
diffbotUri: { type: String, required: true, unique: true },
|
|
31
41
|
|
|
32
42
|
org: {
|
|
@@ -112,6 +122,26 @@ module.exports = function(mongoose, config) {
|
|
|
112
122
|
|
|
113
123
|
};
|
|
114
124
|
|
|
125
|
+
News.statics.delete = function(id, cb) {
|
|
126
|
+
|
|
127
|
+
const run = async () => {
|
|
128
|
+
if (!id) { throw new Error('id is required'); }
|
|
129
|
+
if (!mongoose.Types.ObjectId.isValid(id)) { throw new Error('id is not a valid ObjectId'); }
|
|
130
|
+
|
|
131
|
+
const news = await this.findById(id);
|
|
132
|
+
if (news) await news.deleteOne();
|
|
133
|
+
|
|
134
|
+
// News records are global rather than customer-owned, so deleting one
|
|
135
|
+
// removes its metric reference for every customer.
|
|
136
|
+
await metricSources.unlink('News', id);
|
|
137
|
+
return news;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
if (typeof cb === 'function') { run().then(result => cb(null, result), err => cb(err)); return; }
|
|
141
|
+
else { return run(); }
|
|
142
|
+
|
|
143
|
+
};
|
|
144
|
+
|
|
115
145
|
News.statics.upsert = function (news, cb) {
|
|
116
146
|
|
|
117
147
|
const run = async () => {
|
package/lib/Note.js
CHANGED
|
@@ -5,6 +5,7 @@ module.exports = function(mongoose, config) {
|
|
|
5
5
|
let
|
|
6
6
|
|
|
7
7
|
Schema = mongoose.Schema,
|
|
8
|
+
metricSources = require('./MetricSource')(mongoose),
|
|
8
9
|
querystring = require('querystring');
|
|
9
10
|
|
|
10
11
|
let Note = new Schema({
|
|
@@ -44,9 +45,8 @@ module.exports = function(mongoose, config) {
|
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
const note = await query;
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
await note.deleteOne();
|
|
48
|
+
if (note) await note.deleteOne();
|
|
49
|
+
await metricSources.unlink('Note', noteId, customerId);
|
|
50
50
|
return note;
|
|
51
51
|
};
|
|
52
52
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var should = require('should');
|
|
4
|
+
var createMetricSources = require('../lib/MetricSource');
|
|
5
|
+
|
|
6
|
+
describe('MetricSource', function() {
|
|
7
|
+
it('unlinks a source from current and previous metric states for one customer', async function() {
|
|
8
|
+
var captured;
|
|
9
|
+
var mongoose = {
|
|
10
|
+
model: function(name) {
|
|
11
|
+
name.should.equal('Financials');
|
|
12
|
+
return {
|
|
13
|
+
updateMany: function(filter, update) {
|
|
14
|
+
captured = { filter: filter, update: update };
|
|
15
|
+
return Promise.resolve({ modifiedCount: 1 });
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
await createMetricSources(mongoose).unlink('Meeting', 'meeting-id', 'customer-id');
|
|
22
|
+
|
|
23
|
+
captured.filter.customer.should.equal('customer-id');
|
|
24
|
+
captured.filter.$or.should.have.length(2);
|
|
25
|
+
captured.update.$pull['snapshots.$[].metrics.$[].sources'].should.eql({
|
|
26
|
+
model: 'Meeting', ref: 'meeting-id'
|
|
27
|
+
});
|
|
28
|
+
captured.update.$pull['snapshots.$[].metrics.$[].previous.sources'].should.eql({
|
|
29
|
+
model: 'Meeting', ref: 'meeting-id'
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('rejects unsupported source models', async function() {
|
|
34
|
+
var metricSources = createMetricSources({});
|
|
35
|
+
|
|
36
|
+
await metricSources.unlink('Event', 'event-id', 'customer-id').should.be.rejectedWith(
|
|
37
|
+
'model must be a supported metric source'
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('unlinks global News sources without a customer filter', async function() {
|
|
42
|
+
var capturedFilter;
|
|
43
|
+
var mongoose = {
|
|
44
|
+
model: function() {
|
|
45
|
+
return {
|
|
46
|
+
updateMany: function(filter) {
|
|
47
|
+
capturedFilter = filter;
|
|
48
|
+
return Promise.resolve({ modifiedCount: 1 });
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
await createMetricSources(mongoose).unlink('News', 'news-id');
|
|
55
|
+
|
|
56
|
+
should.not.exist(capturedFilter.customer);
|
|
57
|
+
capturedFilter.$or[0]['snapshots.metrics.sources'].$elemMatch.should.eql({
|
|
58
|
+
model: 'News', ref: 'news-id'
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
package/test/News.js
CHANGED
|
@@ -25,12 +25,23 @@ describe('News', function() {
|
|
|
25
25
|
news.createdBy = 'Jason';
|
|
26
26
|
news.createdOn = Date.now();
|
|
27
27
|
news.title = 'Google';
|
|
28
|
+
news.html = '<p>Google announced quarterly revenue.</p>';
|
|
29
|
+
news.analysis = {
|
|
30
|
+
insights: [{
|
|
31
|
+
text: 'Quarterly revenue reached a new high.',
|
|
32
|
+
category: 'highlight'
|
|
33
|
+
}]
|
|
34
|
+
};
|
|
28
35
|
news.link = 'http://google.com';
|
|
29
36
|
news.internal = false;
|
|
30
37
|
|
|
31
38
|
News.upsert(news, function(err, item) {
|
|
32
39
|
should.not.exist(err);
|
|
33
40
|
should.exist(item);
|
|
41
|
+
item.html.should.equal('<p>Google announced quarterly revenue.</p>');
|
|
42
|
+
item.analysis.insights.should.have.length(1);
|
|
43
|
+
item.analysis.insights[0].text.should.equal('Quarterly revenue reached a new high.');
|
|
44
|
+
item.analysis.insights[0].category.should.equal('highlight');
|
|
34
45
|
news = item;
|
|
35
46
|
done();
|
|
36
47
|
});
|