Skip to content

Commit 920c1aa

Browse files
committed
[Backend] Move population tag filtering to the query
1 parent 31787e6 commit 920c1aa

File tree

3 files changed

+20
-27
lines changed

3 files changed

+20
-27
lines changed

services/backend/src/routes/population.ts

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,6 @@ import { getFullStudyProgrammeRights, hasFullAccessToStudentData, safeJSONParse
1717

1818
const router = Router()
1919

20-
type populationPersonalTagFilter = {
21-
[key: string]: any
22-
students: any[]
23-
}
24-
25-
const filterPersonalTags = (population: populationPersonalTagFilter, userId: string) => {
26-
return {
27-
...population,
28-
students: population.students.map(student => {
29-
student.tags = student.tags.filter(({ tag }) => !tag.personal_user_id || tag.personal_user_id === userId)
30-
return student
31-
}),
32-
}
33-
}
34-
3520
type EncryptedStudent = EncrypterData
3621
const isEncryptedStudent = (student?: string | EncryptedStudent) => {
3722
return (student as EncryptedStudent)?.encryptedData !== undefined
@@ -99,7 +84,7 @@ export type PopulationstatisticsQuery = {
9984
router.get<never, PopulationstatisticsResBody, PopulationstatisticsReqBody, PopulationstatisticsQuery>(
10085
'/v3/populationstatistics',
10186
async (req, res) => {
102-
const { roles: userRoles, programmeRights: userProgrammeRights } = req.user
87+
const { id: userId, roles: userRoles, programmeRights: userProgrammeRights } = req.user
10388
const { year, semesters, studyRights: requestedStudyRightsJSON, studentStatuses } = req.query
10489

10590
const months = req.query.months ?? '12'
@@ -137,7 +122,7 @@ router.get<never, PopulationstatisticsResBody, PopulationstatisticsReqBody, Popu
137122
return res.status(403).json({ error: 'Trying to request unauthorized students data' })
138123
}
139124

140-
let result: CanError<{ students: any[]; courses: any[] }>
125+
let result
141126
if (req.query.years) {
142127
const upperYearBound = new Date().getFullYear() + 1
143128
const multiYearStudents = Promise.all(
@@ -146,6 +131,7 @@ router.get<never, PopulationstatisticsResBody, PopulationstatisticsReqBody, Popu
146131
const monthsForCurrentYear = String((upperYearBound - yearAsNumber) * 12)
147132
return optimizedStatisticsOf({
148133
...req.query,
134+
userId,
149135
studyRights: requestedStudyRights.programme,
150136
year,
151137
months: monthsForCurrentYear,
@@ -174,6 +160,7 @@ router.get<never, PopulationstatisticsResBody, PopulationstatisticsReqBody, Popu
174160
} else {
175161
result = await optimizedStatisticsOf({
176162
...req.query,
163+
userId,
177164
studyRights: requestedStudyRights.programme,
178165
year,
179166
months,
@@ -210,8 +197,7 @@ router.get<never, PopulationstatisticsResBody, PopulationstatisticsReqBody, Popu
210197
})
211198
}
212199

213-
const { id: userId } = req.user
214-
return res.json(filterPersonalTags(result, userId))
200+
return res.json(result)
215201
}
216202
)
217203

@@ -227,7 +213,7 @@ interface GetPopulationStatisticsByCourseRequest extends Request {
227213

228214
router.get('/v3/populationstatisticsbycourse', async (req: GetPopulationStatisticsByCourseRequest, res: Response) => {
229215
const { coursecodes, from, to, separate: separateString, unifyCourses } = req.query
230-
const { id, roles, studentsUserCanAccess: allStudentsUserCanAccess, programmeRights } = req.user
216+
const { id: userId, roles, studentsUserCanAccess: allStudentsUserCanAccess, programmeRights } = req.user
231217

232218
if (!coursecodes || !from || !to) {
233219
return res.status(400).json({ error: 'The body should have a yearcode and coursecode defined' })
@@ -252,6 +238,7 @@ router.get('/v3/populationstatisticsbycourse', async (req: GetPopulationStatisti
252238
{
253239
// Useless, because studentnumbers are already filtered above by from & to.
254240
// We should probably refactor this to avoid more confusement.
241+
userId,
255242
year: '1900',
256243
studyRights: undefined,
257244
semesters: ['FALL', 'SPRING'],
@@ -304,7 +291,7 @@ router.get('/v3/populationstatisticsbycourse', async (req: GetPopulationStatisti
304291
)
305292
}
306293

307-
res.json(filterPersonalTags(result, id))
294+
res.json(result)
308295
})
309296

310297
interface PostByStudentNumbersRequest extends Request {
@@ -319,7 +306,7 @@ interface PostByStudentNumbersRequest extends Request {
319306

320307
router.post('/v3/populationstatisticsbystudentnumbers', async (req: PostByStudentNumbersRequest, res: Response) => {
321308
const { studentnumberlist, tags } = req.body
322-
const { roles, id, studentsUserCanAccess } = req.user
309+
const { id: userId, roles, studentsUserCanAccess } = req.user
323310
const filteredStudentNumbers = hasFullAccessToStudentData(roles)
324311
? studentnumberlist
325312
: intersection(studentnumberlist, studentsUserCanAccess)
@@ -328,6 +315,7 @@ router.post('/v3/populationstatisticsbystudentnumbers', async (req: PostByStuden
328315

329316
const result = await optimizedStatisticsOf(
330317
{
318+
userId,
331319
year: tags?.year ?? '1900',
332320
studyRights: studyProgrammeCode,
333321
semesters: ['FALL', 'SPRING'],
@@ -338,7 +326,7 @@ router.post('/v3/populationstatisticsbystudentnumbers', async (req: PostByStuden
338326
const resultWithStudyProgramme = { ...result, studyProgramme: tags?.studyProgramme }
339327
const discardedStudentNumbers = difference(studentnumberlist, filteredStudentNumbers)
340328

341-
res.status(200).json({ ...filterPersonalTags(resultWithStudyProgramme, id), discardedStudentNumbers })
329+
res.status(200).json({ ...resultWithStudyProgramme, discardedStudentNumbers })
342330
})
343331

344332
router.get('/v3/populationstatistics/studyprogrammes', async (req: Request, res: Response) => {

services/backend/src/services/populations/getStudentsIncludeCoursesBetween.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ import { EnrollmentState } from '../../types'
88
type StudentTags = TagStudent & {
99
tag: Pick<Tag, 'tag_id' | 'tagname' | 'personal_user_id'>
1010
}
11-
const getStudentTags = (studyRights: string[], studentNumbers: string[]): Promise<StudentTags[]> =>
11+
const getStudentTags = (studyRights: string[], studentNumbers: string[], userId: string): Promise<StudentTags[]> =>
1212
TagStudent.findAll({
1313
attributes: ['tag_id', 'studentnumber'],
1414
include: {
1515
model: Tag,
1616
attributes: ['tag_id', 'tagname', 'personal_user_id'],
1717
where: {
1818
studytrack: { [Op.in]: studyRights },
19+
personal_user_id: { [Op.or]: [userId, null] },
1920
},
2021
},
2122
where: {
@@ -248,9 +249,10 @@ export const getStudentsIncludeCoursesBetween = async (
248249
studentNumbers: string[],
249250
startDate: string,
250251
endDate: Date,
251-
studyRights: string[]
252+
studyRights: string[],
253+
userId: string
252254
): Promise<StudentsIncludeCoursesBetween> => {
253-
const studentTags = await getStudentTags(studyRights, studentNumbers)
255+
const studentTags = await getStudentTags(studyRights, studentNumbers, userId)
254256
const studentNumberToTags = studentTags.reduce((acc: Record<string, TagStudent[]>, studentTag) => {
255257
const { studentnumber } = studentTag
256258
acc[studentnumber] = [...(acc[studentnumber] || []), studentTag]

services/backend/src/services/populations/optimizedStatisticsOf.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getOptionsForStudents } from './shared'
99
import { getStudentNumbersWithAllStudyRightElements } from './studentNumbersWithAllElements'
1010

1111
export type OptimizedStatisticsQuery = {
12+
userId: string
1213
semesters: string[]
1314
studentStatuses?: string[]
1415
studyRights?: string | string[]
@@ -58,6 +59,7 @@ const parseQueryParams = (query: OptimizedStatisticsQuery): ParsedQueryParams =>
5859
}
5960

6061
export const optimizedStatisticsOf = async (query: OptimizedStatisticsQuery, studentNumberList?: string[]) => {
62+
const { userId } = query
6163
const {
6264
studyRights,
6365
startDate,
@@ -86,7 +88,8 @@ export const optimizedStatisticsOf = async (query: OptimizedStatisticsQuery, stu
8688
studentNumbers,
8789
startDate,
8890
dateMonthsFromNow(startDate, months),
89-
studyRights
91+
studyRights,
92+
userId
9093
)
9194

9295
const optionData = await getOptionsForStudents(studentNumbers, code, degreeProgrammeType)

0 commit comments

Comments
 (0)