diff --git a/Tsi1.Api/Tsi1.Api.sln b/Tsi1.Api/Tsi1.Api.sln
index d8cbb37464d1f64b8116052f7e82c4b19753afd3..f6d5e83fd98c503609b2069f1f5c2c8a3ddedfba 100644
--- a/Tsi1.Api/Tsi1.Api.sln
+++ b/Tsi1.Api/Tsi1.Api.sln
@@ -3,11 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio Version 16
 VisualStudioVersion = 16.0.30523.141
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tsi1.Api", "Tsi1.Api\Tsi1.Api.csproj", "{02E63197-0AEA-4942-941F-DFB7AD145A1E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tsi1.Api", "Tsi1.Api\Tsi1.Api.csproj", "{02E63197-0AEA-4942-941F-DFB7AD145A1E}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tsi1.BusinessLayer", "Tsi1.BusinessLayer\Tsi1.BusinessLayer.csproj", "{3B46AFDD-AB4A-4D0E-8A94-49559E1D2083}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tsi1.BusinessLayer", "Tsi1.BusinessLayer\Tsi1.BusinessLayer.csproj", "{3B46AFDD-AB4A-4D0E-8A94-49559E1D2083}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tsi1.DataLayer", "Tsi1.DataLayer\Tsi1.DataLayer.csproj", "{57C4932A-C228-4A49-8FAC-8E9447F0E6E0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tsi1.DataLayer", "Tsi1.DataLayer\Tsi1.DataLayer.csproj", "{57C4932A-C228-4A49-8FAC-8E9447F0E6E0}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/Tsi1.Api/Tsi1.Api/Controllers/UserController.cs b/Tsi1.Api/Tsi1.Api/Controllers/UserController.cs
index c952152dc9ddc1d0a5f5913c957fea1d84821af0..56e1e6dc9226d4864088385d994062e3dfa88254 100644
--- a/Tsi1.Api/Tsi1.Api/Controllers/UserController.cs
+++ b/Tsi1.Api/Tsi1.Api/Controllers/UserController.cs
@@ -5,6 +5,8 @@ using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using Tsi1.Api.Infrastructure;
 using Tsi1.Api.Models;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
 using Tsi1.BusinessLayer.Interfaces;
 
 namespace Tsi1.Api.Controllers
@@ -14,26 +16,30 @@ namespace Tsi1.Api.Controllers
     [ApiController]
     public class UserController : ControllerBase
     {
-        private readonly IUserService _userService;
         private readonly IJwtAuthManager _jwtAuthManager;
+        private readonly IUserService _userService;
+        private readonly IUserTypeService _userTypeService;
 
-        public UserController(IUserService userService, IJwtAuthManager jwtAuthManager)
+        public UserController(IJwtAuthManager jwtAuthManager, IUserService userService, IUserTypeService userTypeService)
         {
-            _userService = userService;
             _jwtAuthManager = jwtAuthManager;
+            _userService = userService;
+            _userTypeService = userTypeService;
         }
 
         [AllowAnonymous]
         [HttpPost("Login")]
         public async Task<IActionResult> Login(LoginRequest request)
         {
-            var user = await _userService.Authenticate(request.UserName, request.Password);
+            var result = await _userService.Authenticate(request.UserName, request.Password);
 
-            if (user == null)
+            if (result.HasError)
             {
-                return BadRequest();
+                return BadRequest(result.Message);
             }
 
+            var user = result.Data;
+
             var claims = new[]
             {
                 new Claim(ClaimTypes.Name,user.Username),
@@ -51,11 +57,27 @@ namespace Tsi1.Api.Controllers
             });
         }
 
-        [HttpGet("Register")]
-        public async Task<IActionResult> Register()
+        [Authorize(Roles = UserTypes.FacultyAdmin)]
+        [HttpPost("Register")]
+        public async Task<IActionResult> Register(UserRegisterDto dto)
         {
+            var userTypeResult = await _userTypeService.GetById(dto.UserTypeId);
+
+            if (userTypeResult.HasError)
+            {
+                BadRequest(userTypeResult.Message);
+            }
+
+            var userType = userTypeResult.Data;
+
+            var userServiceResult = await _userService.Create(dto, userType.Name);
+
+            if (userServiceResult.HasError)
+            {
+                BadRequest(userServiceResult.Message);
+            }
+
             return Ok();
         }
-
     }
 }
diff --git a/Tsi1.Api/Tsi1.Api/Infrastructure/JwtAuthManager.cs b/Tsi1.Api/Tsi1.Api/Infrastructure/JwtAuthManager.cs
index b8c4a7b47aa63f84cc285c80cb4beafd2cfb683d..69fe71fbcabbcda7d2cc8fa475e3691df8333400 100644
--- a/Tsi1.Api/Tsi1.Api/Infrastructure/JwtAuthManager.cs
+++ b/Tsi1.Api/Tsi1.Api/Infrastructure/JwtAuthManager.cs
@@ -48,12 +48,14 @@ namespace Tsi1.Api.Infrastructure
         public JwtAuthResult GenerateTokens(string username, Claim[] claims, DateTime now)
         {
             var shouldAddAudienceClaim = string.IsNullOrWhiteSpace(claims?.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Aud)?.Value);
+
             var jwtToken = new JwtSecurityToken(
                 _jwtTokenConfig.Issuer,
                 shouldAddAudienceClaim ? _jwtTokenConfig.Audience : string.Empty,
                 claims,
                 expires: now.AddMinutes(_jwtTokenConfig.AccessTokenExpiration),
                 signingCredentials: new SigningCredentials(new SymmetricSecurityKey(_secret), SecurityAlgorithms.HmacSha256Signature));
+
             var accessToken = new JwtSecurityTokenHandler().WriteToken(jwtToken);
 
             var refreshToken = new RefreshToken
diff --git a/Tsi1.Api/Tsi1.Api/Models/LoginResult.cs b/Tsi1.Api/Tsi1.Api/Models/LoginResult.cs
index 3fd35ddba714f89b0b6bc43f705af662ffd3c6dc..eb78ddbbe7e3582e706f94e9d63d8a75511affdc 100644
--- a/Tsi1.Api/Tsi1.Api/Models/LoginResult.cs
+++ b/Tsi1.Api/Tsi1.Api/Models/LoginResult.cs
@@ -14,9 +14,6 @@ namespace Tsi1.Api.Models
         [JsonPropertyName("role")]
         public string Role { get; set; }
 
-        [JsonPropertyName("originalUserName")]
-        public string OriginalUserName { get; set; }
-
         [JsonPropertyName("accessToken")]
         public string AccessToken { get; set; }
 
diff --git a/Tsi1.Api/Tsi1.Api/Startup.cs b/Tsi1.Api/Tsi1.Api/Startup.cs
index 766b76c5b01dde462ff86d5cbbacbb965cb87b7e..b90bb57de9fed6d8c5d07b97c07c54bd6e6bbacd 100644
--- a/Tsi1.Api/Tsi1.Api/Startup.cs
+++ b/Tsi1.Api/Tsi1.Api/Startup.cs
@@ -38,9 +38,13 @@ namespace Tsi1.Api
 
             services.AddDbContext<Tsi1Context>(x => x.UseNpgsql(Configuration.GetConnectionString("PostgreSql")));
             services.AddScoped<IUserService, UserService>();
+            services.AddScoped<IUserTypeService, UserTypeService>();
+
+            services.AddCors();
 
             var jwtTokenConfig = Configuration.GetSection("jwtTokenConfig").Get<JwtTokenConfig>();
             services.AddSingleton(jwtTokenConfig);
+
             services.AddAuthentication(x =>
             {
                 x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
@@ -61,6 +65,7 @@ namespace Tsi1.Api
                     ClockSkew = TimeSpan.FromMinutes(1)
                 };
             });
+
             services.AddSingleton<IJwtAuthManager, JwtAuthManager>();
             services.AddHostedService<JwtRefreshTokenCache>();
 
@@ -105,7 +110,6 @@ namespace Tsi1.Api
             {
                 c.SwaggerEndpoint("/swagger/v1/swagger.json", "Tsi1 api V1");
                 c.DocumentTitle = "Tsi1 api";
-                //c.RoutePrefix = string.Empty;
             });
 
             app.UseRouting();
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/UserRegisterDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/UserRegisterDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..24616b382bf5c2ef36249f7b8af52e727fbcdae1
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/UserRegisterDto.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Dtos
+{
+    public class UserRegisterDto
+    {
+        [Required]
+        public int UserTypeId { get; set; }
+
+        [Required]
+        public string Username { get; set; }
+
+        [Required]
+        public string Password { get; set; }
+
+        [Required]
+        public string FirstName { get; set; }
+
+        [Required]
+        public string LastName { get; set; }
+
+        [Required]
+        public string Email { get; set; }
+
+        [Required]
+        public string IdentityCard { get; set; }
+
+        public int Age { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
new file mode 100644
index 0000000000000000000000000000000000000000..e36e8f1980228f519813ae1e19ef6452e8a0a365
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Helpers
+{
+    public static class ErrorMessages
+    {
+        public const string UserDoesNotExist = "El usuario '{0}' no existe";
+        public const string IncorrectPassword = "Contraseña incorrecta";
+        public const string UserTypeDoesNotExist = "El tipo de usuario con id '{0}' no existe";
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ServiceResult.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ServiceResult.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ae294d7826fb64ea7a4037019e9003de5d84f9bc
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ServiceResult.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Helpers
+{
+    public class ServiceResult<T>
+    {
+        public T Data { get; set; }
+        public string Message { get; set; }
+        public bool HasError { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/UserTypes.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/UserTypes.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9fb3b0e8bfd691ed0833bde757acb92626676838
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/UserTypes.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Helpers
+{
+    public static class UserTypes
+    {
+        public const string FacultyAdmin = nameof(FacultyAdmin);
+        public const string Professor = nameof(Professor);
+        public const string Student = nameof(Student);
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IUserService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IUserService.cs
index 2c715b938f377846db00cc3d129c9aeaf7ac9e5f..fb5470f6ae4f7e64e5ebdee73b060926276e18a3 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IUserService.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IUserService.cs
@@ -2,12 +2,15 @@
 using System.Collections.Generic;
 using System.Text;
 using System.Threading.Tasks;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
 using Tsi1.DataLayer.Entities;
 
 namespace Tsi1.BusinessLayer.Interfaces
 {
     public interface IUserService
     {
-        Task<User> Authenticate(string username, string password); 
+        Task<ServiceResult<User>> Authenticate(string username, string password);
+        Task<ServiceResult<User>> Create(UserRegisterDto dto, string type);
     }
 }
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IUserTypeService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IUserTypeService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..733e3d045d6811b1d29fcdae88e6427ab51876b0
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IUserTypeService.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Tsi1.BusinessLayer.Helpers;
+using Tsi1.DataLayer.Entities;
+
+namespace Tsi1.BusinessLayer.Interfaces
+{
+    public interface IUserTypeService
+    {
+        public Task<ServiceResult<UserType>> GetById(int id);
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/UserService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/UserService.cs
index 935bddd00e09eee75706f501b247e7c3602a4554..b134703ea0c88827d65103896b470236209503b4 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Services/UserService.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/UserService.cs
@@ -3,6 +3,8 @@ using System;
 using System.Collections.Generic;
 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;
@@ -18,32 +20,69 @@ namespace Tsi1.BusinessLayer.Services
             _context = context;
         }
 
-        public async Task<User> Authenticate(string username, string password)
+        public async Task<ServiceResult<User>> Authenticate(string username, string password)
         {
-            var user = await _context.Users.FirstOrDefaultAsync(x => x.Username == username);
+            var result = new ServiceResult<User>();
 
-            user = new User()
-            {
-                Id = 1,
-                Username = "lucca",
-                UserType = new UserType()
-                {
-                    Id = 1,
-                    Name = "admin"
-                }
-            };
+            var user = await _context.Users
+                .Include(x => x.UserType)
+                .FirstOrDefaultAsync(x => x.Username == username);
 
             if (user == null)
             {
-                // no existe el usuario
+                result.HasError = true;
+                result.Message = string.Format(ErrorMessages.UserDoesNotExist, username);
+                return result;
             }
 
             if (user.Password != password)
             {
-                // contraseña incorrecta
+                result.HasError = true;
+                result.Message = ErrorMessages.IncorrectPassword;
+                return result;
+            }
+
+            result.Data = user;
+
+            return result;
+        }
+
+        public async Task<ServiceResult<User>> Create(UserRegisterDto dto, string type)
+        {
+            var result = new ServiceResult<User>();
+
+            var user = new User()
+            {
+                UserTypeId = dto.UserTypeId,
+                Username = dto.Username,
+                Password = dto.Password,
+                Email = dto.Email,
+                FirstName = dto.FirstName,
+                LastName = dto.LastName
+            };
+
+            if (type == UserTypes.Student)
+            {
+                user.Student = new Student()
+                {
+                    IdentityCard = dto.IdentityCard,
+                    Age = dto.Age
+                };
+            }
+
+            if (type == UserTypes.Professor)
+            {
+                user.Professor = new Professor()
+                {
+                    IdentityCard = dto.IdentityCard
+                };
             }
 
-            return user;
+            _context.Users.Add(user);
+            await _context.SaveChangesAsync();
+            result.Data = user;
+
+            return result;
         }
     }
 }
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/UserTypeService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/UserTypeService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..18180fd57ad7c186d9ff40588009a08457956f56
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/UserTypeService.cs
@@ -0,0 +1,39 @@
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Tsi1.BusinessLayer.Helpers;
+using Tsi1.BusinessLayer.Interfaces;
+using Tsi1.DataLayer;
+using Tsi1.DataLayer.Entities;
+
+namespace Tsi1.BusinessLayer.Services
+{
+    public class UserTypeService : IUserTypeService
+    {
+        private readonly Tsi1Context _context;
+
+        public UserTypeService(Tsi1Context context)
+        {
+            _context = context;
+        }
+
+        public async Task<ServiceResult<UserType>> GetById(int id)
+        {
+            var result = new ServiceResult<UserType>();
+
+            var userType = await _context.UserTypes.FirstOrDefaultAsync(x => x.Id == id);
+
+            if (userType == null)
+            {
+                result.HasError = true;
+                result.Message = string.Format(ErrorMessages.UserTypeDoesNotExist, id);
+            }
+
+            result.Data = userType;
+
+            return result;
+        }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Professor.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Professor.cs
index b72802f9d1ba2255ea1492228b4645f72797784e..a095017f2316ce399aa783be02564ac58fc19a48 100644
--- a/Tsi1.Api/Tsi1.DataLayer/Entities/Professor.cs
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Professor.cs
@@ -12,7 +12,6 @@ namespace Tsi1.DataLayer.Entities
         }
 
         public int Id { get; set; }
-        public int UserId { get; set; }
         public string IdentityCard { get; set; }
 
         public User User { get; set; }
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs
index bf168e33d74bc58bedbcc7c74fdd01bce40dc053..acc85724b189d884047106a3d7423a138d5c639e 100644
--- a/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs
@@ -12,7 +12,6 @@ namespace Tsi1.DataLayer.Entities
         }
 
         public int Id { get; set; }
-        public int UserId { get; set; }
         public string IdentityCard { get; set; }
         public int Age { get; set; }
 
diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201016201059_remove-UserId-from-Student-Professor.Designer.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201016201059_remove-UserId-from-Student-Professor.Designer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..295fe18563f2963d0dbc89f32b245840b9b5e317
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201016201059_remove-UserId-from-Student-Professor.Designer.cs
@@ -0,0 +1,234 @@
+// <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("20201016201059_remove-UserId-from-Student-Professor")]
+    partial class removeUserIdfromStudentProfessor
+    {
+        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.Course", 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("Courses");
+                });
+
+            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.HasKey("Id");
+
+                    b.HasIndex("IdentityCard")
+                        .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.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.HasKey("Id");
+
+                    b.HasIndex("IdentityCard")
+                        .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.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>("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("UserTypeId");
+
+                    b.HasIndex("Username")
+                        .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.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.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.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.UserType", "UserType")
+                        .WithMany()
+                        .HasForeignKey("UserTypeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201016201059_remove-UserId-from-Student-Professor.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201016201059_remove-UserId-from-Student-Professor.cs
new file mode 100644
index 0000000000000000000000000000000000000000..41a552ea80083b691d644d8b17510083a5519f08
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201016201059_remove-UserId-from-Student-Professor.cs
@@ -0,0 +1,35 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Tsi1.DataLayer.Migrations
+{
+    public partial class removeUserIdfromStudentProfessor : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropColumn(
+                name: "UserId",
+                table: "Students");
+
+            migrationBuilder.DropColumn(
+                name: "UserId",
+                table: "Professors");
+        }
+
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AddColumn<int>(
+                name: "UserId",
+                table: "Students",
+                type: "integer",
+                nullable: false,
+                defaultValue: 0);
+
+            migrationBuilder.AddColumn<int>(
+                name: "UserId",
+                table: "Professors",
+                type: "integer",
+                nullable: false,
+                defaultValue: 0);
+        }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs
index 036e9605f4f8d0d7d8f6da51b64a99e3b41e8dcc..ce5698a5c0c92dd12caec2c8cf6bd1e23ed34368 100644
--- a/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs
+++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs
@@ -49,9 +49,6 @@ namespace Tsi1.DataLayer.Migrations
                         .IsRequired()
                         .HasColumnType("character varying(50)");
 
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
                     b.HasKey("Id");
 
                     b.HasIndex("IdentityCard")
@@ -89,9 +86,6 @@ namespace Tsi1.DataLayer.Migrations
                         .IsRequired()
                         .HasColumnType("character varying(50)");
 
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
                     b.HasKey("Id");
 
                     b.HasIndex("IdentityCard")
diff --git a/Tsi1.Api/Tsi1.DataLayer/Tsi1.DataLayer.csproj b/Tsi1.Api/Tsi1.DataLayer/Tsi1.DataLayer.csproj
index f7ccef3b5756bb86b63f32218d76f276a30f1c08..5b5d0ce158fa6a261517baa9e4efd29e61dd2275 100644
--- a/Tsi1.Api/Tsi1.DataLayer/Tsi1.DataLayer.csproj
+++ b/Tsi1.Api/Tsi1.DataLayer/Tsi1.DataLayer.csproj
@@ -9,6 +9,10 @@
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.4">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
     <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.9" />
     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.9" />
     <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.4" />