-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of github.com:parlemonde/1village into publish
- Loading branch information
Showing
128 changed files
with
1,333 additions
and
964 deletions.
There are no files selected for viewing
Empty file.
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
version: '3.7' | ||
services: | ||
backend: | ||
build: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,56 @@ | ||
import type { Request } from 'express'; | ||
|
||
import { | ||
getClassroomsInfos, | ||
getConnectedClassroomsCount, | ||
getContributedClassroomsCount, | ||
getRegisteredClassroomsCount, | ||
} from '../stats/classroomStats'; | ||
import { | ||
getAverageConnections, | ||
getAverageDuration, | ||
getMaxConnections, | ||
getMaxDuration, | ||
getMedianConnections, | ||
getMedianDuration, | ||
getMinConnections, | ||
getMinDuration, | ||
} from '../stats/sessionStats'; | ||
import { Controller } from './controller'; | ||
|
||
export const statisticsController = new Controller('/statistics'); | ||
|
||
statisticsController.get({ path: '/sessions/:phase' }, async (req: Request, res) => { | ||
const phase = req.params.phase ? parseInt(req.params.phase) : null; | ||
|
||
res.sendJSON({ | ||
minDuration: await getMinDuration(), // TODO - add phase | ||
maxDuration: await getMaxDuration(), // TODO - add phase | ||
averageDuration: await getAverageDuration(), // TODO - add phase | ||
medianDuration: await getMedianDuration(), // TODO - add phase | ||
minConnections: await getMinConnections(), // TODO - add phase | ||
maxConnections: await getMaxConnections(), // TODO - add phase | ||
averageConnections: await getAverageConnections(), // TODO - add phase | ||
medianConnections: await getMedianConnections(), // TODO - add phase | ||
registeredClassroomsCount: await getRegisteredClassroomsCount(), | ||
connectedClassroomsCount: await getConnectedClassroomsCount(), // TODO - add phase | ||
contributedClassroomsCount: await getContributedClassroomsCount(phase), | ||
}); | ||
}); | ||
|
||
statisticsController.get({ path: '/classrooms' }, async (_req, res) => { | ||
res.sendJSON({ | ||
classrooms: await getClassroomsInfos(), | ||
}); | ||
}); | ||
import type { Request } from 'express'; | ||
|
||
import { | ||
getClassroomsInfos, | ||
getConnectedClassroomsCount, | ||
getContributedClassroomsCount, | ||
getRegisteredClassroomsCount, | ||
} from '../stats/classroomStats'; | ||
import { | ||
getAverageConnections, | ||
getAverageDuration, | ||
getMaxConnections, | ||
getMaxDuration, | ||
getMedianConnections, | ||
getMedianDuration, | ||
getMinConnections, | ||
getMinDuration, | ||
} from '../stats/sessionStats'; | ||
import { getChildrenCodesCount, getFamilyAccountsCount, getConnectedFamiliesCount, getFamiliesWithoutAccount } from '../stats/villageStats'; | ||
import { Controller } from './controller'; | ||
|
||
export const statisticsController = new Controller('/statistics'); | ||
|
||
statisticsController.get({ path: '/sessions/:phase' }, async (req: Request, res) => { | ||
const phase = req.params.phase ? parseInt(req.params.phase) : null; | ||
|
||
res.sendJSON({ | ||
minDuration: await getMinDuration(), // TODO - add phase | ||
maxDuration: await getMaxDuration(), // TODO - add phase | ||
averageDuration: await getAverageDuration(), // TODO - add phase | ||
medianDuration: await getMedianDuration(), // TODO - add phase | ||
minConnections: await getMinConnections(), // TODO - add phase | ||
maxConnections: await getMaxConnections(), // TODO - add phase | ||
averageConnections: await getAverageConnections(), // TODO - add phase | ||
medianConnections: await getMedianConnections(), // TODO - add phase | ||
registeredClassroomsCount: await getRegisteredClassroomsCount(), | ||
connectedClassroomsCount: await getConnectedClassroomsCount(), // TODO - add phase | ||
contributedClassroomsCount: await getContributedClassroomsCount(phase), | ||
}); | ||
}); | ||
|
||
statisticsController.get({ path: '/classrooms' }, async (_req, res) => { | ||
res.sendJSON({ | ||
classrooms: await getClassroomsInfos(), | ||
}); | ||
}); | ||
|
||
statisticsController.get({ path: '/villages/:villageId' }, async (_req, res) => { | ||
const villageId = parseInt(_req.params.villageId); | ||
res.sendJSON({ | ||
familyAccountsCount: await getFamilyAccountsCount(villageId), | ||
childrenCodesCount: await getChildrenCodesCount(villageId), | ||
connectedFamiliesCount: await getConnectedFamiliesCount(villageId), | ||
familiesWithoutAccount: await getFamiliesWithoutAccount(villageId), | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { Student } from '../entities/student'; | ||
import { User } from '../entities/user'; | ||
import { AppDataSource } from '../utils/data-source'; | ||
|
||
const userRepository = AppDataSource.getRepository(User); | ||
const studentRepository = AppDataSource.getRepository(Student); | ||
|
||
export const getChildrenCodesCount = async (villageId: number) => { | ||
const childrenCodeCount = await studentRepository | ||
.createQueryBuilder('student') | ||
.innerJoin('student.classroom', 'classroom') | ||
.innerJoin('classroom.village', 'village') | ||
.where('classroom.villageId = :villageId', { villageId }) | ||
.getCount(); | ||
return childrenCodeCount; | ||
}; | ||
|
||
export const getFamilyAccountsCount = async (villageId: number) => { | ||
const familyAccountsCount = await userRepository | ||
.createQueryBuilder('user') | ||
.innerJoin('user.village', 'village') | ||
.innerJoin('classroom', 'classroom', 'classroom.villageId = village.id') | ||
.innerJoin('student', 'student', 'student.classroomId = classroom.id') | ||
.where('classroom.villageId = :villageId', { villageId }) | ||
.groupBy('user.id') | ||
.getCount(); | ||
return familyAccountsCount; | ||
}; | ||
|
||
export const getConnectedFamiliesCount = async (villageId: number) => { | ||
const connectedFamiliesCount = await studentRepository | ||
.createQueryBuilder('student') | ||
.innerJoin('classroom', 'classroom', 'classroom.id = student.classroomId') | ||
.where('classroom.villageId = :villageId', { villageId }) | ||
.andWhere('student.numLinkedAccount >= 1') | ||
.getCount(); | ||
|
||
return connectedFamiliesCount; | ||
}; | ||
|
||
export const getFamiliesWithoutAccount = async (villageId: number) => { | ||
const familiesWithoutAccount = await studentRepository | ||
.createQueryBuilder('student') | ||
.innerJoin('student.classroom', 'classroom') | ||
.innerJoin('classroom.user', 'user') | ||
.innerJoin('user.village', 'village') | ||
.where('classroom.villageId = :villageId', { villageId }) | ||
.andWhere('student.numLinkedAccount < 1') | ||
.select([ | ||
'classroom.name AS classroom_name', | ||
'classroom.countryCode as classroom_country', | ||
'student.firstname AS student_firstname', | ||
'student.lastname AS student_lastname', | ||
'student.id AS student_id', | ||
'village.name AS village_name', | ||
]) | ||
.getRawMany(); | ||
|
||
return familiesWithoutAccount; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.