From ac3074e4cb2f426311192f3bc8e555e0c30f7b5f Mon Sep 17 00:00:00 2001
From: MonaS8 <schumo62@gmail.com>
Date: Sun, 30 Mar 2025 16:47:40 +0200
Subject: [PATCH] integrate roles and modes in roomSession and roomSessionUser

---
 .../migrations/.snapshot-collab_space.json    | 158 ++--------
 .../migrations/Migration20250330142342.ts     |  37 +++
 .../migrations/Migration20250330143630.ts     |  13 +
 .../migrations/Migration20250330143957.ts     |  13 +
 src/activities/activities.module.ts           |   9 +-
 src/activities/activities.service.ts          | 289 ++----------------
 src/channel/browser.gateway.ts                |  11 +-
 src/channel/channel.gateway.ts                |  24 +-
 src/channel/notes.gateway.ts                  |   6 +-
 src/channel/whiteboard.gateway.ts             |   4 +-
 src/modes/mode.entity.ts                      |  21 --
 src/modes/mode.module.ts                      |  11 -
 src/modes/mode.service.ts                     |  28 --
 src/points/sessionPoints.entity.ts            |  11 +
 src/points/sessionPoints.module.ts            |   6 +-
 src/points/sessionPoints.service.ts           | 183 +++++++++++
 src/roles/role.entity.ts                      |  21 --
 src/roles/role.module.ts                      |  11 -
 src/roles/role.service.ts                     |  48 ---
 src/room/roomSession.controller.ts            |  27 +-
 src/room/roomSession.dto.ts                   |  12 +
 src/room/roomSession.entity.ts                |   3 +
 src/room/roomSession.module.ts                |   6 +-
 src/room/roomSession.service.ts               |  19 +-
 src/room/roomSessionUser.controller.ts        |  25 +-
 src/room/roomSessionUser.dto.ts               |   6 +
 src/room/roomSessionUser.entity.ts            |   4 +
 src/room/roomSessionUser.module.ts            |   4 +-
 src/room/roomSessionUser.service.ts           |  22 +-
 29 files changed, 452 insertions(+), 580 deletions(-)
 create mode 100644 database/migrations/Migration20250330142342.ts
 create mode 100644 database/migrations/Migration20250330143630.ts
 create mode 100644 database/migrations/Migration20250330143957.ts
 delete mode 100644 src/modes/mode.entity.ts
 delete mode 100644 src/modes/mode.module.ts
 delete mode 100644 src/modes/mode.service.ts
 create mode 100644 src/points/sessionPoints.service.ts
 delete mode 100644 src/roles/role.entity.ts
 delete mode 100644 src/roles/role.module.ts
 delete mode 100644 src/roles/role.service.ts

diff --git a/database/migrations/.snapshot-collab_space.json b/database/migrations/.snapshot-collab_space.json
index d87e4d5..440e28f 100644
--- a/database/migrations/.snapshot-collab_space.json
+++ b/database/migrations/.snapshot-collab_space.json
@@ -327,6 +327,15 @@
           "nullable": true,
           "length": 0,
           "mappedType": "datetime"
+        },
+        "mode_name": {
+          "name": "mode_name",
+          "type": "varchar(255)",
+          "unsigned": false,
+          "autoincrement": false,
+          "primary": false,
+          "nullable": true,
+          "mappedType": "string"
         }
       },
       "name": "roomSession",
@@ -403,6 +412,15 @@
           "primary": false,
           "nullable": false,
           "mappedType": "string"
+        },
+        "role_name": {
+          "name": "role_name",
+          "type": "text",
+          "unsigned": false,
+          "autoincrement": false,
+          "primary": false,
+          "nullable": true,
+          "mappedType": "text"
         }
       },
       "name": "roomSessionUser",
@@ -469,6 +487,7 @@
           "autoincrement": false,
           "primary": false,
           "nullable": false,
+          "default": "0",
           "mappedType": "integer"
         },
         "video_points": {
@@ -478,6 +497,7 @@
           "autoincrement": false,
           "primary": false,
           "nullable": false,
+          "default": "0",
           "mappedType": "integer"
         },
         "browser_points": {
@@ -487,6 +507,7 @@
           "autoincrement": false,
           "primary": false,
           "nullable": false,
+          "default": "0",
           "mappedType": "integer"
         },
         "whiteboard_points": {
@@ -496,6 +517,7 @@
           "autoincrement": false,
           "primary": false,
           "nullable": false,
+          "default": "0",
           "mappedType": "integer"
         },
         "note_points": {
@@ -505,6 +527,7 @@
           "autoincrement": false,
           "primary": false,
           "nullable": false,
+          "default": "0",
           "mappedType": "integer"
         }
       },
@@ -519,72 +542,14 @@
           "primary": false,
           "unique": false
         },
-        {
-          "keyName": "PRIMARY",
-          "columnNames": [
-            "id"
-          ],
-          "composite": false,
-          "primary": true,
-          "unique": true
-        }
-      ],
-      "checks": [],
-      "foreignKeys": {
-        "sessionPoints_room_session_user_id_foreign": {
-          "constraintName": "sessionPoints_room_session_user_id_foreign",
-          "columnNames": [
-            "room_session_user_id"
-          ],
-          "localTableName": "sessionPoints",
-          "referencedColumnNames": [
-            "id"
-          ],
-          "referencedTableName": "roomSessionUser",
-          "updateRule": "cascade"
-        }
-      }
-    },
-    {
-      "columns": {
-        "id": {
-          "name": "id",
-          "type": "int",
-          "unsigned": true,
-          "autoincrement": true,
-          "primary": true,
-          "nullable": false,
-          "mappedType": "integer"
-        },
-        "role_name": {
-          "name": "role_name",
-          "type": "varchar(255)",
-          "unsigned": false,
-          "autoincrement": false,
-          "primary": false,
-          "nullable": false,
-          "mappedType": "string"
-        },
-        "room_session_user_id": {
-          "name": "room_session_user_id",
-          "type": "int",
-          "unsigned": true,
-          "autoincrement": false,
-          "primary": false,
-          "nullable": false,
-          "mappedType": "integer"
-        }
-      },
-      "name": "role",
-      "indexes": [
         {
           "columnNames": [
             "room_session_user_id"
           ],
           "composite": false,
-          "keyName": "role_room_session_user_id_index",
+          "keyName": "sessionPoints_room_session_user_id_unique",
           "primary": false,
-          "unique": false
+          "unique": true
         },
         {
           "keyName": "PRIMARY",
@@ -598,12 +563,12 @@
       ],
       "checks": [],
       "foreignKeys": {
-        "role_room_session_user_id_foreign": {
-          "constraintName": "role_room_session_user_id_foreign",
+        "sessionPoints_room_session_user_id_foreign": {
+          "constraintName": "sessionPoints_room_session_user_id_foreign",
           "columnNames": [
             "room_session_user_id"
           ],
-          "localTableName": "role",
+          "localTableName": "sessionPoints",
           "referencedColumnNames": [
             "id"
           ],
@@ -612,73 +577,6 @@
         }
       }
     },
-    {
-      "columns": {
-        "id": {
-          "name": "id",
-          "type": "int",
-          "unsigned": true,
-          "autoincrement": true,
-          "primary": true,
-          "nullable": false,
-          "mappedType": "integer"
-        },
-        "mode_name": {
-          "name": "mode_name",
-          "type": "varchar(255)",
-          "unsigned": false,
-          "autoincrement": false,
-          "primary": false,
-          "nullable": false,
-          "mappedType": "string"
-        },
-        "room_session_id": {
-          "name": "room_session_id",
-          "type": "int",
-          "unsigned": true,
-          "autoincrement": false,
-          "primary": false,
-          "nullable": false,
-          "mappedType": "integer"
-        }
-      },
-      "name": "mode",
-      "indexes": [
-        {
-          "columnNames": [
-            "room_session_id"
-          ],
-          "composite": false,
-          "keyName": "mode_room_session_id_unique",
-          "primary": false,
-          "unique": true
-        },
-        {
-          "keyName": "PRIMARY",
-          "columnNames": [
-            "id"
-          ],
-          "composite": false,
-          "primary": true,
-          "unique": true
-        }
-      ],
-      "checks": [],
-      "foreignKeys": {
-        "mode_room_session_id_foreign": {
-          "constraintName": "mode_room_session_id_foreign",
-          "columnNames": [
-            "room_session_id"
-          ],
-          "localTableName": "mode",
-          "referencedColumnNames": [
-            "id"
-          ],
-          "referencedTableName": "roomSession",
-          "updateRule": "cascade"
-        }
-      }
-    },
     {
       "columns": {
         "id": {
diff --git a/database/migrations/Migration20250330142342.ts b/database/migrations/Migration20250330142342.ts
new file mode 100644
index 0000000..c7d5c74
--- /dev/null
+++ b/database/migrations/Migration20250330142342.ts
@@ -0,0 +1,37 @@
+import { Migration } from '@mikro-orm/migrations';
+
+export class Migration20250330142342 extends Migration {
+
+  async up(): Promise<void> {
+    this.addSql('drop table if exists `role`;');
+
+    this.addSql('drop table if exists `mode`;');
+
+    this.addSql('alter table `roomSession` add `mode_name` varchar(255) null;');
+
+    this.addSql('alter table `roomSessionUser` add `role_name` varchar(255) not null;');
+
+    this.addSql('alter table `sessionPoints` modify `audio_points` int not null default 0, modify `video_points` int not null default 0, modify `browser_points` int not null default 0, modify `whiteboard_points` int not null default 0, modify `note_points` int not null default 0;');
+    this.addSql('alter table `sessionPoints` add unique `sessionPoints_room_session_user_id_unique`(`room_session_user_id`);');
+  }
+
+  async down(): Promise<void> {
+    this.addSql('create table `role` (`id` int unsigned not null auto_increment primary key, `role_name` varchar(255) not null, `room_session_user_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;');
+    this.addSql('alter table `role` add index `role_room_session_user_id_index`(`room_session_user_id`);');
+
+    this.addSql('create table `mode` (`id` int unsigned not null auto_increment primary key, `mode_name` varchar(255) not null, `room_session_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;');
+    this.addSql('alter table `mode` add unique `mode_room_session_id_unique`(`room_session_id`);');
+
+    this.addSql('alter table `role` add constraint `role_room_session_user_id_foreign` foreign key (`room_session_user_id`) references `roomSessionUser` (`id`) on update cascade;');
+
+    this.addSql('alter table `mode` add constraint `mode_room_session_id_foreign` foreign key (`room_session_id`) references `roomSession` (`id`) on update cascade;');
+
+    this.addSql('alter table `roomSession` drop `mode_name`;');
+
+    this.addSql('alter table `roomSessionUser` drop `role_name`;');
+
+    this.addSql('alter table `sessionPoints` modify `audio_points` int not null, modify `video_points` int not null, modify `browser_points` int not null, modify `whiteboard_points` int not null, modify `note_points` int not null;');
+    this.addSql('alter table `sessionPoints` drop index `sessionPoints_room_session_user_id_unique`;');
+  }
+
+}
diff --git a/database/migrations/Migration20250330143630.ts b/database/migrations/Migration20250330143630.ts
new file mode 100644
index 0000000..dde8f6f
--- /dev/null
+++ b/database/migrations/Migration20250330143630.ts
@@ -0,0 +1,13 @@
+import { Migration } from '@mikro-orm/migrations';
+
+export class Migration20250330143630 extends Migration {
+
+  async up(): Promise<void> {
+    this.addSql('alter table `roomSessionUser` modify `role_name` varchar(255) null;');
+  }
+
+  async down(): Promise<void> {
+    this.addSql('alter table `roomSessionUser` modify `role_name` varchar(255) not null;');
+  }
+
+}
diff --git a/database/migrations/Migration20250330143957.ts b/database/migrations/Migration20250330143957.ts
new file mode 100644
index 0000000..6ee9a2a
--- /dev/null
+++ b/database/migrations/Migration20250330143957.ts
@@ -0,0 +1,13 @@
+import { Migration } from '@mikro-orm/migrations';
+
+export class Migration20250330143957 extends Migration {
+
+  async up(): Promise<void> {
+    this.addSql('alter table `roomSessionUser` modify `role_name` text;');
+  }
+
+  async down(): Promise<void> {
+    this.addSql('alter table `roomSessionUser` modify `role_name` varchar(255);');
+  }
+
+}
diff --git a/src/activities/activities.module.ts b/src/activities/activities.module.ts
index 617c287..c5a2c7a 100644
--- a/src/activities/activities.module.ts
+++ b/src/activities/activities.module.ts
@@ -1,14 +1,19 @@
-import { Global, Module } from '@nestjs/common';
+import { Global, Module, forwardRef } from '@nestjs/common';
 import { MikroOrmModule } from '@mikro-orm/nestjs';
 import { ActivitiesService } from './activities.service';
 import { Activity } from './activities.entity';
+import { SessionPointsService } from 'src/points/sessionPoints.service';
+import { SessionPointsModule } from 'src/points/sessionPoints.module';
+import { SessionPoints } from 'src/points/sessionPoints.entity';
+
 
 /**
  * A global module that encapsulates features related to tracking.
  */
 @Global()
 @Module({
-  imports: [MikroOrmModule.forFeature([Activity])],
+  imports: [MikroOrmModule.forFeature([Activity, SessionPoints]), 
+  forwardRef(() => SessionPointsModule)],
   providers: [ActivitiesService],
   exports: [ActivitiesService],
 })
diff --git a/src/activities/activities.service.ts b/src/activities/activities.service.ts
index f1a0db0..93f02dc 100644
--- a/src/activities/activities.service.ts
+++ b/src/activities/activities.service.ts
@@ -2,14 +2,26 @@ import { Injectable } from '@nestjs/common';
 import { EntityManager } from '@mikro-orm/core';
 import { InjectRepository } from '@mikro-orm/nestjs';
 import { EntityRepository } from '@mikro-orm/mysql';
-import { Room } from '../room/room.entity';
 import { Activity } from './activities.entity';
-import { Note } from '../note/note.entity';
-import { tr } from '@faker-js/faker';
-import { SessionPoints } from '../points/sessionPoints.entity';
 import { RoomSession } from '../room/roomSession.entity';
 import { RoomSessionUser } from '../room/roomSessionUser.entity';
-import { session } from 'passport';
+import { SessionPointsService } from '../points/sessionPoints.service';
+
+export enum ActivityType {
+  NOTE_CREATE = 'note.create',
+  NOTE_UPDATE = 'note.update',
+  WHITEBOARD = 'whiteboard',
+  VIDEO_ON = 'video.on',
+  VIDEO_OFF = 'video.off',
+  AUDIO_ON = 'audio.on',
+  AUDIO_OFF = 'audio.off',
+  AUDIO_TALKING = 'audio.talking',
+  AUDIO_NOT_TALKING = 'audio.nottalking',
+  BROWSER_OPEN = 'browser.open',
+  BROWSER_CLOSE = 'browser.close',
+  BROWSER_MOUSE = 'browser.mouse',
+  BROWSER_KEY = 'browser.key',
+}
 
 /**
  * A service responsible for managing to track the activities.
@@ -28,270 +40,17 @@ export class ActivitiesService {
     private readonly em: EntityManager,
     @InjectRepository(Activity)
     private readonly repository: EntityRepository<Activity>,
+    private readonly sessionPointsService: SessionPointsService,
   ) { }
 
-  /**
-   * Logs the creation of a note.
-   */
-  public async addNoteCreateActivity(userId: string, roomSession: RoomSession, note: Note) {
-    if (await this.em.findOne(RoomSessionUser, { userId: userId, roomSession: roomSession })) {
-      const trackingNote = new Activity(userId, roomSession, "note.create");
-      trackingNote.note = note;
-      await this.em.persistAndFlush(trackingNote);
-      this.calculatePoints(roomSession);
-      return trackingNote;
-    }
-  }
-
-  /**
-   * Logs updates made to a note, capturing the characters added.
-   */
-  public async addNoteUpdateActivity(userId: string, roomSession: RoomSession, note: Note, charactersAdded: number) {
-    if (await this.em.findOne(RoomSessionUser, { userId: userId, roomSession: roomSession })) {
-      const trackingNote = new Activity(userId, roomSession, "note.update");
-      trackingNote.note = note;
-      trackingNote.numericValue = charactersAdded;
-      await this.em.persistAndFlush(trackingNote); 
-      this.calculatePoints(roomSession);
-      return trackingNote;
-    }
-  }
 
-  /**
-   * Logs whiteboard usage in a room.
-   */
-  public async addWhiteboardActivity(userId: string, roomSession: RoomSession) {
+  public async addNewActivity(userId: string, roomSession: RoomSession, activity: string, numericValue?: number) {
     if (await this.em.findOne(RoomSessionUser, { userId: userId, roomSession: roomSession })) {
-      const trackingWhiteboard = new Activity(userId, roomSession, "whiteboard");
-      await this.em.persistAndFlush(trackingWhiteboard);
-      this.calculatePoints(roomSession);
-      return trackingWhiteboard;
+      const trackingActivity = new Activity(userId, roomSession, activity);
+      await this.em.persistAndFlush(trackingActivity);
+      this.sessionPointsService.calculatePoints(roomSession);
+      return trackingActivity;
     }
   }
-
-  /**
-   * Logs video on/off activities.
-   */
-  public async addVideoActivity(userId: string, roomSession: RoomSession, isActive: boolean) {
-    if (await this.em.findOne(RoomSessionUser, { userId: userId, roomSession: roomSession })) {
-      const activity = isActive ? "video.on" : "video.off";
-      const trackingVideo = new Activity(userId, roomSession, activity);
-      await this.em.persistAndFlush(trackingVideo);
-      this.calculatePoints(roomSession);
-      return trackingVideo;
-    }
-  }
-
-  /**
-   * Logs audio on/off activities.
-   */
-  public async addAudioActivity(userId: string, roomSession: RoomSession, isActive: boolean) {
-    if (await this.em.findOne(RoomSessionUser, { userId: userId, roomSession: roomSession })) {
-      const activity = isActive ? "audio.on" : "audio.off";
-      const trackingAudio = new Activity(userId, roomSession, activity);
-      await this.em.persistAndFlush(trackingAudio);
-      this.calculatePoints(roomSession);
-      return trackingAudio;
-    }
-  }
-
-  /**
-   * Logs whether a user is talking or not.
-   */
-  public async addIsTalkingActivity(userId: string, roomSession: RoomSession, isTalking: boolean) {
-    if (await this.em.findOne(RoomSessionUser, { userId: userId, roomSession: roomSession })) {
-      const activity = isTalking ? "audio.talking" : "audio.nottalking";
-      const trackingAudioVolume = new Activity(userId, roomSession, activity);
-      await this.em.persistAndFlush(trackingAudioVolume);
-      this.calculatePoints(roomSession);
-      return trackingAudioVolume;
-    }
-  }
-
-  /**
-   * Logs the moment a browser view is opened.
-   */
-  public async addBrowserOpenActivity(userId: string, roomSession: RoomSession) {
-    if (await this.em.findOne(RoomSessionUser, { userId: userId, roomSession: roomSession })) {
-      const trackingBrowser = new Activity(userId, roomSession, "browser.open");
-      await this.em.persistAndFlush(trackingBrowser);
-      this.calculatePoints(roomSession);
-      return trackingBrowser;
-    }
-  }
-
-  /**
-   * Logs a browser close event.
-   */
-  public async addBrowserCloseActivity(userId: string, roomSession: RoomSession) {
-    if (await this.em.findOne(RoomSessionUser, { userId: userId, roomSession: roomSession })) {
-      const trackingBrowser = new Activity(userId, roomSession, "browser.close");
-      await this.em.persistAndFlush(trackingBrowser);
-      this.calculatePoints(roomSession);
-      return trackingBrowser;
-    }
-  }
-
-  /**
-   * Logs a browser mouse action event.
-   */
-  public async addBrowserMouseActivity(userId: string, roomSession: RoomSession) {
-    if (await this.em.findOne(RoomSessionUser, { userId: userId, roomSession: roomSession })) {
-      const trackingBrowser = new Activity(userId, roomSession, "browser.mouse");
-      await this.em.persistAndFlush(trackingBrowser);
-      this.calculatePoints(roomSession);
-      return trackingBrowser;
-    }
-  }
-
-  /**
-   * Logs a browser keyboard action event.
-   */
-  public async addBrowserKeyActivity(userId: string, roomSession: RoomSession) {
-    if (await this.em.findOne(RoomSessionUser, { userId: userId, roomSession: roomSession })) {
-      const trackingBrowser = new Activity(userId, roomSession, "browser.key");
-      await this.em.persistAndFlush(trackingBrowser);
-      this.calculatePoints(roomSession);
-      return trackingBrowser;
-    }
-  }
-  
-/**
-  /**
-   * Calculates and returns points for user activities in a time range.
-   */
-  public async calculatePoints(
-    roomSession: RoomSession,
-  ) {
-    const activities = await roomSession.activities.loadItems();
-    const users = await roomSession.users.loadItems();
-    
-    const activitiesByUsers = activities.reduce((actsByUsers, activity) => {
-      const user = users.find((user) => user.userId === activity.userId);
-      let acts = actsByUsers.get(user) ?? [];
-      acts = [...acts, activity];
-  
-      actsByUsers.set(user, acts);
-  
-      return actsByUsers;
-    }, new Map<RoomSessionUser, Activity[]>());
-
-    const pointsArray: SessionPoints[] = [];
-  for (const [user, userActivities] of activitiesByUsers) {
-    let points = await this.em.findOne(SessionPoints, { roomSessionUser: user });
-    if (!points) {
-      points = new SessionPoints(user);
-    }
-    points.audioPoints = await this.calculateAudioPoints(userActivities),
-    points.videoPoints = await this.calculateVideoPoints(userActivities),
-    points.browserPoints = await this.calculateBrowserPoints(userActivities),
-    points.whiteboardPoints = await this.calculateWhiteboardPoints(userActivities),
-    points.notePoints = await this.calculateNotePoints(userActivities),
-
-    await this.em.persistAndFlush(points);
-    pointsArray.push(points);
-  }
-
-  return pointsArray;
-
-  }
-
-  /**
-   * Calculates how many audio points (1 point per 5 seconds of talking) a user gets.
-   */
-  private async calculateAudioPoints(activities: Activity[]) {
-    const audioActivities = activities
-      .filter(a => a.activity.startsWith('audio.'))
-      .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
-
-    let totalTalkingTime = 0;
-    let talkingStart: Date | null = null;
-
-    for (const act of audioActivities) {
-      if (act.activity === 'audio.talking' && !talkingStart) {
-        talkingStart = act.timestamp;
-      } else if ((act.activity === 'audio.nottalking' || act.activity === 'audio.off') && talkingStart) {
-        totalTalkingTime += act.timestamp.getTime() - talkingStart.getTime();
-        talkingStart = null;
-      }
-    }
-
-    const audioPoints = Math.floor(totalTalkingTime / 5000);
-    return audioPoints;
-  }
-
-  /**
-   * Calculates how many video points (1 point per 5 minutes of video on) a user gets.
-   */
-  private async calculateVideoPoints(activities: Activity[]) {
-    const videoActivities = activities
-      .filter(a => a.activity.startsWith('video.'))
-      .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
-
-    let totalOnTime = 0;
-    let videoStart: Date | null = null;
-
-    for (const act of videoActivities) {
-      if (act.activity === 'video.on' && !videoStart) {
-        videoStart = act.timestamp;
-      } else if (act.activity === 'video.off' && videoStart) {
-        totalOnTime += act.timestamp.getTime() - videoStart.getTime();
-        videoStart = null;
-      }
-    }
-
-    const videoPoints = Math.floor(totalOnTime / 300000);
-    return videoPoints;
-  }
-
-  /**
-   * Calculates how many browser points (1 point per 50 key events, 1 point per 10 mouse events).
-   */
-  private async calculateBrowserPoints(activities: Activity[]) {
-    const browserActivities = activities
-      .filter(a => a.activity.startsWith('browser.'))
-      .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
-
-    const keyCount = browserActivities.filter(a => a.activity === 'browser.key').length;
-    const mouseCount = browserActivities.filter(a => a.activity === 'browser.mouse').length;
-
-    const keyPoints = Math.floor(keyCount / 50);
-    const mousePoints = Math.floor(mouseCount / 10);
-
-    return keyPoints + mousePoints;
-  }
-
-  /**
-   * Calculates how many whiteboard points (1 point per 5 whiteboard events) a user gets.
-   */
-  private async calculateWhiteboardPoints(activities: Activity[]) {
-    const whiteboardActivities = activities
-      .filter(a => a.activity === 'whiteboard')
-      .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
-
-    const whiteboardPoints = Math.floor(whiteboardActivities.length / 5);
-
-    return whiteboardPoints;
-  }
-  /**
-   * Calculates how many note points (1 point for creating a note, 1 point per 50 characters added, and -1 point per 50 characters removed from the note content).
-   */
-  private async calculateNotePoints(activities: Activity[]) {
-    const noteActivities = activities
-      .filter(a => a.activity.startsWith('note.'))
-      .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
-
-    let notePoints = 0;
-    for (const act of noteActivities) {
-      if (act.activity === 'note.create') {
-        notePoints++;
-      } else if (act.activity === 'note.update' && act.numericValue) {
-        notePoints += Math.floor(act.numericValue / 50);
-      } else if (act.activity === 'note.update' && act.numericValue < 0) {
-        notePoints += Math.ceil(act.numericValue / 50);
-      }
-    }
-    return notePoints;
-  }
-
 }
+  
diff --git a/src/channel/browser.gateway.ts b/src/channel/browser.gateway.ts
index c3d9db6..a2a088e 100644
--- a/src/channel/browser.gateway.ts
+++ b/src/channel/browser.gateway.ts
@@ -11,7 +11,7 @@ import { ChannelService } from './channel.service';
 import * as process from 'process';
 import { BrowserService } from '../browser/browser.service';
 import * as dotenv from 'dotenv';
-import { ActivitiesService } from '../activities/activities.service';
+import { ActivitiesService, ActivityType } from '../activities/activities.service';
 
 dotenv.config();
 
@@ -64,7 +64,7 @@ export class BrowserGateway {
     );
     this.server.to(channel.id).emit('open-website', peerId);
 
-    await this.activitiesService.addBrowserOpenActivity(client.id, channel.session);
+    await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.BROWSER_OPEN);
     
     return true;
   }
@@ -83,7 +83,7 @@ export class BrowserGateway {
     await this.browserService.closeBrowserContext(channel.id);
     this.server.to(channel.id).emit('close-browser');
 
-    await this.activitiesService.addBrowserCloseActivity(client.id, channel.session);
+    await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.BROWSER_CLOSE);
 
     return true;
   }
@@ -121,7 +121,7 @@ export class BrowserGateway {
 
     await this.browserService.mouseDown(channel.id);
 
-    await this.activitiesService.addBrowserMouseActivity(client.id, channel.session);
+    await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.BROWSER_MOUSE);
 
     return true;
   }
@@ -158,7 +158,8 @@ export class BrowserGateway {
     const channel = await this.channels.fromClientOrFail(client);
 
     await this.browserService.keyDown(channel.id, payload.key);
-    await this.activitiesService.addBrowserKeyActivity(client.id, channel.session);
+
+    await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.BROWSER_KEY);
 
     return true;
   }
diff --git a/src/channel/channel.gateway.ts b/src/channel/channel.gateway.ts
index 486fe19..d5dd787 100644
--- a/src/channel/channel.gateway.ts
+++ b/src/channel/channel.gateway.ts
@@ -14,7 +14,7 @@ import * as process from 'process';
 import * as dotenv from 'dotenv';
 import { BrowserService } from '../browser/browser.service';
 import { UnauthorizedException } from '@nestjs/common';
-import { ActivitiesService } from '../activities/activities.service';
+import { ActivitiesService, ActivityType } from '../activities/activities.service';
 import { RoomSession } from '../room/roomSession.entity';
 import { RoomSessionUserService } from '../room/roomSessionUser.service';
 import { RoomSessionUser } from '../room/roomSessionUser.entity';
@@ -270,9 +270,17 @@ export class ChannelGateway implements OnGatewayConnection {
       video: payload.video,
       audio: payload.audio,
     });
-
-    await this.activitiesService.addVideoActivity(client.id, channel.session, payload.video);
-    await this.activitiesService.addAudioActivity(client.id, channel.session, payload.audio);
+    if (payload.video) {
+      await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.VIDEO_ON);
+    } else {
+      await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.VIDEO_OFF);
+    }
+    
+    if (payload.audio) {
+      await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.AUDIO_ON);
+    } else {
+      await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.AUDIO_OFF);
+    }
 
     return true;
   }
@@ -385,7 +393,9 @@ export class ChannelGateway implements OnGatewayConnection {
     @MessageBody() payload: { volume: number }
   ) {
     const channel = await this.channels.fromClientOrFail(client);
-    await this.activitiesService.addIsTalkingActivity(client.id, channel.session, true);
+
+    await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.AUDIO_TALKING);
+    
     return true;
   }
 
@@ -396,7 +406,9 @@ export class ChannelGateway implements OnGatewayConnection {
     @MessageBody() payload: { volume: number }
   ) {
     const channel = await this.channels.fromClientOrFail(client);
-    await this.activitiesService.addIsTalkingActivity(client.id, channel.session, false);
+
+    await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.AUDIO_NOT_TALKING);
+
     return true;
   }
 
diff --git a/src/channel/notes.gateway.ts b/src/channel/notes.gateway.ts
index b60a24a..9363b68 100644
--- a/src/channel/notes.gateway.ts
+++ b/src/channel/notes.gateway.ts
@@ -10,7 +10,7 @@ import { Server, Socket } from 'socket.io';
 import { ChannelService } from './channel.service';
 import * as dotenv from 'dotenv';
 import { NoteService } from '../note/note.service';
-import { ActivitiesService } from '../activities/activities.service';
+import { ActivitiesService, ActivityType } from '../activities/activities.service';
 
 dotenv.config();
 
@@ -58,7 +58,7 @@ export class NotesGateway {
 
     client.broadcast.to(channel.id).emit('note-added', note);
 
-    await this.activitiesService.addNoteCreateActivity(client.id, channel.session, note);
+    await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.NOTE_CREATE);
 
     return note;
   }
@@ -83,7 +83,7 @@ export class NotesGateway {
       content: payload.content,
     });
 
-    await this.activitiesService.addNoteUpdateActivity(client.id, channel.session, note, charactersAdded);
+    await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.NOTE_UPDATE, charactersAdded);
 
     return true;
   }
diff --git a/src/channel/whiteboard.gateway.ts b/src/channel/whiteboard.gateway.ts
index 772cdd4..a380699 100644
--- a/src/channel/whiteboard.gateway.ts
+++ b/src/channel/whiteboard.gateway.ts
@@ -8,7 +8,7 @@ import {
 import { Server, Socket } from 'socket.io';
 import * as dotenv from 'dotenv';
 import { ChannelService } from './channel.service';
-import { ActivitiesService } from '../activities/activities.service';
+import { ActivitiesService, ActivityType } from '../activities/activities.service';
 import { MikroORM, UseRequestContext } from '@mikro-orm/core';
 
 dotenv.config();
@@ -56,6 +56,6 @@ export class WhiteboardGateway {
     // Broadcast the whiteboard change to all clients in the channel
     client.broadcast.to(channel.id).emit('whiteboard-change', payload);
 
-    await this.activitiesService.addWhiteboardActivity(client.id, channel.session);
+    await this.activitiesService.addNewActivity(client.id, channel.session, ActivityType.WHITEBOARD);
   }
 }
diff --git a/src/modes/mode.entity.ts b/src/modes/mode.entity.ts
deleted file mode 100644
index a577dd3..0000000
--- a/src/modes/mode.entity.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Entity, OneToOne, PrimaryKey, Property } from '@mikro-orm/core';
-import { RoomSession } from '../room/roomSession.entity';
-
-
-@Entity({ tableName: 'mode' })
-export class Mode {
-  @PrimaryKey()
-  id!: number;
-
-  @Property()
-  modeName!: string;
-
-  @OneToOne()
-  roomSession!: RoomSession;
-
-  constructor(modeName: string, roomSession: RoomSession) {
-    this.roomSession = roomSession;
-    this.modeName = modeName;
-
-  }
-}
diff --git a/src/modes/mode.module.ts b/src/modes/mode.module.ts
deleted file mode 100644
index a796fbb..0000000
--- a/src/modes/mode.module.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Module } from '@nestjs/common';
-import { MikroOrmModule } from '@mikro-orm/nestjs';
-import { Mode } from './mode.entity';
-import { ModeService } from './mode.service';
-
-@Module({
-  imports: [MikroOrmModule.forFeature([Mode])],
-  providers: [ModeService],
-  exports: [ModeService],
-})
-export class ModeModule {}
diff --git a/src/modes/mode.service.ts b/src/modes/mode.service.ts
deleted file mode 100644
index f65836f..0000000
--- a/src/modes/mode.service.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { Injectable } from '@nestjs/common';
-import { InjectRepository } from '@mikro-orm/nestjs';
-import { EntityRepository } from '@mikro-orm/mysql';
-import { Mode } from './mode.entity';
-import { EntityManager } from '@mikro-orm/mysql';
-import { RoomSession } from '../room/roomSession.entity';
-
-export enum ModeType {
-    PAIR_PROGRAMMING = 'pairProgramming',
-    ROLE_BASED_PROGRAMMING = 'roleBasedProgramming',
-    DEFAULT = 'default',
-}
-
-@Injectable()
-export class ModeService {
-    constructor(
-            private readonly em: EntityManager,
-            @InjectRepository(Mode) 
-            private readonly modeRepository: EntityRepository<Mode>) {}
-    
-    async createMode(roomSession: RoomSession, modeName: ModeType): Promise<Mode> {
-        const mode = new Mode(modeName, roomSession);
-        await this.em.persistAndFlush(mode);
-        return mode;
-    }
-        
-}
-
diff --git a/src/points/sessionPoints.entity.ts b/src/points/sessionPoints.entity.ts
index 6a3f334..a1c7762 100644
--- a/src/points/sessionPoints.entity.ts
+++ b/src/points/sessionPoints.entity.ts
@@ -32,6 +32,17 @@ export class SessionPoints {
     @Property()
     notePoints: number;
 
+    @Property({ persist: false })
+    get allPoints(): { [key: string]: number } {
+        return {
+            audioPoints: this.audioPoints,
+            videoPoints: this.videoPoints,
+            browserPoints: this.browserPoints,
+            whiteboardPoints: this.whiteboardPoints,
+            notePoints: this.notePoints,
+        };
+    }
+
     constructor(roomSessionUser: RoomSessionUser) {
         this.roomSessionUser = roomSessionUser;
         this.audioPoints = 0;
diff --git a/src/points/sessionPoints.module.ts b/src/points/sessionPoints.module.ts
index c7d9c3b..6859f2c 100644
--- a/src/points/sessionPoints.module.ts
+++ b/src/points/sessionPoints.module.ts
@@ -3,8 +3,12 @@ import { MikroOrmModule } from '@mikro-orm/nestjs';
 import { SessionPoints } from './sessionPoints.entity';
 import { RoomSessionUser } from '../room/roomSessionUser.entity';
 import { RoomSessionUserModule } from '../room/roomSessionUser.module';
+import { SessionPointsService } from './sessionPoints.service';
 
 @Module({
-    imports: [MikroOrmModule.forFeature([SessionPoints, RoomSessionUser]), forwardRef(() => RoomSessionUserModule)],
+    imports: [MikroOrmModule.forFeature([SessionPoints, RoomSessionUser]), 
+    forwardRef(() => RoomSessionUserModule)],
+    providers: [SessionPointsService],
+    exports: [SessionPointsService],
 })
 export class SessionPointsModule {}
\ No newline at end of file
diff --git a/src/points/sessionPoints.service.ts b/src/points/sessionPoints.service.ts
new file mode 100644
index 0000000..1d4a7ac
--- /dev/null
+++ b/src/points/sessionPoints.service.ts
@@ -0,0 +1,183 @@
+import { Injectable } from '@nestjs/common';
+import { EntityManager } from '@mikro-orm/core';
+import { InjectRepository } from '@mikro-orm/nestjs';
+import { EntityRepository } from '@mikro-orm/mysql';
+import { Activity } from '../activities/activities.entity';
+import { SessionPoints } from '../points/sessionPoints.entity';
+import { RoomSession } from '../room/roomSession.entity';
+import { RoomSessionUser } from '../room/roomSessionUser.entity';
+import { ActivitiesService } from '../activities/activities.service';
+
+export enum ActivityType {
+  NOTE_CREATE = 'note.create',
+  NOTE_UPDATE = 'note.update',
+  WHITEBOARD = 'whiteboard',
+  VIDEO_ON = 'video.on',
+  VIDEO_OFF = 'video.off',
+  AUDIO_ON = 'audio.on',
+  AUDIO_OFF = 'audio.off',
+  AUDIO_TALKING = 'audio.talking',
+  AUDIO_NOT_TALKING = 'audio.nottalking',
+  BROWSER_OPEN = 'browser.open',
+  BROWSER_CLOSE = 'browser.close',
+  BROWSER_MOUSE = 'browser.mouse',
+  BROWSER_KEY = 'browser.key',
+}
+
+/**
+ * A service responsible for managing to track the activities.
+ */
+@Injectable()
+export class SessionPointsService {
+  /**
+    * Initializes the ActivitiesService.
+    * @param em - The EntityManager instance provided by MikroORM.
+    * @param repository - The repository for the Activity entity.
+    */
+  /**
+   * Initializes the service with a manager and repository.
+   */
+  constructor(
+    private readonly em: EntityManager,
+  ) { }
+
+
+/**
+  /**
+   * Calculates and returns points for user activities in a time range.
+   */
+  public async calculatePoints(
+    roomSession: RoomSession,
+  ) {
+    const activities = await roomSession.activities.loadItems();
+    const users = await roomSession.users.loadItems();
+    
+    const activitiesByUsers = activities.reduce((actsByUsers, activity) => {
+      const user = users.find((user) => user.userId === activity.userId);
+      let acts = actsByUsers.get(user) ?? [];
+      acts = [...acts, activity];
+  
+      actsByUsers.set(user, acts);
+  
+      return actsByUsers;
+    }, new Map<RoomSessionUser, Activity[]>());
+
+    const pointsArray: SessionPoints[] = [];
+  for (const [user, userActivities] of activitiesByUsers) {
+    let points = await this.em.findOne(SessionPoints, { roomSessionUser: user });
+    if (!points) {
+      points = new SessionPoints(user);
+    }
+    points.audioPoints = await this.calculateAudioPoints(userActivities),
+    points.videoPoints = await this.calculateVideoPoints(userActivities),
+    points.browserPoints = await this.calculateBrowserPoints(userActivities),
+    points.whiteboardPoints = await this.calculateWhiteboardPoints(userActivities),
+    points.notePoints = await this.calculateNotePoints(userActivities),
+
+    await this.em.persistAndFlush(points);
+    pointsArray.push(points);
+  }
+
+  return pointsArray;
+
+  }
+
+  /**
+   * Calculates how many audio points (1 point per 5 seconds of talking) a user gets.
+   */
+  private async calculateAudioPoints(activities: Activity[]) {
+    const audioActivities = activities
+      .filter(a => a.activity.startsWith('audio.'))
+      .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
+
+    let totalTalkingTime = 0;
+    let talkingStart: Date | null = null;
+
+    for (const act of audioActivities) {
+      if (act.activity === 'audio.talking' && !talkingStart) {
+        talkingStart = act.timestamp;
+      } else if ((act.activity === 'audio.nottalking' || act.activity === 'audio.off') && talkingStart) {
+        totalTalkingTime += act.timestamp.getTime() - talkingStart.getTime();
+        talkingStart = null;
+      }
+    }
+
+    const audioPoints = Math.floor(totalTalkingTime / 5000);
+    return audioPoints;
+  }
+
+  /**
+   * Calculates how many video points (1 point per 5 minutes of video on) a user gets.
+   */
+  private async calculateVideoPoints(activities: Activity[]) {
+    const videoActivities = activities
+      .filter(a => a.activity.startsWith('video.'))
+      .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
+
+    let totalOnTime = 0;
+    let videoStart: Date | null = null;
+
+    for (const act of videoActivities) {
+      if (act.activity === 'video.on' && !videoStart) {
+        videoStart = act.timestamp;
+      } else if (act.activity === 'video.off' && videoStart) {
+        totalOnTime += act.timestamp.getTime() - videoStart.getTime();
+        videoStart = null;
+      }
+    }
+
+    const videoPoints = Math.floor(totalOnTime / 300000);
+    return videoPoints;
+  }
+
+  /**
+   * Calculates how many browser points (1 point per 50 key events, 1 point per 10 mouse events).
+   */
+  private async calculateBrowserPoints(activities: Activity[]) {
+    const browserActivities = activities
+      .filter(a => a.activity.startsWith('browser.'))
+      .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
+
+    const keyCount = browserActivities.filter(a => a.activity === 'browser.key').length;
+    const mouseCount = browserActivities.filter(a => a.activity === 'browser.mouse').length;
+
+    const keyPoints = Math.floor(keyCount / 50);
+    const mousePoints = Math.floor(mouseCount / 10);
+
+    return keyPoints + mousePoints;
+  }
+
+  /**
+   * Calculates how many whiteboard points (1 point per 5 whiteboard events) a user gets.
+   */
+  private async calculateWhiteboardPoints(activities: Activity[]) {
+    const whiteboardActivities = activities
+      .filter(a => a.activity === 'whiteboard')
+      .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
+
+    const whiteboardPoints = Math.floor(whiteboardActivities.length / 5);
+
+    return whiteboardPoints;
+  }
+  /**
+   * Calculates how many note points (1 point for creating a note, 1 point per 50 characters added, and -1 point per 50 characters removed from the note content).
+   */
+  private async calculateNotePoints(activities: Activity[]) {
+    const noteActivities = activities
+      .filter(a => a.activity.startsWith('note.'))
+      .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
+
+    let notePoints = 0;
+    for (const act of noteActivities) {
+      if (act.activity === 'note.create') {
+        notePoints++;
+      } else if (act.activity === 'note.update' && act.numericValue) {
+        notePoints += Math.floor(act.numericValue / 50);
+      } else if (act.activity === 'note.update' && act.numericValue < 0) {
+        notePoints += Math.ceil(act.numericValue / 50);
+      }
+    }
+    return notePoints;
+  }
+
+}
diff --git a/src/roles/role.entity.ts b/src/roles/role.entity.ts
deleted file mode 100644
index 9df865e..0000000
--- a/src/roles/role.entity.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
-import { RoomSessionUser } from '../room/roomSessionUser.entity';
-
-
-@Entity({ tableName: 'role' })
-export class Role {
-  @PrimaryKey()
-  id!: number;
-
-  @Property()
-  roleName!: string;
-
-  @ManyToOne()
-  roomSessionUser!: RoomSessionUser;
-
-  constructor(roleName: string, roomSessionUser: RoomSessionUser) {
-    this.roomSessionUser = roomSessionUser;
-    this.roleName = roleName;
-
-  }
-}
diff --git a/src/roles/role.module.ts b/src/roles/role.module.ts
deleted file mode 100644
index f2eb8c0..0000000
--- a/src/roles/role.module.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Module } from '@nestjs/common';
-import { MikroOrmModule } from '@mikro-orm/nestjs';
-import { Role } from './role.entity';
-import { RoleService } from './role.service';
-
-@Module({
-  imports: [MikroOrmModule.forFeature([Role])],
-  providers: [RoleService],
-  exports: [RoleService],
-})
-export class RoleModule {}
\ No newline at end of file
diff --git a/src/roles/role.service.ts b/src/roles/role.service.ts
deleted file mode 100644
index bfec83f..0000000
--- a/src/roles/role.service.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { Injectable } from '@nestjs/common';
-import { InjectRepository } from '@mikro-orm/nestjs';
-import { EntityRepository } from '@mikro-orm/mysql';
-import { Role } from './role.entity';
-import { RoomSessionUser } from '../room/roomSessionUser.entity';
-import { EntityManager } from '@mikro-orm/mysql';
-
-export enum RoleType {
-    COORDINATOR = 'COORDINATOR',
-    DOCUMENTER  = 'DOCUMENTER',
-    CODER_DEBUGGER  = 'CODER_DEBUGGER',
-    VISUALIZER  = 'VISUALIZER',
-    ACTIVE_PARTICIPANT  = 'ACTIVE_PARTICIPANT',
-    OBSERVER  = 'OBSERVER',
-    LURKER  = 'LURKER',
-    DISRUPTOR   = 'DISRUPTOR',
-}
-
-@Injectable()
-export class RoleService {
-    constructor(
-        private readonly em: EntityManager,
-        @InjectRepository(Role) 
-        private readonly roleRepository: EntityRepository<Role>) {}
-    
-    async createRole(roleName: RoleType, roomSessionUser: RoomSessionUser): Promise<Role> {
-        const role = new Role(roleName, roomSessionUser);
-        await this.em.persistAndFlush(role);
-        return role;
-    }
-
-    async getRoleById(id: number): Promise<Role | null> {
-        return this.roleRepository.findOne(id);
-    }
-    
-    async getRolesByRoomSessionUser(roomSessionUser: RoomSessionUser): Promise<Role[]> {
-        return this.roleRepository.find({ roomSessionUser });
-    }
-    
-    async deleteRole(id: number): Promise<boolean> {
-        const role = await this.roleRepository.findOne(id);
-        if (!role) {
-        return false;
-        }
-        await this.em.removeAndFlush(role);
-        return true;
-    }
-}
\ No newline at end of file
diff --git a/src/room/roomSession.controller.ts b/src/room/roomSession.controller.ts
index 7c718a4..06838df 100644
--- a/src/room/roomSession.controller.ts
+++ b/src/room/roomSession.controller.ts
@@ -1,25 +1,40 @@
 import { Controller, Get, Param, UseGuards } from '@nestjs/common';
 import { RoomSessionService } from './roomSession.service';
 import { AuthGuard } from '../auth/auth.guard';
-import { RoomSessionPointsRequestDto } from './roomSession.dto';
+import { RoomSessionPointsRequestDto, RoomSessionResponseDto, RoomSessionModeRequestDto } from './roomSession.dto';
+import { RoomSession } from './roomSession.entity';
+import { ModeType } from './roomSession.service';
 
-@Controller('sessionPoints')
+@Controller('roomSession')
 export class RoomSessionPointsController {
   constructor(
       private readonly roomSession: RoomSessionService) {}
 
-      @UseGuards(AuthGuard)
-      @Get('/session/:sessionId')
+      
       /**
        * Retrieves the total points for a specific session based on its session ID.
        *
        * @param sessionId - The unique identifier of the session whose points are being retrieved.
        * @returns A promise that resolves to an object containing the total points and the session ID.
        */
+      @UseGuards(AuthGuard)
+      @Get('/:sessionId/points')
       async getPointsBySession(@Param('sessionId') sessionId: number): Promise<RoomSessionPointsRequestDto> {
         const points = await this.roomSession.getAllPointsBySession(sessionId);
         return points;
       }
-
-
+      
+      
+      /**
+       * Retrieves the mode of a specific session based on its session ID.
+       *
+       * @param sessionId - The unique identifier of the session whose mode is being retrieved.
+       * @returns A promise that resolves to an object containing the mode and the session ID.
+       */
+      @UseGuards(AuthGuard)
+      @Get('/:sessionId/mode')
+      async getModeBySession(@Param('sessionId') sessionId: number): Promise<RoomSessionModeRequestDto> {
+        const modeType = await this.roomSession.assignMode(sessionId);
+        return { modeName: modeType, sessionId };
+      }
 }
\ No newline at end of file
diff --git a/src/room/roomSession.dto.ts b/src/room/roomSession.dto.ts
index 5820c3e..59d5c5c 100644
--- a/src/room/roomSession.dto.ts
+++ b/src/room/roomSession.dto.ts
@@ -9,10 +9,22 @@ export class RoomSessionResponseDto {
     }[];
     roomId: number;
     roomName: string;
+    activities: { 
+      activity: string;
+      timestamp: Date;
+      userId: string;
+    }[];  
+    points: RoomSessionPointsRequestDto;
+    sessionId: number;
+    mode: RoomSessionModeRequestDto;
   }
 
 export class RoomSessionPointsRequestDto {
     allPoints: { audioPoints: number, videoPoints: number, browserPoints: number, whiteboardPoints: number, notePoints: number };
     totalPoints: number;
     sessionId: number;
+}
+export class RoomSessionModeRequestDto {
+    modeName: string;
+    sessionId: number;
 }
\ No newline at end of file
diff --git a/src/room/roomSession.entity.ts b/src/room/roomSession.entity.ts
index 16e7505..7d77d2c 100644
--- a/src/room/roomSession.entity.ts
+++ b/src/room/roomSession.entity.ts
@@ -33,6 +33,9 @@ export class RoomSession {
   @OneToMany(() => Activity, (activity) => activity.roomSession)
   activities = new Collection<Activity>(this);
 
+  @Property()
+  modeName?: string;
+
 
   constructor(room: Room) {
     this.room = room;
diff --git a/src/room/roomSession.module.ts b/src/room/roomSession.module.ts
index dc7f3cd..34e5469 100644
--- a/src/room/roomSession.module.ts
+++ b/src/room/roomSession.module.ts
@@ -5,7 +5,6 @@ import { RoomSession } from './roomSession.entity';
 import { RoomSessionPointsController } from './roomSession.controller';
 import { RoomSessionUserModule } from './roomSessionUser.module';
 import { RoomSessionUser } from './roomSessionUser.entity';
-import { ModeModule } from '../modes/mode.module';
 import { SessionPointsModule } from '../points/sessionPoints.module';
 import { ActivitiesModule } from '../activities/activities.module';
 import { SessionPoints } from '../points/sessionPoints.entity';
@@ -14,9 +13,8 @@ import { SessionPoints } from '../points/sessionPoints.entity';
     imports: [
         MikroOrmModule.forFeature([RoomSession, RoomSessionUser, SessionPoints]), 
         forwardRef(() => RoomSessionUserModule),
-        SessionPointsModule,
-        ModeModule,
-        ActivitiesModule
+        forwardRef(() => SessionPointsModule),
+        forwardRef(() => ActivitiesModule),
     ],
     providers: [RoomSessionService],
     controllers: [RoomSessionPointsController],
diff --git a/src/room/roomSession.service.ts b/src/room/roomSession.service.ts
index 7b2617a..e4f1668 100644
--- a/src/room/roomSession.service.ts
+++ b/src/room/roomSession.service.ts
@@ -9,7 +9,12 @@ import { SessionPoints } from '../points/sessionPoints.entity';
 import { RoomSessionUserService } from './roomSessionUser.service';
 import { RoomSessionPointsRequestDto } from './roomSession.dto';
 import { ActivitiesService } from 'src/activities/activities.service';
-import { ModeType, ModeService } from '../modes/mode.service';
+
+export enum ModeType {
+    PAIR_PROGRAMMING = 'pairProgramming',
+    ROLE_BASED_PROGRAMMING = 'roleBasedProgramming',
+    DEFAULT = 'default',
+}
 
 /**
  * A service responsible for managing room sessions.
@@ -30,7 +35,6 @@ export class RoomSessionService {
         @Inject(forwardRef(() => RoomSessionUserService))
         private readonly roomSessionUserService: RoomSessionUserService,
         private readonly activitiesService: ActivitiesService,
-        private readonly modeService: ModeService,
     ) {}
 
     /**
@@ -106,7 +110,14 @@ export class RoomSessionService {
         return { allPoints, totalPoints, sessionId };
     }
 
-    public async assignMode(roomSession: RoomSession): Promise<ModeType> {
+    async createMode(roomSession: RoomSession, modeType: ModeType): Promise<void> {
+        const modeName = modeType.toString();
+        roomSession.modeName = modeName;
+        await this.em.persistAndFlush(roomSession);
+    }
+
+    public async assignMode(sessionId: number): Promise<ModeType> {
+        const roomSession = await this.repository.findOneOrFail({ id: sessionId });
         let modeType = ModeType.DEFAULT;
         if (this.shouldAssignPairProgramming(roomSession)) {
             modeType = ModeType.PAIR_PROGRAMMING;
@@ -114,7 +125,7 @@ export class RoomSessionService {
         else if (this.shouldAssignRoleBasedProgramming(roomSession)) {
             modeType = ModeType.ROLE_BASED_PROGRAMMING;
         }
-        this.modeService.createMode(roomSession, modeType);
+        this.createMode(roomSession, modeType);
         return modeType;
     }
 
diff --git a/src/room/roomSessionUser.controller.ts b/src/room/roomSessionUser.controller.ts
index df5bb81..2ae62aa 100644
--- a/src/room/roomSessionUser.controller.ts
+++ b/src/room/roomSessionUser.controller.ts
@@ -1,12 +1,14 @@
 import { Controller, Get, Param, UseGuards } from '@nestjs/common';
 import { RoomSessionUserService } from './roomSessionUser.service';
 import { AuthGuard } from '../auth/auth.guard';
-import { RoomSessionUserPointsResponseDto } from './roomSessionUser.dto';
+import { RoomSessionUserPointsResponseDto, RoomSessionUserResponseDto, RoomSessionUserRolesResponseDto } from './roomSessionUser.dto';
+import { RoomSessionUser } from './roomSessionUser.entity';
+import { RoomSession } from './roomSession.entity';
 
-@Controller('sessionPoints')
+@Controller('roomSessionUser')
 export class RoomSessionUserPointsController {
   constructor(
-      private readonly roomSessionUser: RoomSessionUserService) {}
+      private readonly roomSessionUserService: RoomSessionUserService) {}
 
       
       /**
@@ -18,8 +20,23 @@ export class RoomSessionUserPointsController {
   @UseGuards(AuthGuard)
   @Get('/user/:userId')
   async getPointsByRoomSessionUser(@Param('userId') userId: number): Promise<RoomSessionUserPointsResponseDto> {
-    const points = await this.roomSessionUser.getPointsByRoomSessionUser(userId);
+    const points = await this.roomSessionUserService.getPointsByRoomSessionUser(userId);
     return { ...points, userId };
   }
+
+  /**
+   * Assigns a role to a specific user in a room session.
+   *
+   * @param userId - The unique identifier of the user.
+   * @param role - The role to be assigned to the user.
+   * @returns A promise that resolves when the role has been successfully assigned.
+   */
+  @UseGuards(AuthGuard)
+  @Get('/:userId/role')
+  async getRole(@Param('userId') userId: number): Promise<RoomSessionUserRolesResponseDto> {
+    const roles = await this.roomSessionUserService.assignRole(userId);
+    const rolesArray = roles.map(role => role.valueOf());
+    return { userId, roleNames: rolesArray };
+  }
   
 }
\ No newline at end of file
diff --git a/src/room/roomSessionUser.dto.ts b/src/room/roomSessionUser.dto.ts
index 9676639..9cbbc57 100644
--- a/src/room/roomSessionUser.dto.ts
+++ b/src/room/roomSessionUser.dto.ts
@@ -10,5 +10,11 @@ export class RoomSessionUserResponseDto {
     userId: number;
     name: string;
     points: RoomSessionUserPointsResponseDto;
+    roleNames?: RoomSessionUserRolesResponseDto;
+}
+
+export class RoomSessionUserRolesResponseDto {
+    userId: number;
+    roleNames?: string[];
 }
 
diff --git a/src/room/roomSessionUser.entity.ts b/src/room/roomSessionUser.entity.ts
index 9c2ec2a..a423f3a 100644
--- a/src/room/roomSessionUser.entity.ts
+++ b/src/room/roomSessionUser.entity.ts
@@ -23,6 +23,9 @@ import {
   
       @Property()
       name: string;
+
+      @Property()
+      roleName?: string[];
   
       /**
        * Creates a new instance of the Room class.
@@ -33,6 +36,7 @@ import {
           this.roomSession = roomSession;
           this.userId = userId;
           this.name = name;
+          this.roleName = [];
       }
   }
   
diff --git a/src/room/roomSessionUser.module.ts b/src/room/roomSessionUser.module.ts
index 95c8644..afbcdce 100644
--- a/src/room/roomSessionUser.module.ts
+++ b/src/room/roomSessionUser.module.ts
@@ -8,7 +8,6 @@ import { SessionPoints } from '../points/sessionPoints.entity';
 import { RoomSessionModule } from './roomSession.module';
 import { RoomSession } from './roomSession.entity';
 import { ActivitiesModule } from '../activities/activities.module';
-import { RoleModule } from '../roles/role.module';
 
 /**
  * A global module that encapsulates features related to room sessions and users.
@@ -19,8 +18,7 @@ import { RoleModule } from '../roles/role.module';
         MikroOrmModule.forFeature([RoomSessionUser, SessionPoints, RoomSession]), 
         forwardRef (() => SessionPointsModule),
         forwardRef (() => RoomSessionModule),
-        RoleModule,
-        ActivitiesModule
+        forwardRef (() => ActivitiesModule),
     ],
     providers: [RoomSessionUserService],
     controllers: [RoomSessionUserPointsController],
diff --git a/src/room/roomSessionUser.service.ts b/src/room/roomSessionUser.service.ts
index c870dfa..55d2463 100644
--- a/src/room/roomSessionUser.service.ts
+++ b/src/room/roomSessionUser.service.ts
@@ -7,11 +7,19 @@ import { RoomSession } from './roomSession.entity';
 import { RoomSessionUserPointsResponseDto } from './roomSessionUser.dto';
 import { SessionPoints } from '../points/sessionPoints.entity';
 import { ActivitiesService } from '../activities/activities.service';
-import { Role } from '../roles/role.entity';
-import { RoleType, RoleService } from '../roles/role.service';
 import { RoomSessionPointsRequestDto } from './roomSession.dto';
 import { RoomSessionService } from './roomSession.service';
 
+export enum RoleType {
+    COORDINATOR = 'COORDINATOR',
+    DOCUMENTER  = 'DOCUMENTER',
+    CODER_DEBUGGER  = 'CODER_DEBUGGER',
+    VISUALIZER  = 'VISUALIZER',
+    ACTIVE_PARTICIPANT  = 'ACTIVE_PARTICIPANT',
+    OBSERVER  = 'OBSERVER',
+    LURKER  = 'LURKER',
+    DISRUPTOR   = 'DISRUPTOR',
+}
 /**
  * A service responsible for managing room sessions and users.
  */
@@ -29,7 +37,6 @@ export class RoomSessionUserService {
         @InjectRepository(RoomSessionUser)
         private readonly userRepository: EntityRepository<RoomSessionUser>,
         private readonly activitiesService: ActivitiesService,
-        private readonly roleService: RoleService,
         @Inject(forwardRef(() => RoomSessionService))
         private readonly roomSessionService: RoomSessionService,
     ) {}
@@ -107,6 +114,10 @@ export class RoomSessionUserService {
             };
         }
 
+        public async createRole(roomSessionUser: RoomSessionUser, roleType: RoleType): Promise<void> {
+            const role = { type: roleType, roomSessionUser };
+            await this.em.persistAndFlush(role);
+        }
         /**
          * Assigns roles to a given RoomSessionUser based on their points and the session's total points.
          * 
@@ -117,7 +128,8 @@ export class RoomSessionUserService {
          * @param roomSessionUser - The RoomSessionUser entity for which roles are to be assigned.
          * @returns A promise that resolves to an array of assigned RoleType values.
          */
-        public async assignRole(roomSessionUser: RoomSessionUser): Promise<RoleType[]> {
+        public async assignRole(userId: number): Promise<RoleType[]> {
+            const roomSessionUser = await this.userRepository.findOneOrFail({ id: userId });
             const points = await this.getPointsByRoomSessionUser(roomSessionUser.id);
             const sessionPoints = await this.roomSessionService.getAllPointsBySession(roomSessionUser.roomSession.id);
             let roleTypes: RoleType[] = [];
@@ -131,7 +143,7 @@ export class RoomSessionUserService {
                 roleTypes.push(RoleType.LURKER);
             }
             for (let role of roleTypes) {
-                await this.roleService.createRole(role, roomSessionUser);
+                await this.createRole(roomSessionUser, role);
             }
             return roleTypes;
         }
-- 
GitLab