Index: iknow-api/Controllers/AdminController.cs
===================================================================
--- iknow-api/Controllers/AdminController.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Controllers/AdminController.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,119 @@
+using System.Security.Claims;
+using iknow_api.DTOs;
+using iknow_api.Services;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace iknow_api.Controllers
+{
+    /// <summary>
+    /// UC012 subjects, UC013 active semesters, UC014 professor assignments.
+    /// Every action requires the admin role, checked against the validated token.
+    /// </summary>
+    [ApiController]
+    [Route("api/[controller]")]
+    [Authorize]
+    public class AdminController : ControllerBase
+    {
+        private readonly IAdminService _adminService;
+
+        public AdminController(IAdminService adminService)
+        {
+            _adminService = adminService;
+        }
+
+        // ---------- UC012 ----------
+
+        [HttpGet("subjects")]
+        public async Task<IActionResult> GetSubjects() =>
+            RequireAdmin(out var error) ? Ok(await _adminService.GetSubjectsAsync()) : error;
+
+        [HttpPost("subjects")]
+        public async Task<IActionResult> CreateSubject([FromBody] SubjectWriteDto request) =>
+            RequireAdmin(out var error) ? Result(await _adminService.CreateSubjectAsync(request)) : error;
+
+        [HttpPut("subjects/{id:int}")]
+        public async Task<IActionResult> UpdateSubject(int id, [FromBody] SubjectWriteDto request) =>
+            RequireAdmin(out var error) ? Result(await _adminService.UpdateSubjectAsync(id, request)) : error;
+
+        [HttpDelete("subjects/{id:int}")]
+        public async Task<IActionResult> DeleteSubject(int id) =>
+            RequireAdmin(out var error) ? Result(await _adminService.DeleteSubjectAsync(id)) : error;
+
+        [HttpPost("subjects/{id:int}/majors")]
+        public async Task<IActionResult> LinkMajor(int id, [FromBody] MajorLinkDto request) =>
+            RequireAdmin(out var error) ? Result(await _adminService.LinkMajorAsync(id, request)) : error;
+
+        [HttpDelete("subjects/{id:int}/majors/{majorId:int}")]
+        public async Task<IActionResult> UnlinkMajor(int id, int majorId) =>
+            RequireAdmin(out var error) ? Result(await _adminService.UnlinkMajorAsync(id, majorId)) : error;
+
+        [HttpPost("subjects/{id:int}/prerequisites")]
+        public async Task<IActionResult> AddPrerequisite(int id, [FromBody] PrerequisiteDto request) =>
+            RequireAdmin(out var error) ? Result(await _adminService.AddPrerequisiteAsync(id, request)) : error;
+
+        [HttpDelete("subjects/{id:int}/prerequisites/{dependencyId:int}")]
+        public async Task<IActionResult> RemovePrerequisite(int id, int dependencyId) =>
+            RequireAdmin(out var error) ? Result(await _adminService.RemovePrerequisiteAsync(id, dependencyId)) : error;
+
+        // ---------- UC013 ----------
+
+        [HttpGet("semesters")]
+        public async Task<IActionResult> GetSemesters() =>
+            RequireAdmin(out var error) ? Ok(await _adminService.GetSemestersAsync()) : error;
+
+        [HttpPost("semesters")]
+        public async Task<IActionResult> CreateSemester([FromBody] SemesterWriteDto request) =>
+            RequireAdmin(out var error) ? Result(await _adminService.CreateSemesterAsync(request)) : error;
+
+        // ---------- UC014 ----------
+
+        [HttpGet("schedule/{semesterId:int}")]
+        public async Task<IActionResult> GetSchedule(int semesterId)
+        {
+            if (!RequireAdmin(out var error)) return error;
+
+            var schedule = await _adminService.GetScheduleAsync(semesterId);
+            return schedule is null
+                ? NotFound(new AdminResultDto { Ok = false, Message = "Semester not found." })
+                : Ok(schedule);
+        }
+
+        [HttpPost("schedule")]
+        public async Task<IActionResult> Assign([FromBody] ScheduleWriteDto request) =>
+            RequireAdmin(out var error) ? Result(await _adminService.AssignAsync(request)) : error;
+
+        [HttpDelete("schedule")]
+        public async Task<IActionResult> Unassign([FromBody] ScheduleWriteDto request) =>
+            RequireAdmin(out var error) ? Result(await _adminService.UnassignAsync(request)) : error;
+
+        // ---------- shared ----------
+
+        [HttpGet("majors")]
+        public async Task<IActionResult> GetMajors() =>
+            RequireAdmin(out var error) ? Ok(await _adminService.GetMajorsAsync()) : error;
+
+        private IActionResult Result(AdminResultDto result) =>
+            result.Ok ? Ok(result) : BadRequest(result);
+
+        /// <summary>
+        /// The role comes from the validated token, so it cannot be set by the caller.
+        /// </summary>
+        private bool RequireAdmin(out IActionResult error)
+        {
+            var role = User.FindFirst(ClaimTypes.Role)?.Value ?? User.FindFirst("role")?.Value;
+            if (!string.Equals(role, nameof(Models.UserRole.Admin), StringComparison.OrdinalIgnoreCase))
+            {
+                error = StatusCode(403, new AdminResultDto
+                {
+                    Ok = false,
+                    Message = "This endpoint is for administrators."
+                });
+                return false;
+            }
+
+            error = Ok();
+            return true;
+        }
+    }
+}
Index: iknow-api/Controllers/DbHealthController.cs
===================================================================
--- iknow-api/Controllers/DbHealthController.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Controllers/DbHealthController.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,49 @@
+using iknow_api.Data;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+
+namespace iknow_api.Controllers;
+
+[ApiController]
+[Route("[controller]")]
+public class DbHealthController(AppDbContext db) : ControllerBase
+{
+    /// <summary>
+    /// Verifies that the SSH tunnel is up, the DB credentials work, and that
+    /// the entity mapping matches the schema created by sql/ddl.sql.
+    /// </summary>
+    [HttpGet]
+    public async Task<IActionResult> Get()
+    {
+        try
+        {
+            // EF projects SqlQuery onto a column named "Value", hence the alias.
+            var version = await db.Database
+                .SqlQuery<string>($"SELECT version() AS \"Value\"")
+                .SingleAsync();
+
+            return Ok(new
+            {
+                connected = true,
+                server = version,
+                counts = new
+                {
+                    users = await db.User.CountAsync(),
+                    subjects = await db.Subjects.CountAsync(),
+                    enrolledSemesters = await db.EnrolledSemesters.CountAsync(),
+                    semesterSubjects = await db.SemesterSubjects.CountAsync(),
+                    passedSubjects = await db.PassedSubjects.CountAsync(),
+                }
+            });
+        }
+        catch (Exception ex)
+        {
+            return StatusCode(503, new
+            {
+                connected = false,
+                error = ex.Message,
+                hint = "Is tunnel_scripta.cmd running and listening on localhost:9999?"
+            });
+        }
+    }
+}
Index: iknow-api/Controllers/EnrollmentController.cs
===================================================================
--- iknow-api/Controllers/EnrollmentController.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Controllers/EnrollmentController.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,78 @@
+using System.Security.Claims;
+using iknow_api.DTOs;
+using iknow_api.Services;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace iknow_api.Controllers
+{
+    [ApiController]
+    [Route("api/[controller]")]
+    [Authorize]
+    public class EnrollmentController : ControllerBase
+    {
+        private readonly IEnrollmentService _enrollmentService;
+
+        public EnrollmentController(IEnrollmentService enrollmentService)
+        {
+            _enrollmentService = enrollmentService;
+        }
+
+        [HttpGet("options")]
+        public async Task<IActionResult> GetOptions()
+        {
+            if (!TryGetStudentId(out var studentId, out var error))
+            {
+                return error;
+            }
+
+            return Ok(await _enrollmentService.GetOptionsAsync(studentId));
+        }
+
+        [HttpPost]
+        public async Task<IActionResult> Enroll([FromBody] EnrollSemesterRequestDto request)
+        {
+            if (!TryGetStudentId(out var studentId, out var error))
+            {
+                return error;
+            }
+
+            var result = await _enrollmentService.EnrollAsync(studentId, request);
+            return result.Ok ? Ok(result) : BadRequest(result);
+        }
+
+        /// <summary>
+        /// Reads the caller from the validated token, so a student can only ever
+        /// enrol themselves.
+        /// </summary>
+        private bool TryGetStudentId(out int studentId, out IActionResult error)
+        {
+            studentId = 0;
+            error = Forbid();
+
+            var role = User.FindFirst(ClaimTypes.Role)?.Value ?? User.FindFirst("role")?.Value;
+            if (!string.Equals(role, nameof(Models.UserRole.Student), StringComparison.OrdinalIgnoreCase))
+            {
+                error = StatusCode(403, new EnrollSemesterResultDto
+                {
+                    Ok = false,
+                    Message = "Only students can enrol in a semester."
+                });
+                return false;
+            }
+
+            var idClaim = User.FindFirst("id")?.Value;
+            if (!int.TryParse(idClaim, out studentId))
+            {
+                error = Unauthorized(new EnrollSemesterResultDto
+                {
+                    Ok = false,
+                    Message = "Token has no usable user id."
+                });
+                return false;
+            }
+
+            return true;
+        }
+    }
+}
Index: iknow-api/Controllers/ProfController.cs
===================================================================
--- iknow-api/Controllers/ProfController.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Controllers/ProfController.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,93 @@
+using System.Security.Claims;
+using iknow_api.DTOs;
+using iknow_api.Services;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace iknow_api.Controllers
+{
+    [ApiController]
+    [Route("api/[controller]")]
+    [Authorize]
+    public class ProfController : ControllerBase
+    {
+        private readonly IProfService _profService;
+
+        public ProfController(IProfService profService)
+        {
+            _profService = profService;
+        }
+
+        /// <summary>
+        /// The subjects this professor teaches, each with the students enrolled
+        /// in it and their grade so far.
+        /// </summary>
+        [HttpGet("students")]
+        public async Task<IActionResult> GetStudents()
+        {
+            if (!TryGetProfessorId(out var professorId, out var error))
+            {
+                return error;
+            }
+
+            return Ok(await _profService.GetStudentsBySubjectAsync(professorId));
+        }
+
+        [HttpPost("grade/add")]
+        public Task<IActionResult> AddGrade([FromBody] GradeRequestDto request) =>
+            SetGrade(request, GradeAction.Add);
+
+        [HttpPost("grade/edit")]
+        public Task<IActionResult> EditGrade([FromBody] GradeRequestDto request) =>
+            SetGrade(request, GradeAction.Edit);
+
+        [HttpPost("grade/remove")]
+        public Task<IActionResult> RemoveGrade([FromBody] GradeRequestDto request) =>
+            SetGrade(request, GradeAction.Remove);
+
+        private async Task<IActionResult> SetGrade(GradeRequestDto request, GradeAction action)
+        {
+            if (!TryGetProfessorId(out var professorId, out var error))
+            {
+                return error;
+            }
+
+            var result = await _profService.SetGradeAsync(professorId, request, action);
+            return result.Ok ? Ok(result) : BadRequest(result);
+        }
+
+        /// <summary>
+        /// Reads the caller from the validated token and requires the professor
+        /// role, so one professor can never act on another one's subjects.
+        /// </summary>
+        private bool TryGetProfessorId(out int professorId, out IActionResult error)
+        {
+            professorId = 0;
+            error = Forbid();
+
+            var role = User.FindFirst(ClaimTypes.Role)?.Value ?? User.FindFirst("role")?.Value;
+            if (!string.Equals(role, nameof(Models.UserRole.Professor), StringComparison.OrdinalIgnoreCase))
+            {
+                error = StatusCode(403, new GradeResultDto
+                {
+                    Ok = false,
+                    Message = "This endpoint is for professors."
+                });
+                return false;
+            }
+
+            var idClaim = User.FindFirst("id")?.Value;
+            if (!int.TryParse(idClaim, out professorId))
+            {
+                error = Unauthorized(new GradeResultDto
+                {
+                    Ok = false,
+                    Message = "Token has no usable user id."
+                });
+                return false;
+            }
+
+            return true;
+        }
+    }
+}
Index: iknow-api/Controllers/UserController.cs
===================================================================
--- iknow-api/Controllers/UserController.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Controllers/UserController.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -1,3 +1,4 @@
-﻿using iknow_api.DTOs;
+using iknow_api.DTOs;
+using iknow_api.Models;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
@@ -83,4 +84,14 @@
                 var userData = await _userService.GetUserData(token);
                 if (userData == null) return Ok(new { info = "can't get info" });
+
+                // The study programme comes from the student's most recent
+                // enrolment. Within an academic year winter precedes summer,
+                // so order by year first and put winter ahead of summer.
+                var currentEnrolment = userData.Enrolments?
+                    .Where(es => es.Semester != null)
+                    .OrderByDescending(es => es.Semester!.Year)
+                    .ThenByDescending(es => es.Semester!.Type == sType.summer)
+                    .FirstOrDefault();
+
                 var personalInfo = new
                 {
@@ -88,13 +99,13 @@
                     embg = userData.EMBG ?? "",
                     lastName = userData.Surname ?? "",
-                    middleName = userData.MiddleName ?? "",
+                    middleName = "", // Not an attribute of Users in the ER model
                     firstName = userData.Name ?? "",
                     maidenName = "", // Property doesn't exist in User model
-                    dateOfBirth = userData.Bday.ToString("dd.MM.yyyy"),
-                    gender = userData.Gender ?? "",
-                    nationality = userData.Nationality ?? "",
-                    citizenship = userData.Citizenship ?? "",
+                    dateOfBirth = userData.Bday?.ToString("dd.MM.yyyy") ?? "",
+                    gender = "", // Not an attribute of Users in the ER model
+                    nationality = "", // Not an attribute of Users in the ER model
+                    citizenship = "", // Not an attribute of Users in the ER model
                     scholarship = "",
-                    currentPlan = userData.EnrollmentInfo?.EnrollmentYear.ToString() ?? "",
+                    currentPlan = userData.EnrollmentYear?.ToString() ?? "",
                     registryNumber = "",
                     notes = "",
@@ -105,5 +116,5 @@
                     placeOfBirth = userData.ContactInfo?.City ?? "",
                     municipalityOfBirth = userData.ContactInfo?.Municipality ?? "",
-                    country = userData.Citizenship ?? ""
+                    country = "" // Not an attribute of Users in the ER model
                 };
                 var previousEducation = new
@@ -112,6 +123,6 @@
                     profession = "",
                     average = userData.HighSchool?.GPA.ToString() ?? "",
-                    language = userData.Nationality ?? "",
-                    country = userData.Nationality ?? "",
+                    language = "", // Not an attribute of HighSchool in the ER model
+                    country = "",
                     previousUniversity = userData.HighSchool?.HighSchoolType.ToString() ?? "",
                     previousFaculty = "", // Property doesn't exist in HighSchool model
@@ -120,9 +131,9 @@
                 var enrollmentInfo = new
                 {
-                    enrollmentYear = userData.EnrollmentInfo?.EnrollmentYear.ToString() ?? "",
-                    status = userData.EnrollmentInfo?.StudyStatus ?? "",
+                    enrollmentYear = userData.EnrollmentYear?.ToString() ?? "",
+                    status = "", // Not an attribute of Users in the ER model
                     cycle = "Прв циклус",
-                    program = userData.EnrollmentInfo?.Major?.Name ?? "",
-                    quota = userData.EnrollmentInfo?.Quota.ToString() ?? "",
+                    program = currentEnrolment?.Major?.Name ?? "",
+                    quota = userData.Quota?.ToString() ?? "",
                     secondaryEducationNumber = "",
                     previousEducationCredits = ""
@@ -132,5 +143,5 @@
                     placeOfResidence = userData.ContactInfo?.City ?? "",
                     municipalityOfResidence = userData.ContactInfo?.Municipality ?? "",
-                    country = userData.Citizenship ?? "",
+                    country = "", // Not an attribute of Users in the ER model
                     address = userData.ContactInfo?.Address ?? "",
                     temporaryAddress = "",
@@ -165,14 +176,16 @@
                     {
                         id = userData[i].Id,
-                        semester = (userData[i].Semester.Type == 0 ? "Зимски" : "Летен") + $"({userData[i].Semester.Year}/{userData[i].Semester.Year + 1})",
+                        // sType declares summer first, so compare against the member
+                        // rather than the ordinal - == 0 meant summer, not winter.
+                        semester = (userData[i].Semester.Type == sType.winter ? "Зимски" : "Летен") + $"({userData[i].Semester.Year}/{userData[i].Semester.Year + 1})",
                         direction = userData[i].Major?.Name ?? "",
                         quota = userData[i].QuotaType.ToString(),
-                        note = "",
-                        studentCom = "",
+                        note = userData[i].Note ?? "",
+                        studentCom = userData[i].StudentComment ?? "",
                         sum = "0,00",
                         paid = "0,00",
                         ukim = "",
-                        createdOn = DateTime.Now.ToString("dd.MM.yyyy"),
-                        dateChanged = DateTime.Now.ToString("dd.MM.yyyy"),
+                        createdOn = userData[i].CratedAt.ToString("dd.MM.yyyy"),
+                        dateChanged = userData[i].LastChange?.ToString("dd.MM.yyyy") ?? "",
                         credits = "0,00",
                         type = "Ред.",
@@ -183,5 +196,5 @@
                         signatures = "0/5",
                         status = "валиден",
-                        completed = "Не"
+                        completed = userData[i].Verified.HasValue ? "Да" : "Не"
                     };
                     results.Add(newResult);
@@ -208,5 +221,5 @@
                 {
                     id = userData[i].Id,
-                    name = (userData[i].Semester.Type == 0 ? "Зимски" : "Летен") + $"({userData[i].Semester.Year}/{userData[i].Semester.Year + 1})",
+                    name = (userData[i].Semester.Type == sType.winter ? "Зимски" : "Летен") + $"({userData[i].Semester.Year}/{userData[i].Semester.Year + 1})",
                     status = "валиден",
                     serviceNumber = 1000000 + random.Next(10000, 100000)
@@ -221,5 +234,5 @@
             {
                 // Create semester key like "winter_2025_2026" or "summer_2025_2026"
-                var semesterType = enrollment.Semester.Type == 0 ? "winter" : "summer";
+                var semesterType = enrollment.Semester.Type == sType.winter ? "winter" : "summer";
                 var semesterKey = $"{semesterType}_{enrollment.Semester.Year}_{enrollment.Semester.Year + 1}";
 
@@ -258,9 +271,9 @@
             }
             var currentSemester = userData.FirstOrDefault(); // Get the most recent/current semester
-            var semesterTypeGlobal = currentSemester.Semester.Type == 0 ? "winter" : "summer";
+            var semesterTypeGlobal = currentSemester.Semester.Type == sType.winter ? "winter" : "summer";
             var semesterData = new
             {
                 id = $"{semesterTypeGlobal}_{currentSemester.Semester.Year}_{currentSemester.Semester.Year + 1}",
-                name = (currentSemester.Semester.Type == 0 ? "Зимски" : "Летен") + $" ({currentSemester.Semester.Year}/{currentSemester.Semester.Year + 1})",
+                name = (currentSemester.Semester.Type == sType.winter ? "Зимски" : "Летен") + $" ({currentSemester.Semester.Year}/{currentSemester.Semester.Year + 1})",
                 status = "валиден",
                 serviceNumber = (1000000 + random.Next(10000, 100000)).ToString(),
@@ -318,5 +331,5 @@
                         date = passed.DatePassed.ToString("dd.MM.yyyy"),
                         semester = passed.SemesterSubject.EnrolledSemester?.Semester != null
-                            ? (passed.SemesterSubject.EnrolledSemester.Semester.Type == 0 ? "Зимски" : "Летен") + 
+                            ? (passed.SemesterSubject.EnrolledSemester.Semester.Type == sType.winter ? "Зимски" : "Летен") + 
                               $" ({passed.SemesterSubject.EnrolledSemester.Semester.Year}/{passed.SemesterSubject.EnrolledSemester.Semester.Year + 1})"
                             : "",
Index: iknow-api/Controllers/WeatherForecastController.cs
===================================================================
--- iknow-api/Controllers/WeatherForecastController.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ 	(revision )
@@ -1,33 +1,0 @@
-using Microsoft.AspNetCore.Mvc;
-
-namespace iknow_api.Controllers
-{
-    [ApiController]
-    [Route("[controller]")]
-    public class WeatherForecastController : ControllerBase
-    {
-        private static readonly string[] Summaries = new[]
-        {
-            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
-        };
-
-        private readonly ILogger<WeatherForecastController> _logger;
-
-        public WeatherForecastController(ILogger<WeatherForecastController> logger)
-        {
-            _logger = logger;
-        }
-
-        [HttpGet(Name = "GetWeatherForecast")]
-        public IEnumerable<WeatherForecast> Get()
-        {
-            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
-            {
-                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
-                TemperatureC = Random.Shared.Next(-20, 55),
-                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
-            })
-            .ToArray();
-        }
-    }
-}
Index: iknow-api/DTOs/AdminDTO.cs
===================================================================
--- iknow-api/DTOs/AdminDTO.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/DTOs/AdminDTO.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,121 @@
+namespace iknow_api.DTOs
+{
+    // ---------- UC012 subjects ----------
+
+    public class AdminSubjectDto
+    {
+        public int Id { get; set; }
+        public string? Name { get; set; }
+        public string? Code { get; set; }
+        public int AwardedCredits { get; set; }
+        public int? DependencyCredit { get; set; }
+        public List<SubjectMajorDto> Majors { get; set; } = new();
+        public List<SubjectRefDto> Prerequisites { get; set; } = new();
+        /// <summary>How many enrolments already contain this subject; it cannot be deleted while this is above zero.</summary>
+        public int EnrolledCount { get; set; }
+    }
+
+    public class SubjectMajorDto
+    {
+        public int MajorId { get; set; }
+        public string? MajorName { get; set; }
+        public int MandatorySemester { get; set; }
+    }
+
+    public class SubjectRefDto
+    {
+        public int Id { get; set; }
+        public string? Name { get; set; }
+        public string? Code { get; set; }
+    }
+
+    public class SubjectWriteDto
+    {
+        public string? Name { get; set; }
+        public string? Code { get; set; }
+        public int AwardedCredits { get; set; }
+        public int? DependencyCredit { get; set; }
+    }
+
+    public class MajorLinkDto
+    {
+        public int MajorId { get; set; }
+        public int MandatorySemester { get; set; }
+    }
+
+    public class PrerequisiteDto
+    {
+        public int DependencyId { get; set; }
+    }
+
+    // ---------- UC013 semesters ----------
+
+    public class AdminSemesterDto
+    {
+        public int Id { get; set; }
+        public int Year { get; set; }
+        public string? Type { get; set; }
+        public string? Name { get; set; }
+        public int EnrolmentCount { get; set; }
+        /// <summary>Subjects with no professor teaching them in this semester.</summary>
+        public List<SubjectRefDto> UncoveredSubjects { get; set; } = new();
+    }
+
+    public class SemesterWriteDto
+    {
+        public int Year { get; set; }
+        /// <summary>"winter" or "summer".</summary>
+        public string? Type { get; set; }
+    }
+
+    // ---------- UC014 schedule ----------
+
+    public class ScheduleDto
+    {
+        public int SemesterId { get; set; }
+        public string? SemesterName { get; set; }
+        public List<ScheduleRowDto> Assignments { get; set; } = new();
+        public List<ProfessorLoadDto> Load { get; set; } = new();
+        public List<SubjectRefDto> UncoveredSubjects { get; set; } = new();
+        public List<SubjectRefDto> AllSubjects { get; set; } = new();
+        public List<ProfessorRefDto> Professors { get; set; } = new();
+    }
+
+    public class ScheduleRowDto
+    {
+        public int SubjectId { get; set; }
+        public string? SubjectName { get; set; }
+        public string? SubjectCode { get; set; }
+        public int ProfessorId { get; set; }
+        public string? ProfessorName { get; set; }
+    }
+
+    public class ProfessorRefDto
+    {
+        public int Id { get; set; }
+        public string? Name { get; set; }
+    }
+
+    public class ProfessorLoadDto
+    {
+        public int ProfessorId { get; set; }
+        public string? ProfessorName { get; set; }
+        public int Subjects { get; set; }
+    }
+
+    public class ScheduleWriteDto
+    {
+        public int ProfessorId { get; set; }
+        public int SemesterId { get; set; }
+        public int SubjectId { get; set; }
+    }
+
+    // ---------- shared ----------
+
+    public class AdminResultDto
+    {
+        public bool Ok { get; set; }
+        public string? Message { get; set; }
+        public int? Id { get; set; }
+    }
+}
Index: iknow-api/DTOs/EnrollmentDTO.cs
===================================================================
--- iknow-api/DTOs/EnrollmentDTO.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/DTOs/EnrollmentDTO.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,57 @@
+namespace iknow_api.DTOs
+{
+    /// <summary>Everything the enrolment form needs to render.</summary>
+    public class EnrollmentOptionsDto
+    {
+        /// <summary>How many subjects an enrolment must contain.</summary>
+        public int RequiredSubjects { get; set; }
+
+        /// <summary>Semesters this student has not enrolled in yet.</summary>
+        public List<SemesterOptionDto> Semesters { get; set; } = new();
+
+        public List<MajorOptionDto> Majors { get; set; } = new();
+
+        /// <summary>The major from the most recent enrolment, if there is one.</summary>
+        public int? DefaultMajorId { get; set; }
+    }
+
+    public class SemesterOptionDto
+    {
+        public int Id { get; set; }
+        public string? Name { get; set; }
+        public int Year { get; set; }
+        public string? Type { get; set; }
+    }
+
+    public class MajorOptionDto
+    {
+        public int Id { get; set; }
+        public string? Name { get; set; }
+        public List<SubjectOptionDto> Subjects { get; set; } = new();
+    }
+
+    public class SubjectOptionDto
+    {
+        public int Id { get; set; }
+        public string? Name { get; set; }
+        public string? Code { get; set; }
+        public int Credits { get; set; }
+        public int MandatorySemester { get; set; }
+        /// <summary>True when the student already passed this subject.</summary>
+        public bool AlreadyPassed { get; set; }
+    }
+
+    public class EnrollSemesterRequestDto
+    {
+        public int SemesterId { get; set; }
+        public int MajorId { get; set; }
+        public List<int> SubjectIds { get; set; } = new();
+    }
+
+    public class EnrollSemesterResultDto
+    {
+        public bool Ok { get; set; }
+        public string? Message { get; set; }
+        public int? EnrolledSemesterId { get; set; }
+    }
+}
Index: iknow-api/DTOs/ProfDTO.cs
===================================================================
--- iknow-api/DTOs/ProfDTO.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/DTOs/ProfDTO.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,36 @@
+namespace iknow_api.DTOs
+{
+    /// <summary>One subject a professor teaches, with the students enrolled in it.</summary>
+    public class SubjectStudentsDto
+    {
+        public int Id { get; set; }
+        public string? Name { get; set; }
+        public string? Code { get; set; }
+        public List<EnrolledStudentDto> Users { get; set; } = new();
+    }
+
+    public class EnrolledStudentDto
+    {
+        /// <summary>users.id - what the grading endpoints expect as StudentId.</summary>
+        public int Id { get; set; }
+        public string? Name { get; set; }
+        /// <summary>users.index - the number a professor actually recognises.</summary>
+        public string? Index { get; set; }
+        /// <summary>0 when the subject has not been graded yet.</summary>
+        public int Grade { get; set; }
+        public string? Semester { get; set; }
+    }
+
+    public class GradeRequestDto
+    {
+        public int StudentId { get; set; }
+        public int SubjectId { get; set; }
+        public int Grade { get; set; }
+    }
+
+    public class GradeResultDto
+    {
+        public bool Ok { get; set; }
+        public string? Message { get; set; }
+    }
+}
Index: iknow-api/Data/AppDbContext.cs
===================================================================
--- iknow-api/Data/AppDbContext.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Data/AppDbContext.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -4,6 +4,17 @@
 namespace iknow_api.Data
 {
+    /// <summary>
+    /// The schema is owned by sql/ddl.sql, not by EF migrations. Every entity
+    /// below is mapped explicitly onto the table and column names in that
+    /// script; nothing here may rely on EF naming conventions.
+    /// </summary>
     public class AppDbContext : DbContext
     {
+        /// <summary>
+        /// The schema created by sql/schema_creation.sql. Every table and enum
+        /// type is qualified with it, so nothing depends on search_path.
+        /// </summary>
+        public const string ProjectSchema = "project";
+
         public AppDbContext(DbContextOptions<AppDbContext> options)
             : base(options) { }
@@ -12,5 +23,4 @@
         public DbSet<ContactInfo> ContactInfo { get; set; }
         public DbSet<HighSchool> HighSchool { get; set; }
-        public DbSet<EnrollmentInfo> EnrollmentInfo { get; set; }
         public DbSet<RefreshToken> RefreshToken { get; set; }
         public DbSet<Subject> Subjects { get; set; }
@@ -27,169 +37,342 @@
         public DbSet<ProfessorSubjects> ProfessorSubjects { get; set; }
 
-
         protected override void OnModelCreating(ModelBuilder modelBuilder)
         {
             base.OnModelCreating(modelBuilder);
 
-            modelBuilder.Entity<Major>().HasData(
-                new Major { Id = 1, Name = "PIT" },
-                new Major { Id = 2, Name = "SIIS" },
-                new Major { Id = 3, Name = "SEIS" },
-                new Major { Id = 4, Name = "KN" }
-            );
-
-
-            // -------------------------
-            // DependencySubject (self-referencing many-to-many)
-            // -------------------------
-            modelBuilder.Entity<DependencySubject>()
-                .HasKey(ds => new { ds.SubjectId, ds.DependencyId });
-
-            modelBuilder.Entity<DependencySubject>()
-                .HasOne(ds => ds.Subject)
-                .WithMany(s => s.Dependencies)
-                .HasForeignKey(ds => ds.SubjectId)
-                .OnDelete(DeleteBehavior.Restrict);
-
-            modelBuilder.Entity<DependencySubject>()
-                .HasOne(ds => ds.Dependency)
-                .WithMany(s => s.Dependents)
-                .HasForeignKey(ds => ds.DependencyId)
-                .OnDelete(DeleteBehavior.Restrict);
-
-            // -------------------------
-            // MajorSubjects (many-to-many)
-            // -------------------------
-            modelBuilder.Entity<MajorSubjects>()
-                .HasKey(ab => new { ab.MajorId, ab.SubjectId });
-
-            modelBuilder.Entity<MajorSubjects>()
-                .HasOne(ab => ab.Majors)
-                .WithMany(a => a.Subjects)
-                .HasForeignKey(ab => ab.MajorId)
-                .OnDelete(DeleteBehavior.Cascade);
-
-            modelBuilder.Entity<MajorSubjects>()
-                .HasOne(ab => ab.Subjects)
-                .WithMany(b => b.Majors)
-                .HasForeignKey(ab => ab.SubjectId)
-                .OnDelete(DeleteBehavior.Cascade);
-
-            // -------------------------
-            // UserDocuments (many-to-many)
-            // -------------------------
-            modelBuilder.Entity<UserDocuments>()
-                .HasKey(ab => new { ab.UserId, ab.DocumentId });
-
-            modelBuilder.Entity<UserDocuments>()
-                .HasOne(ab => ab.User)
-                .WithMany(a => a.Documents)
-                .HasForeignKey(ab => ab.UserId)
-                .OnDelete(DeleteBehavior.Cascade);
-
-            modelBuilder.Entity<UserDocuments>()
-                .HasOne(ab => ab.Documents)
-                .WithMany(b => b.User)
-                .HasForeignKey(ab => ab.DocumentId)
-                .OnDelete(DeleteBehavior.Cascade);
-
-            // -------------------------
-            // Payment (user enrollment)
-            // -------------------------
-            modelBuilder.Entity<Payment>()
-                .HasKey(p => p.Id);
-
-            modelBuilder.Entity<Payment>()
-                .HasOne(p => p.User)
-                .WithMany(u => u.EnrolledSemesters)
-                .HasForeignKey(p => p.UserId)
-                .OnDelete(DeleteBehavior.Cascade);
-
-            modelBuilder.Entity<Payment>()
-                .HasOne(p => p.EnrolledSemesters)
-                .WithMany(es => es.Users)
-                .HasForeignKey(p => p.EnrollmentInfoId)
-                .OnDelete(DeleteBehavior.Cascade);
-
-            // -------------------------
-            // SemesterSubject (student enrollments and professor assignments)
-            // -------------------------
-            modelBuilder.Entity<SemesterSubject>()
-                .HasKey(ss => ss.Id); // or composite key if you prefer {UserId, EnrolledSemesterId, SubjectId}
-
-            // Student enrollment
-            modelBuilder.Entity<SemesterSubject>()
-                .HasOne(ss => ss.User)
-                .WithMany(u => u.EnrolledSemesterUserSubjects)
-                .HasForeignKey(ss => ss.UserId)
-                .OnDelete(DeleteBehavior.Restrict);
-
-            // Professor teaching
-            modelBuilder.Entity<SemesterSubject>()
-                .HasOne(ss => ss.Professor)
-                .WithMany(u => u.TeachingSubjects)
-                .HasForeignKey(ss => ss.ProfessorId)
-                .OnDelete(DeleteBehavior.Restrict);
-
-            // Subject relation
-            modelBuilder.Entity<SemesterSubject>()
-                .HasOne(ss => ss.Subject)
-                .WithMany(s => s.SemesterSubjects)
-                .HasForeignKey(ss => ss.SubjectId)
-                .OnDelete(DeleteBehavior.Restrict);
-
-            // EnrolledSemester relation
-            modelBuilder.Entity<SemesterSubject>()
-                .HasOne(ss => ss.EnrolledSemester)
-                .WithMany(es => es.SemesterSubjects)
-                .HasForeignKey(ss => ss.EnrolledSemesterId)
-                .OnDelete(DeleteBehavior.Restrict);
-
-            // -------------------------
-            // PassedSubject (one-to-one with SemesterSubject)
-            // -------------------------
-            modelBuilder.Entity<PassedSubject>()
-                .HasKey(ps => ps.Id);
-
-            modelBuilder.Entity<PassedSubject>()
-                .HasOne(ps => ps.SemesterSubject)
-                .WithOne(ss => ss.PassedSubject)
-                .HasForeignKey<PassedSubject>(ps => ps.SemesterSubjectId)
-                .OnDelete(DeleteBehavior.Cascade);
-
-            // -------------------------
-            // ActiveSemesters to EnrolledSemesters (one-to-many)
-            // -------------------------
-            modelBuilder.Entity<EnrolledSemesters>()
-                .HasOne(es => es.Semester)
-                .WithMany(a => a.EnrolledSemesters)
-                .HasForeignKey(es => es.Id)
-                .OnDelete(DeleteBehavior.Restrict);
-
-            // -------------------------
-            // ProfessorSubjects (many-to-many: Professor -> Semester -> Subject)
-            // -------------------------
-            modelBuilder.Entity<ProfessorSubjects>()
-                .HasKey(ps => new { ps.ProfessorId, ps.SemesterId, ps.SubjectId });
-
-            modelBuilder.Entity<ProfessorSubjects>()
-                .HasOne(ps => ps.Professor)
-                .WithMany()
-                .HasForeignKey(ps => ps.ProfessorId)
-                .OnDelete(DeleteBehavior.Cascade);
-
-            modelBuilder.Entity<ProfessorSubjects>()
-                .HasOne(ps => ps.Semester)
-                .WithMany()
-                .HasForeignKey(ps => ps.SemesterId)
-                .OnDelete(DeleteBehavior.Cascade);
-
-            modelBuilder.Entity<ProfessorSubjects>()
-                .HasOne(ps => ps.Subject)
-                .WithMany()
-                .HasForeignKey(ps => ps.SubjectId)
-                .OnDelete(DeleteBehavior.Cascade);
+            // The enum types themselves are declared in ddl.sql; this tells EF
+            // they exist so it does not try to treat the columns as text.
+            modelBuilder.HasPostgresEnum<UserRole>(ProjectSchema, "user_role");
+            modelBuilder.HasPostgresEnum<HighSchoolType>(ProjectSchema, "hs_type");
+            modelBuilder.HasPostgresEnum<Quota>(ProjectSchema, "quota_type");
+            modelBuilder.HasPostgresEnum<sType>(ProjectSchema, "semester_type");
+            modelBuilder.HasPostgresEnum<Grade>(ProjectSchema, "grade_type");
+
+            // -------------------------
+            // users
+            // -------------------------
+            modelBuilder.Entity<User>(e =>
+            {
+                e.ToTable("users", ProjectSchema);
+                e.HasKey(u => u.Id);
+                e.Property(u => u.Id).HasColumnName("id");
+                e.Property(u => u.Name).HasColumnName("name");
+                e.Property(u => u.EMBG).HasColumnName("embg");
+                e.Property(u => u.Surname).HasColumnName("surname");
+                e.Property(u => u.Index).HasColumnName("index");
+                e.Property(u => u.Bday).HasColumnName("bday").HasColumnType("timestamp without time zone");
+                e.Property(u => u.Email).HasColumnName("email");
+                e.Property(u => u.PasswordHash).HasColumnName("password");
+                e.Property(u => u.Role).HasColumnName("role");
+                e.Property(u => u.Quota).HasColumnName("quota");
+                e.Property(u => u.EnrollmentYear).HasColumnName("enrollment_year");
+                e.Property(u => u.CreatedAt).HasColumnName("created_at").HasColumnType("timestamp without time zone");
+                e.HasIndex(u => u.Email).IsUnique();
+            });
+
+            // -------------------------
+            // high_school
+            // -------------------------
+            modelBuilder.Entity<HighSchool>(e =>
+            {
+                e.ToTable("high_school", ProjectSchema);
+                e.HasKey(h => h.Id);
+                e.Property(h => h.Id).HasColumnName("id");
+                e.Property(h => h.UserId).HasColumnName("user_id");
+                e.Property(h => h.GPA).HasColumnName("gpa");
+                e.Property(h => h.HighSchoolType).HasColumnName("type");
+                e.HasOne(h => h.User)
+                 .WithOne(u => u.HighSchool)
+                 .HasForeignKey<HighSchool>(h => h.UserId)
+                 .OnDelete(DeleteBehavior.Restrict);
+            });
+
+            // -------------------------
+            // contact
+            // -------------------------
+            modelBuilder.Entity<ContactInfo>(e =>
+            {
+                e.ToTable("contact", ProjectSchema);
+                e.HasKey(c => c.Id);
+                e.Property(c => c.Id).HasColumnName("id");
+                e.Property(c => c.UserId).HasColumnName("user_id");
+                e.Property(c => c.City).HasColumnName("city");
+                e.Property(c => c.Municipality).HasColumnName("municipality");
+                e.Property(c => c.Address).HasColumnName("address");
+                e.Property(c => c.PhoneNumber).HasColumnName("number");
+                e.Property(c => c.MicrosoftEmail).HasColumnName("microsoft_email");
+                e.HasOne(c => c.User)
+                 .WithOne(u => u.ContactInfo)
+                 .HasForeignKey<ContactInfo>(c => c.UserId)
+                 .OnDelete(DeleteBehavior.Restrict);
+            });
+
+            // -------------------------
+            // major
+            // -------------------------
+            modelBuilder.Entity<Major>(e =>
+            {
+                e.ToTable("major", ProjectSchema);
+                e.HasKey(m => m.Id);
+                e.Property(m => m.Id).HasColumnName("id");
+                e.Property(m => m.Name).HasColumnName("name");
+            });
+
+            // -------------------------
+            // active_semesters
+            // -------------------------
+            modelBuilder.Entity<ActiveSemesters>(e =>
+            {
+                e.ToTable("active_semesters", ProjectSchema);
+                e.HasKey(a => a.Id);
+                e.Property(a => a.Id).HasColumnName("id");
+                e.Property(a => a.Year).HasColumnName("year");
+                e.Property(a => a.Type).HasColumnName("type");
+            });
+
+            // -------------------------
+            // subjects
+            // -------------------------
+            modelBuilder.Entity<Subject>(e =>
+            {
+                e.ToTable("subjects", ProjectSchema);
+                e.HasKey(s => s.Id);
+                e.Property(s => s.Id).HasColumnName("id");
+                e.Property(s => s.Name).HasColumnName("name");
+                e.Property(s => s.Code).HasColumnName("code");
+                e.Property(s => s.AwardedCredits).HasColumnName("awarded_credits");
+                e.Property(s => s.DependencyCredit).HasColumnName("dependency_credit");
+            });
+
+            // -------------------------
+            // enrolled_semesters
+            // -------------------------
+            modelBuilder.Entity<EnrolledSemesters>(e =>
+            {
+                e.ToTable("enrolled_semesters", ProjectSchema);
+                e.HasKey(es => es.Id);
+                e.Property(es => es.Id).HasColumnName("id");
+                e.Property(es => es.UserId).HasColumnName("user_id");
+                e.Property(es => es.QuotaType).HasColumnName("quota");
+                e.Property(es => es.MajorId).HasColumnName("major_id");
+                e.Property(es => es.Note).HasColumnName("note");
+                e.Property(es => es.StudentComment).HasColumnName("student_comment");
+                e.Property(es => es.CratedAt).HasColumnName("created_at").HasColumnType("timestamp without time zone");
+                e.Property(es => es.LastChange).HasColumnName("last_change").HasColumnType("timestamp without time zone");
+                e.Property(es => es.Verified).HasColumnName("completed").HasColumnType("timestamp without time zone");
+                e.Property(es => es.SemesterId).HasColumnName("semester_id");
+
+                e.HasOne(es => es.User)
+                 .WithMany(u => u.Enrolments)
+                 .HasForeignKey(es => es.UserId)
+                 .OnDelete(DeleteBehavior.Restrict);
+
+                // Note: this deliberately keys off SemesterId. An earlier version
+                // pointed the foreign key at es.Id, which silently tied every
+                // enrolment to the semester that happened to share its id.
+                e.HasOne(es => es.Semester)
+                 .WithMany(a => a.EnrolledSemesters)
+                 .HasForeignKey(es => es.SemesterId)
+                 .OnDelete(DeleteBehavior.Restrict);
+
+                e.HasOne(es => es.Major)
+                 .WithMany()
+                 .HasForeignKey(es => es.MajorId)
+                 .OnDelete(DeleteBehavior.Restrict);
+            });
+
+            // -------------------------
+            // semesters_subjects
+            // -------------------------
+            modelBuilder.Entity<SemesterSubject>(e =>
+            {
+                e.ToTable("semesters_subjects", ProjectSchema);
+                e.HasKey(ss => ss.Id);
+                e.Property(ss => ss.Id).HasColumnName("id");
+                e.Property(ss => ss.EnrolledSemesterId).HasColumnName("enrolled_semesters_id");
+                e.Property(ss => ss.SubjectId).HasColumnName("subjects_id");
+                e.Property(ss => ss.ProfessorId).HasColumnName("professor_id");
+                e.Property(ss => ss.Signature).HasColumnName("signature");
+
+                e.HasOne(ss => ss.Professor)
+                 .WithMany(u => u.TeachingSubjects)
+                 .HasForeignKey(ss => ss.ProfessorId)
+                 .OnDelete(DeleteBehavior.Restrict);
+
+                e.HasOne(ss => ss.Subject)
+                 .WithMany(s => s.SemesterSubjects)
+                 .HasForeignKey(ss => ss.SubjectId)
+                 .OnDelete(DeleteBehavior.Restrict);
+
+                e.HasOne(ss => ss.EnrolledSemester)
+                 .WithMany(es => es.SemesterSubjects)
+                 .HasForeignKey(ss => ss.EnrolledSemesterId)
+                 .OnDelete(DeleteBehavior.Restrict);
+            });
+
+            // -------------------------
+            // passed_subjects
+            // -------------------------
+            modelBuilder.Entity<PassedSubject>(e =>
+            {
+                e.ToTable("passed_subjects", ProjectSchema);
+                e.HasKey(ps => ps.Id);
+                e.Property(ps => ps.Id).HasColumnName("id");
+                e.Property(ps => ps.SemesterSubjectId).HasColumnName("enrolled_id");
+                e.Property(ps => ps.Grade).HasColumnName("grade");
+                e.Property(ps => ps.DatePassed).HasColumnName("date_passed").HasColumnType("timestamp without time zone");
+
+                e.HasOne(ps => ps.SemesterSubject)
+                 .WithOne(ss => ss.PassedSubject)
+                 .HasForeignKey<PassedSubject>(ps => ps.SemesterSubjectId)
+                 .OnDelete(DeleteBehavior.Cascade);
+            });
+
+            // -------------------------
+            // documents
+            // -------------------------
+            modelBuilder.Entity<Documents>(e =>
+            {
+                e.ToTable("documents", ProjectSchema);
+                e.HasKey(d => d.Id);
+                e.Property(d => d.Id).HasColumnName("id");
+                e.Property(d => d.Name).HasColumnName("type");
+                e.Property(d => d.Body).HasColumnName("body");
+                e.Property(d => d.Cost).HasColumnName("cost");
+            });
+
+            // -------------------------
+            // user_documents
+            // -------------------------
+            modelBuilder.Entity<UserDocuments>(e =>
+            {
+                e.ToTable("user_documents", ProjectSchema);
+                e.HasKey(ud => new { ud.UserId, ud.DocumentId });
+                e.Property(ud => ud.UserId).HasColumnName("user_id");
+                e.Property(ud => ud.DocumentId).HasColumnName("document_id");
+
+                e.HasOne(ud => ud.User)
+                 .WithMany(u => u.Documents)
+                 .HasForeignKey(ud => ud.UserId)
+                 .OnDelete(DeleteBehavior.Cascade);
+
+                e.HasOne(ud => ud.Documents)
+                 .WithMany(d => d.User)
+                 .HasForeignKey(ud => ud.DocumentId)
+                 .OnDelete(DeleteBehavior.Cascade);
+            });
+
+            // -------------------------
+            // token
+            // -------------------------
+            modelBuilder.Entity<RefreshToken>(e =>
+            {
+                e.ToTable("token", ProjectSchema);
+                e.HasKey(t => t.Id);
+                e.Property(t => t.Id).HasColumnName("id");
+                e.Property(t => t.UserId).HasColumnName("user_id");
+                e.Property(t => t.Token).HasColumnName("token");
+                e.Property(t => t.ExpiresAt).HasColumnName("expires_at").HasColumnType("timestamp without time zone");
+                e.Property(t => t.IsValid).HasColumnName("is_valid");
+
+                e.HasOne(t => t.User)
+                 .WithMany()
+                 .HasForeignKey(t => t.UserId)
+                 .OnDelete(DeleteBehavior.Cascade);
+            });
+
+            // -------------------------
+            // payment
+            // -------------------------
+            modelBuilder.Entity<Payment>(e =>
+            {
+                e.ToTable("payment", ProjectSchema);
+                e.HasKey(p => p.Id);
+                e.Property(p => p.Id).HasColumnName("id");
+                e.Property(p => p.UserId).HasColumnName("user_id");
+                e.Property(p => p.EnrollmentInfoId).HasColumnName("enrollment_id");
+                e.Property(p => p.Amount).HasColumnName("amount");
+
+                e.HasOne(p => p.User)
+                 .WithMany(u => u.Payments)
+                 .HasForeignKey(p => p.UserId)
+                 .OnDelete(DeleteBehavior.Cascade);
+
+                e.HasOne(p => p.EnrolledSemesters)
+                 .WithMany(es => es.Users)
+                 .HasForeignKey(p => p.EnrollmentInfoId)
+                 .OnDelete(DeleteBehavior.Cascade);
+            });
+
+            // -------------------------
+            // major_subjects
+            // -------------------------
+            modelBuilder.Entity<MajorSubjects>(e =>
+            {
+                e.ToTable("major_subjects", ProjectSchema);
+                e.HasKey(ms => new { ms.MajorId, ms.SubjectId });
+                e.Property(ms => ms.MajorId).HasColumnName("major_id");
+                e.Property(ms => ms.SubjectId).HasColumnName("subject_id");
+                e.Property(ms => ms.MandatorySemester).HasColumnName("mandatory_semester");
+
+                e.HasOne(ms => ms.Majors)
+                 .WithMany(m => m.Subjects)
+                 .HasForeignKey(ms => ms.MajorId)
+                 .OnDelete(DeleteBehavior.Cascade);
+
+                e.HasOne(ms => ms.Subjects)
+                 .WithMany(s => s.Majors)
+                 .HasForeignKey(ms => ms.SubjectId)
+                 .OnDelete(DeleteBehavior.Cascade);
+            });
+
+            // -------------------------
+            // dependency_subject
+            // -------------------------
+            modelBuilder.Entity<DependencySubject>(e =>
+            {
+                e.ToTable("dependency_subject", ProjectSchema);
+                e.HasKey(ds => new { ds.SubjectId, ds.DependencyId });
+                e.Property(ds => ds.SubjectId).HasColumnName("subject_id");
+                e.Property(ds => ds.DependencyId).HasColumnName("dependency_id");
+
+                e.HasOne(ds => ds.Subject)
+                 .WithMany(s => s.Dependencies)
+                 .HasForeignKey(ds => ds.SubjectId)
+                 .OnDelete(DeleteBehavior.Restrict);
+
+                e.HasOne(ds => ds.Dependency)
+                 .WithMany(s => s.Dependents)
+                 .HasForeignKey(ds => ds.DependencyId)
+                 .OnDelete(DeleteBehavior.Restrict);
+            });
+
+            // -------------------------
+            // professour_subjects  (spelling matches the table in ddl.sql)
+            // -------------------------
+            modelBuilder.Entity<ProfessorSubjects>(e =>
+            {
+                e.ToTable("professour_subjects", ProjectSchema);
+                e.HasKey(ps => new { ps.ProfessorId, ps.SemesterId, ps.SubjectId });
+                e.Property(ps => ps.ProfessorId).HasColumnName("prof_id");
+                e.Property(ps => ps.SemesterId).HasColumnName("active_semester_id");
+                e.Property(ps => ps.SubjectId).HasColumnName("subject_id");
+
+                e.HasOne(ps => ps.Professor)
+                 .WithMany()
+                 .HasForeignKey(ps => ps.ProfessorId)
+                 .OnDelete(DeleteBehavior.Cascade);
+
+                e.HasOne(ps => ps.Semester)
+                 .WithMany()
+                 .HasForeignKey(ps => ps.SemesterId)
+                 .OnDelete(DeleteBehavior.Cascade);
+
+                e.HasOne(ps => ps.Subject)
+                 .WithMany()
+                 .HasForeignKey(ps => ps.SubjectId)
+                 .OnDelete(DeleteBehavior.Cascade);
+            });
         }
-
     }
 }
Index: iknow-api/Data/PgEnumLabels.cs
===================================================================
--- iknow-api/Data/PgEnumLabels.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Data/PgEnumLabels.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,49 @@
+using iknow_api.Models;
+using Npgsql;
+
+namespace iknow_api.Data
+{
+    /// <summary>
+    /// Maps CLR enum member names onto the labels declared in sql/ddl.sql.
+    /// Most labels are just the lowercased member name; the ones that are not
+    /// (UserRole.Professor -> 'prof', Grade.Ten -> '10') are listed explicitly.
+    ///
+    /// The instances are static on purpose. EF Core caches its internal service
+    /// provider against the DbContext options, and a fresh translator instance
+    /// on every resolution makes each set of options look different - EF then
+    /// builds a new provider per resolution and throws
+    /// ManyServiceProvidersCreatedWarning once it has built twenty.
+    /// </summary>
+    public sealed class PgEnumLabels : INpgsqlNameTranslator
+    {
+        public static readonly PgEnumLabels UserRole = new(
+            new Dictionary<string, string>
+            {
+                [nameof(Models.UserRole.Admin)] = "admin",
+                [nameof(Models.UserRole.Professor)] = "prof",
+                [nameof(Models.UserRole.Student)] = "student",
+            });
+
+        public static readonly PgEnumLabels Grade = new(
+            new Dictionary<string, string>
+            {
+                [nameof(Models.Grade.Six)] = "6",
+                [nameof(Models.Grade.Seven)] = "7",
+                [nameof(Models.Grade.Eight)] = "8",
+                [nameof(Models.Grade.Nine)] = "9",
+                [nameof(Models.Grade.Ten)] = "10",
+            });
+
+        /// <summary>Lowercases the member name, which is all the other enums need.</summary>
+        public static readonly PgEnumLabels Lowercase = new(new Dictionary<string, string>());
+
+        private readonly IReadOnlyDictionary<string, string> _labels;
+
+        private PgEnumLabels(IReadOnlyDictionary<string, string> labels) => _labels = labels;
+
+        public string TranslateTypeName(string clrName) => clrName;
+
+        public string TranslateMemberName(string clrName) =>
+            _labels.TryGetValue(clrName, out var label) ? label : clrName.ToLowerInvariant();
+    }
+}
Index: iknow-api/Migrations/20251216191800_InitialCreate.Designer.cs
===================================================================
--- iknow-api/Migrations/20251216191800_InitialCreate.Designer.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ 	(revision )
@@ -1,790 +1,0 @@
-﻿// <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 iknow_api.Data;
-
-#nullable disable
-
-namespace iknow_api.Migrations
-{
-    [DbContext(typeof(AppDbContext))]
-    [Migration("20251216191800_InitialCreate")]
-    partial class InitialCreate
-    {
-        /// <inheritdoc />
-        protected override void BuildTargetModel(ModelBuilder modelBuilder)
-        {
-#pragma warning disable 612, 618
-            modelBuilder
-                .HasAnnotation("ProductVersion", "9.0.10")
-                .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
-            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
-            modelBuilder.Entity("iknow_api.Models.ActiveSemesters", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<int>("Type")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("Year")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("ActiveSemesters");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.ContactInfo", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<string>("Address")
-                        .HasColumnType("text");
-
-                    b.Property<string>("City")
-                        .HasColumnType("text");
-
-                    b.Property<string>("MicrosoftEmail")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Municipality")
-                        .HasColumnType("text");
-
-                    b.Property<string>("PhoneNumber")
-                        .HasColumnType("text");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("UserId")
-                        .IsUnique();
-
-                    b.ToTable("ContactInfo");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.DependencySubject", b =>
-                {
-                    b.Property<int>("SubjectId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("DependencyId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("SubjectId", "DependencyId");
-
-                    b.HasIndex("DependencyId");
-
-                    b.ToTable("DependencySubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Documents", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<string>("Body")
-                        .HasColumnType("text");
-
-                    b.Property<int>("Cost")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("Name")
-                        .HasColumnType("text");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("Documents");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.EnrolledSemesters", b =>
-                {
-                    b.Property<int>("Id")
-                        .HasColumnType("integer");
-
-                    b.Property<DateTime>("CratedAt")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<DateTime>("LastChange")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<int>("MajorId")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("Note")
-                        .HasColumnType("text");
-
-                    b.Property<int>("QuotaType")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("SemesterId")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("StudentComment")
-                        .HasColumnType("text");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.Property<DateTime>("Verified")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("MajorId");
-
-                    b.HasIndex("UserId");
-
-                    b.ToTable("EnrolledSemesters");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.EnrollmentInfo", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<int>("EnrollmentYear")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("MajorId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("Quota")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("StudyStatus")
-                        .HasColumnType("text");
-
-                    b.Property<string>("StudyType")
-                        .HasColumnType("text");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("MajorId");
-
-                    b.HasIndex("UserId")
-                        .IsUnique();
-
-                    b.ToTable("EnrollmentInfo");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.HighSchool", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<float>("GPA")
-                        .HasColumnType("real");
-
-                    b.Property<int>("HighSchoolType")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("StudyLanguage")
-                        .HasColumnType("text");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("UserId")
-                        .IsUnique();
-
-                    b.ToTable("HighSchool");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Major", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<string>("Name")
-                        .HasColumnType("text");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("Majors");
-
-                    b.HasData(
-                        new
-                        {
-                            Id = 1,
-                            Name = "PIT"
-                        },
-                        new
-                        {
-                            Id = 2,
-                            Name = "SIIS"
-                        },
-                        new
-                        {
-                            Id = 3,
-                            Name = "SEIS"
-                        },
-                        new
-                        {
-                            Id = 4,
-                            Name = "KN"
-                        });
-                });
-
-            modelBuilder.Entity("iknow_api.Models.MajorSubjects", b =>
-                {
-                    b.Property<int>("MajorId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("SubjectId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("Accreditation")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("MandatorySemester")
-                        .HasColumnType("integer");
-
-                    b.HasKey("MajorId", "SubjectId");
-
-                    b.HasIndex("SubjectId");
-
-                    b.ToTable("MajorSubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.PassedSubject", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<DateTime>("DatePassed")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<int>("Grade")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("SemesterSubjectId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("SemesterSubjectId")
-                        .IsUnique();
-
-                    b.ToTable("PassedSubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Payment", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<int>("EnrollmentInfoId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("EnrollmentInfoId");
-
-                    b.HasIndex("UserId");
-
-                    b.ToTable("Payments");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.ProfessorSubjects", b =>
-                {
-                    b.Property<int>("ProfessorId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("SemesterId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("SubjectId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("ProfessorId", "SemesterId", "SubjectId");
-
-                    b.HasIndex("SemesterId");
-
-                    b.HasIndex("SubjectId");
-
-                    b.ToTable("ProfessorSubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.RefreshToken", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<DateTime>("ExpiresAt")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<bool>("IsValid")
-                        .HasColumnType("boolean");
-
-                    b.Property<string>("Token")
-                        .HasColumnType("text");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("UserId");
-
-                    b.ToTable("RefreshToken");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.SemesterSubject", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<int>("EnrolledSemesterId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("ProfessorId")
-                        .HasColumnType("integer");
-
-                    b.Property<bool>("Signature")
-                        .HasColumnType("boolean");
-
-                    b.Property<int>("SubjectId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("EnrolledSemesterId");
-
-                    b.HasIndex("ProfessorId");
-
-                    b.HasIndex("SubjectId");
-
-                    b.HasIndex("UserId");
-
-                    b.ToTable("SemesterSubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Subject", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<int?>("AwardedCredits")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("Code")
-                        .HasColumnType("text");
-
-                    b.Property<int?>("DependencyCredit")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("Name")
-                        .HasColumnType("text");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("Subjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.User", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<DateTime>("Bday")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<string>("Citizenship")
-                        .HasColumnType("text");
-
-                    b.Property<DateTime>("CreatedAt")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<string>("EMBG")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Email")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Gender")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Index")
-                        .HasColumnType("text");
-
-                    b.Property<string>("MiddleName")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Name")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Nationality")
-                        .HasColumnType("text");
-
-                    b.Property<string>("PasswordHash")
-                        .HasColumnType("text");
-
-                    b.Property<int>("Role")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("Surname")
-                        .HasColumnType("text");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.UserDocuments", b =>
-                {
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("DocumentId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("UserId", "DocumentId");
-
-                    b.HasIndex("DocumentId");
-
-                    b.ToTable("UserDocuments");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.ContactInfo", b =>
-                {
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithOne("ContactInfo")
-                        .HasForeignKey("iknow_api.Models.ContactInfo", "UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.DependencySubject", b =>
-                {
-                    b.HasOne("iknow_api.Models.Subject", "Dependency")
-                        .WithMany("Dependents")
-                        .HasForeignKey("DependencyId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.Subject", "Subject")
-                        .WithMany("Dependencies")
-                        .HasForeignKey("SubjectId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.Navigation("Dependency");
-
-                    b.Navigation("Subject");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.EnrolledSemesters", b =>
-                {
-                    b.HasOne("iknow_api.Models.ActiveSemesters", "Semester")
-                        .WithMany("EnrolledSemesters")
-                        .HasForeignKey("Id")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.Major", "Major")
-                        .WithMany()
-                        .HasForeignKey("MajorId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithMany()
-                        .HasForeignKey("UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("Major");
-
-                    b.Navigation("Semester");
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.EnrollmentInfo", b =>
-                {
-                    b.HasOne("iknow_api.Models.Major", "Major")
-                        .WithMany()
-                        .HasForeignKey("MajorId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithOne("EnrollmentInfo")
-                        .HasForeignKey("iknow_api.Models.EnrollmentInfo", "UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("Major");
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.HighSchool", b =>
-                {
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithOne("HighSchool")
-                        .HasForeignKey("iknow_api.Models.HighSchool", "UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.MajorSubjects", b =>
-                {
-                    b.HasOne("iknow_api.Models.Major", "Majors")
-                        .WithMany("Subjects")
-                        .HasForeignKey("MajorId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.Subject", "Subjects")
-                        .WithMany("Majors")
-                        .HasForeignKey("SubjectId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("Majors");
-
-                    b.Navigation("Subjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.PassedSubject", b =>
-                {
-                    b.HasOne("iknow_api.Models.SemesterSubject", "SemesterSubject")
-                        .WithOne("PassedSubject")
-                        .HasForeignKey("iknow_api.Models.PassedSubject", "SemesterSubjectId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("SemesterSubject");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Payment", b =>
-                {
-                    b.HasOne("iknow_api.Models.EnrolledSemesters", "EnrolledSemesters")
-                        .WithMany("Users")
-                        .HasForeignKey("EnrollmentInfoId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithMany("EnrolledSemesters")
-                        .HasForeignKey("UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("EnrolledSemesters");
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.ProfessorSubjects", b =>
-                {
-                    b.HasOne("iknow_api.Models.User", "Professor")
-                        .WithMany()
-                        .HasForeignKey("ProfessorId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.ActiveSemesters", "Semester")
-                        .WithMany()
-                        .HasForeignKey("SemesterId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.Subject", "Subject")
-                        .WithMany()
-                        .HasForeignKey("SubjectId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("Professor");
-
-                    b.Navigation("Semester");
-
-                    b.Navigation("Subject");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.RefreshToken", b =>
-                {
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithMany()
-                        .HasForeignKey("UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.SemesterSubject", b =>
-                {
-                    b.HasOne("iknow_api.Models.EnrolledSemesters", "EnrolledSemester")
-                        .WithMany("SemesterSubjects")
-                        .HasForeignKey("EnrolledSemesterId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "Professor")
-                        .WithMany("TeachingSubjects")
-                        .HasForeignKey("ProfessorId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.Subject", "Subject")
-                        .WithMany("SemesterSubjects")
-                        .HasForeignKey("SubjectId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithMany("EnrolledSemesterUserSubjects")
-                        .HasForeignKey("UserId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.Navigation("EnrolledSemester");
-
-                    b.Navigation("Professor");
-
-                    b.Navigation("Subject");
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.UserDocuments", b =>
-                {
-                    b.HasOne("iknow_api.Models.Documents", "Documents")
-                        .WithMany("User")
-                        .HasForeignKey("DocumentId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithMany("Documents")
-                        .HasForeignKey("UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("Documents");
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.ActiveSemesters", b =>
-                {
-                    b.Navigation("EnrolledSemesters");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Documents", b =>
-                {
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.EnrolledSemesters", b =>
-                {
-                    b.Navigation("SemesterSubjects");
-
-                    b.Navigation("Users");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Major", b =>
-                {
-                    b.Navigation("Subjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.SemesterSubject", b =>
-                {
-                    b.Navigation("PassedSubject");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Subject", b =>
-                {
-                    b.Navigation("Dependencies");
-
-                    b.Navigation("Dependents");
-
-                    b.Navigation("Majors");
-
-                    b.Navigation("SemesterSubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.User", b =>
-                {
-                    b.Navigation("ContactInfo");
-
-                    b.Navigation("Documents");
-
-                    b.Navigation("EnrolledSemesterUserSubjects");
-
-                    b.Navigation("EnrolledSemesters");
-
-                    b.Navigation("EnrollmentInfo");
-
-                    b.Navigation("HighSchool");
-
-                    b.Navigation("TeachingSubjects");
-                });
-#pragma warning restore 612, 618
-        }
-    }
-}
Index: iknow-api/Migrations/20251216191800_InitialCreate.cs
===================================================================
--- iknow-api/Migrations/20251216191800_InitialCreate.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ 	(revision )
@@ -1,595 +1,0 @@
-﻿using System;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
-
-namespace iknow_api.Migrations
-{
-    /// <inheritdoc />
-    public partial class InitialCreate : Migration
-    {
-        /// <inheritdoc />
-        protected override void Up(MigrationBuilder migrationBuilder)
-        {
-            migrationBuilder.CreateTable(
-                name: "ActiveSemesters",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    Year = table.Column<int>(type: "integer", nullable: false),
-                    Type = table.Column<int>(type: "integer", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_ActiveSemesters", x => x.Id);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "Documents",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    Name = table.Column<string>(type: "text", nullable: true),
-                    Body = table.Column<string>(type: "text", nullable: true),
-                    Cost = table.Column<int>(type: "integer", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_Documents", x => x.Id);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "Majors",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    Name = table.Column<string>(type: "text", nullable: true)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_Majors", x => x.Id);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "Subjects",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    Name = table.Column<string>(type: "text", nullable: true),
-                    Code = table.Column<string>(type: "text", nullable: true),
-                    AwardedCredits = table.Column<int>(type: "integer", nullable: true),
-                    DependencyCredit = table.Column<int>(type: "integer", nullable: true)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_Subjects", x => x.Id);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "User",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    Name = table.Column<string>(type: "text", nullable: true),
-                    EMBG = table.Column<string>(type: "text", nullable: true),
-                    Surname = table.Column<string>(type: "text", nullable: true),
-                    Index = table.Column<string>(type: "text", nullable: true),
-                    Email = table.Column<string>(type: "text", nullable: true),
-                    PasswordHash = table.Column<string>(type: "text", nullable: true),
-                    MiddleName = table.Column<string>(type: "text", nullable: true),
-                    Gender = table.Column<string>(type: "text", nullable: true),
-                    Nationality = table.Column<string>(type: "text", nullable: true),
-                    Citizenship = table.Column<string>(type: "text", nullable: true),
-                    Bday = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
-                    CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
-                    Role = table.Column<int>(type: "integer", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_User", x => x.Id);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "DependencySubjects",
-                columns: table => new
-                {
-                    SubjectId = table.Column<int>(type: "integer", nullable: false),
-                    DependencyId = table.Column<int>(type: "integer", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_DependencySubjects", x => new { x.SubjectId, x.DependencyId });
-                    table.ForeignKey(
-                        name: "FK_DependencySubjects_Subjects_DependencyId",
-                        column: x => x.DependencyId,
-                        principalTable: "Subjects",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Restrict);
-                    table.ForeignKey(
-                        name: "FK_DependencySubjects_Subjects_SubjectId",
-                        column: x => x.SubjectId,
-                        principalTable: "Subjects",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Restrict);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "MajorSubjects",
-                columns: table => new
-                {
-                    MajorId = table.Column<int>(type: "integer", nullable: false),
-                    SubjectId = table.Column<int>(type: "integer", nullable: false),
-                    MandatorySemester = table.Column<int>(type: "integer", nullable: false),
-                    Accreditation = table.Column<int>(type: "integer", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_MajorSubjects", x => new { x.MajorId, x.SubjectId });
-                    table.ForeignKey(
-                        name: "FK_MajorSubjects_Majors_MajorId",
-                        column: x => x.MajorId,
-                        principalTable: "Majors",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                    table.ForeignKey(
-                        name: "FK_MajorSubjects_Subjects_SubjectId",
-                        column: x => x.SubjectId,
-                        principalTable: "Subjects",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "ContactInfo",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    City = table.Column<string>(type: "text", nullable: true),
-                    Address = table.Column<string>(type: "text", nullable: true),
-                    Municipality = table.Column<string>(type: "text", nullable: true),
-                    PhoneNumber = table.Column<string>(type: "text", nullable: true),
-                    MicrosoftEmail = table.Column<string>(type: "text", nullable: true),
-                    UserId = table.Column<int>(type: "integer", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_ContactInfo", x => x.Id);
-                    table.ForeignKey(
-                        name: "FK_ContactInfo_User_UserId",
-                        column: x => x.UserId,
-                        principalTable: "User",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "EnrolledSemesters",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false),
-                    UserId = table.Column<int>(type: "integer", nullable: false),
-                    QuotaType = table.Column<int>(type: "integer", nullable: false),
-                    MajorId = table.Column<int>(type: "integer", nullable: false),
-                    StudentComment = table.Column<string>(type: "text", nullable: true),
-                    Note = table.Column<string>(type: "text", nullable: true),
-                    CratedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
-                    LastChange = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
-                    Verified = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
-                    SemesterId = table.Column<int>(type: "integer", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_EnrolledSemesters", x => x.Id);
-                    table.ForeignKey(
-                        name: "FK_EnrolledSemesters_ActiveSemesters_Id",
-                        column: x => x.Id,
-                        principalTable: "ActiveSemesters",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Restrict);
-                    table.ForeignKey(
-                        name: "FK_EnrolledSemesters_Majors_MajorId",
-                        column: x => x.MajorId,
-                        principalTable: "Majors",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                    table.ForeignKey(
-                        name: "FK_EnrolledSemesters_User_UserId",
-                        column: x => x.UserId,
-                        principalTable: "User",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "EnrollmentInfo",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    EnrollmentYear = table.Column<int>(type: "integer", nullable: false),
-                    Quota = table.Column<int>(type: "integer", nullable: false),
-                    MajorId = table.Column<int>(type: "integer", nullable: false),
-                    UserId = table.Column<int>(type: "integer", nullable: false),
-                    StudyType = table.Column<string>(type: "text", nullable: true),
-                    StudyStatus = table.Column<string>(type: "text", nullable: true)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_EnrollmentInfo", x => x.Id);
-                    table.ForeignKey(
-                        name: "FK_EnrollmentInfo_Majors_MajorId",
-                        column: x => x.MajorId,
-                        principalTable: "Majors",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                    table.ForeignKey(
-                        name: "FK_EnrollmentInfo_User_UserId",
-                        column: x => x.UserId,
-                        principalTable: "User",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "HighSchool",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    GPA = table.Column<float>(type: "real", nullable: false),
-                    HighSchoolType = table.Column<int>(type: "integer", nullable: false),
-                    UserId = table.Column<int>(type: "integer", nullable: false),
-                    StudyLanguage = table.Column<string>(type: "text", nullable: true)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_HighSchool", x => x.Id);
-                    table.ForeignKey(
-                        name: "FK_HighSchool_User_UserId",
-                        column: x => x.UserId,
-                        principalTable: "User",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "ProfessorSubjects",
-                columns: table => new
-                {
-                    ProfessorId = table.Column<int>(type: "integer", nullable: false),
-                    SemesterId = table.Column<int>(type: "integer", nullable: false),
-                    SubjectId = table.Column<int>(type: "integer", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_ProfessorSubjects", x => new { x.ProfessorId, x.SemesterId, x.SubjectId });
-                    table.ForeignKey(
-                        name: "FK_ProfessorSubjects_ActiveSemesters_SemesterId",
-                        column: x => x.SemesterId,
-                        principalTable: "ActiveSemesters",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                    table.ForeignKey(
-                        name: "FK_ProfessorSubjects_Subjects_SubjectId",
-                        column: x => x.SubjectId,
-                        principalTable: "Subjects",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                    table.ForeignKey(
-                        name: "FK_ProfessorSubjects_User_ProfessorId",
-                        column: x => x.ProfessorId,
-                        principalTable: "User",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "RefreshToken",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    UserId = table.Column<int>(type: "integer", nullable: false),
-                    Token = table.Column<string>(type: "text", nullable: true),
-                    ExpiresAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
-                    IsValid = table.Column<bool>(type: "boolean", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_RefreshToken", x => x.Id);
-                    table.ForeignKey(
-                        name: "FK_RefreshToken_User_UserId",
-                        column: x => x.UserId,
-                        principalTable: "User",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "UserDocuments",
-                columns: table => new
-                {
-                    UserId = table.Column<int>(type: "integer", nullable: false),
-                    DocumentId = table.Column<int>(type: "integer", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_UserDocuments", x => new { x.UserId, x.DocumentId });
-                    table.ForeignKey(
-                        name: "FK_UserDocuments_Documents_DocumentId",
-                        column: x => x.DocumentId,
-                        principalTable: "Documents",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                    table.ForeignKey(
-                        name: "FK_UserDocuments_User_UserId",
-                        column: x => x.UserId,
-                        principalTable: "User",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "Payments",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    UserId = table.Column<int>(type: "integer", nullable: false),
-                    EnrollmentInfoId = table.Column<int>(type: "integer", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_Payments", x => x.Id);
-                    table.ForeignKey(
-                        name: "FK_Payments_EnrolledSemesters_EnrollmentInfoId",
-                        column: x => x.EnrollmentInfoId,
-                        principalTable: "EnrolledSemesters",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                    table.ForeignKey(
-                        name: "FK_Payments_User_UserId",
-                        column: x => x.UserId,
-                        principalTable: "User",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "SemesterSubjects",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    UserId = table.Column<int>(type: "integer", nullable: false),
-                    EnrolledSemesterId = table.Column<int>(type: "integer", nullable: false),
-                    SubjectId = table.Column<int>(type: "integer", nullable: false),
-                    ProfessorId = table.Column<int>(type: "integer", nullable: false),
-                    Signature = table.Column<bool>(type: "boolean", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_SemesterSubjects", x => x.Id);
-                    table.ForeignKey(
-                        name: "FK_SemesterSubjects_EnrolledSemesters_EnrolledSemesterId",
-                        column: x => x.EnrolledSemesterId,
-                        principalTable: "EnrolledSemesters",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Restrict);
-                    table.ForeignKey(
-                        name: "FK_SemesterSubjects_Subjects_SubjectId",
-                        column: x => x.SubjectId,
-                        principalTable: "Subjects",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Restrict);
-                    table.ForeignKey(
-                        name: "FK_SemesterSubjects_User_ProfessorId",
-                        column: x => x.ProfessorId,
-                        principalTable: "User",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Restrict);
-                    table.ForeignKey(
-                        name: "FK_SemesterSubjects_User_UserId",
-                        column: x => x.UserId,
-                        principalTable: "User",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Restrict);
-                });
-
-            migrationBuilder.CreateTable(
-                name: "PassedSubjects",
-                columns: table => new
-                {
-                    Id = table.Column<int>(type: "integer", nullable: false)
-                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
-                    SemesterSubjectId = table.Column<int>(type: "integer", nullable: false),
-                    Grade = table.Column<int>(type: "integer", nullable: false),
-                    DatePassed = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
-                },
-                constraints: table =>
-                {
-                    table.PrimaryKey("PK_PassedSubjects", x => x.Id);
-                    table.ForeignKey(
-                        name: "FK_PassedSubjects_SemesterSubjects_SemesterSubjectId",
-                        column: x => x.SemesterSubjectId,
-                        principalTable: "SemesterSubjects",
-                        principalColumn: "Id",
-                        onDelete: ReferentialAction.Cascade);
-                });
-
-            migrationBuilder.InsertData(
-                table: "Majors",
-                columns: new[] { "Id", "Name" },
-                values: new object[,]
-                {
-                    { 1, "PIT" },
-                    { 2, "SIIS" },
-                    { 3, "SEIS" },
-                    { 4, "KN" }
-                });
-
-            migrationBuilder.CreateIndex(
-                name: "IX_ContactInfo_UserId",
-                table: "ContactInfo",
-                column: "UserId",
-                unique: true);
-
-            migrationBuilder.CreateIndex(
-                name: "IX_DependencySubjects_DependencyId",
-                table: "DependencySubjects",
-                column: "DependencyId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_EnrolledSemesters_MajorId",
-                table: "EnrolledSemesters",
-                column: "MajorId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_EnrolledSemesters_UserId",
-                table: "EnrolledSemesters",
-                column: "UserId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_EnrollmentInfo_MajorId",
-                table: "EnrollmentInfo",
-                column: "MajorId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_EnrollmentInfo_UserId",
-                table: "EnrollmentInfo",
-                column: "UserId",
-                unique: true);
-
-            migrationBuilder.CreateIndex(
-                name: "IX_HighSchool_UserId",
-                table: "HighSchool",
-                column: "UserId",
-                unique: true);
-
-            migrationBuilder.CreateIndex(
-                name: "IX_MajorSubjects_SubjectId",
-                table: "MajorSubjects",
-                column: "SubjectId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_PassedSubjects_SemesterSubjectId",
-                table: "PassedSubjects",
-                column: "SemesterSubjectId",
-                unique: true);
-
-            migrationBuilder.CreateIndex(
-                name: "IX_Payments_EnrollmentInfoId",
-                table: "Payments",
-                column: "EnrollmentInfoId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_Payments_UserId",
-                table: "Payments",
-                column: "UserId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_ProfessorSubjects_SemesterId",
-                table: "ProfessorSubjects",
-                column: "SemesterId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_ProfessorSubjects_SubjectId",
-                table: "ProfessorSubjects",
-                column: "SubjectId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_RefreshToken_UserId",
-                table: "RefreshToken",
-                column: "UserId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_SemesterSubjects_EnrolledSemesterId",
-                table: "SemesterSubjects",
-                column: "EnrolledSemesterId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_SemesterSubjects_ProfessorId",
-                table: "SemesterSubjects",
-                column: "ProfessorId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_SemesterSubjects_SubjectId",
-                table: "SemesterSubjects",
-                column: "SubjectId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_SemesterSubjects_UserId",
-                table: "SemesterSubjects",
-                column: "UserId");
-
-            migrationBuilder.CreateIndex(
-                name: "IX_UserDocuments_DocumentId",
-                table: "UserDocuments",
-                column: "DocumentId");
-        }
-
-        /// <inheritdoc />
-        protected override void Down(MigrationBuilder migrationBuilder)
-        {
-            migrationBuilder.DropTable(
-                name: "ContactInfo");
-
-            migrationBuilder.DropTable(
-                name: "DependencySubjects");
-
-            migrationBuilder.DropTable(
-                name: "EnrollmentInfo");
-
-            migrationBuilder.DropTable(
-                name: "HighSchool");
-
-            migrationBuilder.DropTable(
-                name: "MajorSubjects");
-
-            migrationBuilder.DropTable(
-                name: "PassedSubjects");
-
-            migrationBuilder.DropTable(
-                name: "Payments");
-
-            migrationBuilder.DropTable(
-                name: "ProfessorSubjects");
-
-            migrationBuilder.DropTable(
-                name: "RefreshToken");
-
-            migrationBuilder.DropTable(
-                name: "UserDocuments");
-
-            migrationBuilder.DropTable(
-                name: "SemesterSubjects");
-
-            migrationBuilder.DropTable(
-                name: "Documents");
-
-            migrationBuilder.DropTable(
-                name: "EnrolledSemesters");
-
-            migrationBuilder.DropTable(
-                name: "Subjects");
-
-            migrationBuilder.DropTable(
-                name: "ActiveSemesters");
-
-            migrationBuilder.DropTable(
-                name: "Majors");
-
-            migrationBuilder.DropTable(
-                name: "User");
-        }
-    }
-}
Index: iknow-api/Migrations/AppDbContextModelSnapshot.cs
===================================================================
--- iknow-api/Migrations/AppDbContextModelSnapshot.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ 	(revision )
@@ -1,787 +1,0 @@
-﻿// <auto-generated />
-using System;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-using iknow_api.Data;
-
-#nullable disable
-
-namespace iknow_api.Migrations
-{
-    [DbContext(typeof(AppDbContext))]
-    partial class AppDbContextModelSnapshot : ModelSnapshot
-    {
-        protected override void BuildModel(ModelBuilder modelBuilder)
-        {
-#pragma warning disable 612, 618
-            modelBuilder
-                .HasAnnotation("ProductVersion", "9.0.10")
-                .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
-            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
-            modelBuilder.Entity("iknow_api.Models.ActiveSemesters", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<int>("Type")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("Year")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("ActiveSemesters");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.ContactInfo", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<string>("Address")
-                        .HasColumnType("text");
-
-                    b.Property<string>("City")
-                        .HasColumnType("text");
-
-                    b.Property<string>("MicrosoftEmail")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Municipality")
-                        .HasColumnType("text");
-
-                    b.Property<string>("PhoneNumber")
-                        .HasColumnType("text");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("UserId")
-                        .IsUnique();
-
-                    b.ToTable("ContactInfo");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.DependencySubject", b =>
-                {
-                    b.Property<int>("SubjectId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("DependencyId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("SubjectId", "DependencyId");
-
-                    b.HasIndex("DependencyId");
-
-                    b.ToTable("DependencySubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Documents", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<string>("Body")
-                        .HasColumnType("text");
-
-                    b.Property<int>("Cost")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("Name")
-                        .HasColumnType("text");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("Documents");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.EnrolledSemesters", b =>
-                {
-                    b.Property<int>("Id")
-                        .HasColumnType("integer");
-
-                    b.Property<DateTime>("CratedAt")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<DateTime>("LastChange")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<int>("MajorId")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("Note")
-                        .HasColumnType("text");
-
-                    b.Property<int>("QuotaType")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("SemesterId")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("StudentComment")
-                        .HasColumnType("text");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.Property<DateTime>("Verified")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("MajorId");
-
-                    b.HasIndex("UserId");
-
-                    b.ToTable("EnrolledSemesters");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.EnrollmentInfo", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<int>("EnrollmentYear")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("MajorId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("Quota")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("StudyStatus")
-                        .HasColumnType("text");
-
-                    b.Property<string>("StudyType")
-                        .HasColumnType("text");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("MajorId");
-
-                    b.HasIndex("UserId")
-                        .IsUnique();
-
-                    b.ToTable("EnrollmentInfo");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.HighSchool", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<float>("GPA")
-                        .HasColumnType("real");
-
-                    b.Property<int>("HighSchoolType")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("StudyLanguage")
-                        .HasColumnType("text");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("UserId")
-                        .IsUnique();
-
-                    b.ToTable("HighSchool");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Major", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<string>("Name")
-                        .HasColumnType("text");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("Majors");
-
-                    b.HasData(
-                        new
-                        {
-                            Id = 1,
-                            Name = "PIT"
-                        },
-                        new
-                        {
-                            Id = 2,
-                            Name = "SIIS"
-                        },
-                        new
-                        {
-                            Id = 3,
-                            Name = "SEIS"
-                        },
-                        new
-                        {
-                            Id = 4,
-                            Name = "KN"
-                        });
-                });
-
-            modelBuilder.Entity("iknow_api.Models.MajorSubjects", b =>
-                {
-                    b.Property<int>("MajorId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("SubjectId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("Accreditation")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("MandatorySemester")
-                        .HasColumnType("integer");
-
-                    b.HasKey("MajorId", "SubjectId");
-
-                    b.HasIndex("SubjectId");
-
-                    b.ToTable("MajorSubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.PassedSubject", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<DateTime>("DatePassed")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<int>("Grade")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("SemesterSubjectId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("SemesterSubjectId")
-                        .IsUnique();
-
-                    b.ToTable("PassedSubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Payment", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<int>("EnrollmentInfoId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("EnrollmentInfoId");
-
-                    b.HasIndex("UserId");
-
-                    b.ToTable("Payments");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.ProfessorSubjects", b =>
-                {
-                    b.Property<int>("ProfessorId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("SemesterId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("SubjectId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("ProfessorId", "SemesterId", "SubjectId");
-
-                    b.HasIndex("SemesterId");
-
-                    b.HasIndex("SubjectId");
-
-                    b.ToTable("ProfessorSubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.RefreshToken", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<DateTime>("ExpiresAt")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<bool>("IsValid")
-                        .HasColumnType("boolean");
-
-                    b.Property<string>("Token")
-                        .HasColumnType("text");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("UserId");
-
-                    b.ToTable("RefreshToken");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.SemesterSubject", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<int>("EnrolledSemesterId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("ProfessorId")
-                        .HasColumnType("integer");
-
-                    b.Property<bool>("Signature")
-                        .HasColumnType("boolean");
-
-                    b.Property<int>("SubjectId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("EnrolledSemesterId");
-
-                    b.HasIndex("ProfessorId");
-
-                    b.HasIndex("SubjectId");
-
-                    b.HasIndex("UserId");
-
-                    b.ToTable("SemesterSubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Subject", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<int?>("AwardedCredits")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("Code")
-                        .HasColumnType("text");
-
-                    b.Property<int?>("DependencyCredit")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("Name")
-                        .HasColumnType("text");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("Subjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.User", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<DateTime>("Bday")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<string>("Citizenship")
-                        .HasColumnType("text");
-
-                    b.Property<DateTime>("CreatedAt")
-                        .HasColumnType("timestamp with time zone");
-
-                    b.Property<string>("EMBG")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Email")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Gender")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Index")
-                        .HasColumnType("text");
-
-                    b.Property<string>("MiddleName")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Name")
-                        .HasColumnType("text");
-
-                    b.Property<string>("Nationality")
-                        .HasColumnType("text");
-
-                    b.Property<string>("PasswordHash")
-                        .HasColumnType("text");
-
-                    b.Property<int>("Role")
-                        .HasColumnType("integer");
-
-                    b.Property<string>("Surname")
-                        .HasColumnType("text");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.UserDocuments", b =>
-                {
-                    b.Property<int>("UserId")
-                        .HasColumnType("integer");
-
-                    b.Property<int>("DocumentId")
-                        .HasColumnType("integer");
-
-                    b.HasKey("UserId", "DocumentId");
-
-                    b.HasIndex("DocumentId");
-
-                    b.ToTable("UserDocuments");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.ContactInfo", b =>
-                {
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithOne("ContactInfo")
-                        .HasForeignKey("iknow_api.Models.ContactInfo", "UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.DependencySubject", b =>
-                {
-                    b.HasOne("iknow_api.Models.Subject", "Dependency")
-                        .WithMany("Dependents")
-                        .HasForeignKey("DependencyId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.Subject", "Subject")
-                        .WithMany("Dependencies")
-                        .HasForeignKey("SubjectId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.Navigation("Dependency");
-
-                    b.Navigation("Subject");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.EnrolledSemesters", b =>
-                {
-                    b.HasOne("iknow_api.Models.ActiveSemesters", "Semester")
-                        .WithMany("EnrolledSemesters")
-                        .HasForeignKey("Id")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.Major", "Major")
-                        .WithMany()
-                        .HasForeignKey("MajorId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithMany()
-                        .HasForeignKey("UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("Major");
-
-                    b.Navigation("Semester");
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.EnrollmentInfo", b =>
-                {
-                    b.HasOne("iknow_api.Models.Major", "Major")
-                        .WithMany()
-                        .HasForeignKey("MajorId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithOne("EnrollmentInfo")
-                        .HasForeignKey("iknow_api.Models.EnrollmentInfo", "UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("Major");
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.HighSchool", b =>
-                {
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithOne("HighSchool")
-                        .HasForeignKey("iknow_api.Models.HighSchool", "UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.MajorSubjects", b =>
-                {
-                    b.HasOne("iknow_api.Models.Major", "Majors")
-                        .WithMany("Subjects")
-                        .HasForeignKey("MajorId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.Subject", "Subjects")
-                        .WithMany("Majors")
-                        .HasForeignKey("SubjectId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("Majors");
-
-                    b.Navigation("Subjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.PassedSubject", b =>
-                {
-                    b.HasOne("iknow_api.Models.SemesterSubject", "SemesterSubject")
-                        .WithOne("PassedSubject")
-                        .HasForeignKey("iknow_api.Models.PassedSubject", "SemesterSubjectId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("SemesterSubject");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Payment", b =>
-                {
-                    b.HasOne("iknow_api.Models.EnrolledSemesters", "EnrolledSemesters")
-                        .WithMany("Users")
-                        .HasForeignKey("EnrollmentInfoId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithMany("EnrolledSemesters")
-                        .HasForeignKey("UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("EnrolledSemesters");
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.ProfessorSubjects", b =>
-                {
-                    b.HasOne("iknow_api.Models.User", "Professor")
-                        .WithMany()
-                        .HasForeignKey("ProfessorId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.ActiveSemesters", "Semester")
-                        .WithMany()
-                        .HasForeignKey("SemesterId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.Subject", "Subject")
-                        .WithMany()
-                        .HasForeignKey("SubjectId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("Professor");
-
-                    b.Navigation("Semester");
-
-                    b.Navigation("Subject");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.RefreshToken", b =>
-                {
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithMany()
-                        .HasForeignKey("UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.SemesterSubject", b =>
-                {
-                    b.HasOne("iknow_api.Models.EnrolledSemesters", "EnrolledSemester")
-                        .WithMany("SemesterSubjects")
-                        .HasForeignKey("EnrolledSemesterId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "Professor")
-                        .WithMany("TeachingSubjects")
-                        .HasForeignKey("ProfessorId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.Subject", "Subject")
-                        .WithMany("SemesterSubjects")
-                        .HasForeignKey("SubjectId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithMany("EnrolledSemesterUserSubjects")
-                        .HasForeignKey("UserId")
-                        .OnDelete(DeleteBehavior.Restrict)
-                        .IsRequired();
-
-                    b.Navigation("EnrolledSemester");
-
-                    b.Navigation("Professor");
-
-                    b.Navigation("Subject");
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.UserDocuments", b =>
-                {
-                    b.HasOne("iknow_api.Models.Documents", "Documents")
-                        .WithMany("User")
-                        .HasForeignKey("DocumentId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.HasOne("iknow_api.Models.User", "User")
-                        .WithMany("Documents")
-                        .HasForeignKey("UserId")
-                        .OnDelete(DeleteBehavior.Cascade)
-                        .IsRequired();
-
-                    b.Navigation("Documents");
-
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.ActiveSemesters", b =>
-                {
-                    b.Navigation("EnrolledSemesters");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Documents", b =>
-                {
-                    b.Navigation("User");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.EnrolledSemesters", b =>
-                {
-                    b.Navigation("SemesterSubjects");
-
-                    b.Navigation("Users");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Major", b =>
-                {
-                    b.Navigation("Subjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.SemesterSubject", b =>
-                {
-                    b.Navigation("PassedSubject");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.Subject", b =>
-                {
-                    b.Navigation("Dependencies");
-
-                    b.Navigation("Dependents");
-
-                    b.Navigation("Majors");
-
-                    b.Navigation("SemesterSubjects");
-                });
-
-            modelBuilder.Entity("iknow_api.Models.User", b =>
-                {
-                    b.Navigation("ContactInfo");
-
-                    b.Navigation("Documents");
-
-                    b.Navigation("EnrolledSemesterUserSubjects");
-
-                    b.Navigation("EnrolledSemesters");
-
-                    b.Navigation("EnrollmentInfo");
-
-                    b.Navigation("HighSchool");
-
-                    b.Navigation("TeachingSubjects");
-                });
-#pragma warning restore 612, 618
-        }
-    }
-}
Index: iknow-api/Models/EnrolledSemesters.cs
===================================================================
--- iknow-api/Models/EnrolledSemesters.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Models/EnrolledSemesters.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -14,6 +14,6 @@
         public string? Note { get; set; }
         public DateTime CratedAt { get; set; }
-        public DateTime LastChange { get; set; }
-        public DateTime Verified { get; set; }
+        public DateTime? LastChange { get; set; }
+        public DateTime? Verified { get; set; }
         public int SemesterId { get; set; }
         public ActiveSemesters? Semester { get; set; }
Index: iknow-api/Models/EnrollmentInfo.cs
===================================================================
--- iknow-api/Models/EnrollmentInfo.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ 	(revision )
@@ -1,24 +1,0 @@
-﻿using System.ComponentModel.DataAnnotations.Schema;
-using Microsoft.AspNetCore.SignalR;
-using Microsoft.Net.Http.Headers;
-
-namespace iknow_api.Models
-{
-    public enum Quota
-    {
-        drzavna, privatna, stipendija
-    }
-    public class EnrollmentInfo
-    {
-        public int Id { get; set; }
-        public int EnrollmentYear { get; set; }
-        public Quota Quota { get; set; }
-        public int MajorId { get; set; }
-        public Major? Major { get; set; }
-        public int UserId { get; set; }
-        public User? User { get; set; }
-        public string? StudyType { get; set; }
-        public string? StudyStatus { get; set; }
-
-    }
-}
Index: iknow-api/Models/HighSchool.cs
===================================================================
--- iknow-api/Models/HighSchool.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Models/HighSchool.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -1,4 +1,2 @@
-﻿using System.ComponentModel.DataAnnotations.Schema;
-
 namespace iknow_api.Models
 {
@@ -7,4 +5,5 @@
         Strucen, Gimnazija
     }
+
     public class HighSchool
     {
@@ -14,5 +13,4 @@
         public int UserId { get; set; }
         public User? User { get; set; }
-        public string? StudyLanguage { get; set; }
     }
 }
Index: iknow-api/Models/MajorSubjects.cs
===================================================================
--- iknow-api/Models/MajorSubjects.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Models/MajorSubjects.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -6,5 +6,4 @@
         public int SubjectId { get; set; }
         public int MandatorySemester { get; set; }
-        public int Accreditation { get; set; }
         public Major? Majors { get; set; }
         public Subject? Subjects { get; set; }
Index: iknow-api/Models/Payment.cs
===================================================================
--- iknow-api/Models/Payment.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Models/Payment.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -10,4 +10,5 @@
         public User? User { get; set; }
         public int EnrollmentInfoId { get; set; }
+        public int Amount { get; set; }
         public EnrolledSemesters? EnrolledSemesters { get; set; }
 
Index: iknow-api/Models/Quota.cs
===================================================================
--- iknow-api/Models/Quota.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Models/Quota.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,7 @@
+namespace iknow_api.Models
+{
+    public enum Quota
+    {
+        drzavna, privatna, stipendija
+    }
+}
Index: iknow-api/Models/SemesterSubjects.cs
===================================================================
--- iknow-api/Models/SemesterSubjects.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Models/SemesterSubjects.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -1,17 +1,18 @@
 namespace iknow_api.Models
 {
+    // The student is reached through EnrolledSemester.UserId; the ER model
+    // links SemestersSubjects to Users only through the professor.
     public class SemesterSubject
     {
-        public int Id { get; set; } 
-        
-        public int UserId { get; set; }                 
+        public int Id { get; set; }
+
         public int EnrolledSemesterId { get; set; }
         public int SubjectId { get; set; }
         public int ProfessorId { get; set; }
         public bool Signature { get; set; }
-        public User? User { get; set; }                 
+
         public EnrolledSemesters? EnrolledSemester { get; set; }
         public Subject? Subject { get; set; }
-        public User? Professor { get; set; }           
+        public User? Professor { get; set; }
         public PassedSubject? PassedSubject { get; set; }
     }
Index: iknow-api/Models/User.cs
===================================================================
--- iknow-api/Models/User.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Models/User.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -1,4 +1,2 @@
-
-
 namespace iknow_api.Models
 {
@@ -10,31 +8,32 @@
     }
 
+    // Attributes follow the Users entity in the ER model exactly.
     public class User
     {
-        internal object Payments;
-
         public int Id { get; set; }
         public string? Name { get; set; }
-        public string? EMBG {get; set; }
+        public string? EMBG { get; set; }
         public string? Surname { get; set; }
         public string? Index { get; set; }
         public string? Email { get; set; }
         public string? PasswordHash { get; set; }
-        public string? MiddleName { get; set; }
-        public string? Gender { get; set; }
-        public string? Nationality { get; set; }
-        public string? Citizenship { get; set; }
-        public DateTime Bday { get; set; }
+        public DateTime? Bday { get; set; }
         public DateTime CreatedAt { get; set; }
         public UserRole Role { get; set; }
+        public Quota? Quota { get; set; }
+        public int? EnrollmentYear { get; set; }
+
         public HighSchool? HighSchool { get; set; }
         public ContactInfo? ContactInfo { get; set; }
-        public EnrollmentInfo? EnrollmentInfo { get; set; }
         public ICollection<UserDocuments>? Documents { get; set; }
-        public ICollection<Payment>? EnrolledSemesters { get; set; }
-        public ICollection<SemesterSubject>? EnrolledSemesterUserSubjects { get; set; }
 
+        // Named for the relationship it carries: Users 1 --pays-- N Payment.
+        public ICollection<Payment>? Payments { get; set; }
+
+        // Users 1 --submits-- N EnrolledSemesters
+        public ICollection<EnrolledSemesters>? Enrolments { get; set; }
+
+        // Users 1 --teaches-- N SemestersSubjects
         public ICollection<SemesterSubject>? TeachingSubjects { get; set; }
-
     }
 }
Index: iknow-api/Program.cs
===================================================================
--- iknow-api/Program.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Program.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -2,4 +2,5 @@
 using System.Text.Json.Serialization;
 using iknow_api.Data;
+using iknow_api.Models;
 using iknow_api.Repositories;
 using iknow_api.Services;
@@ -59,7 +60,21 @@
 builder.Services.AddOpenApi();
 
-// Register DbContext
+// Register DbContext.
+// The database lives behind the SSH tunnel: tunnel_scripta.cmd maps
+// localhost:9999 to the faculty Postgres server. Start it before the API.
+// The enum labels come from sql/ddl.sql, so each CLR enum is mapped onto its
+// Postgres type by name; PgEnumLabels covers the members whose label is not
+// simply the lowercased member name.
 builder.Services.AddDbContext<AppDbContext>(options =>
-    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
+    options.UseNpgsql(
+        builder.Configuration.GetConnectionString("DefaultConnection"),
+        npgsql =>
+        {
+            npgsql.MapEnum<UserRole>("user_role", AppDbContext.ProjectSchema, PgEnumLabels.UserRole);
+            npgsql.MapEnum<HighSchoolType>("hs_type", AppDbContext.ProjectSchema, PgEnumLabels.Lowercase);
+            npgsql.MapEnum<Quota>("quota_type", AppDbContext.ProjectSchema, PgEnumLabels.Lowercase);
+            npgsql.MapEnum<sType>("semester_type", AppDbContext.ProjectSchema, PgEnumLabels.Lowercase);
+            npgsql.MapEnum<Grade>("grade_type", AppDbContext.ProjectSchema, PgEnumLabels.Grade);
+        }));
 
 // Register your services
@@ -71,4 +86,8 @@
 builder.Services.AddScoped<IUserRepository, UserRepository>(); 
 builder.Services.AddScoped<IRefreshTokenRepository, RefreshTokenRepository>(); 
+builder.Services.AddScoped<IProfRepository, ProfRepository>();
+builder.Services.AddScoped<IProfService, ProfService>();
+builder.Services.AddScoped<IEnrollmentService, EnrollmentService>();
+builder.Services.AddScoped<IAdminService, AdminService>();
 builder.Services.AddAuthorization();
 var app = builder.Build();
Index: iknow-api/Repository/Implementations/ProfRepository.cs
===================================================================
--- iknow-api/Repository/Implementations/ProfRepository.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Repository/Implementations/ProfRepository.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,77 @@
+using iknow_api.Data;
+using iknow_api.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace iknow_api.Repositories
+{
+    public class ProfRepository : IProfRepository
+    {
+        private readonly AppDbContext _context;
+
+        public ProfRepository(AppDbContext context)
+        {
+            _context = context;
+        }
+
+        /// <summary>
+        /// A professor teaches a subject for a given enrolment, so the students
+        /// are reached through semesters_subjects.professor_id and the student
+        /// through the enrolment - matching the ER model, which does not link
+        /// SemestersSubjects to a student directly.
+        /// </summary>
+        private IQueryable<SemesterSubject> TaughtBy(int professorId) =>
+            _context.SemesterSubjects
+                .Where(ss => ss.ProfessorId == professorId)
+                .Include(ss => ss.Subject)
+                .Include(ss => ss.PassedSubject)
+                .Include(ss => ss.EnrolledSemester!)
+                    .ThenInclude(es => es.User)
+                .Include(ss => ss.EnrolledSemester!)
+                    .ThenInclude(es => es.Semester);
+
+        public async Task<List<SemesterSubject>> GetTaughtSemesterSubjectsAsync(int professorId) =>
+            await TaughtBy(professorId)
+                .AsNoTracking()
+                .AsSplitQuery()
+                .ToListAsync();
+
+        public async Task<SemesterSubject?> FindTaughtSemesterSubjectAsync(
+            int professorId, int studentId, int subjectId)
+        {
+            var candidates = await TaughtBy(professorId)
+                .Where(ss => ss.SubjectId == subjectId
+                          && ss.EnrolledSemester!.UserId == studentId)
+                .AsSplitQuery()
+                .ToListAsync();
+
+            // Most recent enrolment first. Semesters are labelled Year/Year+1
+            // throughout the app, so within one year summer follows winter.
+            return candidates
+                .OrderByDescending(ss => ss.EnrolledSemester!.Semester!.Year)
+                .ThenByDescending(ss => ss.EnrolledSemester!.Semester!.Type == sType.summer)
+                .FirstOrDefault();
+        }
+
+        public async Task<PassedSubject?> GetPassedSubjectAsync(int semesterSubjectId) =>
+            await _context.PassedSubjects
+                .FirstOrDefaultAsync(ps => ps.SemesterSubjectId == semesterSubjectId);
+
+        public async Task AddPassedSubjectAsync(PassedSubject passed)
+        {
+            _context.PassedSubjects.Add(passed);
+            await _context.SaveChangesAsync();
+        }
+
+        public async Task UpdatePassedSubjectAsync(PassedSubject passed)
+        {
+            _context.PassedSubjects.Update(passed);
+            await _context.SaveChangesAsync();
+        }
+
+        public async Task RemovePassedSubjectAsync(PassedSubject passed)
+        {
+            _context.PassedSubjects.Remove(passed);
+            await _context.SaveChangesAsync();
+        }
+    }
+}
Index: iknow-api/Repository/Implementations/RefreshTokenRepository.cs
===================================================================
--- iknow-api/Repository/Implementations/RefreshTokenRepository.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Repository/Implementations/RefreshTokenRepository.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -41,5 +41,5 @@
                     rt.Token == refreshTokenDto.token &&
                     rt.IsValid &&
-                    rt.ExpiresAt > DateTime.UtcNow);
+                    rt.ExpiresAt > DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified));
 
             return token != null;
Index: iknow-api/Repository/Implementations/UserRepository.cs
===================================================================
--- iknow-api/Repository/Implementations/UserRepository.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Repository/Implementations/UserRepository.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -28,6 +28,12 @@
             return await _context.User
                 .Include(u => u.ContactInfo)
-                .Include(u => u.EnrollmentInfo)
                 .Include(u => u.HighSchool)
+                // The study programme is reached through the enrolment, since
+                // Major hangs off EnrolledSemesters rather than off Users.
+                .Include(u => u.Enrolments!)
+                    .ThenInclude(es => es.Major)
+                .Include(u => u.Enrolments!)
+                    .ThenInclude(es => es.Semester)
+                .AsSplitQuery()
                 .FirstOrDefaultAsync(u => u.Id == id);
         }
@@ -48,9 +54,4 @@
             await _context.SaveChangesAsync();
         }
-        public async Task AddEnrollmentAsync(EnrollmentInfo enrollment)
-        {
-            _context.EnrollmentInfo.Add(enrollment);
-            await _context.SaveChangesAsync();
-        }   
         public async Task AddHighSchoolAsync(HighSchool highSchool)
         {
@@ -89,5 +90,7 @@
                 .Include(ps => ps.SemesterSubject)
                     .ThenInclude(ss => ss.Professor)
-                .Where(ps => ps.SemesterSubject.UserId == id)
+                // The ER model reaches the student through the enrolment,
+                // not through a user_id on semesters_subjects.
+                .Where(ps => ps.SemesterSubject.EnrolledSemester.UserId == id)
                 .ToListAsync();
         }
Index: iknow-api/Repository/Interface/IProfRepository.cs
===================================================================
--- iknow-api/Repository/Interface/IProfRepository.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Repository/Interface/IProfRepository.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,26 @@
+using iknow_api.Models;
+
+namespace iknow_api.Repositories
+{
+    public interface IProfRepository
+    {
+        /// <summary>
+        /// Every semester-subject row taught by this professor, with the
+        /// enrolment, student, subject, semester and grade loaded.
+        /// </summary>
+        Task<List<SemesterSubject>> GetTaughtSemesterSubjectsAsync(int professorId);
+
+        /// <summary>
+        /// The semester-subject row this professor teaches for one student and
+        /// subject. When a student has taken the subject more than once, the
+        /// most recent enrolment wins. Null when the professor does not teach
+        /// that student in that subject.
+        /// </summary>
+        Task<SemesterSubject?> FindTaughtSemesterSubjectAsync(int professorId, int studentId, int subjectId);
+
+        Task<PassedSubject?> GetPassedSubjectAsync(int semesterSubjectId);
+        Task AddPassedSubjectAsync(PassedSubject passed);
+        Task UpdatePassedSubjectAsync(PassedSubject passed);
+        Task RemovePassedSubjectAsync(PassedSubject passed);
+    }
+}
Index: iknow-api/Repository/Interface/IUserRepository.cs
===================================================================
--- iknow-api/Repository/Interface/IUserRepository.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Repository/Interface/IUserRepository.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -1,3 +1,3 @@
-﻿using iknow_api.Models;
+using iknow_api.Models;
 namespace iknow_api.Repositories
 {
@@ -8,5 +8,4 @@
         Task AddUserAsync(User user);
         Task AddContactAsync(ContactInfo contactInfo);
-        Task AddEnrollmentAsync(EnrollmentInfo enrollment);
         Task AddHighSchoolAsync(HighSchool highSchool);
         Task<int> GetUsersCountAsync();
Index: iknow-api/Services/Implementations/AdminService.cs
===================================================================
--- iknow-api/Services/Implementations/AdminService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Services/Implementations/AdminService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,445 @@
+using iknow_api.Data;
+using iknow_api.DTOs;
+using iknow_api.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace iknow_api.Services
+{
+    /// <summary>
+    /// Backs UC012 (subjects), UC013 (active semesters) and UC014 (professor
+    /// assignments). Every method reports constraint problems as a sentence
+    /// rather than letting a database exception reach the controller.
+    /// </summary>
+    public class AdminService : IAdminService
+    {
+        private readonly AppDbContext _context;
+
+        public AdminService(AppDbContext context)
+        {
+            _context = context;
+        }
+
+        private static string SemesterName(ActiveSemesters s) =>
+            $"{(s.Type == sType.winter ? "Зимски" : "Летен")}({s.Year}/{s.Year + 1})";
+
+        // ============================================================
+        //  UC012 - subjects
+        // ============================================================
+
+        public async Task<List<AdminSubjectDto>> GetSubjectsAsync()
+        {
+            var subjects = await _context.Subjects.AsNoTracking().ToListAsync();
+
+            var majorLinks = await _context.MajorSubjects.AsNoTracking()
+                .Include(ms => ms.Majors).ToListAsync();
+
+            var prerequisites = await _context.DependencySubjects.AsNoTracking().ToListAsync();
+
+            // A subject that students already took cannot be deleted.
+            var enrolledCounts = await _context.SemesterSubjects.AsNoTracking()
+                .GroupBy(ss => ss.SubjectId)
+                .Select(g => new { SubjectId = g.Key, Count = g.Count() })
+                .ToDictionaryAsync(x => x.SubjectId, x => x.Count);
+
+            var byId = subjects.ToDictionary(s => s.Id);
+
+            return subjects
+                .OrderBy(s => s.Code)
+                .Select(s => new AdminSubjectDto
+                {
+                    Id = s.Id,
+                    Name = s.Name,
+                    Code = s.Code,
+                    AwardedCredits = s.AwardedCredits ?? 0,
+                    DependencyCredit = s.DependencyCredit,
+                    EnrolledCount = enrolledCounts.TryGetValue(s.Id, out var c) ? c : 0,
+                    Majors = majorLinks
+                        .Where(ms => ms.SubjectId == s.Id)
+                        .Select(ms => new SubjectMajorDto
+                        {
+                            MajorId = ms.MajorId,
+                            MajorName = ms.Majors?.Name,
+                            MandatorySemester = ms.MandatorySemester
+                        })
+                        .OrderBy(m => m.MajorName)
+                        .ToList(),
+                    Prerequisites = prerequisites
+                        .Where(d => d.SubjectId == s.Id && byId.ContainsKey(d.DependencyId))
+                        .Select(d => new SubjectRefDto
+                        {
+                            Id = d.DependencyId,
+                            Name = byId[d.DependencyId].Name,
+                            Code = byId[d.DependencyId].Code
+                        })
+                        .OrderBy(p => p.Code)
+                        .ToList()
+                })
+                .ToList();
+        }
+
+        public async Task<AdminResultDto> CreateSubjectAsync(SubjectWriteDto request)
+        {
+            if (string.IsNullOrWhiteSpace(request.Name) || string.IsNullOrWhiteSpace(request.Code))
+            {
+                return Fail("Name and code are required.");
+            }
+            if (request.AwardedCredits <= 0)
+            {
+                return Fail("Awarded credits must be greater than zero.");
+            }
+            // subjects.name and subjects.code are both UNIQUE.
+            if (await _context.Subjects.AnyAsync(s => s.Name == request.Name))
+            {
+                return Fail($"A subject named '{request.Name}' already exists.");
+            }
+            if (await _context.Subjects.AnyAsync(s => s.Code == request.Code))
+            {
+                return Fail($"Subject code '{request.Code}' is already taken.");
+            }
+
+            var subject = new Subject
+            {
+                Name = request.Name,
+                Code = request.Code,
+                AwardedCredits = request.AwardedCredits,
+                DependencyCredit = request.DependencyCredit
+            };
+            _context.Subjects.Add(subject);
+            await _context.SaveChangesAsync();
+
+            return Ok($"Subject '{subject.Name}' created.", subject.Id);
+        }
+
+        public async Task<AdminResultDto> UpdateSubjectAsync(int subjectId, SubjectWriteDto request)
+        {
+            var subject = await _context.Subjects.FirstOrDefaultAsync(s => s.Id == subjectId);
+            if (subject is null) return Fail("Subject not found.");
+
+            if (string.IsNullOrWhiteSpace(request.Name) || string.IsNullOrWhiteSpace(request.Code))
+            {
+                return Fail("Name and code are required.");
+            }
+            if (request.AwardedCredits <= 0)
+            {
+                return Fail("Awarded credits must be greater than zero.");
+            }
+            if (await _context.Subjects.AnyAsync(s => s.Name == request.Name && s.Id != subjectId))
+            {
+                return Fail($"Another subject is already named '{request.Name}'.");
+            }
+            if (await _context.Subjects.AnyAsync(s => s.Code == request.Code && s.Id != subjectId))
+            {
+                return Fail($"Subject code '{request.Code}' is already taken.");
+            }
+
+            subject.Name = request.Name;
+            subject.Code = request.Code;
+            subject.AwardedCredits = request.AwardedCredits;
+            subject.DependencyCredit = request.DependencyCredit;
+            await _context.SaveChangesAsync();
+
+            return Ok($"Subject '{subject.Name}' updated.", subject.Id);
+        }
+
+        public async Task<AdminResultDto> DeleteSubjectAsync(int subjectId)
+        {
+            var subject = await _context.Subjects.FirstOrDefaultAsync(s => s.Id == subjectId);
+            if (subject is null) return Fail("Subject not found.");
+
+            // semesters_subjects references subjects, so a taken subject cannot go.
+            var taken = await _context.SemesterSubjects.CountAsync(ss => ss.SubjectId == subjectId);
+            if (taken > 0)
+            {
+                return Fail($"Cannot delete: {taken} enrolment(s) already contain this subject.");
+            }
+
+            await using var transaction = await _context.Database.BeginTransactionAsync();
+            try
+            {
+                // The mapping rows must go first; their foreign keys would block the delete.
+                var prereqs = await _context.DependencySubjects
+                    .Where(d => d.SubjectId == subjectId || d.DependencyId == subjectId)
+                    .ToListAsync();
+                _context.DependencySubjects.RemoveRange(prereqs);
+
+                var majors = await _context.MajorSubjects
+                    .Where(ms => ms.SubjectId == subjectId).ToListAsync();
+                _context.MajorSubjects.RemoveRange(majors);
+
+                var teaching = await _context.ProfessorSubjects
+                    .Where(ps => ps.SubjectId == subjectId).ToListAsync();
+                _context.ProfessorSubjects.RemoveRange(teaching);
+
+                _context.Subjects.Remove(subject);
+                await _context.SaveChangesAsync();
+                await transaction.CommitAsync();
+
+                return Ok($"Subject '{subject.Name}' deleted.");
+            }
+            catch
+            {
+                await transaction.RollbackAsync();
+                throw;
+            }
+        }
+
+        public async Task<AdminResultDto> LinkMajorAsync(int subjectId, MajorLinkDto request)
+        {
+            if (!await _context.Subjects.AnyAsync(s => s.Id == subjectId))
+                return Fail("Subject not found.");
+            if (!await _context.Majors.AnyAsync(m => m.Id == request.MajorId))
+                return Fail("Study programme not found.");
+            if (request.MandatorySemester < 1)
+                return Fail("Semester must be 1 or greater.");
+
+            var existing = await _context.MajorSubjects
+                .FirstOrDefaultAsync(ms => ms.SubjectId == subjectId && ms.MajorId == request.MajorId);
+
+            if (existing is not null)
+            {
+                existing.MandatorySemester = request.MandatorySemester;
+                await _context.SaveChangesAsync();
+                return Ok("Study programme mapping updated.");
+            }
+
+            _context.MajorSubjects.Add(new MajorSubjects
+            {
+                SubjectId = subjectId,
+                MajorId = request.MajorId,
+                MandatorySemester = request.MandatorySemester
+            });
+            await _context.SaveChangesAsync();
+            return Ok("Subject added to the study programme.");
+        }
+
+        public async Task<AdminResultDto> UnlinkMajorAsync(int subjectId, int majorId)
+        {
+            var row = await _context.MajorSubjects
+                .FirstOrDefaultAsync(ms => ms.SubjectId == subjectId && ms.MajorId == majorId);
+            if (row is null) return Fail("That subject is not in that study programme.");
+
+            _context.MajorSubjects.Remove(row);
+            await _context.SaveChangesAsync();
+            return Ok("Subject removed from the study programme.");
+        }
+
+        public async Task<AdminResultDto> AddPrerequisiteAsync(int subjectId, PrerequisiteDto request)
+        {
+            if (subjectId == request.DependencyId)
+            {
+                // Mirrors CHECK (subject_id <> dependency_id).
+                return Fail("A subject cannot be its own prerequisite.");
+            }
+            if (!await _context.Subjects.AnyAsync(s => s.Id == subjectId))
+                return Fail("Subject not found.");
+            if (!await _context.Subjects.AnyAsync(s => s.Id == request.DependencyId))
+                return Fail("Prerequisite subject not found.");
+            if (await _context.DependencySubjects.AnyAsync(
+                    d => d.SubjectId == subjectId && d.DependencyId == request.DependencyId))
+                return Fail("That prerequisite is already set.");
+
+            // Refuse a direct cycle: A requires B while B already requires A.
+            if (await _context.DependencySubjects.AnyAsync(
+                    d => d.SubjectId == request.DependencyId && d.DependencyId == subjectId))
+                return Fail("That would create a circular prerequisite.");
+
+            _context.DependencySubjects.Add(new DependencySubject
+            {
+                SubjectId = subjectId,
+                DependencyId = request.DependencyId
+            });
+            await _context.SaveChangesAsync();
+            return Ok("Prerequisite added.");
+        }
+
+        public async Task<AdminResultDto> RemovePrerequisiteAsync(int subjectId, int dependencyId)
+        {
+            var row = await _context.DependencySubjects
+                .FirstOrDefaultAsync(d => d.SubjectId == subjectId && d.DependencyId == dependencyId);
+            if (row is null) return Fail("That prerequisite is not set.");
+
+            _context.DependencySubjects.Remove(row);
+            await _context.SaveChangesAsync();
+            return Ok("Prerequisite removed.");
+        }
+
+        // ============================================================
+        //  UC013 - active semesters
+        // ============================================================
+
+        public async Task<List<AdminSemesterDto>> GetSemestersAsync()
+        {
+            var semesters = await _context.ActiveSemesters.AsNoTracking().ToListAsync();
+            var subjects = await _context.Subjects.AsNoTracking().ToListAsync();
+            var teaching = await _context.ProfessorSubjects.AsNoTracking().ToListAsync();
+
+            var enrolments = await _context.EnrolledSemesters.AsNoTracking()
+                .GroupBy(es => es.SemesterId)
+                .Select(g => new { SemesterId = g.Key, Count = g.Count() })
+                .ToDictionaryAsync(x => x.SemesterId, x => x.Count);
+
+            return semesters
+                .OrderByDescending(s => s.Year)
+                .ThenByDescending(s => s.Type == sType.summer)
+                .Select(s =>
+                {
+                    var covered = teaching
+                        .Where(t => t.SemesterId == s.Id)
+                        .Select(t => t.SubjectId)
+                        .ToHashSet();
+
+                    return new AdminSemesterDto
+                    {
+                        Id = s.Id,
+                        Year = s.Year,
+                        Type = s.Type.ToString(),
+                        Name = SemesterName(s),
+                        EnrolmentCount = enrolments.TryGetValue(s.Id, out var c) ? c : 0,
+                        UncoveredSubjects = subjects
+                            .Where(sub => !covered.Contains(sub.Id))
+                            .OrderBy(sub => sub.Code)
+                            .Select(sub => new SubjectRefDto { Id = sub.Id, Name = sub.Name, Code = sub.Code })
+                            .ToList()
+                    };
+                })
+                .ToList();
+        }
+
+        public async Task<AdminResultDto> CreateSemesterAsync(SemesterWriteDto request)
+        {
+            if (!Enum.TryParse<sType>(request.Type, ignoreCase: true, out var type))
+            {
+                return Fail("Semester type must be 'winter' or 'summer'.");
+            }
+            if (request.Year < 2000 || request.Year > 2100)
+            {
+                return Fail("Year looks wrong; expected something between 2000 and 2100.");
+            }
+            // active_semesters has UNIQUE (year, type).
+            if (await _context.ActiveSemesters.AnyAsync(a => a.Year == request.Year && a.Type == type))
+            {
+                return Fail("That semester is already open.");
+            }
+
+            var semester = new ActiveSemesters { Year = request.Year, Type = type };
+            _context.ActiveSemesters.Add(semester);
+            await _context.SaveChangesAsync();
+
+            return Ok($"Semester {SemesterName(semester)} opened.", semester.Id);
+        }
+
+        // ============================================================
+        //  UC014 - professor assignments
+        // ============================================================
+
+        public async Task<ScheduleDto?> GetScheduleAsync(int semesterId)
+        {
+            var semester = await _context.ActiveSemesters.AsNoTracking()
+                .FirstOrDefaultAsync(a => a.Id == semesterId);
+            if (semester is null) return null;
+
+            var subjects = await _context.Subjects.AsNoTracking().ToListAsync();
+            var professors = await _context.User.AsNoTracking()
+                .Where(u => u.Role == Models.UserRole.Professor).ToListAsync();
+            var assignments = await _context.ProfessorSubjects.AsNoTracking()
+                .Where(ps => ps.SemesterId == semesterId).ToListAsync();
+
+            var subjectById = subjects.ToDictionary(s => s.Id);
+            var profById = professors.ToDictionary(p => p.Id);
+            var covered = assignments.Select(a => a.SubjectId).ToHashSet();
+
+            return new ScheduleDto
+            {
+                SemesterId = semester.Id,
+                SemesterName = SemesterName(semester),
+                Assignments = assignments
+                    .Where(a => subjectById.ContainsKey(a.SubjectId) && profById.ContainsKey(a.ProfessorId))
+                    .Select(a => new ScheduleRowDto
+                    {
+                        SubjectId = a.SubjectId,
+                        SubjectName = subjectById[a.SubjectId].Name,
+                        SubjectCode = subjectById[a.SubjectId].Code,
+                        ProfessorId = a.ProfessorId,
+                        ProfessorName = $"{profById[a.ProfessorId].Name} {profById[a.ProfessorId].Surname}".Trim()
+                    })
+                    .OrderBy(r => r.SubjectCode)
+                    .ToList(),
+                Load = professors
+                    .Select(p => new ProfessorLoadDto
+                    {
+                        ProfessorId = p.Id,
+                        ProfessorName = $"{p.Name} {p.Surname}".Trim(),
+                        Subjects = assignments.Count(a => a.ProfessorId == p.Id)
+                    })
+                    .OrderByDescending(l => l.Subjects).ThenBy(l => l.ProfessorName)
+                    .ToList(),
+                UncoveredSubjects = subjects
+                    .Where(s => !covered.Contains(s.Id))
+                    .OrderBy(s => s.Code)
+                    .Select(s => new SubjectRefDto { Id = s.Id, Name = s.Name, Code = s.Code })
+                    .ToList(),
+                AllSubjects = subjects
+                    .OrderBy(s => s.Code)
+                    .Select(s => new SubjectRefDto { Id = s.Id, Name = s.Name, Code = s.Code })
+                    .ToList(),
+                Professors = professors
+                    .OrderBy(p => p.Surname)
+                    .Select(p => new ProfessorRefDto { Id = p.Id, Name = $"{p.Name} {p.Surname}".Trim() })
+                    .ToList()
+            };
+        }
+
+        public async Task<AdminResultDto> AssignAsync(ScheduleWriteDto request)
+        {
+            var professor = await _context.User
+                .FirstOrDefaultAsync(u => u.Id == request.ProfessorId);
+            if (professor is null) return Fail("Professor not found.");
+            if (professor.Role != Models.UserRole.Professor)
+                return Fail("That user is not a professor.");
+            if (!await _context.ActiveSemesters.AnyAsync(a => a.Id == request.SemesterId))
+                return Fail("Semester not found.");
+            if (!await _context.Subjects.AnyAsync(s => s.Id == request.SubjectId))
+                return Fail("Subject not found.");
+
+            var exists = await _context.ProfessorSubjects.AnyAsync(
+                ps => ps.ProfessorId == request.ProfessorId
+                   && ps.SemesterId == request.SemesterId
+                   && ps.SubjectId == request.SubjectId);
+            if (exists) return Ok("That assignment already exists.");
+
+            _context.ProfessorSubjects.Add(new ProfessorSubjects
+            {
+                ProfessorId = request.ProfessorId,
+                SemesterId = request.SemesterId,
+                SubjectId = request.SubjectId
+            });
+            await _context.SaveChangesAsync();
+            return Ok("Professor assigned to the subject.");
+        }
+
+        public async Task<AdminResultDto> UnassignAsync(ScheduleWriteDto request)
+        {
+            var row = await _context.ProfessorSubjects.FirstOrDefaultAsync(
+                ps => ps.ProfessorId == request.ProfessorId
+                   && ps.SemesterId == request.SemesterId
+                   && ps.SubjectId == request.SubjectId);
+            if (row is null) return Fail("That assignment does not exist.");
+
+            _context.ProfessorSubjects.Remove(row);
+            await _context.SaveChangesAsync();
+            return Ok("Assignment removed.");
+        }
+
+        public async Task<List<SubjectRefDto>> GetMajorsAsync() =>
+            await _context.Majors.AsNoTracking()
+                .OrderBy(m => m.Name)
+                .Select(m => new SubjectRefDto { Id = m.Id, Name = m.Name, Code = null })
+                .ToListAsync();
+
+        private static AdminResultDto Ok(string message, int? id = null) =>
+            new() { Ok = true, Message = message, Id = id };
+
+        private static AdminResultDto Fail(string message) =>
+            new() { Ok = false, Message = message };
+    }
+}
Index: iknow-api/Services/Implementations/AuthService.cs
===================================================================
--- iknow-api/Services/Implementations/AuthService.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Services/Implementations/AuthService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -1,3 +1,3 @@
-﻿using System.IdentityModel.Tokens.Jwt;
+using System.IdentityModel.Tokens.Jwt;
 using System.Security.Claims;
 using System.Text;
@@ -51,19 +51,19 @@
             try
             {
+                // quota and enrollment_year are attributes of Users in the ER
+                // model, so they are set here rather than on a separate entity.
                 var user = new User
                 {
                     Name = registerDto.Name,
-                    MiddleName = registerDto.MiddleName,
                     Surname = registerDto.Surname,
                     Index = registerDto.Index,
                     Email = registerDto.Email,
                     PasswordHash = BCrypt.Net.BCrypt.HashPassword(registerDto.Password),
-                    Bday = DateTime.SpecifyKind(registerDto.Bday, DateTimeKind.Utc),
-                    CreatedAt = DateTime.UtcNow,
+                    Bday = DateTime.SpecifyKind(registerDto.Bday, DateTimeKind.Unspecified),
+                    CreatedAt = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified),
                     Role = (Models.UserRole)registerDto.Role,
                     EMBG = registerDto.EMBG,
-                    Nationality = registerDto.nationality,
-                    Citizenship = registerDto.citizenship,
-                    Gender = registerDto.gender
+                    Quota = (Models.Quota)registerDto.quotaType,
+                    EnrollmentYear = registerDto.enrollmentYear
                 };
 
@@ -83,14 +83,4 @@
                 };
                 
-                var enrollmentInfo = new EnrollmentInfo
-                {
-                    UserId = userId,
-                    EnrollmentYear = registerDto.enrollmentYear,
-                    Quota = (Models.Quota)registerDto.quotaType,
-                    MajorId = registerDto.majorType,
-                    StudyStatus = registerDto.studyStatus,
-                    StudyType = registerDto.studyType
-                };
-                
                 var highSchool = new HighSchool
                 {
@@ -101,5 +91,4 @@
 
                 _context.ContactInfo.Add(contactInfo);
-                _context.EnrollmentInfo.Add(enrollmentInfo);
                 _context.HighSchool.Add(highSchool);
                 
Index: iknow-api/Services/Implementations/EnrollmentService.cs
===================================================================
--- iknow-api/Services/Implementations/EnrollmentService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Services/Implementations/EnrollmentService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,232 @@
+using iknow_api.Data;
+using iknow_api.DTOs;
+using iknow_api.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace iknow_api.Services
+{
+    public class EnrollmentService : IEnrollmentService
+    {
+        /// <summary>An enrolment is exactly this many subjects.</summary>
+        public const int RequiredSubjects = 5;
+
+        private readonly AppDbContext _context;
+
+        public EnrollmentService(AppDbContext context)
+        {
+            _context = context;
+        }
+
+        public async Task<EnrollmentOptionsDto> GetOptionsAsync(int studentId)
+        {
+            var enrolments = await _context.EnrolledSemesters
+                .AsNoTracking()
+                .Include(es => es.Semester)
+                .Where(es => es.UserId == studentId)
+                .ToListAsync();
+
+            var takenSemesterIds = enrolments.Select(es => es.SemesterId).ToHashSet();
+
+            var available = await _context.ActiveSemesters
+                .AsNoTracking()
+                .Where(a => !takenSemesterIds.Contains(a.Id))
+                .ToListAsync();
+
+            // Semesters are labelled Year/Year+1, so within a year winter comes first.
+            var semesters = available
+                .OrderBy(a => a.Year)
+                .ThenBy(a => a.Type == sType.summer)
+                .Select(a => new SemesterOptionDto
+                {
+                    Id = a.Id,
+                    Year = a.Year,
+                    Type = a.Type.ToString(),
+                    Name = $"{(a.Type == sType.winter ? "Зимски" : "Летен")}({a.Year}/{a.Year + 1})"
+                })
+                .ToList();
+
+            var passedSubjectIds = await _context.PassedSubjects
+                .AsNoTracking()
+                .Where(ps => ps.SemesterSubject!.EnrolledSemester!.UserId == studentId)
+                .Select(ps => ps.SemesterSubject!.SubjectId)
+                .ToListAsync();
+            var passed = passedSubjectIds.ToHashSet();
+
+            var majorRows = await _context.MajorSubjects
+                .AsNoTracking()
+                .Include(ms => ms.Majors)
+                .Include(ms => ms.Subjects)
+                .ToListAsync();
+
+            var majors = majorRows
+                .Where(ms => ms.Majors != null && ms.Subjects != null)
+                .GroupBy(ms => ms.Majors!.Id)
+                .Select(g => new MajorOptionDto
+                {
+                    Id = g.Key,
+                    Name = g.First().Majors!.Name,
+                    Subjects = g
+                        .Select(ms => new SubjectOptionDto
+                        {
+                            Id = ms.Subjects!.Id,
+                            Name = ms.Subjects.Name,
+                            Code = ms.Subjects.Code,
+                            Credits = ms.Subjects.AwardedCredits ?? 0,
+                            MandatorySemester = ms.MandatorySemester,
+                            AlreadyPassed = passed.Contains(ms.Subjects.Id)
+                        })
+                        .OrderBy(x => x.MandatorySemester)
+                        .ThenBy(x => x.Name)
+                        .ToList()
+                })
+                .OrderBy(m => m.Name)
+                .ToList();
+
+            var latest = enrolments
+                .Where(es => es.Semester != null)
+                .OrderByDescending(es => es.Semester!.Year)
+                .ThenByDescending(es => es.Semester!.Type == sType.summer)
+                .FirstOrDefault();
+
+            return new EnrollmentOptionsDto
+            {
+                RequiredSubjects = RequiredSubjects,
+                Semesters = semesters,
+                Majors = majors,
+                DefaultMajorId = latest?.MajorId
+            };
+        }
+
+        public async Task<EnrollSemesterResultDto> EnrollAsync(
+            int studentId, EnrollSemesterRequestDto request)
+        {
+            var subjectIds = request.SubjectIds?.Distinct().ToList() ?? new List<int>();
+
+            if (subjectIds.Count != RequiredSubjects)
+            {
+                return Fail($"Pick exactly {RequiredSubjects} different subjects; got {subjectIds.Count}.");
+            }
+
+            if (!await _context.ActiveSemesters.AnyAsync(a => a.Id == request.SemesterId))
+            {
+                return Fail("That semester does not exist.");
+            }
+
+            // enrolled_semesters has UNIQUE (user_id, semester_id); check first so
+            // the student gets a sentence rather than a constraint violation.
+            if (await _context.EnrolledSemesters.AnyAsync(
+                    es => es.UserId == studentId && es.SemesterId == request.SemesterId))
+            {
+                return Fail("You are already enrolled in that semester.");
+            }
+
+            if (!await _context.Majors.AnyAsync(m => m.Id == request.MajorId))
+            {
+                return Fail("That study programme does not exist.");
+            }
+
+            var offered = await _context.MajorSubjects
+                .Where(ms => ms.MajorId == request.MajorId)
+                .Select(ms => ms.SubjectId)
+                .ToListAsync();
+
+            var notOffered = subjectIds.Except(offered).ToList();
+            if (notOffered.Count > 0)
+            {
+                return Fail($"Subject(s) {string.Join(", ", notOffered)} are not offered by that study programme.");
+            }
+
+            // semesters_subjects.professor_id is NOT NULL, so every chosen subject
+            // needs somebody teaching it that semester.
+            var teachers = await _context.ProfessorSubjects
+                .Where(ps => ps.SemesterId == request.SemesterId && subjectIds.Contains(ps.SubjectId))
+                .ToListAsync();
+
+            // A subject can be taught by more than one professor in the same
+            // semester. Spread students over them instead of always taking the
+            // lowest id, which would leave the other professor with nobody.
+            var currentLoad = await _context.SemesterSubjects
+                .Where(ss => subjectIds.Contains(ss.SubjectId)
+                          && ss.EnrolledSemester!.SemesterId == request.SemesterId)
+                .GroupBy(ss => new { ss.SubjectId, ss.ProfessorId })
+                .Select(g => new { g.Key.SubjectId, g.Key.ProfessorId, Count = g.Count() })
+                .ToListAsync();
+
+            var loadLookup = currentLoad.ToDictionary(
+                x => (x.SubjectId, x.ProfessorId), x => x.Count);
+
+            var professorBySubject = teachers
+                .GroupBy(ps => ps.SubjectId)
+                .ToDictionary(
+                    g => g.Key,
+                    // Fewest students first; professor id only breaks ties, so
+                    // the choice stays deterministic and testable.
+                    g => g.OrderBy(ps => loadLookup.TryGetValue((ps.SubjectId, ps.ProfessorId), out var n) ? n : 0)
+                          .ThenBy(ps => ps.ProfessorId)
+                          .First().ProfessorId);
+
+            var untaught = subjectIds.Where(id => !professorBySubject.ContainsKey(id)).ToList();
+            if (untaught.Count > 0)
+            {
+                return Fail($"Subject(s) {string.Join(", ", untaught)} are not taught in that semester.");
+            }
+
+            var student = await _context.User.FirstOrDefaultAsync(u => u.Id == studentId);
+            if (student is null)
+            {
+                return Fail("Student not found.");
+            }
+
+            var now = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified);
+
+            await using var transaction = await _context.Database.BeginTransactionAsync();
+            try
+            {
+                var enrolment = new EnrolledSemesters
+                {
+                    UserId = studentId,
+                    SemesterId = request.SemesterId,
+                    MajorId = request.MajorId,
+                    // enrolled_semesters.quota is NOT NULL; fall back to the
+                    // state quota when the student record has none.
+                    QuotaType = student.Quota ?? Models.Quota.drzavna,
+                    CratedAt = now,
+                    LastChange = now,
+                    Verified = null
+                };
+
+                _context.EnrolledSemesters.Add(enrolment);
+                await _context.SaveChangesAsync();
+
+                foreach (var subjectId in subjectIds)
+                {
+                    _context.SemesterSubjects.Add(new SemesterSubject
+                    {
+                        EnrolledSemesterId = enrolment.Id,
+                        SubjectId = subjectId,
+                        ProfessorId = professorBySubject[subjectId],
+                        Signature = false
+                    });
+                }
+
+                await _context.SaveChangesAsync();
+                await transaction.CommitAsync();
+
+                return new EnrollSemesterResultDto
+                {
+                    Ok = true,
+                    Message = $"Enrolled with {subjectIds.Count} subjects.",
+                    EnrolledSemesterId = enrolment.Id
+                };
+            }
+            catch
+            {
+                await transaction.RollbackAsync();
+                throw;
+            }
+        }
+
+        private static EnrollSemesterResultDto Fail(string message) =>
+            new() { Ok = false, Message = message };
+    }
+}
Index: iknow-api/Services/Implementations/ProfService.cs
===================================================================
--- iknow-api/Services/Implementations/ProfService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Services/Implementations/ProfService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,122 @@
+using iknow_api.DTOs;
+using iknow_api.Models;
+using iknow_api.Repositories;
+
+namespace iknow_api.Services
+{
+    public class ProfService : IProfService
+    {
+        private readonly IProfRepository _profRepository;
+
+        public ProfService(IProfRepository profRepository)
+        {
+            _profRepository = profRepository;
+        }
+
+        public async Task<List<SubjectStudentsDto>> GetStudentsBySubjectAsync(int professorId)
+        {
+            var taught = await _profRepository.GetTaughtSemesterSubjectsAsync(professorId);
+
+            return taught
+                .Where(ss => ss.Subject != null && ss.EnrolledSemester?.User != null)
+                .GroupBy(ss => ss.Subject!.Id)
+                .Select(group =>
+                {
+                    var subject = group.First().Subject!;
+                    return new SubjectStudentsDto
+                    {
+                        Id = subject.Id,
+                        Name = subject.Name,
+                        Code = subject.Code,
+                        Users = group
+                            .Select(ss =>
+                            {
+                                var student = ss.EnrolledSemester!.User!;
+                                var semester = ss.EnrolledSemester.Semester;
+                                return new EnrolledStudentDto
+                                {
+                                    Id = student.Id,
+                                    Name = $"{student.Name} {student.Surname}".Trim(),
+                                    Index = student.Index,
+                                    // 0 means "not graded yet"; the enum starts at 6.
+                                    Grade = ss.PassedSubject is null ? 0 : (int)ss.PassedSubject.Grade,
+                                    Semester = semester is null
+                                        ? null
+                                        : $"{(semester.Type == sType.winter ? "Зимски" : "Летен")}({semester.Year}/{semester.Year + 1})"
+                                };
+                            })
+                            .OrderBy(u => u.Name)
+                            .ToList()
+                    };
+                })
+                .OrderBy(s => s.Name)
+                .ToList();
+        }
+
+        public async Task<GradeResultDto> SetGradeAsync(
+            int professorId, GradeRequestDto request, GradeAction action)
+        {
+            // grade_type only declares 6..10, so anything else cannot be stored.
+            if (action != GradeAction.Remove && !Enum.IsDefined(typeof(Grade), request.Grade))
+            {
+                return Fail($"Grade must be between 6 and 10; got {request.Grade}.");
+            }
+
+            // This also enforces authorisation: the lookup is scoped to the
+            // subjects this professor actually teaches.
+            var semesterSubject = await _profRepository.FindTaughtSemesterSubjectAsync(
+                professorId, request.StudentId, request.SubjectId);
+
+            if (semesterSubject is null)
+            {
+                return Fail("You do not teach this student in this subject.");
+            }
+
+            var existing = await _profRepository.GetPassedSubjectAsync(semesterSubject.Id);
+
+            switch (action)
+            {
+                case GradeAction.Add:
+                    if (existing is not null)
+                    {
+                        return Fail("This subject is already graded. Use edit to change the grade.");
+                    }
+                    await _profRepository.AddPassedSubjectAsync(new PassedSubject
+                    {
+                        SemesterSubjectId = semesterSubject.Id,
+                        Grade = (Grade)request.Grade,
+                        // date_passed is `timestamp without time zone`.
+                        DatePassed = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified)
+                    });
+                    return Ok($"Grade {request.Grade} added.");
+
+                case GradeAction.Edit:
+                    if (existing is null)
+                    {
+                        return Fail("This subject has no grade yet. Use add first.");
+                    }
+                    existing.Grade = (Grade)request.Grade;
+                    existing.DatePassed = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified);
+                    await _profRepository.UpdatePassedSubjectAsync(existing);
+                    return Ok($"Grade changed to {request.Grade}.");
+
+                case GradeAction.Remove:
+                    if (existing is null)
+                    {
+                        return Fail("This subject has no grade to remove.");
+                    }
+                    await _profRepository.RemovePassedSubjectAsync(existing);
+                    return Ok("Grade removed.");
+
+                default:
+                    return Fail("Unknown action.");
+            }
+        }
+
+        private static GradeResultDto Ok(string message) =>
+            new() { Ok = true, Message = message };
+
+        private static GradeResultDto Fail(string message) =>
+            new() { Ok = false, Message = message };
+    }
+}
Index: iknow-api/Services/Implementations/RefreshTokenService.cs
===================================================================
--- iknow-api/Services/Implementations/RefreshTokenService.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/Services/Implementations/RefreshTokenService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -31,5 +31,5 @@
                 Token = refreshToken,
                 UserId = userid,
-                ExpiresAt = DateTime.UtcNow.AddMonths(1),
+                ExpiresAt = DateTime.SpecifyKind(DateTime.UtcNow.AddMonths(1), DateTimeKind.Unspecified),
                 IsValid = true
             };
Index: iknow-api/Services/Interfaces/IAdminService.cs
===================================================================
--- iknow-api/Services/Interfaces/IAdminService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Services/Interfaces/IAdminService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,28 @@
+using iknow_api.DTOs;
+
+namespace iknow_api.Services
+{
+    public interface IAdminService
+    {
+        // UC012 - subjects
+        Task<List<AdminSubjectDto>> GetSubjectsAsync();
+        Task<AdminResultDto> CreateSubjectAsync(SubjectWriteDto request);
+        Task<AdminResultDto> UpdateSubjectAsync(int subjectId, SubjectWriteDto request);
+        Task<AdminResultDto> DeleteSubjectAsync(int subjectId);
+        Task<AdminResultDto> LinkMajorAsync(int subjectId, MajorLinkDto request);
+        Task<AdminResultDto> UnlinkMajorAsync(int subjectId, int majorId);
+        Task<AdminResultDto> AddPrerequisiteAsync(int subjectId, PrerequisiteDto request);
+        Task<AdminResultDto> RemovePrerequisiteAsync(int subjectId, int dependencyId);
+
+        // UC013 - active semesters
+        Task<List<AdminSemesterDto>> GetSemestersAsync();
+        Task<AdminResultDto> CreateSemesterAsync(SemesterWriteDto request);
+
+        // UC014 - professor assignments
+        Task<ScheduleDto?> GetScheduleAsync(int semesterId);
+        Task<AdminResultDto> AssignAsync(ScheduleWriteDto request);
+        Task<AdminResultDto> UnassignAsync(ScheduleWriteDto request);
+
+        Task<List<SubjectRefDto>> GetMajorsAsync();
+    }
+}
Index: iknow-api/Services/Interfaces/IEnrollmentService.cs
===================================================================
--- iknow-api/Services/Interfaces/IEnrollmentService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Services/Interfaces/IEnrollmentService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,16 @@
+using iknow_api.DTOs;
+
+namespace iknow_api.Services
+{
+    public interface IEnrollmentService
+    {
+        /// <summary>The semesters, majors and subjects this student may enrol in.</summary>
+        Task<EnrollmentOptionsDto> GetOptionsAsync(int studentId);
+
+        /// <summary>
+        /// Creates one enrolled_semesters row and its semesters_subjects rows,
+        /// or returns why it could not.
+        /// </summary>
+        Task<EnrollSemesterResultDto> EnrollAsync(int studentId, EnrollSemesterRequestDto request);
+    }
+}
Index: iknow-api/Services/Interfaces/IProfService.cs
===================================================================
--- iknow-api/Services/Interfaces/IProfService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/Services/Interfaces/IProfService.cs	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,18 @@
+using iknow_api.DTOs;
+
+namespace iknow_api.Services
+{
+    public enum GradeAction
+    {
+        Add,
+        Edit,
+        Remove
+    }
+
+    public interface IProfService
+    {
+        Task<List<SubjectStudentsDto>> GetStudentsBySubjectAsync(int professorId);
+
+        Task<GradeResultDto> SetGradeAsync(int professorId, GradeRequestDto request, GradeAction action);
+    }
+}
Index: iknow-api/WeatherForecast.cs
===================================================================
--- iknow-api/WeatherForecast.cs	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ 	(revision )
@@ -1,13 +1,0 @@
-namespace iknow_api
-{
-    public class WeatherForecast
-    {
-        public DateOnly Date { get; set; }
-
-        public int TemperatureC { get; set; }
-
-        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
-
-        public string? Summary { get; set; }
-    }
-}
Index: iknow-api/appsettings.Development.json.example
===================================================================
--- iknow-api/appsettings.Development.json.example	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
+++ iknow-api/appsettings.Development.json.example	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -0,0 +1,14 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  },
+  "ConnectionStrings": {
+    "DefaultConnection": "Host=localhost;Port=9999;Database=db_202526z_va_prj_know2026;Username=db_202526z_va_prj_iknow2026_owner;Password=YOUR_DB_PASSWORD_HERE;Search Path=project;Include Error Detail=true"
+  },
+  "Jwt": {
+    "Key": "ANY_LOCAL_SIGNING_KEY_AT_LEAST_32_CHARACTERS_LONG"
+  }
+}
Index: iknow-api/appsettings.json
===================================================================
--- iknow-api/appsettings.json	(revision 10009b9505124c201c365c19c07a9df40b091035)
+++ iknow-api/appsettings.json	(revision ea405569ef29f56fbfc4d77708b6b3faf9286097)
@@ -10,9 +10,4 @@
     "https://iknow-remaster.vercel.app"
   ],
-  "ConnectionStrings": {
-    "DefaultConnection": "Host=ep-divine-term-aghfotgc-pooler.c-2.eu-central-1.aws.neon.tech; Database=neondb; Username=neondb_owner; Password=npg_SxbBZmtw4I7P; SSL Mode=VerifyFull; Channel Binding=Require;"
-  },
-  "Jwt": {
-    "Key": "YourSecretKeyHereMustBeAtLeast32CharactersLongForHS256Algorithm"
-  }
+  "AllowedHosts": "*"
 }
