diff --git a/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs b/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..d8593231480eb1fd0522e128aaf581bd75f34cd9
--- /dev/null
+++ b/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs
@@ -0,0 +1,84 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
+using Tsi1.BusinessLayer.Interfaces;
+
+namespace Tsi1.Api.Controllers
+{
+    [Route("api/[controller]")]
+    [ApiController]
+    public class ActivityController : ControllerBase
+    {
+        private readonly IActivityService _activityService;
+
+        public ActivityController(IActivityService activityService)
+        {
+            _activityService = activityService;
+        }
+
+        [Authorize(Roles = UserTypes.FacultyAdmin  + ", " + UserTypes.Professor + ", " + UserTypes.Student)]
+        [HttpGet("GetAll/{courseId}")]
+        public async Task<IActionResult> GetAll(int courseId)
+        {
+            var result = await _activityService.GetAll(courseId);
+
+            if (result.HasError)
+            {
+                return BadRequest(result.Message);
+            }
+
+            return Ok(result.Data);
+        }
+
+        [Authorize(Roles = UserTypes.FacultyAdmin + ", " + UserTypes.Professor)]
+        [HttpPost("Create")]
+        public async Task<IActionResult> Create(ActivityCreateDto newActivity)
+        {
+            var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value);
+            var result = await _activityService.Create(newActivity, userId);
+
+            if (result.HasError)
+            {
+                return BadRequest(result.Message);
+            }
+
+            return Ok(result.Data);
+        }
+
+        [Authorize(Roles = UserTypes.FacultyAdmin + ", " + UserTypes.Professor)]
+        [HttpPut("Modify/{activityId}")]
+        public async Task<IActionResult> Modify(int activityId, ActivityModifyDto activityDto)
+        {
+            var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value);
+            var result = await _activityService.Modify(activityId, activityDto, userId);
+
+            if (result.HasError)
+            {
+                return BadRequest(result.Message);
+            }
+
+            return Ok();
+        }
+
+        [Authorize(Roles = UserTypes.FacultyAdmin + ", " + UserTypes.Professor)]
+        [HttpDelete("Delete/{activityId}")]
+        public async Task<IActionResult> Delete(int activityId)
+        {
+            var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value);
+            var result = await _activityService.Delete(activityId, userId);
+
+            if (result.HasError)
+            {
+                return BadRequest(result.Message);
+            }
+
+            return Ok();
+        }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs b/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs
index 12046260b0b893041955a44bd2388bf916f083ad..9ffbc2b3037b88c37929ffa00ef8036999aafa3a 100644
--- a/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs
+++ b/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs
@@ -106,7 +106,7 @@ namespace Tsi1.Api.Controllers
         [HttpGet("AllCourseStudentQuantity")]
         public async Task<IActionResult> AllCourseStudentQuantity()
         {
-            var result = await _tenantService.CourseStudentQuantity();
+            var result = await _tenantService.AllCourseStudentQuantity();
 
             if (result.HasError)
             {
@@ -145,5 +145,21 @@ namespace Tsi1.Api.Controllers
 
             return Ok(result.Data);
         }
+
+        [Authorize(Roles = UserTypes.FacultyAdmin)]
+        [HttpGet("CourseAttendance")]
+        public async Task<IActionResult> CourseAttendance()
+        {
+            var tenantId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "TenantId").Value);
+
+            var result = await _tenantService.CourseAttendance(tenantId);
+
+            if (result.HasError)
+            {
+                return BadRequest(result.Message);
+            }
+
+            return Ok(result.Data);
+        }
     }
 }
diff --git a/Tsi1.Api/Tsi1.Api/SignalR/VideoHub.cs b/Tsi1.Api/Tsi1.Api/SignalR/VideoHub.cs
index f0c0eeeb4f242aea7a4343fac04136bc42c982fa..4744e3c5304f6f3e848bc92fbd163c60d84a93e7 100644
--- a/Tsi1.Api/Tsi1.Api/SignalR/VideoHub.cs
+++ b/Tsi1.Api/Tsi1.Api/SignalR/VideoHub.cs
@@ -5,12 +5,20 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using Tsi1.BusinessLayer.Helpers;
+using Tsi1.BusinessLayer.Interfaces;
 
 namespace Tsi1.Api.SignalR
 {
     [Authorize]
     public class VideoHub : Hub
     {
+        private readonly IActivityService _activityService;
+
+        public VideoHub(IActivityService activityService)
+        {
+            _activityService = activityService;
+        }
+
         public override async Task OnConnectedAsync()
         {
             await Groups.AddToGroupAsync(Context.ConnectionId, Context.ConnectionId);
@@ -19,18 +27,34 @@ namespace Tsi1.Api.SignalR
         }
 
         [Authorize(Roles = UserTypes.Professor)]
-        public async Task CreateRoom(string roomName)
+        public async Task CreateRoom(int activityId)
         {
-            await Groups.AddToGroupAsync(Context.ConnectionId, roomName);
+            var result = await _activityService.ActivityValidation(activityId);
+
+            if (result.HasError)
+            {
+                throw new HubException(result.Message);
+            }
 
-            await Clients.Caller.SendAsync("CreateRoom", roomName);
+            await Groups.AddToGroupAsync(Context.ConnectionId, activityId.ToString());
+
+            await Clients.Caller.SendAsync("CreateRoom", activityId);
         }
 
-        public async Task Join(string roomName, string offer)
+        public async Task Join(int activityId, string offer)
         {
-            await Clients.Group(roomName).SendAsync("Join", Context.ConnectionId, offer);
+            var userId = int.Parse(Context.User.Claims.FirstOrDefault(x => x.Type == "Id").Value);
+
+            var result = await _activityService.AttendVirtualClass(activityId, userId);
+
+            if (result.HasError)
+            {
+                throw new HubException(result.Message);
+            }
+
+            await Clients.Group(activityId.ToString()).SendAsync("Join", Context.ConnectionId, offer);
 
-            await Groups.AddToGroupAsync(Context.ConnectionId, roomName);
+            await Groups.AddToGroupAsync(Context.ConnectionId, activityId.ToString());
         }
 
         public async Task Leave(string roomName)
diff --git a/Tsi1.Api/Tsi1.Api/Startup.cs b/Tsi1.Api/Tsi1.Api/Startup.cs
index 90bca24e58e0280359f8a1a93b2ecf7f173109cb..d27fa6ae2007f1b94d51e98e5f22d00c440ed32d 100644
--- a/Tsi1.Api/Tsi1.Api/Startup.cs
+++ b/Tsi1.Api/Tsi1.Api/Startup.cs
@@ -95,6 +95,7 @@ namespace Tsi1.Api
             services.AddScoped<ISurveyService, SurveyService>();
             services.AddScoped<ICommunicationService, CommunicationService>();
             services.AddScoped<IChatService, ChatService>();
+            services.AddScoped<IActivityService, ActivityService>();
 
             services.AddSingleton<PresenceTracker>();
 
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityCreateDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityCreateDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c320b4602d2b2bdfe628999a22f53a36eb728650
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityCreateDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Dtos
+{
+    public class ActivityCreateDto
+    {
+        public string Name { get; set; }
+
+        public bool IsVideoConference { get; set; }
+
+        public int CourseId { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ce33fcc5be89071ca759f3085112e5743c3a444b
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Dtos
+{
+    public class ActivityDto
+    {
+        public int Id { get; set; }
+
+        public string Name { get; set; }
+
+        public bool IsVideoConference { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityModifyDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityModifyDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..084adde789d42cc7542cd6585e793690323a13d3
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityModifyDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Dtos
+{
+    public class ActivityModifyDto
+    {
+        public string Name { get; set; }
+
+        public bool IsVideoConference { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/CourseAttendanceDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/CourseAttendanceDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..608b1cdc3c112e139f2789ee499bfd3ba54f7ae0
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/CourseAttendanceDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Dtos
+{
+    public class CourseAttendanceDto
+    {
+        public int Id { get; set; }
+
+        public string Name { get; set; }
+
+        public List<UserAttendanceDto> Users { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/UserAttendanceDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/UserAttendanceDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f46bfda426217a11e19cabbe96ace8f802e3b369
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/UserAttendanceDto.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Dtos
+{
+    public class UserAttendanceDto
+    {
+        public string FirstName { get; set; }
+
+        public string LastName { get; set; }
+
+        public string Email { get; set; }
+
+        public int Quantity { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
index b049c0244d6ec63c379544c1c0da7f90a475a6ad..1cffd0551686cd30f851493c7d64788b98fe0b2a 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
@@ -12,7 +12,7 @@ namespace Tsi1.BusinessLayer.Helpers
         public const string StudentDoesNotExist = "El estudiante con Id de usuario: '{0}' no existe";
         public const string StudentCourseDoesNotExists = "El estudiante '{0}' no se encuentra matriculado en el curso '{1}'";
         public const string StudentCourseAlreadyExists = "El estudiante '{0}' ya se encuentra matriculado en el curso '{1}'";
-        public const string ProffesorDoesNotExist = "El profesor con Id de usuario: '{0}' no existe";
+        public const string ProfessorDoesNotExist = "El profesor con Id de usuario: '{0}' no existe";
         public const string ProfessorCourseAlreadyExists = "El profesor '{0}' ya es docente del curso '{1}'";
         public const string ProfessorCourseDoesNotExists = "El profesor '{0}' no es docente del curso '{1}'";
         public const string InvalidUsername = "El nombre de usuario debe ser de la forma: 'usuario@facultad'";
@@ -64,5 +64,7 @@ namespace Tsi1.BusinessLayer.Helpers
 
         public const string CommunicationDoesNotExist = "La comunicación con id '{0}' no existe";
         public const string InvalidTenant = "El usuario no pertenece a la facultad con id '{0}'";
+
+        public const string ActivityDoesNotExist = "La actividad con id '{0}' no existe";
     }
 }
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs
index a72d596c8c6f48de65abdf53c03fd9c2fee4e78a..8116ab99f8b1205330ca9a3e615ea49ff68fb9c3 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs
@@ -54,6 +54,9 @@ namespace Tsi1.BusinessLayer.Helpers
             CreateMap<AnswerOption, AnswerOptionDetailDto>();
             CreateMap<Tenant, RegistrationDto>();
             CreateMap<Course, RegistrationDto>();
+            CreateMap<Activity, ActivityCreateDto>();
+            CreateMap<Activity, ActivityModifyDto>();
+            CreateMap<Activity, ActivityDto>();
 
             CreateMap<ForumCreateDto, Forum>();
             CreateMap<ForumPreviewDto, Forum>();
@@ -97,6 +100,9 @@ namespace Tsi1.BusinessLayer.Helpers
             CreateMap<AnswerOptionDetailDto, AnswerOption>();
             CreateMap<RegistrationDto, Tenant>();
             CreateMap<RegistrationDto, Course>();
+            CreateMap<ActivityCreateDto, Activity>();
+            CreateMap<ActivityModifyDto, Activity>();
+            CreateMap<ActivityDto, Activity>();
         }
     }
 }
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4b0e88ad468dc25357ddc96aef56ce4b4143ead4
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
+
+namespace Tsi1.BusinessLayer.Interfaces
+{
+    public interface IActivityService
+    {
+        Task<ServiceResult<bool>> AttendVirtualClass(int activityId, int userId);
+        Task<ServiceResult<List<ActivityDto>>> GetAll(int courseId);
+        Task<ServiceResult<int>> Create(ActivityCreateDto newActivity, int userId);
+        Task<ServiceResult<int>> Modify(int activityId, ActivityModifyDto activityDto, int userId);
+        Task<ServiceResult<int>> Delete(int activityId, int userId);
+
+        Task<ServiceResult<int>> ActivityValidation(int activityId);
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/ITenantService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/ITenantService.cs
index fb19c6e5f9572ae47fdf81b69074e699ada0828a..4390132671345531ee26f7a02b93ccda724d30f4 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/ITenantService.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/ITenantService.cs
@@ -23,10 +23,11 @@ namespace Tsi1.BusinessLayer.Interfaces
 
         Task<ServiceResult<List<TenantPreviewDto>>> FacultyList();
 
-        Task<ServiceResult<List<TenantCourseDto>>> CourseStudentQuantity();
+        Task<ServiceResult<List<TenantCourseDto>>> AllCourseStudentQuantity();
 
         Task<ServiceResult<List<RegistrationDto>>> FacultyRegistrations();
 
         Task<ServiceResult<List<RegistrationDto>>> CourseStudentQuantity(int tenantId);
+        Task<ServiceResult<List<CourseAttendanceDto>>> CourseAttendance(int tenantId);
     }
 }
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9ab568e205b73ebae1f82ae0844478cb6f772fc7
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs
@@ -0,0 +1,227 @@
+using AutoMapper;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
+using Tsi1.BusinessLayer.Interfaces;
+using Tsi1.DataLayer;
+using Tsi1.DataLayer.Entities;
+
+namespace Tsi1.BusinessLayer.Services
+{
+    public class ActivityService : IActivityService
+    {
+        private readonly Tsi1Context _context;
+        private readonly IMapper _mapper;
+
+        public ActivityService(Tsi1Context context, IMapper mapper)
+        {
+            _context = context;
+            _mapper = mapper;
+        }
+
+        public async Task<ServiceResult<bool>> AttendVirtualClass(int activityId, int userId)
+        {
+            var result = new ServiceResult<bool>();
+
+            var activity = await _context.Activities.FirstOrDefaultAsync(x => x.Id == activityId);
+
+            if (activity == null)
+            {
+                result.HasError = true;
+                result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, activityId));
+            }
+
+            var attendance = await _context.Attendances
+                .FirstOrDefaultAsync(x => x.ActivityId == activityId && x.UserId == userId);
+
+            if (attendance == null)
+            {
+                attendance = new Attendance
+                {
+                    Activity = activity,
+                    UserId = userId,
+                    Date = DateTime.Now,
+                };
+            }
+            
+            return result;
+        }
+
+        public async Task<ServiceResult<int>> ActivityValidation(int activityId)
+        {
+            var result = new ServiceResult<int>();
+
+            var activity = await _context.Activities.AsNoTracking().FirstOrDefaultAsync(x => x.Id == activityId);
+
+            if (activity == null)
+            {
+                result.HasError = true;
+                result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, activityId));
+            }
+
+            return result;
+        }
+
+        private async Task<ServiceResult<bool>> UserTypeValidation(int courseId, int userId)
+        {
+            var result = new ServiceResult<bool>();
+
+            var user = await _context.Users.AsNoTracking()
+                .Include(x => x.UserType)
+                .FirstOrDefaultAsync(x => x.Id == userId);
+
+            if (user == null)
+            {
+                result.HasError = true;
+                result.AddMessage(string.Format(ErrorMessages.UserDoesNotExist, userId));
+                return result;
+            }
+
+            if (user.UserType.Name == UserTypes.Professor)
+            {
+                var isProfessorCourse = await _context.ProfessorCourses
+                    .AsNoTracking()
+                    .AnyAsync(x => x.ProfessorId == user.ProfessorId && x.CourseId == courseId);
+
+                if (!isProfessorCourse)
+                {
+                    result.HasError = true;
+                    result.AddMessage(string.Format(ErrorMessages.ProfessorCourseDoesNotExists, user.Id, courseId));
+
+                }
+            }
+
+            return result;
+        }
+
+        private async Task<ServiceResult<bool>> CourseValidation(int courseId)
+        {
+            var result = new ServiceResult<bool>();
+
+            var course = await _context.Courses.AsNoTracking().FirstOrDefaultAsync(x => x.Id == courseId);
+
+            if (course == null)
+            {
+                result.HasError = true;
+                result.AddMessage(string.Format(ErrorMessages.CourseDoesNotExist, courseId));
+            }
+
+            return result;
+        }
+
+        public async Task<ServiceResult<List<ActivityDto>>> GetAll(int courseId)
+        {
+            var result = new ServiceResult<List<ActivityDto>>();
+
+            var validation = await this.CourseValidation(courseId);
+
+            if (validation.HasError)
+            {
+                result.HasError = true;
+                result.AddMessage(validation.Message);
+                return result;
+            }
+
+            var activities = await _context.Activities.AsNoTracking().Where(x => x.CourseId == courseId).ToListAsync();
+
+            result.Data = _mapper.Map<List<ActivityDto>>(activities);
+            return result;
+        }
+
+        public async Task<ServiceResult<int>> Create(ActivityCreateDto newActivity, int userId)
+        {
+            var result = new ServiceResult<int>();
+
+            var courseValidation = await this.CourseValidation(newActivity.CourseId);
+
+            if (courseValidation.HasError)
+            {
+                result.HasError = true;
+                result.AddMessage(courseValidation.Message);
+                return result;
+            }
+
+            var userTypeValidation = await this.UserTypeValidation(newActivity.CourseId, userId);
+
+            if (userTypeValidation.HasError)
+            {
+                result.HasError = true;
+                result.AddMessage(userTypeValidation.Message);
+                return result;
+            }
+
+            var activity = _mapper.Map<Activity>(newActivity);
+            _context.Activities.Add(activity);
+
+            await _context.SaveChangesAsync();
+
+            result.Data = activity.Id;
+            return result;
+        }
+
+        public async Task<ServiceResult<int>> Modify(int activityId, ActivityModifyDto activityDto, int userId)
+        {
+            var result = new ServiceResult<int>();
+
+            var activity = await _context.Activities.FirstOrDefaultAsync(x => x.Id == activityId);
+
+            if (activity == null)
+            {
+                result.HasError = true;
+                result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, activityId));
+                return result;
+            }
+
+            var userTypeValidation = await this.UserTypeValidation(activity.CourseId, userId);
+
+            if (userTypeValidation.HasError)
+            {
+                result.HasError = true;
+                result.AddMessage(userTypeValidation.Message);
+                return result;
+            }
+
+            _mapper.Map(activityDto, activity);
+
+            await _context.SaveChangesAsync();
+
+            result.Data = activity.Id;
+            return result;
+        }
+
+        public async Task<ServiceResult<int>> Delete(int activityId, int userId)
+        {
+            var result = new ServiceResult<int>();
+
+            var activity = await _context.Activities.FirstOrDefaultAsync(x => x.Id == activityId);
+
+            if (activity == null)
+            {
+                result.HasError = true;
+                result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, activityId));
+                return result;
+            }
+
+            var userTypeValidation = await this.UserTypeValidation(activity.CourseId, userId);
+
+            if (userTypeValidation.HasError)
+            {
+                result.HasError = true;
+                result.AddMessage(userTypeValidation.Message);
+                return result;
+            }
+
+            _context.Activities.Remove(activity);
+
+            await _context.SaveChangesAsync();
+
+            result.Data = activity.Id;
+            return result;
+        }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/TenantService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/TenantService.cs
index e38b78b8b60391907877802ec9f7b4f3da6e4e81..2a41d0d352248bc47e19f1a1430a644396a11f83 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Services/TenantService.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/TenantService.cs
@@ -158,7 +158,7 @@ namespace Tsi1.BusinessLayer.Services
             return result;
         }
 
-        public async Task<ServiceResult<List<TenantCourseDto>>> CourseStudentQuantity()
+        public async Task<ServiceResult<List<TenantCourseDto>>> AllCourseStudentQuantity()
         {
             var result = new ServiceResult<List<TenantCourseDto>>();
 
@@ -238,5 +238,69 @@ namespace Tsi1.BusinessLayer.Services
 
             return result;
         }
+
+        public async Task<ServiceResult<List<CourseAttendanceDto>>> CourseAttendance(int tenantId)
+        {
+            var result = new ServiceResult<List<CourseAttendanceDto>>();
+
+            var tenant = await _context.Tenants.FirstOrDefaultAsync(x => x.Id == tenantId && x.Name != TenantAdmin.Name);
+
+            if (tenant == null)
+            {
+                result.HasError = true;
+                result.AddMessage(string.Format(ErrorMessages.TenantDoesNotExist, tenantId));
+                return result;
+            }
+
+            var courses = await _context.Courses
+                .AsNoTracking()
+                .Include(x => x.StudentCourses)
+                .Where(x => x.TenantId == tenantId && !x.IsTemplate)
+                .ToListAsync();
+
+            var attendances = await _context.Attendances
+                .AsNoTracking()
+                .Include(x => x.Activity)
+                .Where(x => x.User.TenantId == tenantId)
+                .ToListAsync();
+
+            var courseAttendanceDtos = new List<CourseAttendanceDto>();
+            foreach (var course in courses)
+            {
+                var courseAttendanceDto = new CourseAttendanceDto
+                {
+                    Id = course.Id,
+                    Name = course.Name,
+                    Users = new List<UserAttendanceDto>(),
+                };
+
+                var studentIds = course.StudentCourses.Select(x => x.StudentId).ToList();
+
+                var users = await _context.Users
+                    .AsNoTracking()
+                    .Where(x => x.TenantId == tenantId && studentIds.Contains((int)x.StudentId))
+                    .ToListAsync();
+
+                foreach (var user in users)
+                {
+                    var attendanceQuantity = attendances.Where(x => x.UserId == user.Id && x.Activity.CourseId == course.Id).Count();
+
+                    var userAttendanceDto = new UserAttendanceDto 
+                    { 
+                        Email = user.Email,
+                        FirstName = user.FirstName,
+                        LastName = user.LastName,
+                        Quantity = attendanceQuantity
+                    };
+
+                    courseAttendanceDto.Users.Add(userAttendanceDto);
+                }
+
+                courseAttendanceDtos.Add(courseAttendanceDto);
+            }
+
+            result.Data = courseAttendanceDtos;
+            return result;
+        }
     }
 }
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/UserService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/UserService.cs
index ca09556ce683038f99c0841051b99a58b7e6cb49..1536b9635bc33adbf87e259503498e3eec976906 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Services/UserService.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/UserService.cs
@@ -178,7 +178,7 @@ namespace Tsi1.BusinessLayer.Services
             else if(userType == UserTypes.Professor && user.Professor == null)
             {
                 result.HasError = true;
-                result.Message = string.Format(ErrorMessages.ProffesorDoesNotExist, userId);
+                result.Message = string.Format(ErrorMessages.ProfessorDoesNotExist, userId);
                 return result;
             }
 
@@ -219,7 +219,7 @@ namespace Tsi1.BusinessLayer.Services
             else if (userType == UserTypes.Professor && user.Professor == null)
             {
                 result.HasError = true;
-                result.Message = string.Format(ErrorMessages.ProffesorDoesNotExist, username);
+                result.Message = string.Format(ErrorMessages.ProfessorDoesNotExist, username);
                 return result;
             }
 
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4a0ad033eb9e53de2188c8f90652f206fe309ef3
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.DataLayer.Entities
+{
+    public class Activity
+    {
+        public Activity()
+        {
+            Attendances = new HashSet<Attendance>();
+        }
+
+        public int Id { get; set; }
+
+        public string Name { get; set; }
+
+        public bool IsVideoConference { get; set; }
+
+        public int CourseId { get; set; }
+
+        public Course Course { get; set; }
+
+        public ICollection<Attendance> Attendances { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Attendance.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Attendance.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4c2257aefd62a77cafff5ba058d7b50a4b0de595
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Attendance.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.DataLayer.Entities
+{
+    public class Attendance
+    {
+        public int Id { get; set; }
+
+        public DateTime Date { get; set; }
+
+        public int UserId { get; set; }
+
+        public int ActivityId { get; set; }
+
+        public User User { get; set; }
+
+        public Activity Activity { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Course.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Course.cs
index f7efedf6afcfa34052001aa393799e23773d8eb3..c09ae3aa10f4233b77cc2c99e2c06fc9983619bb 100644
--- a/Tsi1.Api/Tsi1.DataLayer/Entities/Course.cs
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Course.cs
@@ -12,6 +12,7 @@ namespace Tsi1.DataLayer.Entities
             ProfessorCourses = new HashSet<ProfessorCourse>();
             Sections = new HashSet<Section>();
             Communications = new HashSet<Communication>();
+            Activities = new HashSet<Activity>();
         }
 
         public int Id { get; set; }
@@ -25,5 +26,7 @@ namespace Tsi1.DataLayer.Entities
         public ICollection<Section> Sections { get; set; }
 
         public ICollection<Communication> Communications { get; set; }
+
+        public ICollection<Activity> Activities { get; set; }
     }
 }
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/User.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/User.cs
index e3656322faa236d10a84b18c1fc4985cb240280d..fb5427eb77f6c5ea543ea0b1bdb210617d8631ff 100644
--- a/Tsi1.Api/Tsi1.DataLayer/Entities/User.cs
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/User.cs
@@ -12,6 +12,7 @@ namespace Tsi1.DataLayer.Entities
             PostMessages = new HashSet<PostMessage>();
             ForumUsers = new HashSet<ForumUser>();
             SurveyResponses = new HashSet<SurveyResponse>();
+            Attendances = new HashSet<Attendance>();
         }
 
         public int Id { get; set; }
@@ -43,5 +44,6 @@ namespace Tsi1.DataLayer.Entities
         public ICollection<PostMessage> PostMessages { get; set; }
         public ICollection<ForumUser> ForumUsers { get; set; }
         public ICollection<SurveyResponse> SurveyResponses { get; set; }
+        public ICollection<Attendance> Attendances { get; set; }
     }
 }
diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ActivityConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ActivityConfiguration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..bb240989a2fd94ea21c55cf70fe94ffb6f144f78
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ActivityConfiguration.cs
@@ -0,0 +1,25 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Tsi1.DataLayer.Entities;
+
+namespace Tsi1.DataLayer.EntityConfiguration
+{
+    public class ActivityConfiguration : IEntityTypeConfiguration<Activity>
+    {
+        public void Configure(EntityTypeBuilder<Activity> builder)
+        {
+            builder.HasKey(x => x.Id);
+
+            builder.Property(x => x.Name)
+                .IsRequired()
+                .HasColumnType("character varying(50)");
+
+            builder.HasOne(x => x.Course)
+                .WithMany(x => x.Activities)
+                .HasForeignKey(x => x.CourseId);
+        }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/AttendanceConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/AttendanceConfiguration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..d8e88def61900fd6ef56bd068896877b4b53d0e0
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/AttendanceConfiguration.cs
@@ -0,0 +1,25 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Tsi1.DataLayer.Entities;
+
+namespace Tsi1.DataLayer.EntityConfiguration
+{
+    public class AttendanceConfiguration : IEntityTypeConfiguration<Attendance>
+    {
+        public void Configure(EntityTypeBuilder<Attendance> builder)
+        {
+            builder.HasKey(x => x.Id);
+
+            builder.HasOne(x => x.User)
+                .WithMany(x => x.Attendances)
+                .HasForeignKey(x => x.UserId);
+
+            builder.HasOne(x => x.Activity)
+                .WithMany(x => x.Attendances)
+                .HasForeignKey(x => x.ActivityId);
+        }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201129171433_add-activity-attendance-entities.Designer.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201129171433_add-activity-attendance-entities.Designer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..41dcf6ded41a333032e7d0b4c60628fc48f05521
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201129171433_add-activity-attendance-entities.Designer.cs
@@ -0,0 +1,905 @@
+// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using Tsi1.DataLayer;
+
+namespace Tsi1.DataLayer.Migrations
+{
+    [DbContext(typeof(Tsi1Context))]
+    [Migration("20201129171433_add-activity-attendance-entities")]
+    partial class addactivityattendanceentities
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
+                .HasAnnotation("ProductVersion", "3.1.4")
+                .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<int>("CourseId")
+                        .HasColumnType("integer");
+
+                    b.Property<bool>("IsVideoConference")
+                        .HasColumnType("boolean");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(50)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CourseId");
+
+                    b.ToTable("Activities");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.AnswerOption", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(100)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("Name");
+
+                    b.ToTable("AnswerOptions");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<int>("ActivityId")
+                        .HasColumnType("integer");
+
+                    b.Property<DateTime>("Date")
+                        .HasColumnType("timestamp without time zone");
+
+                    b.Property<int>("UserId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ActivityId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("Attendances");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<int?>("CourseId")
+                        .HasColumnType("integer");
+
+                    b.Property<bool>("IsGlobal")
+                        .HasColumnType("boolean");
+
+                    b.Property<int?>("TenantId")
+                        .HasColumnType("integer");
+
+                    b.Property<string>("Text")
+                        .IsRequired()
+                        .HasColumnType("character varying(1000)");
+
+                    b.Property<DateTime>("ValidUntil")
+                        .HasColumnType("timestamp without time zone");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CourseId");
+
+                    b.HasIndex("TenantId");
+
+                    b.HasIndex("ValidUntil");
+
+                    b.ToTable("Communications");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Connection", b =>
+                {
+                    b.Property<string>("ConnectionId")
+                        .HasColumnType("text");
+
+                    b.Property<string>("GroupName")
+                        .HasColumnType("text");
+
+                    b.Property<int>("UserId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("ConnectionId");
+
+                    b.HasIndex("GroupName");
+
+                    b.ToTable("Connections");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Course", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<bool>("IsTemplate")
+                        .HasColumnType("boolean");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(50)");
+
+                    b.Property<int>("TenantId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("TenantId");
+
+                    b.HasIndex("Name", "TenantId")
+                        .IsUnique();
+
+                    b.ToTable("Courses");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.File", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(50)");
+
+                    b.Property<string>("Path")
+                        .IsRequired()
+                        .HasColumnType("character varying(1000)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("Path")
+                        .IsUnique();
+
+                    b.ToTable("Files");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Forum", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(50)");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("Forums");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b =>
+                {
+                    b.Property<int>("ForumId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("UserId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("ForumId", "UserId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("ForumUsers");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Group", b =>
+                {
+                    b.Property<string>("Name")
+                        .HasColumnType("text");
+
+                    b.HasKey("Name");
+
+                    b.ToTable("Groups");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<DateTime>("Date")
+                        .HasColumnType("timestamp without time zone");
+
+                    b.Property<int>("ForumId")
+                        .HasColumnType("integer");
+
+                    b.Property<string>("Title")
+                        .IsRequired()
+                        .HasColumnType("character varying(100)");
+
+                    b.Property<int>("UserId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.HasIndex("ForumId", "Title")
+                        .IsUnique();
+
+                    b.ToTable("Posts");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.PostMessage", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<string>("Content")
+                        .IsRequired()
+                        .HasColumnType("character varying(10485760)");
+
+                    b.Property<DateTime>("Date")
+                        .HasColumnType("timestamp without time zone");
+
+                    b.Property<int>("PostId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("UserId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("PostId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("PostMessages");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Professor", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<string>("IdentityCard")
+                        .IsRequired()
+                        .HasColumnType("character varying(50)");
+
+                    b.Property<int>("TenantId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("TenantId");
+
+                    b.HasIndex("IdentityCard", "TenantId")
+                        .IsUnique();
+
+                    b.ToTable("Professors");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.ProfessorCourse", b =>
+                {
+                    b.Property<int>("ProfessorId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("CourseId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("ProfessorId", "CourseId");
+
+                    b.HasIndex("CourseId");
+
+                    b.ToTable("ProfessorCourses");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Section", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<int>("CourseId")
+                        .HasColumnType("integer");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(255)");
+
+                    b.Property<int>("Order")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CourseId");
+
+                    b.ToTable("Sections");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItem", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<int?>("FileId")
+                        .HasColumnType("integer");
+
+                    b.Property<int?>("ForumId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("Order")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("SectionId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("SectionItemTypeId")
+                        .HasColumnType("integer");
+
+                    b.Property<int?>("SurveyId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("FileId")
+                        .IsUnique();
+
+                    b.HasIndex("ForumId")
+                        .IsUnique();
+
+                    b.HasIndex("SectionId");
+
+                    b.HasIndex("SectionItemTypeId");
+
+                    b.HasIndex("SurveyId")
+                        .IsUnique();
+
+                    b.ToTable("SectionItems");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItemType", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(100)");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("SectionItemTypes");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Student", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<int>("Age")
+                        .HasColumnType("integer");
+
+                    b.Property<string>("IdentityCard")
+                        .IsRequired()
+                        .HasColumnType("character varying(50)");
+
+                    b.Property<int>("TenantId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("TenantId");
+
+                    b.HasIndex("IdentityCard", "TenantId")
+                        .IsUnique();
+
+                    b.ToTable("Students");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.StudentCourse", b =>
+                {
+                    b.Property<int>("StudentId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("CourseId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("StudentId", "CourseId");
+
+                    b.HasIndex("CourseId");
+
+                    b.ToTable("StudentCourses");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<bool>("IsGlobal")
+                        .HasColumnType("boolean");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(255)");
+
+                    b.Property<int?>("TenantId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("Name");
+
+                    b.HasIndex("TenantId");
+
+                    b.ToTable("Surveys");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyAnswer", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<int>("AnswerOptionId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("SurveyQuestionId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("SurveyResponseId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("AnswerOptionId");
+
+                    b.HasIndex("SurveyQuestionId");
+
+                    b.HasIndex("SurveyResponseId");
+
+                    b.ToTable("SurveyAnswers");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyQuestion", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<string>("Question")
+                        .IsRequired()
+                        .HasColumnType("character varying(255)");
+
+                    b.Property<int>("SurveyId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("SurveyId");
+
+                    b.ToTable("SurveyQuestions");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyResponse", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<int>("SurveyId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("UserId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("SurveyId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("SurveyResponses");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Tenant", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(50)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("Name")
+                        .IsUnique();
+
+                    b.ToTable("Tenants");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.User", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<string>("Email")
+                        .IsRequired()
+                        .HasColumnType("character varying(255)");
+
+                    b.Property<string>("FirstName")
+                        .IsRequired()
+                        .HasColumnType("character varying(255)");
+
+                    b.Property<string>("LastName")
+                        .IsRequired()
+                        .HasColumnType("character varying(255)");
+
+                    b.Property<string>("Password")
+                        .IsRequired()
+                        .HasColumnType("character varying(255)");
+
+                    b.Property<int?>("ProfessorId")
+                        .HasColumnType("integer");
+
+                    b.Property<int?>("StudentId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("TenantId")
+                        .HasColumnType("integer");
+
+                    b.Property<int>("UserTypeId")
+                        .HasColumnType("integer");
+
+                    b.Property<string>("Username")
+                        .IsRequired()
+                        .HasColumnType("character varying(50)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ProfessorId")
+                        .IsUnique();
+
+                    b.HasIndex("StudentId")
+                        .IsUnique();
+
+                    b.HasIndex("TenantId");
+
+                    b.HasIndex("UserTypeId");
+
+                    b.HasIndex("Username", "TenantId")
+                        .IsUnique();
+
+                    b.ToTable("Users");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.UserType", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(50)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("Name")
+                        .IsUnique();
+
+                    b.ToTable("UserTypes");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Course", "Course")
+                        .WithMany("Activities")
+                        .HasForeignKey("CourseId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity")
+                        .WithMany("Attendances")
+                        .HasForeignKey("ActivityId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.User", "User")
+                        .WithMany("Attendances")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Course", "Course")
+                        .WithMany("Communications")
+                        .HasForeignKey("CourseId");
+
+                    b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant")
+                        .WithMany("Communications")
+                        .HasForeignKey("TenantId");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Connection", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Group", "Group")
+                        .WithMany("Connections")
+                        .HasForeignKey("GroupName");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Course", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant")
+                        .WithMany("Courses")
+                        .HasForeignKey("TenantId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum")
+                        .WithMany("ForumUsers")
+                        .HasForeignKey("ForumId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.User", "User")
+                        .WithMany("ForumUsers")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum")
+                        .WithMany("Posts")
+                        .HasForeignKey("ForumId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.User", "User")
+                        .WithMany("Posts")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.PostMessage", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Post", "Post")
+                        .WithMany("PostMessages")
+                        .HasForeignKey("PostId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.User", "User")
+                        .WithMany("PostMessages")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Professor", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant")
+                        .WithMany("Professors")
+                        .HasForeignKey("TenantId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.ProfessorCourse", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Course", "Course")
+                        .WithMany("ProfessorCourses")
+                        .HasForeignKey("CourseId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.Professor", "Professor")
+                        .WithMany("ProfessorCourses")
+                        .HasForeignKey("ProfessorId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Section", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Course", "Course")
+                        .WithMany("Sections")
+                        .HasForeignKey("CourseId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItem", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.File", "File")
+                        .WithOne("SectionItem")
+                        .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "FileId");
+
+                    b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum")
+                        .WithOne("SectionItem")
+                        .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "ForumId");
+
+                    b.HasOne("Tsi1.DataLayer.Entities.Section", "Section")
+                        .WithMany("SectionItems")
+                        .HasForeignKey("SectionId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.SectionItemType", "SectionItemType")
+                        .WithMany("SectionItems")
+                        .HasForeignKey("SectionItemTypeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey")
+                        .WithOne("SectionItem")
+                        .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "SurveyId");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Student", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant")
+                        .WithMany("Students")
+                        .HasForeignKey("TenantId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.StudentCourse", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Course", "Course")
+                        .WithMany("StudentCourses")
+                        .HasForeignKey("CourseId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.Student", "Student")
+                        .WithMany("StudentCourses")
+                        .HasForeignKey("StudentId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant")
+                        .WithMany("Surveys")
+                        .HasForeignKey("TenantId");
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyAnswer", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.AnswerOption", "AnswerOption")
+                        .WithMany("SurveyAnswers")
+                        .HasForeignKey("AnswerOptionId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.SurveyQuestion", "SurveyQuestion")
+                        .WithMany("SurveyAnswers")
+                        .HasForeignKey("SurveyQuestionId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.SurveyResponse", "SurveyResponse")
+                        .WithMany("SurveyAnswers")
+                        .HasForeignKey("SurveyResponseId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyQuestion", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey")
+                        .WithMany("SurveyQuestions")
+                        .HasForeignKey("SurveyId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyResponse", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey")
+                        .WithMany("SurveyResponses")
+                        .HasForeignKey("SurveyId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.User", "User")
+                        .WithMany("SurveyResponses")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.User", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Professor", "Professor")
+                        .WithOne("User")
+                        .HasForeignKey("Tsi1.DataLayer.Entities.User", "ProfessorId");
+
+                    b.HasOne("Tsi1.DataLayer.Entities.Student", "Student")
+                        .WithOne("User")
+                        .HasForeignKey("Tsi1.DataLayer.Entities.User", "StudentId");
+
+                    b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant")
+                        .WithMany("Users")
+                        .HasForeignKey("TenantId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.UserType", "UserType")
+                        .WithMany()
+                        .HasForeignKey("UserTypeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201129171433_add-activity-attendance-entities.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201129171433_add-activity-attendance-entities.cs
new file mode 100644
index 0000000000000000000000000000000000000000..cc65e21a03d7809ded0edbe10be674b098b7ce7c
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201129171433_add-activity-attendance-entities.cs
@@ -0,0 +1,84 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+namespace Tsi1.DataLayer.Migrations
+{
+    public partial class addactivityattendanceentities : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.CreateTable(
+                name: "Activities",
+                columns: table => new
+                {
+                    Id = table.Column<int>(nullable: false)
+                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+                    Name = table.Column<string>(type: "character varying(50)", nullable: false),
+                    IsVideoConference = table.Column<bool>(nullable: false),
+                    CourseId = table.Column<int>(nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_Activities", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_Activities_Courses_CourseId",
+                        column: x => x.CourseId,
+                        principalTable: "Courses",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "Attendances",
+                columns: table => new
+                {
+                    Id = table.Column<int>(nullable: false)
+                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+                    Date = table.Column<DateTime>(nullable: false),
+                    UserId = table.Column<int>(nullable: false),
+                    ActivityId = table.Column<int>(nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_Attendances", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_Attendances_Activities_ActivityId",
+                        column: x => x.ActivityId,
+                        principalTable: "Activities",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                    table.ForeignKey(
+                        name: "FK_Attendances_Users_UserId",
+                        column: x => x.UserId,
+                        principalTable: "Users",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.CreateIndex(
+                name: "IX_Activities_CourseId",
+                table: "Activities",
+                column: "CourseId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_Attendances_ActivityId",
+                table: "Attendances",
+                column: "ActivityId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_Attendances_UserId",
+                table: "Attendances",
+                column: "UserId");
+        }
+
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropTable(
+                name: "Attendances");
+
+            migrationBuilder.DropTable(
+                name: "Activities");
+        }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs
index 58d7225c9f4c36aae6f9178010638a5c4ec352b0..08b6205591575da1bd95ae3d6fa4276b1e64a3d4 100644
--- a/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs
+++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs
@@ -19,6 +19,30 @@ namespace Tsi1.DataLayer.Migrations
                 .HasAnnotation("ProductVersion", "3.1.4")
                 .HasAnnotation("Relational:MaxIdentifierLength", 63);
 
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<int>("CourseId")
+                        .HasColumnType("integer");
+
+                    b.Property<bool>("IsVideoConference")
+                        .HasColumnType("boolean");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("character varying(50)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CourseId");
+
+                    b.ToTable("Activities");
+                });
+
             modelBuilder.Entity("Tsi1.DataLayer.Entities.AnswerOption", b =>
                 {
                     b.Property<int>("Id")
@@ -37,6 +61,31 @@ namespace Tsi1.DataLayer.Migrations
                     b.ToTable("AnswerOptions");
                 });
 
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+
+                    b.Property<int>("ActivityId")
+                        .HasColumnType("integer");
+
+                    b.Property<DateTime>("Date")
+                        .HasColumnType("timestamp without time zone");
+
+                    b.Property<int>("UserId")
+                        .HasColumnType("integer");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ActivityId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("Attendances");
+                });
+
             modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b =>
                 {
                     b.Property<int>("Id")
@@ -594,6 +643,30 @@ namespace Tsi1.DataLayer.Migrations
                     b.ToTable("UserTypes");
                 });
 
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Course", "Course")
+                        .WithMany("Activities")
+                        .HasForeignKey("CourseId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b =>
+                {
+                    b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity")
+                        .WithMany("Attendances")
+                        .HasForeignKey("ActivityId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("Tsi1.DataLayer.Entities.User", "User")
+                        .WithMany("Attendances")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
             modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b =>
                 {
                     b.HasOne("Tsi1.DataLayer.Entities.Course", "Course")
diff --git a/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs b/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs
index b35e7b2f0949cb8086fb134fe60f1d66e79e658b..bda60bbf54d151e5d680b5a78772624a78456bfb 100644
--- a/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs
+++ b/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs
@@ -32,8 +32,9 @@ namespace Tsi1.DataLayer
         public DbSet<SurveyQuestion> SurveyQuestions { get; set; }
         public DbSet<SurveyResponse> SurveyResponses { get; set; }
         public DbSet<AnswerOption> AnswerOptions { get; set; }
-
         public DbSet<Communication> Communications { get; set; }
+        public DbSet<Activity> Activities { get; set; }
+        public DbSet<Attendance> Attendances { get; set; }
 
 
 
@@ -65,6 +66,8 @@ namespace Tsi1.DataLayer
             modelBuilder.ApplyConfiguration(new SurveyResponseConfiguration());
             modelBuilder.ApplyConfiguration(new AnswerOptionConfiguration());
             modelBuilder.ApplyConfiguration(new CommunicationConfiguration());
+            modelBuilder.ApplyConfiguration(new ActivityConfiguration());
+            modelBuilder.ApplyConfiguration(new AttendanceConfiguration());
         }
     }
 }