diff --git a/server/controllers/analytic.ts b/server/controllers/analytic.ts index 1eebd5d1f..50269be6c 100644 --- a/server/controllers/analytic.ts +++ b/server/controllers/analytic.ts @@ -180,6 +180,7 @@ analyticController.get({ path: '', userType: UserType.ADMIN }, async (req, res) type AddAnalytic = { sessionId: string; userId?: number; + phase: number; event: string; location: string; referrer?: string | null; @@ -201,6 +202,10 @@ const ADD_ANALYTIC_SCHEMA: JSONSchemaType = { type: 'number', nullable: true, }, + phase: { + type: 'number', + nullable: false, + }, event: { type: 'string', nullable: false, @@ -271,15 +276,17 @@ analyticController.router.post( } // Retrieve current user session or save the new one. - let sessionCount = await AppDataSource.getRepository(AnalyticSession).count({ where: { id: data.sessionId } }); - const userPhase = await AppDataSource.getRepository(User) - .createQueryBuilder('user') - .select('user.firstlogin') - .where({ id: data?.userId }) - .getRawOne(); + // Retrieve current user session or save the new one. + // eslint-disable-next-line prefer-const + let [sessionCount, userPhase] = await Promise.all([ + AppDataSource.getRepository(AnalyticSession).count({ where: { id: data.sessionId } }), + AppDataSource.getRepository(User).createQueryBuilder('user').select('user.firstlogin').where({ id: data.userId }).getRawOne(), + ]); + + console.log('USER IN CONTROLLER %!!!!!', data.userId); + console.log('USER PHASE IN CONTROLLER %!!!!!', userPhase); if (sessionCount === 0 && data.event === 'pageview' && data.params?.isInitial) { - // phase ?? const session = new AnalyticSession(); session.id = data.sessionId; session.uniqueId = uniqueSessionId; @@ -291,10 +298,27 @@ analyticController.router.post( session.width = data.width || 0; session.duration = null; session.initialPage = data.location; - session.userId = data?.userId ?? null; - session.phase = userPhase ? parseInt(userPhase) : 0; + session.userId = data.userId ?? 1; + session.phase = userPhase ? userPhase.firstlogin : 0; - // FIND PHASE OF USER VILLAGE session.phase = ; + await AppDataSource.getRepository(AnalyticSession).save(session); + sessionCount = 1; + } + + if (sessionCount === 0 && data.event === 'pageview' && data.params?.isInitial) { + const session = new AnalyticSession(); + session.id = data.sessionId; + session.uniqueId = uniqueSessionId; + session.date = new Date(); + session.browserName = req.useragent?.browser ?? ''; + session.browserVersion = req.useragent?.version ?? ''; + session.os = req.useragent?.os ?? ''; + session.type = req.useragent?.isDesktop ? 'desktop' : req.useragent?.isTablet ? 'tablet' : req.useragent?.isMobile ? 'mobile' : 'other'; + session.width = data.width || 0; + session.duration = null; + session.initialPage = data.location; + session.userId = data.userId ?? 1; + session.phase = userPhase ? userPhase.firstlogin : 0; await AppDataSource.getRepository(AnalyticSession).save(session); sessionCount = 1; diff --git a/server/migrations/1725348767523-AlterAnalyticSessionsByAddPhaseAndUser.ts b/server/migrations/1725362341071-AlterAnalyticSessionWithUserAndPhase.ts similarity index 92% rename from server/migrations/1725348767523-AlterAnalyticSessionsByAddPhaseAndUser.ts rename to server/migrations/1725362341071-AlterAnalyticSessionWithUserAndPhase.ts index 74f8e62ca..ae9d4b6cf 100644 --- a/server/migrations/1725348767523-AlterAnalyticSessionsByAddPhaseAndUser.ts +++ b/server/migrations/1725362341071-AlterAnalyticSessionWithUserAndPhase.ts @@ -1,7 +1,7 @@ import type { MigrationInterface, QueryRunner } from 'typeorm'; import { TableColumn, TableForeignKey } from 'typeorm'; -export class AlterAnalyticSessionsByAddPhaseAndUser1725348767523 implements MigrationInterface { +export class AlterAnalyticSessionWithUserAndPhase1725362341071 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.addColumn( 'analytic_session', @@ -17,7 +17,7 @@ export class AlterAnalyticSessionsByAddPhaseAndUser1725348767523 implements Migr new TableColumn({ name: 'phase', type: 'int', - isNullable: true, + isNullable: false, }), ); diff --git a/server/stats/classroomStats.ts b/server/stats/classroomStats.ts index 53c9b7ee1..86ad62ad9 100644 --- a/server/stats/classroomStats.ts +++ b/server/stats/classroomStats.ts @@ -8,6 +8,8 @@ const classroomRepository = AppDataSource.getRepository(Classroom); const teacherType = UserType.TEACHER; +// const classroomStatusQuery = ; + export const getClassroomsInfos = async () => { return await classroomRepository .createQueryBuilder('classroom') diff --git a/server/stats/sessionStats.ts b/server/stats/sessionStats.ts index 3800e066a..6fab6554f 100644 --- a/server/stats/sessionStats.ts +++ b/server/stats/sessionStats.ts @@ -12,6 +12,7 @@ export const getMinDuration = async () => { .createQueryBuilder('analytic_session') .select('MIN(DISTINCT(analytic_session.duration))', 'minDuration') .innerJoin('analytic_session.user', 'user') + .innerJoin('user.classroom', 'classroom') .where('analytic_session.duration >= :durationThreshold', { durationThreshold }) .andWhere('user.type === :teacherType', { teacherType }) .andWhere('user IS NOT NULL') @@ -26,6 +27,7 @@ export const getMaxDuration = async () => { .createQueryBuilder('analytic_session') .select('MAX(DISTINCT(analytic_session.duration))', 'maxDuration') .innerJoin('analytic_session.user', 'user') + .innerJoin('user.classroom', 'classroom') .where('user.type === :teacherType', { teacherType }) .andWhere('user IS NOT NULL') .getRawOne(); @@ -39,6 +41,7 @@ export const getAverageDuration = async () => { .createQueryBuilder('analytic_session') .select('ROUND(AVG(analytic_session.duration), 0)', 'averageDuration') .innerJoin('analytic_session.user', 'user') + .innerJoin('user.classroom', 'classroom') .where('analytic_session.duration >= :durationThreshold', { durationThreshold }) .andWhere('user IS NOT NULL') .andWhere('user.type === :teacherType', { teacherType }) @@ -53,6 +56,7 @@ export const getMedianDuration = async () => { .createQueryBuilder('analytic_session') .select('duration') .innerJoin('analytic_session.user', 'user') + .innerJoin('user.classroom', 'classroom') .where('analytic_session.duration >= :durationThreshold', { durationThreshold }) .andWhere('user IS NOT NULL') .andWhere('user.type === :teacherType', { teacherType }) @@ -80,6 +84,8 @@ export const getMinConnections = async () => { return subQuery .select('COUNT(*)', 'occurrences') .from('analytic_session', 'as') + .innerJoin('analytic_session.user', 'user') + .innerJoin('user.classroom', 'classroom') .where('analytic_session.duration >= :durationThreshold', { durationThreshold }) .andWhere('user IS NOT NULL') .andWhere('user.type === :teacherType', { teacherType }) @@ -99,6 +105,8 @@ export const getMaxConnections = async () => { return subQuery .select('COUNT(*)', 'occurrences') .from('analytic_session', 'as') + .innerJoin('analytic_session.user', 'user') + .innerJoin('user.classroom', 'classroom') .where('analytic_session.duration >= :durationThreshold', { durationThreshold }) .andWhere('user IS NOT NULL') .andWhere('user.type === :teacherType', { teacherType }) @@ -118,6 +126,8 @@ export const getAverageConnections = async () => { return subQuery .select('COUNT(*)', 'occurrences') .from('analytic_session', 'as') + .innerJoin('analytic_session.user', 'user') + .innerJoin('user.classroom', 'classroom') .where('analytic_session.duration >= :durationThreshold', { durationThreshold }) .andWhere('user IS NOT NULL') .andWhere('user.type === :teacherType', { teacherType }) @@ -134,6 +144,8 @@ export const getMedianConnections = async () => { .createQueryBuilder('analytic_session') .select('COUNT(*)', 'occurrences') .from('analytic_session', 'as') + .innerJoin('analytic_session.user', 'user') + .innerJoin('user.classroom', 'classroom') .where('analytic_session.duration >= :durationThreshold', { durationThreshold }) .andWhere('user IS NOT NULL') .andWhere('user.type === :teacherType', { teacherType })