Skip to content

Commit

Permalink
Merge pull request #4666 from UniversityOfHelsinkiCS/study-track-sele…
Browse files Browse the repository at this point in the history
…ctor

[Class statistics] Add selector for study tracks in population search
  • Loading branch information
rikurauhala authored Oct 30, 2024
2 parents 0bdd010 + 6808bfd commit 6a9d92e
Show file tree
Hide file tree
Showing 19 changed files with 193 additions and 134 deletions.
2 changes: 1 addition & 1 deletion services/backend/src/config/organizationConstants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Linter was not having any of this so neeeded to add resolveJsonModule:true to tsconfig
// Linter was not having any of this so needed to add resolveJsonModule:true to tsconfig
// export const { facultyCodes, ignoredFacultyCodes, magicFacultyCode } = require('../environment/organizationConfig.json')

export { facultyCodes, ignoredFacultyCodes, magicFacultyCode } from '../environment/organizationConfig.json'
10 changes: 5 additions & 5 deletions services/backend/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { computeLanguageCenterData, LANGUAGE_CENTER_REDIS_KEY } from './services
import { findStudentsCloseToGraduation, CLOSE_TO_GRADUATION_REDIS_KEY } from './services/populations/closeToGraduation'
import { redisClient } from './services/redis'
import { getCurrentSemester } from './services/semesters'
import { combinedStudyprogrammes, isRelevantProgramme } from './services/studyProgramme/studyProgrammeHelpers'
import { updateBasicView, updateStudytrackView } from './services/studyProgramme/studyProgrammeUpdates'
import { combinedStudyProgrammes, isRelevantProgramme } from './services/studyProgramme/studyProgrammeHelpers'
import { updateBasicView, updateStudyTrackView } from './services/studyProgramme/studyProgrammeUpdates'
import { findAndSaveTeachers } from './services/teachers/top'
import { deleteOutdatedUsers } from './services/userService'
import logger from './util/logger'
Expand Down Expand Up @@ -61,10 +61,10 @@ const refreshProgrammesAndFaculties = async () => {

export const refreshProgramme = async (code: string) => {
await updateBasicView(code, '')
await updateStudytrackView(code, '')
const combinedProgramme = combinedStudyprogrammes[code] || ''
await updateStudyTrackView(code, '')
const combinedProgramme = combinedStudyProgrammes[code] || ''
await updateBasicView(code, combinedProgramme)
await updateStudytrackView(code, combinedProgramme)
await updateStudyTrackView(code, combinedProgramme)
}

export const refreshProgrammes = async () => {
Expand Down
37 changes: 25 additions & 12 deletions services/backend/src/routes/studyProgramme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
setBasicStats,
getGraduationStats,
setGraduationStats,
getStudytrackStats,
setStudytrackStats,
getStudyTrackStats,
setStudyTrackStats,
} from '../services/analyticsService'
import { getCreditsProduced } from '../services/providerCredits'
import { getProgrammeName } from '../services/studyProgramme'
Expand All @@ -15,9 +15,9 @@ import {
getStudyProgrammeCoursesForStudyTrack,
getStudyProgrammeStatsForColorizedCoursesTable,
} from '../services/studyProgramme/studyProgrammeCourses'
import { getGraduationStatsForStudytrack } from '../services/studyProgramme/studyProgrammeGraduations'
import { updateBasicView, updateStudytrackView } from '../services/studyProgramme/studyProgrammeUpdates'
import { getStudyRightsInProgramme } from '../services/studyProgramme/studyRightFinders'
import { getGraduationStatsForStudyTrack } from '../services/studyProgramme/studyProgrammeGraduations'
import { updateBasicView, updateStudyTrackView } from '../services/studyProgramme/studyProgrammeUpdates'
import { getStudyRightsInProgramme, getStudyTracksForProgramme } from '../services/studyProgramme/studyRightFinders'
import { getStudyTrackStatsForStudyProgramme } from '../services/studyProgramme/studyTrackStats'
import { Graduated, SpecialGroups, YearType } from '../types'
import logger from '../util/logger'
Expand Down Expand Up @@ -89,7 +89,7 @@ router.get('/:id/graduationstats', async (req: GetStatsRequest, res: Response) =
return res.json(data)
}

const updatedStats = await getGraduationStatsForStudytrack({
const updatedStats = await getGraduationStatsForStudyTrack({
studyProgramme: code,
combinedProgramme,
settings: {
Expand Down Expand Up @@ -142,7 +142,7 @@ router.get('/:id/studytrackstats', async (req: GetStudyTrackStatsRequest, res: R
}

logInfoForGrafana(code, combinedProgramme)
const data = await getStudytrackStats(code, combinedProgramme, graduated, specialGroups)
const data = await getStudyTrackStats(code, combinedProgramme, graduated, specialGroups)
if (data) {
return res.json(data)
}
Expand All @@ -158,7 +158,7 @@ router.get('/:id/studytrackstats', async (req: GetStudyTrackStatsRequest, res: R
studyRightsOfProgramme,
})
if (updated) {
await setStudytrackStats(updated, graduated, specialGroups)
await setStudyTrackStats(updated, graduated, specialGroups)
}
return res.json(updated)
})
Expand All @@ -173,6 +173,19 @@ router.get('/:id/colorizedtablecoursestats', async (req: Request, res: Response)
}
})

router.get('/:id/studytracks', async (req: Request, res: Response) => {
const code = req.params.id
if (!code) {
return res.status(422).end()
}
try {
const data = await getStudyTracksForProgramme(code)
return res.json(data)
} catch (error) {
logger.error({ message: `Failed to get study tracks for study programme ${code}`, meta: `${error}` })
}
})

interface GetUpdateViewRequest extends Request {
query: {
combined_programme: string
Expand Down Expand Up @@ -202,7 +215,7 @@ router.get('/:id/update_studytrackview', async (req: GetUpdateViewRequest, res:
return res.status(400).json({ error: 'Missing code' })
}
try {
const result = await updateStudytrackView(code, combinedProgramme)
const result = await updateStudyTrackView(code, combinedProgramme)
return res.json(result)
} catch (error) {
const message = `Failed to update study track stats for programme ${code}${combinedProgramme ? `+${combinedProgramme}` : ''}`
Expand All @@ -229,7 +242,7 @@ router.get('/:id/evaluationstats', async (req: GetEvaluationStatsRequest, res: R
const combinedProgramme = ''
let gradData = await getGraduationStats(code, combinedProgramme, yearType, specialGroups)
if (!gradData) {
const updatedStats = await getGraduationStatsForStudytrack({
const updatedStats = await getGraduationStatsForStudyTrack({
studyProgramme: code,
combinedProgramme,
settings: {
Expand All @@ -243,7 +256,7 @@ router.get('/:id/evaluationstats', async (req: GetEvaluationStatsRequest, res: R
}
}

let progressData = await getStudytrackStats(code, combinedProgramme, graduated, specialGroups)
let progressData = await getStudyTrackStats(code, combinedProgramme, graduated, specialGroups)
if (!progressData) {
const studyRightsOfProgramme = await getStudyRightsInProgramme(code, false, true)
const updated = await getStudyTrackStatsForStudyProgramme({
Expand All @@ -256,7 +269,7 @@ router.get('/:id/evaluationstats', async (req: GetEvaluationStatsRequest, res: R
studyRightsOfProgramme,
})
if (updated) {
await setStudytrackStats(updated, graduated, specialGroups)
await setStudyTrackStats(updated, graduated, specialGroups)
progressData = updated
}
}
Expand Down
20 changes: 10 additions & 10 deletions services/backend/src/services/analyticsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const createRedisKeyForCreditStats = (id: string, yearType: YearType, specialGro
const createRedisKeyForGraduationStats = (id: string, yearType: YearType, specialGroups: SpecialGroups) => {
return `GRADUATION_STATS_${id}_${yearType}_${specialGroups}`
}
const createRedisKeyForStudytrackStats = (id: string, graduated: Graduated, specialGroups: SpecialGroups) => {
const createRedisKeyForStudyTrackStats = (id: string, graduated: Graduated, specialGroups: SpecialGroups) => {
return `STUDYTRACK_STATS_${id}_${graduated}_${specialGroups}`
}

Expand All @@ -34,8 +34,8 @@ export const getBasicStats = async (
yearType: YearType,
specialGroups: SpecialGroups
) => {
const searchkey = combinedProgramme ? `${id}-${combinedProgramme}` : id
const redisKey = createRedisKeyForBasicStats(searchkey, yearType, specialGroups)
const searchKey = combinedProgramme ? `${id}-${combinedProgramme}` : id
const redisKey = createRedisKeyForBasicStats(searchKey, yearType, specialGroups)
const dataFromRedis = await redisClient.get(redisKey)
if (!dataFromRedis) {
return null
Expand Down Expand Up @@ -102,8 +102,8 @@ export const getGraduationStats = async (
yearType: YearType,
specialGroups: SpecialGroups
) => {
const searchkey = combinedProgramme ? `${id}-${combinedProgramme}` : id
const redisKey = createRedisKeyForGraduationStats(searchkey, yearType, specialGroups)
const searchKey = combinedProgramme ? `${id}-${combinedProgramme}` : id
const redisKey = createRedisKeyForGraduationStats(searchKey, yearType, specialGroups)
const dataFromRedis = await redisClient.get(redisKey)
if (!dataFromRedis) {
return null
Expand All @@ -129,24 +129,24 @@ export const setGraduationStats = async (data, yearType: YearType, specialGroups
return dataToRedis
}

export const getStudytrackStats = async (
export const getStudyTrackStats = async (
id: string,
combinedProgramme: string | null,
graduated: Graduated,
specialGroups: SpecialGroups
) => {
const searchkey = combinedProgramme ? `${id}-${combinedProgramme}` : id
const redisKey = createRedisKeyForStudytrackStats(searchkey, graduated, specialGroups)
const searchKey = combinedProgramme ? `${id}-${combinedProgramme}` : id
const redisKey = createRedisKeyForStudyTrackStats(searchKey, graduated, specialGroups)
const dataFromRedis = await redisClient.get(redisKey)
if (!dataFromRedis) {
return null
}
return JSON.parse(dataFromRedis)
}

export const setStudytrackStats = async (data, graduated: Graduated, specialGroups: SpecialGroups) => {
export const setStudyTrackStats = async (data, graduated: Graduated, specialGroups: SpecialGroups) => {
const { id } = data
const redisKey = createRedisKeyForStudytrackStats(id, graduated, specialGroups)
const redisKey = createRedisKeyForStudyTrackStats(id, graduated, specialGroups)
const dataToRedis = {
...data,
status: 'DONE',
Expand Down
12 changes: 6 additions & 6 deletions services/backend/src/services/faculty/facultyGraduationTimes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { cloneDeep, omit } from 'lodash'

import { DegreeProgrammeType, Name } from '../../types'
import { getGraduationStats, getStudytrackStats, setGraduationStats, setStudytrackStats } from '../analyticsService'
import { getGraduationStatsForStudytrack, GraduationTimes } from '../studyProgramme/studyProgrammeGraduations'
import { getGraduationStats, getStudyTrackStats, setGraduationStats, setStudyTrackStats } from '../analyticsService'
import { getGraduationStatsForStudyTrack, GraduationTimes } from '../studyProgramme/studyProgrammeGraduations'
import { getMedian } from '../studyProgramme/studyProgrammeHelpers'
import { getStudyRightsInProgramme } from '../studyProgramme/studyRightFinders'
import {
Expand All @@ -25,7 +25,7 @@ export const programmeTypes = {
} as const

const getStatsByGraduationYear = async (facultyProgrammes: ProgrammesOfOrganization) => {
const newStats: Array<Awaited<ReturnType<typeof getGraduationStatsForStudytrack>>> = []
const newStats: Array<Awaited<ReturnType<typeof getGraduationStatsForStudyTrack>>> = []
const medians: Record<string, LevelGraduationStats[]> = {}
const programmes: { medians: Record<string, Record<string, ProgrammeStats>> } = { medians: {} }

Expand All @@ -38,7 +38,7 @@ const getStatsByGraduationYear = async (facultyProgrammes: ProgrammesOfOrganizat
newStats.push(statsFromRedis)
continue
}
const updatedStats = await getGraduationStatsForStudytrack({
const updatedStats = await getGraduationStatsForStudyTrack({
studyProgramme: programme.code,
combinedProgramme: '',
settings: {
Expand Down Expand Up @@ -136,7 +136,7 @@ const getStatsByStartYear = async (facultyProgrammes: ProgrammesOfOrganization)
if (programme.degreeProgrammeType == null || !(programme.degreeProgrammeType in programmeTypes)) {
continue
}
const statsFromRedis = await getStudytrackStats(programme.code, '', 'GRADUATED_INCLUDED', 'SPECIAL_EXCLUDED')
const statsFromRedis = await getStudyTrackStats(programme.code, '', 'GRADUATED_INCLUDED', 'SPECIAL_EXCLUDED')
if (statsFromRedis) {
newStats.push(statsFromRedis)
continue
Expand All @@ -152,7 +152,7 @@ const getStatsByStartYear = async (facultyProgrammes: ProgrammesOfOrganization)
},
studyRightsOfProgramme,
})
await setStudytrackStats(updatedStats, 'GRADUATED_INCLUDED', 'SPECIAL_EXCLUDED')
await setStudyTrackStats(updatedStats, 'GRADUATED_INCLUDED', 'SPECIAL_EXCLUDED')
newStats.push(updatedStats)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import moment from 'moment'

import { rootOrgId } from '../../config'
import { Graduated, SpecialGroups, Unarray } from '../../types'
import { getStudytrackStats, setStudytrackStats } from '../analyticsService'
import { getStudyTrackStats, setStudyTrackStats } from '../analyticsService'
import { getYearsArray } from '../studyProgramme/studyProgrammeHelpers'
import { getStudyRightsInProgramme } from '../studyProgramme/studyRightFinders'
import { getStudyTrackStatsForStudyProgramme } from '../studyProgramme/studyTrackStats'
Expand Down Expand Up @@ -114,7 +114,7 @@ export const combineFacultyStudentProgress = async (
) {
continue
}
const statsFromRedis = await getStudytrackStats(studyProgramme, null, graduated, specialGroups)
const statsFromRedis = await getStudyTrackStats(studyProgramme, null, graduated, specialGroups)
if (statsFromRedis) {
statsOfProgrammes.push(statsFromRedis)
} else {
Expand All @@ -128,7 +128,7 @@ export const combineFacultyStudentProgress = async (
studyRightsOfProgramme,
})
statsOfProgrammes.push(updatedStats)
setStudytrackStats(updatedStats, graduated, specialGroups)
setStudyTrackStats(updatedStats, graduated, specialGroups)
}
}

Expand Down
6 changes: 3 additions & 3 deletions services/backend/src/services/faculty/facultyStudents.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Unarray } from '../../types'
import { getStudytrackStats, setStudytrackStats } from '../analyticsService'
import { getStudyTrackStats, setStudyTrackStats } from '../analyticsService'
import { getPercentage, tableTitles } from '../studyProgramme/studyProgrammeHelpers'
import { getStudyRightsInProgramme } from '../studyProgramme/studyRightFinders'
import { getStudyTrackStatsForStudyProgramme } from '../studyProgramme/studyTrackStats'
Expand Down Expand Up @@ -65,7 +65,7 @@ export const combineFacultyStudents = async (
const newStats: StudyTrackStats[] = []

for (const studyProgramme of programmeCodes) {
const statsFromRedis = await getStudytrackStats(studyProgramme, null, graduated, specialGroups)
const statsFromRedis = await getStudyTrackStats(studyProgramme, null, graduated, specialGroups)
if (statsFromRedis) {
newStats.push(statsFromRedis)
if (!years.length) {
Expand All @@ -82,7 +82,7 @@ export const combineFacultyStudents = async (
},
studyRightsOfProgramme,
})
setStudytrackStats(updatedStats, graduated, specialGroups)
setStudyTrackStats(updatedStats, graduated, specialGroups)
if (!years.length) {
years = updatedStats.years
}
Expand Down
6 changes: 3 additions & 3 deletions services/backend/src/services/faculty/facultyThesisWriters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { cloneDeep } from 'lodash'

import { DegreeProgrammeType } from '../../types'
import { getGraduationStats, setGraduationStats } from '../analyticsService'
import { getGraduationStatsForStudytrack } from '../studyProgramme/studyProgrammeGraduations'
import { getGraduationStatsForStudyTrack } from '../studyProgramme/studyProgrammeGraduations'
import { getDegreeProgrammesOfFaculty, ProgrammesOfOrganization } from './faculty'

type ProgrammeName = {
Expand All @@ -25,7 +25,7 @@ const calculateCombinedStats = async (
]
const programmeTableStats: Record<string, Array<Array<string | number>>> = {}

const newStats: Array<Awaited<ReturnType<typeof getGraduationStatsForStudytrack>>> = []
const newStats: Array<Awaited<ReturnType<typeof getGraduationStatsForStudyTrack>>> = []
const combinedTableStats: Array<Array<string | number>> = []
let years: Array<string | number> = []
const programmeNames: Record<string, ProgrammeName> = {}
Expand All @@ -47,7 +47,7 @@ const calculateCombinedStats = async (
newStats.push(statsFromRedis)
continue
}
const updatedStats = await getGraduationStatsForStudytrack({
const updatedStats = await getGraduationStatsForStudyTrack({
studyProgramme: programme.code,
combinedProgramme: '',
settings: {
Expand Down
6 changes: 3 additions & 3 deletions services/backend/src/services/programmeModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ProgrammeModule } from '../models'
import { ExcludedCourse } from '../models/kone'
import { Name } from '../types'
import logger from '../util/logger'
import { combinedStudyprogrammes } from './studyProgramme/studyProgrammeHelpers'
import { combinedStudyProgrammes } from './studyProgramme/studyProgrammeHelpers'

export const getCurriculumVersions = async (code: string) => {
try {
Expand Down Expand Up @@ -134,8 +134,8 @@ const getCoursesAndModulesForProgramme = async (code: string, periodIds: string)

export const getCoursesAndModules = async (code: string, periodIds: string) => {
const defaultProgrammeCourses = await getCoursesAndModulesForProgramme(code, periodIds)
if (code in combinedStudyprogrammes) {
const secondProgramme = combinedStudyprogrammes[code as keyof typeof combinedStudyprogrammes]
if (code in combinedStudyProgrammes) {
const secondProgramme = combinedStudyProgrammes[code as keyof typeof combinedStudyProgrammes]
const secondProgrammeCourses = await getCoursesAndModulesForProgramme(secondProgramme, periodIds)
return { defaultProgrammeCourses, secondProgrammeCourses }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ const getProgrammesBeforeOrAfter = async (studyprogramme: string, queryParameter
return null
}

export const getGraduationStatsForStudytrack = async ({
export const getGraduationStatsForStudyTrack = async ({
studyProgramme,
combinedProgramme,
settings,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const getStartDate = (isAcademicYear: boolean) => {
}

// In the object programmes should be {bachelorCode: masterCode}
export const combinedStudyprogrammes = { KH90_001: 'MH90_001' } as const
export const combinedStudyProgrammes = { KH90_001: 'MH90_001' } as const

// There are 9 course_unit_types
// 1. urn:code:course-unit-type:regular
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { setBasicStats, setCreditStats, setGraduationStats, setStudytrackStats } from '../analyticsService'
import { setBasicStats, setCreditStats, setGraduationStats, setStudyTrackStats } from '../analyticsService'
import { computeCreditsProduced } from '../providerCredits'
import { getBasicStatsForStudytrack } from './studyProgrammeBasics'
import { getGraduationStatsForStudytrack } from './studyProgrammeGraduations'
import { getGraduationStatsForStudyTrack } from './studyProgrammeGraduations'
import { getStudyRightsInProgramme } from './studyRightFinders'
import { getStudyTrackStatsForStudyProgramme } from './studyTrackStats'

Expand Down Expand Up @@ -29,7 +29,7 @@ export const updateBasicView = async (code: string, combinedProgramme: string) =
await setCreditStats(creditStats, isAcademicYear, includeAllSpecials)
}

const graduationStats = await getGraduationStatsForStudytrack({
const graduationStats = await getGraduationStatsForStudyTrack({
studyProgramme: code,
combinedProgramme,
settings: { isAcademicYear, includeAllSpecials },
Expand All @@ -41,7 +41,7 @@ export const updateBasicView = async (code: string, combinedProgramme: string) =
return 'OK'
}

export const updateStudytrackView = async (code: string, combinedProgramme: string) => {
export const updateStudyTrackView = async (code: string, combinedProgramme: string) => {
const graduatedOptions = ['GRADUATED_INCLUDED', 'GRADUATED_EXCLUDED'] as const
const specialGroupOptions = ['SPECIAL_INCLUDED', 'SPECIAL_EXCLUDED'] as const
const studyRightsOfProgramme = await getStudyRightsInProgramme(code, false, true)
Expand All @@ -57,7 +57,7 @@ export const updateStudytrackView = async (code: string, combinedProgramme: stri
},
studyRightsOfProgramme,
})
await setStudytrackStats(stats, graduated, specialGroup)
await setStudyTrackStats(stats, graduated, specialGroup)
}
}

Expand Down
Loading

0 comments on commit 6a9d92e

Please sign in to comment.