-
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathsurvey.service.ts
More file actions
134 lines (118 loc) · 3.81 KB
/
survey.service.ts
File metadata and controls
134 lines (118 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import mongoose from 'mongoose';
import SequenceService from './sequence.service.js';
import logger from "./logger.js";
// Define the SurveyType interface here instead of importing it
export interface SurveyType {
id: number;
userId: string;
org?: string;
repo?: string;
prNumber?: number;
usedCopilot?: boolean;
percentTimeSaved?: number;
reason?: string;
timeUsedFor?: string;
kudos?: number;
status?: string;
hits?: number;
createdAt?: Date;
updatedAt?: Date;
}
class SurveyService {
async createSurvey(survey: SurveyType) {
survey.id = await SequenceService.getNextSequenceValue('survey-sequence');
const Survey = mongoose.model('Survey');
return await Survey.create(survey);
}
async updateSurvey(survey: SurveyType) {
if (!survey || !survey.id || typeof survey.id !== 'number') {
throw new Error('Invalid survey data provided');
}
const Survey = mongoose.model('Survey');
const result = await Survey.updateOne({ id: { $eq: survey.id } }, { $set: survey });
// Check if the update modified any document.
if (result.modifiedCount === 0) {
throw new Error('Survey update failed: no document was modified');
}
const updatedSurvey = await Survey.findOne({ id: survey.id });
if (!updatedSurvey) {
throw new Error('Survey update failed: survey not found');
}
logger.info(`Survey updated: ${survey.id}`);
return updatedSurvey;
}
async getRecentSurveysWithGoodReasons(minReasonLength: number): Promise<SurveyType[]> {
if (typeof minReasonLength !== 'number' || isNaN(minReasonLength) || minReasonLength < 1) {
throw new Error('Invalid minReasonLength provided');
}
const Survey = mongoose.model('Survey');
return Survey.find({
reason: {
$and: [
{ $ne: null },
{ $ne: '' },
{ $gte: minReasonLength }
]
}
}).sort({ updatedAt: -1 }).limit(20).exec();
}
/**
* Get all surveys based on filtering criteria
*/
async getAllSurveys(params: {
org?: string;
team?: string;
reasonLength?: string;
since?: string;
until?: string;
status?: string;
userId?: string;
}) {
const { org, team, reasonLength, since, until, status, userId } = params;
const dateFilter: mongoose.FilterQuery<SurveyType> = {};
// Validate the date strings before creating Date objects
if (since) {
try {
const sinceDate = new Date(since);
// Check if the date is valid
if (!isNaN(sinceDate.getTime())) {
dateFilter.$gte = sinceDate;
} else {
logger.warn(`Invalid 'since' date parameter: ${since}`);
}
} catch (error) {
logger.error(`Error parsing 'since' date: ${since}`, error);
}
}
if (until) {
try {
const untilDate = new Date(until);
// Check if the date is valid
if (!isNaN(untilDate.getTime())) {
dateFilter.$lte = untilDate;
} else {
logger.warn(`Invalid 'until' date parameter: ${until}`);
}
} catch (error) {
logger.error(`Error parsing 'until' date: ${until}`, error);
}
}
const query = {
filter: {
...(org ? { org: String(org) } : {}),
...(team ? { team: String(team) } : {}),
...(userId ? { userId: String(userId) } : {}),
...(reasonLength ? { $expr: { $and: [{ $gt: [{ $strLenCP: { $ifNull: ['$reason', ''] } }, 40] }, { $ne: ['$reason', null] }] } } : {}),
...(Object.keys(dateFilter).length > 0 ? { createdAt: dateFilter } : {}),
...(status ? { status } : {}),
},
projection: {
_id: 0,
__v: 0,
}
};
const Survey = mongoose.model('Survey');
return Survey.find(query.filter, query.projection);
}
}
export default new SurveyService();