From d6e2a917b54e1de0e755a87181ca1d27c74b749a Mon Sep 17 00:00:00 2001
From: Carina Antunes <carina.oliveira.antunes@cern.ch>
Date: Tue, 14 May 2024 19:09:38 +0200
Subject: [PATCH] add more stats per dep

---
 src/models/cern-activedirectory.ts            |  5 ++
 src/models/statistics.ts                      |  3 +
 .../impl/statistics/get-statistics.ts         | 57 ++++++++++++++++++-
 3 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/src/models/cern-activedirectory.ts b/src/models/cern-activedirectory.ts
index 4edea6f3..b935e32d 100644
--- a/src/models/cern-activedirectory.ts
+++ b/src/models/cern-activedirectory.ts
@@ -148,6 +148,11 @@ export class CERNActiveDirectory {
     );
   }
 
+  static memoizedGetUserDepartment = memoize(CERNActiveDirectory.getUserDepartment, {
+    maxAge: Number(process.env.CACHE_TOKEN_TTL || 5) * 1000, // means we need default 5 seconds for changes to manual membership to be visible
+    preFetch: false, // Prefetch is useless if token is expired it will fail to verify
+  });
+
   static async getUserDepartment(mailTarget: string) {
     const filter = ldapEscape.filter`(&\
 (|(mail=${mailTarget})(proxyAddresses=smtp:${mailTarget}))\
diff --git a/src/models/statistics.ts b/src/models/statistics.ts
index 4f027d7e..ddf9fe0c 100644
--- a/src/models/statistics.ts
+++ b/src/models/statistics.ts
@@ -2,6 +2,7 @@ type LastStatistics = {
   channels_created: number;
   notifications_sent: number;
   users_active: number;
+  users_active_per_department: Record<string, number>;
 };
 
 export class Statistics {
@@ -36,6 +37,8 @@ export class Statistics {
   channels_per_department: Record<string, number>;
 
   last_10_notifications_reach: Record<string, Record<string, number>>;
+  last_week_reach_per_department: Record<string, number>;
+
   avg_users_reached_per_notification_weekly: number;
   avg_devices_reached_per_notification_weekly: number;
   total_end_notifications_weekly: number;
diff --git a/src/services/impl/statistics/get-statistics.ts b/src/services/impl/statistics/get-statistics.ts
index 4ea9b7e6..489a4bd3 100644
--- a/src/services/impl/statistics/get-statistics.ts
+++ b/src/services/impl/statistics/get-statistics.ts
@@ -81,6 +81,25 @@ export class GetStatistics implements Command {
       .where('"lastLogin" > NOW() - INTERVAL \'1 DAY\'')
       .getCount();
 
+    const usersWeekly = await transactionManager
+      .getRepository(User)
+      .createQueryBuilder('user')
+      .where('"lastLogin" > NOW() - INTERVAL \'1 DAY\'')
+      .select('user.email')
+      .getRawMany();
+
+    // channels per department
+    this.s.last_day.users_active_per_department = {};
+    for (const user of usersWeekly) {
+      let dept = await CERNActiveDirectory.memoizedGetUserDepartment(user.user_email);
+      if (!dept) {
+        dept = '-';
+      }
+      if (dept in this.s.last_day.users_active_per_department)
+        this.s.last_day.users_active_per_department[dept] = this.s.last_day.users_active_per_department[dept] + 1;
+      else this.s.last_day.users_active_per_department[dept] = 1;
+    }
+
     // Monthly numbers
     this.s.last_month.channels_created = await transactionManager
       .getRepository(Channel)
@@ -98,6 +117,25 @@ export class GetStatistics implements Command {
       .where('"lastLogin" > NOW() - INTERVAL \'1 month\'')
       .getCount();
 
+    const usersMonthly = await transactionManager
+      .getRepository(User)
+      .createQueryBuilder('user')
+      .where('"lastLogin" > NOW() - INTERVAL \'1 DAY\'')
+      .select('user.email')
+      .getRawMany();
+
+    // channels per department
+    this.s.last_month.users_active_per_department = {};
+    for (const user of usersMonthly) {
+      let dept = await CERNActiveDirectory.memoizedGetUserDepartment(user.user_email);
+      if (!dept) {
+        dept = '-';
+      }
+      if (dept in this.s.last_month.users_active_per_department)
+        this.s.last_month.users_active_per_department[dept] = this.s.last_month.users_active_per_department[dept] + 1;
+      else this.s.last_month.users_active_per_department[dept] = 1;
+    }
+
     await this.calculateDeviceStats(transactionManager);
     await this.calculateMuteStats(transactionManager);
     await this.calculatePreferenceStats(transactionManager);
@@ -118,8 +156,11 @@ export class GetStatistics implements Command {
     // channels per department
     this.s.channels_per_department = {};
     for (const owner of owners) {
-      let ownerDepartment = await CERNActiveDirectory.getUserDepartment(owner.owner_email);
-      if (!ownerDepartment) ownerDepartment = '-';
+      let ownerDepartment = await CERNActiveDirectory.memoizedGetUserDepartment(owner.owner_email);
+      if (!ownerDepartment) {
+        ownerDepartment = '-';
+        console.log(owner, ownerDepartment);
+      }
       if (ownerDepartment in this.s.channels_per_department)
         this.s.channels_per_department[ownerDepartment] = this.s.channels_per_department[ownerDepartment] + 1;
       else this.s.channels_per_department[ownerDepartment] = 1;
@@ -268,7 +309,7 @@ export class GetStatistics implements Command {
     this.s.users_active = arrayActiveUser.length;
     this.s.active_users_per_department = {};
     for (const user of arrayActiveUser) {
-      let userDepartment = await CERNActiveDirectory.getUserDepartment(user.user_email);
+      let userDepartment = await CERNActiveDirectory.memoizedGetUserDepartment(user.user_email);
       if (!userDepartment) userDepartment = '-';
       if (userDepartment in this.s.active_users_per_department)
         this.s.active_users_per_department[userDepartment] = this.s.active_users_per_department[userDepartment] + 1;
@@ -325,6 +366,7 @@ export class GetStatistics implements Command {
     this.s.avg_devices_reached_per_notification_weekly = 0;
     this.s.total_end_notifications_weekly = 0;
     this.s.total_end_notifications_weekly_across_devices = 0;
+    this.s.last_week_reach_per_department = {};
 
     for (const notification of arrayNotification) {
       try {
@@ -357,6 +399,15 @@ export class GetStatistics implements Command {
               const anon_id = '***-' + count; // anonymize notification id
               this.s.last_10_notifications_reach[anon_id]['total_device_reach'] += total_device_reach;
             }
+
+            // reach per department
+            let dept = await CERNActiveDirectory.memoizedGetUserDepartment(user);
+            if (!dept) {
+              dept = '-';
+            }
+            if (dept in this.s.last_week_reach_per_department)
+              this.s.last_week_reach_per_department[dept] = this.s.last_week_reach_per_department[dept] + 1;
+            else this.s.last_week_reach_per_department[dept] = 1;
           }
           count++;
         }
-- 
GitLab